This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: case ranges in C++ (extension)


Hi,

On Tue, 27 Jan 2004, Mark Mitchell wrote:

> > still accepts it.  Would reimplementing this be accepted?
> >  
> Yes.

See below.  I survives building the libraries and C and C++ checking 
without changes in results.

I tested it with this program:
--------------------
// #define ERROR

const int low = -2;
const int high = 15;

template <typename T>
T f2 (T i)
{
  switch (i)
  {
    case low ... high : return i + 1;
#ifdef ERROR
    case 5 : return i + 2;
    case 6 ... 8 : return i + 3;
#endif
    default : return 0;
  }
}

int f (int i)
{
  switch (i) {
    case 1 ... 10: return i + 1;
#ifdef ERROR
    case 2 : return i + 2;
    case 3 ... 5 : return i + 3;
#endif
    default: return f2 (i);
  }
}
--------------------

(with and without -DERROR, which then gives correct diagnostics).  With 
-pedantic the common code already throws a pedwarn as expected.


Ciao,
Michael.
-- 
        * parser.c (cp_parser_labeled_statement): Accept case ranges.

Index: cp/parser.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/parser.c,v
retrieving revision 1.163
diff -u -p -r1.163 parser.c
--- cp/parser.c	29 Jan 2004 04:23:37 -0000	1.163
+++ cp/parser.c	29 Jan 2004 19:13:16 -0000
@@ -5472,7 +5472,10 @@ cp_parser_statement (cp_parser* parser, 
    labeled-statement:
      identifier : statement
      case constant-expression : statement
-     default : statement  
+     case constant-expression ... constant-expression : statement
+     default : statement
+
+   Accepting a range (with ...) is an extension.
 
    Returns the new CASE_LABEL, for a `case' or `default' label.  For
    an ordinary label, returns a LABEL_STMT.  */
@@ -5496,7 +5499,8 @@ cp_parser_labeled_statement (cp_parser* 
     {
     case RID_CASE:
       {
-	tree expr;
+	tree expr, expr_hi;
+	cp_token *ellipsis;
 
 	/* Consume the `case' token.  */
 	cp_lexer_consume_token (parser->lexer);
@@ -5504,10 +5508,26 @@ cp_parser_labeled_statement (cp_parser* 
 	expr = cp_parser_constant_expression (parser, 
 					      /*allow_non_constant_p=*/false,
 					      NULL);
+
+	ellipsis = cp_lexer_peek_token (parser->lexer);
+	if (ellipsis->type == CPP_ELLIPSIS)
+	  {
+            /* Consume the `...' token.  */
+	    cp_lexer_consume_token (parser->lexer);
+	    expr_hi =
+	      cp_parser_constant_expression (parser,
+	    				     /*allow_non_constant_p=*/false,
+					     NULL);
+	    /* We don't need to emit warnings here, as the common code
+	       will do this for us.  */
+	  }
+	else
+	  expr_hi = NULL_TREE;
+
 	if (!parser->in_switch_statement_p)
 	  error ("case label `%E' not within a switch statement", expr);
 	else
-	  statement = finish_case_label (expr, NULL_TREE);
+	  statement = finish_case_label (expr, expr_hi);
       }
       break;
 


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]