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++ parser patch


The following patch from Alastair Houghton (I adapted it egcs snapshots
from FSF gcc and added/updated ChangeLog) fixes attribute parsing in the
C++ parser that is already supported by the C parser. The following test 
case shows the cases where the current C++ parser files, and with this
patch, it can handle it all.

Patch against CVS version 980621. No testsuite regression. 

Regards,
Mumit

================ TESTCASE: c++-attrib-test.cc
/*
 * Attribute handling in C vs C++ parsers. All of these are accepted
 * by C parser, but the ones marked "bad" are rejected by C++.
 */

#define STDCALL __attribute__((stdcall))
#define NO_COPY __attribute__((section (".data$cygwin_nocopy")))

int (STDCALL *foo) ();				/* bad */

int STDCALL * funcname();
int * STDCALL funcname();			/* bad */

int NO_COPY var1;
int NO_COPY *var2;
int NO_COPY **var3;

int * NO_COPY var4;				/* bad */
int ** NO_COPY var5;				/* bad */
int NO_COPY **var6;
int NO_COPY var7 = 5;
static int NO_COPY var8 = 5;
static NO_COPY int var9 = 5;
static NO_COPY char *var10 = 0;
static char * NO_COPY var11 = 0;		/* bad */
static char * NO_COPY * var12 = 0;		/* bad */
struct foobar * NO_COPY * var13 = 0;		/* bad */

typedef int BOOL;
static NO_COPY BOOL var14;
static NO_COPY BOOL var15 = 0;

typedef struct {
  int i;
} foobar2;

static NO_COPY foobar2 var16;
NO_COPY static foobar2 var17;

/* C++ PROBLEMS
stdcall3.cc:9: parse error before `__attribute__'
stdcall3.cc:12: parse error before `__attribute__'
stdcall3.cc:18: parse error before `__attribute__'
stdcall3.cc:19: parse error before `__attribute__'
stdcall3.cc:25: parse error before `__attribute__'
stdcall3.cc:26: parse error before `__attribute__'
stdcall3.cc:27: parse error before `__attribute__'
*/
================ Patch

Sat Jun 20 21:47:00 1998  Alastair J. Houghton <ajh8@doc.ic.ac.uk>

	Changes to better support __attribute__ keyword:

	* Makefile.in (CONFLICTS): Update.
	* decl.c (start_method): Added extra parameter for attributes.
	* decl2.c (prefixed_attribute_node): New static variable. 
	(possibly_prefixed_decl): New function.
	(build_prefixed_decl): New function. 
	* cp-tree.h (start_method): Update prototype.
	(possibly_prefixed_decl, build_prefixed_decl): Declare.
	* semantics.c (begin_function_definition): Use possibly_prefixed_decl.
	* parse.y (parse_decl, fn.def2, explicit_instantiation, condition,
	expr_or_declarator, primary, component_decl_1, 
	notype_component_declarator0, notype_component_declarator,
	notype_declarator, complex_notype_declarator,
	complex_direct_notype_declarator, functional_cast, named_parm
	bad_parm): Use possibly_prefixed_decl.
	(expr_or_declarator_intern, expr_or_declarator,
	notype_declarator_intern, notype_declarator,
	complex_notype_declarator, complex_direct_notype_declarator): Use
	build_prefixed_decl.
	(expr_or_declarator_intern): New rule.
	(expr_or_declarator, direct_notype_declarator, primary,
	functional_cast): Use it.
	(notype_declarator_intern): New rule.
	(notype_declarator, complex_notype_declarator): Use it.
	(fn.def2): Update start_method parameter list.
	(condition): Pass attributes instead of NULL to start_decl.

Index: Makefile.in
===================================================================
RCS file: /egcs/carton/cvsfiles/egcs/gcc/cp/Makefile.in,v
retrieving revision 1.23
diff -u -3 -p -r1.23 Makefile.in
--- Makefile.in	1998/06/08 17:52:34	1.23
+++ Makefile.in	1998/06/23 04:59:33
@@ -214,7 +214,7 @@ parse.o : $(PARSE_C) $(CONFIG_H) $(CXX_T
 	$(CC) -c $(ALL_CFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) $(BIG_SWITCHFLAG) \
   `echo $(PARSE_C) | sed 's,^\./,,'`
 
-CONFLICTS = expect 21 shift/reduce conflicts and 39 reduce/reduce conflicts.
+CONFLICTS = expect 29 shift/reduce conflicts and 39 reduce/reduce conflicts.
 $(PARSE_H) : $(PARSE_C)
 $(PARSE_C) : $(srcdir)/parse.y
 	@echo $(CONFLICTS)
Index: decl.c
===================================================================
RCS file: /egcs/carton/cvsfiles/egcs/gcc/cp/decl.c,v
retrieving revision 1.140
diff -u -3 -p -r1.140 decl.c
--- decl.c	1998/06/17 23:51:41	1.140
+++ decl.c	1998/06/23 04:59:34
@@ -12923,11 +12923,11 @@ finish_function (lineno, call_poplevel, 
    CHANGES TO CODE IN `grokfield'.  */
 
 tree
-start_method (declspecs, declarator)
-     tree declarator, declspecs;
+start_method (declspecs, declarator, attrlist)
+     tree declarator, declspecs, attrlist;
 {
   tree fndecl = grokdeclarator (declarator, declspecs, MEMFUNCDEF, 0,
-				NULL_TREE);
+				attrlist);
 
   /* Something too ugly to handle.  */
   if (fndecl == NULL_TREE)
Index: decl2.c
===================================================================
RCS file: /egcs/carton/cvsfiles/egcs/gcc/cp/decl2.c,v
retrieving revision 1.87
diff -u -3 -p -r1.87 decl2.c
--- decl2.c	1998/06/10 10:16:41	1.87
+++ decl2.c	1998/06/23 04:59:35
@@ -4601,3 +4601,68 @@ handle_class_head (aggr, scope, id)
     (aggr, make_anon_name (), NULL_TREE, 1);
   return TYPE_MAIN_DECL (id);
 }
+
+/* code to process declarations with prefix attributes */
+
+/* Used to check that a declarator was encoded by build_prefixed_decl. */
+
+static union tree_node prefixed_attribute_node;
+
+/* Decode a declarator originally encoded by build_prefixed_decl. May be 
+   called on a declarator not encoded by build_prefixed_decl, in which
+   case it just returns the declarator unchanged.  */
+
+tree
+possibly_prefixed_decl(decl, prefix)
+     tree decl, *prefix;
+{
+  if (TREE_CODE (decl) != TREE_LIST)
+    return decl;
+  if (TREE_PURPOSE (decl) != &prefixed_attribute_node)
+    return decl;
+  if (prefix)
+    {
+      if (*prefix == NULL_TREE)
+	*prefix = TREE_CHAIN (decl);
+      else
+	*prefix = chainon (*prefix,
+			   TREE_CHAIN (decl));
+    }
+  else
+    {
+      tree attrs;
+
+      attrs = decl;
+
+      while (attrs = TREE_CHAIN (attrs))
+	{
+	  warning("`%s' attribute ignored.",
+		  IDENTIFIER_POINTER (TREE_PURPOSE (attrs)));
+	}
+    }
+  
+  return (TREE_VALUE (decl));
+}
+
+/* Build a TREE_LIST node from a declarator and a set of attributes. The 
+   TREE_PURPOSE is set to &prefixed_attribute_node, with the declarator 
+   as the TREE_VALUE, and TREE_CHAIN pointing on to the attribute list.  */
+
+tree
+build_prefixed_decl(decl, prefix)
+     tree decl, prefix;
+{
+  tree list;
+
+  if (prefix == NULL_TREE)
+      return decl;
+  
+  if (TREE_CODE (decl) != TREE_LIST)
+      list = decl_tree_cons (&prefixed_attribute_node, decl, NULL_TREE);
+  else
+      list = decl;
+  
+  list = chainon (list, prefix);
+
+  return list;
+}
Index: cp-tree.h
===================================================================
RCS file: /egcs/carton/cvsfiles/egcs/gcc/cp/cp-tree.h,v
retrieving revision 1.87
diff -u -3 -p -r1.87 cp-tree.h
--- cp-tree.h	1998/06/22 05:59:19	1.87
+++ cp-tree.h	1998/06/23 04:59:35
@@ -2402,7 +2402,7 @@ extern void expand_start_early_try_stmts
 extern void store_parm_decls			PROTO((void));
 extern void store_return_init			PROTO((tree, tree));
 extern void finish_function			PROTO((int, int, int));
-extern tree start_method			PROTO((tree, tree));
+extern tree start_method			PROTO((tree, tree, tree));
 extern tree finish_method			PROTO((tree));
 extern void hack_incomplete_structures		PROTO((tree));
 extern tree maybe_build_cleanup_and_delete	PROTO((tree));
@@ -2479,6 +2479,8 @@ extern void check_default_args			PROTO((
 extern void mark_used				PROTO((tree));
 extern tree handle_class_head			PROTO((tree, tree, tree));
 extern tree lookup_arg_dependent                PROTO((tree, tree, tree));
+extern tree possibly_prefixed_decl		PROTO((tree, tree *));
+extern tree build_prefixed_decl			PROTO((tree, tree));
 
 /* in errfn.c */
 extern void cp_error				();
Index: semantics.c
===================================================================
RCS file: /egcs/carton/cvsfiles/egcs/gcc/cp/semantics.c,v
retrieving revision 1.12
diff -u -3 -p -r1.12 semantics.c
--- semantics.c	1998/06/09 13:28:25	1.12
+++ semantics.c	1998/06/23 04:59:35
@@ -1072,6 +1072,7 @@ begin_function_definition (decl_specs, d
   tree specs;
   tree attrs;
   split_specs_attrs (decl_specs, &specs, &attrs);
+  declarator = possibly_prefixed_decl (declarator, &attrs);
   if (!start_function (specs, declarator, attrs, 0))
     return 0;
   
Index: parse.y
===================================================================
RCS file: /egcs/carton/cvsfiles/egcs/gcc/cp/parse.y,v
retrieving revision 1.63
diff -u -3 -p -r1.63 parse.y
--- parse.y	1998/06/17 02:07:26	1.63
+++ parse.y	1998/06/23 04:59:35
@@ -203,6 +203,7 @@ empty_parms ()
 %type <ttype> compstmt implicitly_scoped_stmt
 
 %type <ttype> declarator notype_declarator after_type_declarator
+%type <ttype> notype_declarator_intern
 %type <ttype> direct_notype_declarator direct_after_type_declarator
 
 %type <ttype> opt.component_decl_list component_decl_list
@@ -217,7 +218,8 @@ empty_parms ()
 %type <ttype> xexpr parmlist parms bad_parm 
 %type <ttype> identifiers_or_typenames
 %type <ttype> fcast_or_absdcl regcast_or_absdcl
-%type <ttype> expr_or_declarator complex_notype_declarator
+%type <ttype> expr_or_declarator expr_or_declarator_intern
+%type <ttype> complex_notype_declarator
 %type <ttype> notype_unqualified_id unqualified_id qualified_id
 %type <ttype> template_id do_id object_template_id notype_template_declarator
 %type <ttype> overqualified_id notype_qualified_id any_id
@@ -308,6 +310,7 @@ parse_decl(declarator, specs_attrs, attr
   int  sm;
 
   split_specs_attrs (specs_attrs, &current_declspecs, &prefix_attributes);
+  declarator = possibly_prefixed_decl (declarator, &prefix_attributes);
   if (current_declspecs
       && TREE_CODE (current_declspecs) != TREE_LIST)
     current_declspecs = get_decl_list (current_declspecs);
@@ -658,8 +661,9 @@ component_constructor_declarator:
    reduce/reduce conflict introduced by these rules.  */
 fn.def2:
 	  declmods component_constructor_declarator
-		{ tree specs = strip_attrs ($1);
-		  $$ = start_method (specs, $2);
+		{ tree specs, attrs;
+		  split_specs_attrs ($1, &specs, &attrs);
+		  $$ = start_method (specs, $2, attrs);
 		 rest_of_mdef:
 		  if (! $$)
 		    YYERROR1;
@@ -667,20 +671,32 @@ fn.def2:
 		    yychar = YYLEX;
 		  reinit_parse_for_method (yychar, $$); }
 	| component_constructor_declarator
-		{ $$ = start_method (NULL_TREE, $1); goto rest_of_mdef; }
+		{ $$ = start_method (NULL_TREE, $1, NULL_TREE); 
+		  goto rest_of_mdef; }
 	| typed_declspecs declarator
-		{ tree specs = strip_attrs ($1.t);
-		  $$ = start_method (specs, $2); goto rest_of_mdef; }
+		{ tree specs, attrs;
+		  split_specs_attrs ($1.t, &specs, &attrs);
+		  $2 = possibly_prefixed_decl ($2, &attrs);
+		  $$ = start_method (specs, $2, attrs); goto rest_of_mdef; }
 	| declmods notype_declarator
-		{ tree specs = strip_attrs ($1);
-		  $$ = start_method (specs, $2); goto rest_of_mdef; }
+		{ tree specs, attrs;
+		  split_specs_attrs ($1, &specs, &attrs);
+		  $2 = possibly_prefixed_decl ($2, &attrs);
+		  $$ = start_method (specs, $2, attrs); goto rest_of_mdef; }
 	| notype_declarator
-		{ $$ = start_method (NULL_TREE, $$); goto rest_of_mdef; }
+		{ tree attrs;
+		  attrs = NULL_TREE;
+		  $$ = possibly_prefixed_decl ($$, &attrs);
+		  $$ = start_method (NULL_TREE, $$, attrs); 
+		  goto rest_of_mdef; }
 	| declmods constructor_declarator
-		{ tree specs = strip_attrs ($1);
-		  $$ = start_method (specs, $2); goto rest_of_mdef; }
+		{ tree specs, attrs;
+		  split_specs_attrs ($1, &specs, &attrs);
+		  $2 = possibly_prefixed_decl ($2, &attrs);
+		  $$ = start_method (specs, $2, attrs); goto rest_of_mdef; }
 	| constructor_declarator
-		{ $$ = start_method (NULL_TREE, $$); goto rest_of_mdef; }
+		{ $$ = start_method (NULL_TREE, $$, NULL_TREE); 
+		  goto rest_of_mdef; }
 	;
 
 return_id:
@@ -798,11 +814,14 @@ explicit_instantiation:
 		  yyungetc (';', 1); }
           end_explicit_instantiation
 	| TEMPLATE begin_explicit_instantiation typed_declspecs declarator
-		{ tree specs = strip_attrs ($3.t);
+		{ tree specs;
+		  $4 = possibly_prefixed_decl ($4, NULL);
+		  specs = strip_attrs ($3.t);
 		  do_decl_instantiation (specs, $4, NULL_TREE); }
           end_explicit_instantiation
 	| TEMPLATE begin_explicit_instantiation notype_declarator
-		{ do_decl_instantiation (NULL_TREE, $3, NULL_TREE); }
+		{ $3 = possibly_prefixed_decl ($3, NULL);
+		  do_decl_instantiation (NULL_TREE, $3, NULL_TREE); }
           end_explicit_instantiation
 	| TEMPLATE begin_explicit_instantiation constructor_declarator
 		{ do_decl_instantiation (NULL_TREE, $3, NULL_TREE); }
@@ -813,11 +832,14 @@ explicit_instantiation:
           end_explicit_instantiation
 	| SCSPEC TEMPLATE begin_explicit_instantiation typed_declspecs 
           declarator
-		{ tree specs = strip_attrs ($4.t);
+		{ tree specs;
+		  $5 = possibly_prefixed_decl ($5, NULL);
+		  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); }
+		{ $4 = possibly_prefixed_decl ($4, NULL);
+		  do_decl_instantiation (NULL_TREE, $4, $1); }
           end_explicit_instantiation
 	| SCSPEC TEMPLATE begin_explicit_instantiation constructor_declarator
 		{ do_decl_instantiation (NULL_TREE, $4, $1); }
@@ -937,8 +959,13 @@ xcond:
 
 condition:
 	  type_specifier_seq declarator maybeasm maybe_attribute '='
-		{ {
-		  tree d;
+		{ 
+		  tree d, attrs;
+		  
+		  attrs = NULL_TREE;
+		  $2 = possibly_prefixed_decl ($2, &attrs);
+		  
+		  {
 		  for (d = getdecls (); d; d = TREE_CHAIN (d))
 		    if (TREE_CODE (d) == TYPE_DECL) {
 		      tree s = TREE_TYPE (d);
@@ -948,10 +975,11 @@ condition:
 			cp_error ("definition of enum `%T' in condition", s);
 		    }
 		  }
+
 		  current_declspecs = $1.t;
 		  $<itype>5 = suspend_momentary ();
 		  $<ttype>$ = start_decl ($<ttype>2, current_declspecs, 1,
-					  $4, /*prefix_attributes*/ NULL_TREE);
+					  $4, /*prefix_attributes*/ attrs);
 		}
 	  init
 		{ 
@@ -1264,13 +1292,33 @@ unqualified_id:
 	| SELFNAME
 	;
 
+expr_or_declarator_intern:
+	  expr_or_declarator
+	| attributes expr_or_declarator
+		{
+		  /* Provide support for '(' attributes '*' declarator ')'
+		     etc */
+		  $$ = build_prefixed_decl ($2, $1);
+		}
+	;
+
 expr_or_declarator:
 	  notype_unqualified_id
-	| '*' expr_or_declarator  %prec UNARY
-		{ $$ = build_parse_node (INDIRECT_REF, $2); }
-	| '&' expr_or_declarator  %prec UNARY
-		{ $$ = build_parse_node (ADDR_EXPR, $2); }
-	| '(' expr_or_declarator ')'
+	| '*' expr_or_declarator_intern  %prec UNARY
+		{
+		  tree attr = NULL_TREE;
+		  $$ = build_parse_node (INDIRECT_REF,
+					 possibly_prefixed_decl ($2, &attr));
+		  $$ = build_prefixed_decl ($$, attr);
+		}
+	| '&' expr_or_declarator_intern  %prec UNARY
+		{
+		  tree attr = NULL_TREE;
+		  $$ = build_parse_node (ADDR_EXPR,
+					 possibly_prefixed_decl ($2, &attr));
+		  $$ = build_prefixed_decl ($$, attr);
+		}
+	| '(' expr_or_declarator_intern ')'
 		{ $$ = $2; }
 	;
 
@@ -1285,8 +1333,8 @@ direct_notype_declarator:
 	  complex_direct_notype_declarator
 	| notype_unqualified_id
 	| notype_template_declarator
-	| '(' expr_or_declarator ')'
-		{ $$ = finish_decl_parsing ($2); }
+	| '(' expr_or_declarator_intern ')'
+                { $$ = $2; }
 	;
 
 primary:
@@ -1309,8 +1357,9 @@ primary:
 		}
 	| '(' expr ')'
 		{ $$ = finish_parenthesized_expr ($2); }
-	| '(' expr_or_declarator ')'
-		{ $2 = reparse_decl_as_expr (NULL_TREE, $2);
+	| '(' expr_or_declarator_intern ')'
+		{ $2 = reparse_decl_as_expr (NULL_TREE, 
+		                             possibly_prefixed_decl ($2, NULL));
 		  $$ = finish_parenthesized_expr ($2); }
 	| '(' error ')'
 		{ $$ = error_mark_node; }
@@ -2419,8 +2468,10 @@ component_decl_1:
 	| declmods notype_components
 		{ $$ = grok_x_components ($1, $2); }
 	| notype_declarator maybeasm maybe_attribute maybe_init
-		{ $$ = grokfield ($$, NULL_TREE, $4, $2,
-				  build_tree_list ($3, NULL_TREE)); }
+		{ tree attrs = build_tree_list ($3, NULL_TREE);
+		  $$ = possibly_prefixed_decl ($$, &attrs);
+		  $$ = grokfield ($$, NULL_TREE, $4, $2,
+				  attrs); }
 	| constructor_declarator maybeasm maybe_attribute maybe_init
 		{ $$ = grokfield ($$, NULL_TREE, $4, $2,
 				  build_tree_list ($3, NULL_TREE)); }
@@ -2509,12 +2560,14 @@ notype_component_declarator0:
 	  notype_declarator maybeasm maybe_attribute maybe_init
 		{ split_specs_attrs ($<ttype>0, &current_declspecs,
 				     &prefix_attributes);
+		  $$ = possibly_prefixed_decl ($$, &prefix_attributes);
 		  $<ttype>0 = current_declspecs;
 		  $$ = grokfield ($$, current_declspecs, $4, $2,
 				  build_tree_list ($3, prefix_attributes)); }
 	| constructor_declarator maybeasm maybe_attribute maybe_init
 		{ split_specs_attrs ($<ttype>0, &current_declspecs,
 				     &prefix_attributes);
+		  $$ = possibly_prefixed_decl ($$, &prefix_attributes);
 		  $<ttype>0 = current_declspecs;
 		  $$ = grokfield ($$, current_declspecs, $4, $2,
 				  build_tree_list ($3, prefix_attributes)); }
@@ -2543,7 +2596,8 @@ after_type_component_declarator:
 
 notype_component_declarator:
 	  notype_declarator maybeasm maybe_attribute maybe_init
-		{ $$ = grokfield ($$, current_declspecs, $4, $2,
+		{ $$ = possibly_prefixed_decl ($$, &prefix_attributes);
+		  $$ = grokfield ($$, current_declspecs, $4, $2,
 				  build_tree_list ($3, prefix_attributes)); }
 	| IDENTIFIER ':' expr_no_commas maybe_attribute
 		{ $$ = grokbitfield ($$, current_declspecs, $3);
@@ -2710,47 +2764,124 @@ direct_after_type_declarator:
 /* A declarator allowed whether or not there has been
    an explicit typespec.  These cannot redeclare a typedef-name.  */
 
+notype_declarator_intern:
+	  notype_declarator
+	| attributes notype_declarator
+                {
+		  /* Provide support for '(' attributes '*' declarator ')'
+		     etc */
+		  $$ = build_prefixed_decl ($2, $1);
+		}
+	;
+	
 notype_declarator:
-	  '*' nonempty_cv_qualifiers notype_declarator  %prec UNARY
-		{ $$ = make_pointer_declarator ($2.t, $3); }
-	| '&' nonempty_cv_qualifiers notype_declarator  %prec UNARY
-		{ $$ = make_reference_declarator ($2.t, $3); }
-	| '*' notype_declarator  %prec UNARY
-		{ $$ = make_pointer_declarator (NULL_TREE, $2); }
-	| '&' notype_declarator  %prec UNARY
-		{ $$ = make_reference_declarator (NULL_TREE, $2); }
-	| ptr_to_mem cv_qualifiers notype_declarator
-		{ tree arg = make_pointer_declarator ($2, $3);
+	  '*' nonempty_cv_qualifiers notype_declarator_intern  %prec UNARY
+		{
+		  tree attrs = NULL_TREE;
+		  $$ = make_pointer_declarator ($2.t,
+			   possibly_prefixed_decl ($3, &attrs));
+		  $$ = build_prefixed_decl ($$, attrs);
+		}
+	| '&' nonempty_cv_qualifiers notype_declarator_intern  %prec UNARY
+		{
+		  tree attrs = NULL_TREE;
+		  $$ = make_reference_declarator ($2.t,
+			   possibly_prefixed_decl ($3, &attrs));
+		  $$ = build_prefixed_decl ($$, attrs);
+		}
+	| '*' notype_declarator_intern  %prec UNARY
+		{
+		  tree attrs = NULL_TREE;
+		  $$ = make_pointer_declarator (NULL_TREE,
+			   possibly_prefixed_decl ($2, &attrs));
+		  $$ = build_prefixed_decl ($$, attrs);
+		}
+	| '&' notype_declarator_intern  %prec UNARY
+		{
+		  tree attrs = NULL_TREE;
+		  $$ = make_reference_declarator (NULL_TREE,
+			   possibly_prefixed_decl ($2, &attrs));
+		  $$ = build_prefixed_decl ($$, attrs);
+		}
+	| ptr_to_mem cv_qualifiers notype_declarator_intern
+		{
+		  tree arg, attrs = NULL_TREE;
+
+		  arg=make_pointer_declarator ($2,
+			   possibly_prefixed_decl ($3, &attrs));
 		  $$ = build_parse_node (SCOPE_REF, $1, arg);
+		  $$ = build_prefixed_decl ($$, attrs);
 		}
 	| direct_notype_declarator
-	;
+  	;
 
 complex_notype_declarator:
-	  '*' nonempty_cv_qualifiers notype_declarator  %prec UNARY
-		{ $$ = make_pointer_declarator ($2.t, $3); }
-	| '&' nonempty_cv_qualifiers notype_declarator  %prec UNARY
-		{ $$ = make_reference_declarator ($2.t, $3); }
+	  '*' nonempty_cv_qualifiers notype_declarator_intern  %prec UNARY
+		{
+		  tree attrs = NULL_TREE;
+		  $$ = make_pointer_declarator ($2.t,
+			   possibly_prefixed_decl ($3, &attrs));
+		  $$ = build_prefixed_decl ($$, attrs);
+		}
+	| '&' nonempty_cv_qualifiers notype_declarator_intern  %prec UNARY
+		{
+		  tree attrs = NULL_TREE;
+		  $$ = make_reference_declarator ($2.t,
+			   possibly_prefixed_decl ($3, &attrs));
+		  $$ = build_prefixed_decl ($$, attrs);
+		}
 	| '*' complex_notype_declarator  %prec UNARY
-		{ $$ = make_pointer_declarator (NULL_TREE, $2); }
+		{
+		  tree attrs = NULL_TREE;
+		  $$ = make_pointer_declarator (NULL_TREE,
+			   possibly_prefixed_decl ($2, &attrs));
+		  $$ = build_prefixed_decl ($$, attrs);
+		}
 	| '&' complex_notype_declarator  %prec UNARY
-		{ $$ = make_reference_declarator (NULL_TREE, $2); }
-	| ptr_to_mem cv_qualifiers notype_declarator
-		{ tree arg = make_pointer_declarator ($2, $3);
+		{
+		  tree attrs = NULL_TREE;
+		  $$ = make_reference_declarator (NULL_TREE,
+			   possibly_prefixed_decl ($2, &attrs));
+		  $$ = build_prefixed_decl ($$, attrs);
+		}
+	| ptr_to_mem cv_qualifiers notype_declarator_intern
+		{
+		  tree arg, attrs = NULL_TREE;
+
+		  arg = make_pointer_declarator ($2,
+			   possibly_prefixed_decl ($3, &attrs));
 		  $$ = build_parse_node (SCOPE_REF, $1, arg);
+		  $$ = build_prefixed_decl ($$, attrs);
 		}
 	| complex_direct_notype_declarator
 	;
 
 complex_direct_notype_declarator:
 	  direct_notype_declarator maybe_parmlist cv_qualifiers exception_specification_opt  %prec '.'
-		{ $$ = make_call_declarator ($$, $2, $3, $4); }
+		{
+		  tree attrs = NULL_TREE;
+		  $$ = make_call_declarator (
+			   possibly_prefixed_decl ($$, &attrs), $2, $3, $4);
+		  $$ = build_prefixed_decl ($$, attrs);
+		}
 	| '(' complex_notype_declarator ')'
 		{ $$ = $2; }
 	| direct_notype_declarator '[' nonmomentary_expr ']'
-		{ $$ = build_parse_node (ARRAY_REF, $$, $3); }
+		{
+		  tree attrs = NULL_TREE;
+		  $$ = build_parse_node (ARRAY_REF,
+					 possibly_prefixed_decl ($$, &attrs),
+					 $3);
+		  $$ = build_prefixed_decl ($$, attrs);
+		}
 	| direct_notype_declarator '[' ']'
-		{ $$ = build_parse_node (ARRAY_REF, $$, NULL_TREE); }
+		{
+		  tree attrs = NULL_TREE;
+		  $$ = build_parse_node (ARRAY_REF,
+					 possibly_prefixed_decl ($$, &attrs),
+					 NULL_TREE);
+		  $$ = build_prefixed_decl ($$, attrs);
+		}
 	| notype_qualified_id
 		{ if (OP0 ($1) != current_class_type)
 		    {
@@ -2796,8 +2927,11 @@ overqualified_id:
 functional_cast:
 	  typespec '(' nonnull_exprlist ')'
 		{ $$ = build_functional_cast ($1.t, $3); }
-	| typespec '(' expr_or_declarator ')'
-		{ $$ = reparse_decl_as_expr ($1.t, $3); }
+	| typespec '(' expr_or_declarator_intern ')'
+		{
+		  $$ = reparse_decl_as_expr ($1.t,
+					     possibly_prefixed_decl ($3, NULL));
+		}
 	| typespec fcast_or_absdcl  %prec EMPTY
 		{ $$ = reparse_absdcl_as_expr ($1.t, $2); }
 	;
@@ -3484,13 +3618,16 @@ named_parm:
 	   TYPESPEC IDENTIFIER.  */
 	  typed_declspecs1 declarator
 		{ tree specs = strip_attrs ($1.t);
-		  $$.new_type_flag = $1.new_type_flag;
-		  $$.t = build_tree_list (specs, $2); }
+		  $2 = possibly_prefixed_decl ($2, NULL);
+		  $$.t = build_tree_list (specs, $2);
+		  $$.new_type_flag = $1.new_type_flag; }
 	| typed_typespecs declarator
-		{ $$.t = build_tree_list ($1.t, $2); 
+		{ $$.t = build_tree_list ($1.t,
+					  possibly_prefixed_decl ($2, NULL)); 
 		  $$.new_type_flag = $1.new_type_flag; }
 	| typespec declarator
-		{ $$.t = build_tree_list (get_decl_list ($1.t), $2); 
+		{ $$.t = build_tree_list (get_decl_list ($1.t),
+					  possibly_prefixed_decl ($2, NULL)); 
 		  $$.new_type_flag = $1.new_type_flag; }
 	| typed_declspecs1 absdcl
 		{ tree specs = strip_attrs ($1.t);
@@ -3502,6 +3639,7 @@ named_parm:
 		  $$.new_type_flag = $1.new_type_flag; }
 	| declmods notype_declarator
 		{ tree specs = strip_attrs ($1);
+		  $2 = possibly_prefixed_decl ($2, NULL);
 		  $$.t = build_tree_list (specs, $2); 
 		  $$.new_type_flag = 0; }
 	;
@@ -3533,7 +3671,12 @@ bad_parm:
 		}
 	| notype_declarator
 		{
+		  tree attrs = NULL_TREE;
+		  
 		  error ("type specifier omitted for parameter");
+		  
+		  $$ = possibly_prefixed_decl ($$, &attrs);
+		  
 		  if (TREE_CODE ($$) == SCOPE_REF
 		      && (TREE_CODE (TREE_OPERAND ($$, 0)) == TEMPLATE_TYPE_PARM
 			  || TREE_CODE (TREE_OPERAND ($$, 0)) == TEMPLATE_TEMPLATE_PARM))


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