This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
C++ parser patch
- To: egcs-patches at cygnus dot com
- Subject: C++ parser patch
- From: Mumit Khan <khan at xraylith dot wisc dot edu>
- Date: Tue, 23 Jun 1998 08:54:22 -0500
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, ¤t_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, ¤t_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, ¤t_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))