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]

C++ PATCH: enum location


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

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