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]
Other format: [Raw text]

Re: Bug: gcc/cp/parse.y & gcc/cp/decl.h: Conflict on TYPENAME


The following patch supersedes my previous patch: it addresses two
parser related issues: one is that:

| | The parser declares token TYPENAME and decl.h declares an enum
| | including TYPENAME.  Several files include both, what results in a
| | dangerous clash.
| | 
| | Given the risks, I suggest that the parser slowly moves to using the
| | `tFOO' convention, so, amongst the various possible changes, I
| | preferred this one: instead of token TYPENAME, using token tTYPENAME.
| | If you have another preference, please tell me, I'll adjust the patch
| | accordingly.
|
| Without this patch, expect next Bison to create a failure of the
| compilation: it nows outputs the tokens as enums (when __STDC__), and
| therefore, the compilation will fail (as is to be expected from id
| clashes).

And the second issue is a typing issue.  On a rule such as

        foo: bar {} baz;

because of the default action $$ = $1, you have to ensure %typeof (foo)
== %typeof (bar), which was not the case of these rules:


explicit_instantiation:
	[...]
	| SCSPEC TEMPLATE begin_explicit_instantiation typespec ';'
		{ do_type_instantiation ($4.t, $1, 1);
		  yyungetc (';', 1); }
          end_explicit_instantiation
		{}
        [...]

Because %type <ttype> SCSPEC.

So you have to write

        foo: bar {} baz {};

The test suite exhibits exactly the same behavior before and after
this patch, i.e.:

Test Run By akim on Wed Jun 12 12:34:58 2002
      Native configuration is i686-pc-linux-gnu
      
                      === g++ tests ===
      [..]
                      === g++ Summary ===
      
      # of expected passes            6808
      # of unexpected failures        568
      # of unexpected successes       1
      # of expected failures          86
      # of untested testcases         9
      # of unsupported tests          3
      /home/akim/src/gcc/gcc/testsuite/../g++ version gcc 3.2 20020611 (experimental)


I would like to emphasize that this patch is a simple bug fix.  As is,
this grammar does not compile with CVS Bison.



Note: I have my editor systematically remove the trailing spaces, and
there appears to be many in these files.  So the patch comes in two
``flavors'': the first one is `diff -w' so that you can see the real
content of the patch, but the real patch, which includes the trailing
blank (automated) removal, is below.

Index: ChangeLog
from  Akim Demaille  <akim@epita.fr>

	* parse.y (TYPENAME): Rename as tTYPENAME to avoid the clash with
	decl.h's TYPENAME.
	* spew.c, lex.c: Adjust.
	* parse.y (explicit_instantiation): Add empty action to override
	the default $$ = $1 where it introduces a type clash.

Index: lex.c
===================================================================
RCS file: /cvsroot/gcc/gcc/gcc/cp/lex.c,v
retrieving revision 1.282
diff -u -u -w -r1.282 lex.c
--- lex.c 4 Jun 2002 07:10:10 -0000 1.282
+++ lex.c 12 Jun 2002 11:14:43 -0000
@@ -86,10 +86,11 @@
 int warn_traditional = 0;
 int flag_digraphs = 1;
 
-/* the declaration found for the last IDENTIFIER token read in.
-   yylex must look this up to detect typedefs, which get token type TYPENAME,
-   so it is left around in case the identifier is not a typedef but is
-   used in a context which makes it a reference to a variable.  */
+/* the declaration found for the last IDENTIFIER token read in.  yylex
+   must look this up to detect typedefs, which get token type
+   tTYPENAME, so it is left around in case the identifier is not a
+   typedef but is used in a context which makes it a reference to a
+   variable.  */
 tree lastiddecl;
 
 /* Array for holding counts of the numbers of tokens seen.  */
@@ -692,7 +693,7 @@
   switch (yychar)
     {
     case IDENTIFIER:
-    case TYPENAME:
+    case tTYPENAME:
     case TYPESPEC:
     case PTYPENAME:
     case PFUNCNAME:
@@ -914,7 +915,7 @@
   if ((yychar > 255
        && yychar != SCSPEC
        && yychar != IDENTIFIER
-       && yychar != TYPENAME
+       && yychar != tTYPENAME
        && yychar != CV_QUALIFIER
        && yychar != SELFNAME)
       || yychar == 0  /* EOF */)
Index: parse.y
===================================================================
RCS file: /cvsroot/gcc/gcc/gcc/cp/parse.y,v
retrieving revision 1.262
diff -u -u -w -r1.262 parse.y
--- parse.y 4 Jun 2002 07:10:14 -0000 1.262
+++ parse.y 12 Jun 2002 11:14:44 -0000
@@ -283,7 +283,7 @@
 /* All identifiers that are declared typedefs in the current block.
    In some contexts, they are treated just like IDENTIFIER,
    but they can also serve as typespecs in declarations.  */
-%token TYPENAME
+%token tTYPENAME
 %token SELFNAME
 
 /* A template function.  */
@@ -345,7 +345,7 @@
 %nonassoc IF
 %nonassoc ELSE
 
-%left IDENTIFIER PFUNCNAME TYPENAME SELFNAME PTYPENAME SCSPEC TYPESPEC CV_QUALIFIER ENUM AGGR ELLIPSIS TYPEOF SIGOF OPERATOR NSNAME TYPENAME_KEYWORD ATTRIBUTE
+%left IDENTIFIER PFUNCNAME tTYPENAME SELFNAME PTYPENAME SCSPEC TYPESPEC CV_QUALIFIER ENUM AGGR ELLIPSIS TYPEOF SIGOF OPERATOR NSNAME TYPENAME_KEYWORD ATTRIBUTE
 
 %left '{' ',' ';'
 
@@ -375,7 +375,7 @@
 
 %type <code> unop
 
-%type <ttype> identifier IDENTIFIER TYPENAME CONSTANT expr nonnull_exprlist
+%type <ttype> identifier IDENTIFIER tTYPENAME CONSTANT expr nonnull_exprlist
 %type <ttype> PFUNCNAME maybe_identifier
 %type <ttype> paren_expr_or_null nontrivial_exprlist SELFNAME
 %type <ttype> expr_no_commas expr_no_comma_rangle
@@ -1023,7 +1023,7 @@
 
 identifier:
 	  IDENTIFIER
-	| TYPENAME
+	| tTYPENAME
 	| SELFNAME
 	| PTYPENAME
 	| NSNAME
@@ -1060,17 +1060,21 @@
 		{ do_type_instantiation ($4.t, $1, 1);
 		  yyungetc (';', 1); }
           end_explicit_instantiation
+		{}
 	| SCSPEC TEMPLATE begin_explicit_instantiation typed_declspecs 
           declarator
 		{ tree specs = strip_attrs ($4.t);
 		  do_decl_instantiation (specs, $5, $1); }
           end_explicit_instantiation
+		{}
 	| SCSPEC TEMPLATE begin_explicit_instantiation notype_declarator
 		{ do_decl_instantiation (NULL_TREE, $4, $1); }
           end_explicit_instantiation
+		{}
 	| SCSPEC TEMPLATE begin_explicit_instantiation constructor_declarator
 		{ do_decl_instantiation (NULL_TREE, $4, $1); }
           end_explicit_instantiation
+		{}
 	;
 
 begin_explicit_instantiation: 
@@ -1089,7 +1093,7 @@
 	  PTYPENAME '<' template_arg_list_opt template_close_bracket
 	    finish_template_type_
                 { $$ = $5; }
-	| TYPENAME  '<' template_arg_list_opt template_close_bracket
+	| tTYPENAME  '<' template_arg_list_opt template_close_bracket
 	    finish_template_type_
                 { $$ = $5; }
 	| self_template_type
@@ -1557,7 +1561,7 @@
 
 unqualified_id:
 	  notype_unqualified_id
-	| TYPENAME
+	| tTYPENAME
 	| SELFNAME
 	;
 
@@ -2770,7 +2774,7 @@
 	  after_type_declarator maybeasm maybe_attribute maybe_init
 		{ $$ = parse_field0 ($1, $<ftype>0.t, $<ftype>0.lookups,
 				     $3, $2, $4); }
-	| TYPENAME ':' expr_no_commas maybe_attribute
+	| tTYPENAME ':' expr_no_commas maybe_attribute
 		{ $$ = parse_bitfield0 ($1, $<ftype>0.t, $<ftype>0.lookups,
 					$4, $3); }
 	;
@@ -2793,7 +2797,7 @@
 after_type_component_declarator:
 	  after_type_declarator maybeasm maybe_attribute maybe_init
 		{ $$ = parse_field ($1, $3, $2, $4); }
-	| TYPENAME ':' expr_no_commas maybe_attribute
+	| tTYPENAME ':' expr_no_commas maybe_attribute
 		{ $$ = parse_bitfield ($1, $4, $3); }
 	;
 
@@ -3065,7 +3069,7 @@
 	;
 
 type_name:
-	  TYPENAME
+	  tTYPENAME
 	| SELFNAME
 	| template_type  %prec EMPTY
 	;
@@ -3089,7 +3093,7 @@
 /* Why the @#$%^& do type_name and notype_identifier need to be expanded
    inline here?!?  (jason) */
 nested_name_specifier_1:
-	  TYPENAME SCOPE
+	  tTYPENAME SCOPE
 		{
 		  if (TREE_CODE ($1) == IDENTIFIER_NODE)
 		    {
@@ -3175,7 +3179,7 @@
 /* This needs to return a TYPE_DECL for simple names so that we don't
    forget what name was used.  */
 typename_sub2:
-	  TYPENAME SCOPE
+	  tTYPENAME SCOPE
 		{
 		  if (TREE_CODE ($1) != TYPE_DECL)
 		    $$ = lastiddecl;
@@ -3613,7 +3617,7 @@
                 { finish_label_stmt ($1); }
 	| PTYPENAME ':'
                 { finish_label_stmt ($1); }
-	| TYPENAME ':'
+	| tTYPENAME ':'
                 { finish_label_stmt ($1); }
 	| SELFNAME ':'
                 { finish_label_stmt ($1); }
Index: spew.c
===================================================================
RCS file: /cvsroot/gcc/gcc/gcc/cp/spew.c,v
retrieving revision 1.65
diff -u -u -w -r1.65 spew.c
--- spew.c 4 Jun 2002 07:10:23 -0000 1.65
+++ spew.c 12 Jun 2002 11:14:44 -0000
@@ -161,10 +161,11 @@
 static tree last_token_id;
 
 /* From lex.c: */
-/* the declaration found for the last IDENTIFIER token read in.
-   yylex must look this up to detect typedefs, which get token type TYPENAME,
-   so it is left around in case the identifier is not a typedef but is
-   used in a context which makes it a reference to a variable.  */
+/* the declaration found for the last IDENTIFIER token read in.  yylex
+   must look this up to detect typedefs, which get token type
+   tTYPENAME, so it is left around in case the identifier is not a
+   typedef but is used in a context which makes it a reference to a
+   variable.  */
 extern tree lastiddecl;		/* let our brains leak out here too */
 extern int	yychar;		/*  the lookahead symbol		*/
 extern YYSTYPE	yylval;		/*  the semantic value of the		*/
@@ -636,11 +637,11 @@
   if (t && t == decl)
     return SELFNAME;
 
-  return TYPENAME;
+  return tTYPENAME;
 }
 
 /* token[0] == AGGR (struct/union/enum)
-   Thus, token[1] is either a TYPENAME or a TYPENAME_DEFN.
+   Thus, token[1] is either a tTYPENAME or a TYPENAME_DEFN.
    If token[2] == '{' or ':' then it's TYPENAME_DEFN.
    It's also a definition if it's a forward declaration (as in 'struct Foo;')
    which we can tell if token[2] == ';' *and* token[-1] != FRIEND or NEW.  */
@@ -652,7 +653,7 @@
   
   scan_tokens (2);
   yc1 = nth_token (1)->yychar;
-  if (yc1 != TYPENAME && yc1 != IDENTIFIER && yc1 != PTYPENAME)
+  if (yc1 != tTYPENAME && yc1 != IDENTIFIER && yc1 != PTYPENAME)
     return;
   yc2 = nth_token (2)->yychar;
   if (yc2 == ';')
@@ -667,7 +668,7 @@
 
   switch (yc1)
     {
-    case TYPENAME:
+    case tTYPENAME:
       nth_token (1)->yychar = TYPENAME_DEFN;
       break;
     case PTYPENAME:
@@ -765,7 +766,7 @@
       break;
     }
     case IDENTIFIER_DEFN:
-    case TYPENAME:
+    case tTYPENAME:
     case TYPENAME_DEFN:
     case PTYPENAME:
     case PTYPENAME_DEFN:
@@ -898,7 +899,7 @@
       yyc = identifier_type (trrr);
       switch(yyc)
         {
-          case TYPENAME:
+          case tTYPENAME:
           case SELFNAME:
           case NSNAME:
           case PTYPENAME:
@@ -1469,7 +1470,7 @@
 {
   if (yy<256)
     fprintf (stderr, "->%d < %c >\n", lineno, yy);
-  else if (yy == IDENTIFIER || yy == TYPENAME)
+  else if (yy == IDENTIFIER || yy == tTYPENAME)
     {
       const char *id;
       if (TREE_CODE (yylval.ttype) == IDENTIFIER_NODE)
Now the real patch, including trailing spaces nuking.

Attachment: fix-TYPENAME-conflict.patch.gz
Description: Binary data


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