decl.c (build_enumerator): Use add_double and int_fits_type_p instead of cp_build_binary_op...

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
This commit is contained in:
Zack Weinberg 2004-09-06 17:38:18 +00:00
parent 8a57cd3d5e
commit ff4eb0b5ff
5 changed files with 104 additions and 77 deletions

View 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,
@ -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.

View 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 ... */
prev_value = DECL_INITIAL (TREE_VALUE (TYPE_VALUES (enumtype)));
/* ... plus one. */
value = cp_build_binary_op (PLUS_EXPR,
prev_value,
integer_one_node);
HOST_WIDE_INT hi;
unsigned HOST_WIDE_INT lo;
tree prev_value;
bool overflowed;
if (tree_int_cst_lt (value, prev_value))
/* 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)));
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 (overflowed)
error ("overflow in enumeration values at `%D'", name);
}
else

View 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);

View 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.
@ -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

View 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
};