From 637fdc50bd3029c843d6b08c00321528328cf74c Mon Sep 17 00:00:00 2001
From: zack <zack@138bc75d-0d04-0410-961f-82ee72b054a4>
Date: Mon, 6 Sep 2004 17:38:18 +0000
Subject: [PATCH] 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.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@87121 138bc75d-0d04-0410-961f-82ee72b054a4
---
 gcc/cp/ChangeLog                             | 22 +++--
 gcc/cp/decl.c                                | 23 +++--
 gcc/cp/parser.c                              | 95 ++++++++++----------
 gcc/testsuite/ChangeLog                      | 29 +++---
 gcc/testsuite/g++.old-deja/g++.other/enum2.C | 10 +--
 5 files changed, 103 insertions(+), 76 deletions(-)

diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index 32a1b7eb372f..fd9b97d66775 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -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,
@@ -95,7 +107,7 @@
 	* 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
@@ -403,7 +415,7 @@
 	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.
diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c
index 607b907078d8..5cb43d2b3705 100644
--- a/gcc/cp/decl.c
+++ b/gcc/cp/decl.c
@@ -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
diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c
index 45eb20aa4659..6d56f976c62b 100644
--- a/gcc/cp/parser.c
+++ b/gcc/cp/parser.c
@@ -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);
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 076bbf594da0..5dc8128b4463 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -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.
@@ -22,10 +27,10 @@
 	* 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.
@@ -97,7 +102,7 @@
 	* 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.
@@ -155,7 +160,7 @@
 
 	PR fortran/16579
 	* gfortran.fortran-torture/execute/intrinsic_i_char.f90: New test.
-	
+
 2004-08-31  Bud Davis  <bdavis9659@comcast.net>
 
 	PR libfortran/16805
@@ -453,7 +458,7 @@
 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>
@@ -518,7 +523,7 @@
 
 	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.
@@ -600,11 +605,11 @@
 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.
@@ -651,7 +656,7 @@
 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.
@@ -718,7 +723,7 @@
 
 	* 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
diff --git a/gcc/testsuite/g++.old-deja/g++.other/enum2.C b/gcc/testsuite/g++.old-deja/g++.other/enum2.C
index 456c205f4d40..40328bfc6b9c 100644
--- a/gcc/testsuite/g++.old-deja/g++.other/enum2.C
+++ b/gcc/testsuite/g++.old-deja/g++.other/enum2.C
@@ -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
 };
-- 
GitLab