This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
C++ PATCH: enum location
- To: egcs-patches at egcs dot cygnus dot com
- Subject: C++ PATCH: enum location
- From: Nathan Sidwell <nathan at acm dot org>
- Date: Fri, 04 Jun 1999 09:49:28 +0100
- Organization: University of Bristol
- Reply-To: nathan at compsci dot bristol dot ac dot uk
Hi,
here's a patch to set an enum location to be the open `{' rather than some
`random' point within the enum. (this makes the behaviour the same as gcc).
The difficulty is in the grammar, the enum reduction requires the parser to
look ahead a bit to distinguish enum `{ something}' from `enum { }', this moves
the current line number into the enum, before the enum head can be processed.
The patch merges these two rules by using a new `enumlist-opt' rule which DTRT.
It also makes us consistent about handling a trailing comma, currently we don't
parse `enum { , }' even though `enum { something , }' is accepted (with a
warning).
I modified start_enum to show the location of the previous duplicate defn --
this is consistent with what we do with duplicate structs.
I attach a new testcase.
old behaviour-
enumtest.C:16: multiple definition of `enum thing'
new behaviour-
enumtest.C:14: multiple definition of `enum thing'
enumtest.C:9: previous definition here
gcc behaviour-
enumtest.C:14: redeclaration of `enum thing'
ok?
nathan
--
Dr Nathan Sidwell :: Computer Science Department :: Bristol University
I have seen the death of PhotoShop -- it is called GIMP
nathan@acm.org http://www.cs.bris.ac.uk/~nathan/ nathan@cs.bris.ac.uk
1999-06-03 Nathan Sidwell <nathan@acm.org>
* decl.c (start_enum): Show location of previous definition.
* parse.y (enumlist_opt): New reduction.
(structsp): Simplify enum rules to use enumlist_opt.
Index: egcs/gcc/cp/decl.c
===================================================================
RCS file: /egcs/carton/cvsfiles/egcs/gcc/cp/decl.c,v
retrieving revision 1.369
diff -c -3 -p -r1.369 decl.c
*** decl.c 1999/06/03 07:16:07 1.369
--- decl.c 1999/06/03 16:36:58
*************** start_enum (name)
*** 12978,12984 ****
enumtype = lookup_tag (ENUMERAL_TYPE, name, b, 1);
if (enumtype != NULL_TREE && TREE_CODE (enumtype) == ENUMERAL_TYPE)
! cp_error ("multiple definition of `%#T'", enumtype);
else
{
enumtype = make_node (ENUMERAL_TYPE);
--- 12978,12987 ----
enumtype = lookup_tag (ENUMERAL_TYPE, name, b, 1);
if (enumtype != NULL_TREE && TREE_CODE (enumtype) == ENUMERAL_TYPE)
! {
! cp_error ("multiple definition of `%#T'", enumtype);
! cp_error_at ("previous definition here", enumtype);
! }
else
{
enumtype = make_node (ENUMERAL_TYPE);
Index: egcs/gcc/cp/parse.y
===================================================================
RCS file: /egcs/carton/cvsfiles/egcs/gcc/cp/parse.y,v
retrieving revision 1.123
diff -c -3 -p -r1.123 parse.y
*** parse.y 1999/05/24 00:46:54 1.123
--- parse.y 1999/06/03 16:37:00
*************** empty_parms ()
*** 212,218 ****
%type <ttype> component_declarator component_declarator0
%type <ttype> notype_component_declarator notype_component_declarator0
%type <ttype> after_type_component_declarator after_type_component_declarator0
! %type <ttype> enumlist enumerator
%type <ttype> absdcl cv_qualifiers
%type <ttype> direct_abstract_declarator conversion_declarator
%type <ttype> new_declarator direct_new_declarator
--- 212,218 ----
%type <ttype> component_declarator component_declarator0
%type <ttype> notype_component_declarator notype_component_declarator0
%type <ttype> after_type_component_declarator after_type_component_declarator0
! %type <ttype> enumlist_opt enumlist enumerator
%type <ttype> absdcl cv_qualifiers
%type <ttype> direct_abstract_declarator conversion_declarator
%type <ttype> new_declarator direct_new_declarator
*************** structsp:
*** 2102,2133 ****
{ $<itype>3 = suspend_momentary ();
$<ttype>$ = current_enum_type;
current_enum_type = start_enum ($2); }
! enumlist maybecomma_warn '}'
{ TYPE_VALUES (current_enum_type) = $5;
$$.t = finish_enum (current_enum_type);
$$.new_type_flag = 1;
current_enum_type = $<ttype>4;
resume_momentary ((int) $<itype>3);
check_for_missing_semicolon ($$.t); }
- | ENUM identifier '{' '}'
- { $$.t = finish_enum (start_enum ($2));
- $$.new_type_flag = 1;
- check_for_missing_semicolon ($$.t); }
| ENUM '{'
{ $<itype>2 = suspend_momentary ();
$<ttype>$ = current_enum_type;
current_enum_type = start_enum (make_anon_name ()); }
! enumlist maybecomma_warn '}'
{ TYPE_VALUES (current_enum_type) = $4;
$$.t = finish_enum (current_enum_type);
$$.new_type_flag = 1;
current_enum_type = $<ttype>3;
resume_momentary ((int) $<itype>1);
check_for_missing_semicolon ($$.t); }
- | ENUM '{' '}'
- { $$.t = finish_enum (start_enum (make_anon_name()));
- $$.new_type_flag = 1;
- check_for_missing_semicolon ($$.t); }
| ENUM identifier
{ $$.t = xref_tag (enum_type_node, $2, 1);
$$.new_type_flag = 0; }
--- 2102,2125 ----
{ $<itype>3 = suspend_momentary ();
$<ttype>$ = current_enum_type;
current_enum_type = start_enum ($2); }
! enumlist_opt '}'
{ TYPE_VALUES (current_enum_type) = $5;
$$.t = finish_enum (current_enum_type);
$$.new_type_flag = 1;
current_enum_type = $<ttype>4;
resume_momentary ((int) $<itype>3);
check_for_missing_semicolon ($$.t); }
| ENUM '{'
{ $<itype>2 = suspend_momentary ();
$<ttype>$ = current_enum_type;
current_enum_type = start_enum (make_anon_name ()); }
! enumlist_opt '}'
{ TYPE_VALUES (current_enum_type) = $4;
$$.t = finish_enum (current_enum_type);
$$.new_type_flag = 1;
current_enum_type = $<ttype>3;
resume_momentary ((int) $<itype>1);
check_for_missing_semicolon ($$.t); }
| ENUM identifier
{ $$.t = xref_tag (enum_type_node, $2, 1);
$$.new_type_flag = 0; }
*************** notype_component_declarator:
*** 2677,2682 ****
--- 2669,2680 ----
| ':' expr_no_commas maybe_attribute
{ $$ = grokbitfield (NULL_TREE, current_declspecs, $2);
cplus_decl_attributes ($$, $3, prefix_attributes); }
+ ;
+
+ enumlist_opt:
+ enumlist maybecomma_warn
+ | maybecomma_warn
+ { $$ = NULL_TREE; }
;
/* We chain the enumerators in reverse order.
// Build don't link:
// 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.
enum thing
{ // ERROR - previous def
val1
};
enum thing
{ // ERROR - multiple def
val2
};