decl.c (build_enumerator): Use add_double and int_fits_type_p instead of cp_build_bin...
authorZack Weinberg <zack@gcc.gnu.org>
Mon, 6 Sep 2004 17:38:18 +0000 (17:38 +0000)
committerZack Weinberg <zack@gcc.gnu.org>
Mon, 6 Sep 2004 17:38:18 +0000 (17:38 +0000)
cp:
* decl.c (build_enumerator): Use add_double and int_fits_type_p
instead of cp_build_binary_op, to avoid creating short-lived trees.
* parser.c (cp_parse_type_specifier <RID_ENUM>): Use two-token
lookahead instead of backtracking.  Move some code to avoid a
conditional branch.
(cp_parser_enum_specifier): Avoid duplication of effort with caller.
Use cp_lexer_next_token_is/cp_lexer_next_token_is_not as appropriate.
(cp_parser_enumerator_list, cp_parser_enumerator_definition):
Use cp_lexer_next_token_is/cp_lexer_next_token_is_not as appropriate.
testsuite:
* g++.old-deja/g++.other/enum2.C: Move dg-error markers to
reflect changed line numbering of diagnostics.

From-SVN: r87121

gcc/cp/ChangeLog
gcc/cp/decl.c
gcc/cp/parser.c
gcc/testsuite/ChangeLog
gcc/testsuite/g++.old-deja/g++.other/enum2.C

index 32a1b7eb372fde31b9efddfdf3cbbee547f96c17..fd9b97d66775a2f616335a5acdb750ea71d97f8c 100644 (file)
@@ -1,3 +1,15 @@
+2004-09-06  Zack Weinberg  <zack@codesourcery.com>
+
+       * decl.c (build_enumerator): Use add_double and int_fits_type_p
+       instead of cp_build_binary_op, to avoid creating short-lived trees.
+       * parser.c (cp_parse_type_specifier <RID_ENUM>): Use two-token
+       lookahead instead of backtracking.  Move some code to avoid a
+       conditional branch.
+       (cp_parser_enum_specifier): Avoid duplication of effort with caller.
+       Use cp_lexer_next_token_is/cp_lexer_next_token_is_not as appropriate.
+       (cp_parser_enumerator_list, cp_parser_enumerator_definition):
+       Use cp_lexer_next_token_is/cp_lexer_next_token_is_not as appropriate.
+
 2004-09-04  Kriang Lerdsuwanakij  <lerdsuwa@users.sourceforge.net>
 
        * decl.c (grok_declarator): Remove a redundant semicolon.
@@ -17,7 +29,7 @@
        define a stub macro that expands to NULL.
        (cp_lexer_new_main): Only set debugging_p if ENABLE_CHECKING set.
        (cp_lexer_new_from_tokens): Likewise.
-       
+
 2004-09-03  Jan Hubicka  <jh@suse.cz>
 
        * decl.c (finish_function): Clean out pointers we no longer need.
@@ -36,7 +48,7 @@
 
        * cp-tree.h (DECL_CONSTRUCTION_VTABLE_P): New macro.
        * class.c (build_ctor_vtbl_group): Set DECL_CONSTRUCTION_VTABLE_P.
-       * decl2.c (determine_visibility): Honor 
+       * decl2.c (determine_visibility): Honor
        TARGET_CXX_EXPORT_CLASS_DATA.
 
        * class.c (key_method): Rename to ...
@@ -76,7 +88,7 @@
        LANG_HOOKS_ATTRIBUTE_TABLE, LANG_HOOKS_TREE_INLINING_WALK_SUBTREES,
        LANG_HOOKS_TREE_INLINING_CANNOT_INLINE_TREE_FN,
        LANG_HOOKS_TREE_INLINING_ADD_PENDING_FN_DECLS,
-       LANG_HOOKS_TREE_INLINING_AUTO_VAR_IN_FN_P, 
+       LANG_HOOKS_TREE_INLINING_AUTO_VAR_IN_FN_P,
        LANG_HOOKS_TREE_INLINING_ANON_AGGR_TYPE_P,
        LANG_HOOKS_TREE_INLINING_VAR_MOD_TYPE_P,
        LANG_HOOKS_TREE_DUMP_DUMP_TREE_FN,
        * cp-tree.h (cp_finish_file): New prototype.
        * decl.c: Do not include gtype-cp.h.
        * decl2.c (finish_file): Rename to cp_finish_file.
-       
+
 2004-08-31  Richard Henderson  <rth@redhat.com>
 
        PR c++/17221
        build_dynamic_cast_1, ptr_initializer, ptm_initializer,
        get_pseudo_ti_init): Likewise.
        * search.c (get_dynamic_cast_base_type): Likewise.
-       
+
 2004-08-25  Zack Weinberg  <zack@codesourcery.com>
 
        * class.c, search.c: Remove references to DWARF_DEBUG.
index 607b907078d8c914c862a9da5a7602df2f1cca43..5cb43d2b3705d6be1c99594770a424d895eb3c02 100644 (file)
@@ -9520,18 +9520,25 @@ build_enumerator (tree name, tree value, tree enumtype)
       /* Default based on previous value.  */
       if (value == NULL_TREE)
        {
-         tree prev_value;
-
          if (TYPE_VALUES (enumtype))
            {
-             /* The next value is the previous value ...  */
+             HOST_WIDE_INT hi;
+             unsigned HOST_WIDE_INT lo;
+             tree prev_value;
+             bool overflowed;
+
+             /* The next value is the previous value plus one.  We can
+                safely assume that the previous value is an INTEGER_CST.
+                add_double doesn't know the type of the target expression,
+                so we must check with int_fits_type_p as well.  */
              prev_value = DECL_INITIAL (TREE_VALUE (TYPE_VALUES (enumtype)));
-             /* ... plus one.  */
-             value = cp_build_binary_op (PLUS_EXPR,
-                                         prev_value,
-                                         integer_one_node);
+             overflowed = add_double (TREE_INT_CST_LOW (prev_value),
+                                      TREE_INT_CST_HIGH (prev_value),
+                                      1, 0, &lo, &hi);
+             value = build_int_cst_wide (TREE_TYPE (prev_value), lo, hi);
+             overflowed |= !int_fits_type_p (value, TREE_TYPE (prev_value));
 
-             if (tree_int_cst_lt (value, prev_value))
+             if (overflowed)
                error ("overflow in enumeration values at `%D'", name);
            }
          else
index 45eb20aa4659d4b8365cf0e7c7776e01dc244046..6d56f976c62b6426cbaa1e76c27bd417459ebbe9 100644 (file)
@@ -9265,21 +9265,36 @@ cp_parser_type_specifier (cp_parser* parser,
   keyword = token->keyword;
   switch (keyword)
     {
+    case RID_ENUM:
+      /* 'enum' [identifier] '{' introduces an enum-specifier;
+        'enum' <anything else> introduces an elaborated-type-specifier.  */
+      if (cp_lexer_peek_nth_token (parser->lexer, 2)->type == CPP_OPEN_BRACE
+         || (cp_lexer_peek_nth_token (parser->lexer, 2)->type == CPP_NAME
+             && cp_lexer_peek_nth_token (parser->lexer, 3)->type
+                == CPP_OPEN_BRACE))
+       {
+         type_spec = cp_parser_enum_specifier (parser);
+         if (declares_class_or_enum)
+           *declares_class_or_enum = 2;
+         if (decl_specs)
+           cp_parser_set_decl_spec_type (decl_specs,
+                                         type_spec,
+                                         /*user_defined_p=*/true);
+         return type_spec;
+       }
+      else
+       goto elaborated_type_specifier;
+
       /* Any of these indicate either a class-specifier, or an
         elaborated-type-specifier.  */
     case RID_CLASS:
     case RID_STRUCT:
     case RID_UNION:
-    case RID_ENUM:
       /* Parse tentatively so that we can back up if we don't find a
-        class-specifier or enum-specifier.  */
+        class-specifier.  */
       cp_parser_parse_tentatively (parser);
-      /* Look for the class-specifier or enum-specifier.  */
-      if (keyword == RID_ENUM)
-       type_spec = cp_parser_enum_specifier (parser);
-      else
-       type_spec = cp_parser_class_specifier (parser);
-
+      /* Look for the class-specifier.  */
+      type_spec = cp_parser_class_specifier (parser);
       /* If that worked, we're done.  */
       if (cp_parser_parse_definitely (parser))
        {
@@ -9293,7 +9308,12 @@ cp_parser_type_specifier (cp_parser* parser,
        }
 
       /* Fall through.  */
+    elaborated_type_specifier:
+      /* We're declaring (not defining) a class or enum.  */
+      if (declares_class_or_enum)
+       *declares_class_or_enum = 1;
 
+      /* Fall through.  */
     case RID_TYPENAME:
       /* Look for an elaborated-type-specifier.  */
       type_spec
@@ -9301,10 +9321,6 @@ cp_parser_type_specifier (cp_parser* parser,
           (parser,
            decl_specs && decl_specs->specs[(int) ds_friend],
            is_declaration));
-      /* We're declaring a class or enum -- unless we're using
-        `typename'.  */
-      if (declares_class_or_enum && keyword != RID_TYPENAME)
-       *declares_class_or_enum = 1;
       if (decl_specs)
        cp_parser_set_decl_spec_type (decl_specs,
                                      type_spec,
@@ -9906,40 +9922,33 @@ cp_parser_elaborated_type_specifier (cp_parser* parser,
 static tree
 cp_parser_enum_specifier (cp_parser* parser)
 {
-  cp_token *token;
-  tree identifier = NULL_TREE;
+  tree identifier;
   tree type;
 
-  /* Look for the `enum' keyword.  */
-  if (!cp_parser_require_keyword (parser, RID_ENUM, "`enum'"))
-    return error_mark_node;
-  /* Peek at the next token.  */
-  token = cp_lexer_peek_token (parser->lexer);
+  /* Caller guarantees that the current token is 'enum', an identifier
+     possibly follows, and the token after that is an opening brace.
+     If we don't have an identifier, fabricate an anonymous name for
+     the enumeration being defined.  */
+  cp_lexer_consume_token (parser->lexer);
 
-  /* See if it is an identifier.  */
-  if (token->type == CPP_NAME)
+  if (cp_lexer_next_token_is (parser->lexer, CPP_NAME))
     identifier = cp_parser_identifier (parser);
+  else
+    identifier = make_anon_name ();
 
-  /* Look for the `{'.  */
-  if (!cp_parser_require (parser, CPP_OPEN_BRACE, "`{'"))
-    return error_mark_node;
-
-  /* At this point, we're going ahead with the enum-specifier, even
-     if some other problem occurs.  */
-  cp_parser_commit_to_tentative_parse (parser);
+  cp_lexer_consume_token (parser->lexer);
 
   /* Issue an error message if type-definitions are forbidden here.  */
   cp_parser_check_type_definition (parser);
 
   /* Create the new type.  */
-  type = start_enum (identifier ? identifier : make_anon_name ());
+  type = start_enum (identifier);
 
-  /* Peek at the next token.  */
-  token = cp_lexer_peek_token (parser->lexer);
-  /* If it's not a `}', then there are some enumerators.  */
-  if (token->type != CPP_CLOSE_BRACE)
+  /* If the next token is not '}', then there are some enumerators.  */
+  if (cp_lexer_next_token_is_not (parser->lexer, CPP_CLOSE_BRACE))
     cp_parser_enumerator_list (parser, type);
-  /* Look for the `}'.  */
+
+  /* Consume the final '}'.  */
   cp_parser_require (parser, CPP_CLOSE_BRACE, "`}'");
 
   /* Finish up the enumeration.  */
@@ -9960,15 +9969,12 @@ cp_parser_enumerator_list (cp_parser* parser, tree type)
 {
   while (true)
     {
-      cp_token *token;
-
       /* Parse an enumerator-definition.  */
       cp_parser_enumerator_definition (parser, type);
-      /* Peek at the next token.  */
-      token = cp_lexer_peek_token (parser->lexer);
-      /* If it's not a `,', then we've reached the end of the
-        list.  */
-      if (token->type != CPP_COMMA)
+
+      /* If the next token is not a ',', we've reached the end of
+        the list.  */
+      if (cp_lexer_next_token_is_not (parser->lexer, CPP_COMMA))
        break;
       /* Otherwise, consume the `,' and keep going.  */
       cp_lexer_consume_token (parser->lexer);
@@ -9995,7 +10001,6 @@ cp_parser_enumerator_list (cp_parser* parser, tree type)
 static void
 cp_parser_enumerator_definition (cp_parser* parser, tree type)
 {
-  cp_token *token;
   tree identifier;
   tree value;
 
@@ -10004,10 +10009,8 @@ cp_parser_enumerator_definition (cp_parser* parser, tree type)
   if (identifier == error_mark_node)
     return;
 
-  /* Peek at the next token.  */
-  token = cp_lexer_peek_token (parser->lexer);
-  /* If it's an `=', then there's an explicit value.  */
-  if (token->type == CPP_EQ)
+  /* If the next token is an '=', then there is an explicit value.  */
+  if (cp_lexer_next_token_is (parser->lexer, CPP_EQ))
     {
       /* Consume the `=' token.  */
       cp_lexer_consume_token (parser->lexer);
index 076bbf594da0626020425d46bfe9edb447c5987e..5dc8128b4463d766cb7b89c086894d6217794e7f 100644 (file)
@@ -1,3 +1,8 @@
+2004-09-06  Zack Weinberg  <zack@codesourcery.com>
+
+       * g++.old-deja/g++.other/enum2.C: Move dg-error markers to
+       reflect changed line numbering of diagnostics.
+
 2004-09-06  Paul Brook  <paul@codesourcery.com>
 
        * gfortran.dg/edit_real_1.f90: Add new test.
        * testsuite/gcc.dg/builtins-46.c: New.
 
 2004-09-03  Devang Patel  <dpatel@apple.com>
-       
+
        * gcc.dg/tree-ssa/ifc-20040816-1.c: New test.
        * gcc.dg/tree-ssa/ifc-20040816-2.c: New test.
-       
+
 2004-09-03  Jan Beulich  <jbeulich@novell.com>
 
        * g++.dg/abi/bitfield5.C: Use -mno-ms-bitfields.
@@ -61,7 +66,7 @@
 2004-09-03  Devang Patel  <dpatel@apple.com>
 
        * g++.dg/debug/pr15736.cc: New test.
-       
+
 2004-09-02  Mark Mitchell  <mark@codesourcery.com>
 
        * README.QMTEST: Fix out-of-date link.
@@ -71,7 +76,7 @@
        PR fortran/16579
        * gfortran.fortran-torture/execute/intrinsic_i_char.f90:
        Delete.  Duplicate of gfortran.dg/g77/20010610.f
-       
+
 2004-09-02  Mark Mitchell  <mark@codesourcery.com>
 
        * g++.dg/abi/arm_rtti1.C: New test.
        * gcc.target/mips/mips-ps-3.c: New test.
        * gcc.target/mips/mips-ps-4.c: New test.
        * gcc.target/mips/mips-ps-type.c: New test.
-       
+
 2004-09-02  Paul Brook  <paul@codesourcery.com>
 
        * gfortran.dg/edit_real_1.f90: Add new tests.
 
        PR fortran/16579
        * gfortran.fortran-torture/execute/intrinsic_i_char.f90: New test.
-       
+
 2004-08-31  Bud Davis  <bdavis9659@comcast.net>
 
        PR libfortran/16805
 2004-08-19  Paul Brook  <paul@codesourcery.com>
 
        PR fortran/14976
-       PR fortran/16228 
+       PR fortran/16228
        * gfortran.dg/data_char_1.f90: New test.
 
 2004-08-19  Erik Schnetter  <schnetter@aei.mpg.de>
 
        PR c++/16965
        * g++.dg/parse/error17.C: New test.
-       
+
 2004-08-17  Dorit Naishlos  <dorit@il.ibm.com>
 
        * gcc.dg/vect: New directory for vectorizer tests.
 2004-08-17  Paolo Bonzini  <bonzini@gnu.org>
 
        * gcc.dg/pr17036-1.c: New test.
-       
+
 2004-08-16  Devang Patel  <dpatel@apple.com>
 
        * gcc.dg/darwin-20040809-1.c: New test.
-       
+
 2004-08-16  Joseph S. Myers  <jsm@polyomino.org.uk>
 
        * gcc.dg/funcdef-attr-1.c: New test.
 2004-08-12  Devang patel  <dpatel@apple.com>
 
        * gcc.dg/darwin-20040809-2.c: New test.
-       
+
 2004-08-12  Janis Johnson  <janis1872us.ibm.com>
 
        * g++.dg/ext/altivec-12.C: New test.
 
        * gcc.dg/darwin-ld-20040809-1.c: New test.
        * gcc.dg/darwin-ld-20040809-2.c: New test.
-       
+
 2004-08-11  Steven G. Kargl  <kargls@comcast.net>
 
        PR fortran/16917
index 456c205f4d40bcf3e1d2d2450136847ba109cd82..40328bfc6b9cc9128d278e45cd245536ab217c59 100644 (file)
@@ -3,14 +3,14 @@
 // Copyright (C) 1999 Free Software Foundation, Inc.
 // Contributed by Nathan Sidwell 3 Jun 1999 <nathan@acm.org>
 
-// We'd like the enum location to be its open brace.
+// We'd like the enum location to be its identifier.
 
-enum thing
-{ // { dg-error "" } previous def
+enum thing // { dg-error "" } previous def
+{
   val1
 };
 
-enum thing
-{ // { dg-error "" } multiple def
+enum thing // { dg-error "" } multiple def
+{
   val2
 };