Allow attributes in parms and casts.
* parse.y (named_parm): Don't strip attrs. (declmods): Remove 'attributes' production. (nonempty_cv_qualifiers): Accept attributes. (ATTRIBUTE): Give precedence. * decl.c (groktypename): Handle attributes. (grokparms): Likewise. From-SVN: r49373
This commit is contained in:
parent
8512bbd752
commit
98884b2676
@ -1,3 +1,13 @@
|
||||
2002-01-31 Jason Merrill <jason@redhat.com>
|
||||
|
||||
Allow attributes in parms and casts.
|
||||
* parse.y (named_parm): Don't strip attrs.
|
||||
(declmods): Remove 'attributes' production.
|
||||
(nonempty_cv_qualifiers): Accept attributes.
|
||||
(ATTRIBUTE): Give precedence.
|
||||
* decl.c (groktypename): Handle attributes.
|
||||
(grokparms): Likewise.
|
||||
|
||||
2002-01-29 Jakub Jelinek <jakub@redhat.com>
|
||||
|
||||
* decl2.c (cxx_decode_option): Pass 0 as last argument to
|
||||
|
@ -7127,11 +7127,16 @@ tree
|
||||
groktypename (typename)
|
||||
tree typename;
|
||||
{
|
||||
tree specs, attrs;
|
||||
tree type;
|
||||
if (TREE_CODE (typename) != TREE_LIST)
|
||||
return typename;
|
||||
return grokdeclarator (TREE_VALUE (typename),
|
||||
TREE_PURPOSE (typename),
|
||||
TYPENAME, 0, NULL);
|
||||
split_specs_attrs (TREE_PURPOSE (typename), &specs, &attrs);
|
||||
type = grokdeclarator (TREE_VALUE (typename), specs,
|
||||
TYPENAME, 0, &attrs);
|
||||
if (attrs)
|
||||
cplus_decl_attributes (&type, attrs, 0);
|
||||
return type;
|
||||
}
|
||||
|
||||
/* Decode a declarator in an ordinary declaration or data definition.
|
||||
@ -11997,8 +12002,9 @@ grokparms (first_parm)
|
||||
for (parm = first_parm; parm != NULL_TREE; parm = chain)
|
||||
{
|
||||
tree type = NULL_TREE;
|
||||
register tree decl = TREE_VALUE (parm);
|
||||
tree decl = TREE_VALUE (parm);
|
||||
tree init = TREE_PURPOSE (parm);
|
||||
tree specs, attrs;
|
||||
|
||||
chain = TREE_CHAIN (parm);
|
||||
/* @@ weak defense against parse errors. */
|
||||
@ -12016,11 +12022,15 @@ grokparms (first_parm)
|
||||
if (parm == void_list_node)
|
||||
break;
|
||||
|
||||
decl = grokdeclarator (TREE_VALUE (decl), TREE_PURPOSE (decl),
|
||||
PARM, init != NULL_TREE, NULL);
|
||||
split_specs_attrs (TREE_PURPOSE (decl), &specs, &attrs);
|
||||
decl = grokdeclarator (TREE_VALUE (decl), specs,
|
||||
PARM, init != NULL_TREE, &attrs);
|
||||
if (! decl || TREE_TYPE (decl) == error_mark_node)
|
||||
continue;
|
||||
|
||||
if (attrs)
|
||||
cplus_decl_attributes (&decl, attrs, 0);
|
||||
|
||||
type = TREE_TYPE (decl);
|
||||
if (VOID_TYPE_P (type))
|
||||
{
|
||||
|
@ -301,7 +301,7 @@ cp_parse_init ()
|
||||
%nonassoc IF
|
||||
%nonassoc ELSE
|
||||
|
||||
%left IDENTIFIER PFUNCNAME TYPENAME SELFNAME PTYPENAME SCSPEC TYPESPEC CV_QUALIFIER ENUM AGGR ELLIPSIS TYPEOF SIGOF OPERATOR NSNAME TYPENAME_KEYWORD
|
||||
%left IDENTIFIER PFUNCNAME TYPENAME SELFNAME PTYPENAME SCSPEC TYPESPEC CV_QUALIFIER ENUM AGGR ELLIPSIS TYPEOF SIGOF OPERATOR NSNAME TYPENAME_KEYWORD ATTRIBUTE
|
||||
|
||||
%left '{' ',' ';'
|
||||
|
||||
@ -1938,11 +1938,6 @@ declmods:
|
||||
}
|
||||
| declmods attributes
|
||||
{ $$.t = hash_tree_cons ($2, NULL_TREE, $1.t); }
|
||||
| attributes %prec EMPTY
|
||||
{
|
||||
$$.t = hash_tree_cons ($1, NULL_TREE, NULL_TREE);
|
||||
$$.new_type_flag = 0; $$.lookups = NULL_TREE;
|
||||
}
|
||||
;
|
||||
|
||||
/* Used instead of declspecs where storage classes are not allowed
|
||||
@ -2819,6 +2814,12 @@ nonempty_cv_qualifiers:
|
||||
| nonempty_cv_qualifiers CV_QUALIFIER
|
||||
{ $$.t = hash_tree_cons (NULL_TREE, $2, $1.t);
|
||||
$$.new_type_flag = $1.new_type_flag; }
|
||||
| attributes %prec EMPTY
|
||||
{ $$.t = hash_tree_cons ($1, NULL_TREE, NULL_TREE);
|
||||
$$.new_type_flag = 0; }
|
||||
| nonempty_cv_qualifiers attributes %prec EMPTY
|
||||
{ $$.t = hash_tree_cons ($2, NULL_TREE, $1.t);
|
||||
$$.new_type_flag = $1.new_type_flag; }
|
||||
;
|
||||
|
||||
/* These rules must follow the rules for function declarations
|
||||
@ -3718,9 +3719,8 @@ named_parm:
|
||||
/* Here we expand typed_declspecs inline to avoid mis-parsing of
|
||||
TYPESPEC IDENTIFIER. */
|
||||
typed_declspecs1 declarator
|
||||
{ tree specs = strip_attrs ($1.t);
|
||||
$$.new_type_flag = $1.new_type_flag;
|
||||
$$.t = build_tree_list (specs, $2); }
|
||||
{ $$.new_type_flag = $1.new_type_flag;
|
||||
$$.t = build_tree_list ($1.t, $2); }
|
||||
| typed_typespecs declarator
|
||||
{ $$.t = build_tree_list ($1.t, $2);
|
||||
$$.new_type_flag = $1.new_type_flag; }
|
||||
@ -3729,16 +3729,13 @@ named_parm:
|
||||
$2);
|
||||
$$.new_type_flag = $1.new_type_flag; }
|
||||
| typed_declspecs1 absdcl
|
||||
{ tree specs = strip_attrs ($1.t);
|
||||
$$.t = build_tree_list (specs, $2);
|
||||
{ $$.t = build_tree_list ($1.t, $2);
|
||||
$$.new_type_flag = $1.new_type_flag; }
|
||||
| typed_declspecs1 %prec EMPTY
|
||||
{ tree specs = strip_attrs ($1.t);
|
||||
$$.t = build_tree_list (specs, NULL_TREE);
|
||||
{ $$.t = build_tree_list ($1.t, NULL_TREE);
|
||||
$$.new_type_flag = $1.new_type_flag; }
|
||||
| declmods notype_declarator
|
||||
{ tree specs = strip_attrs ($1.t);
|
||||
$$.t = build_tree_list (specs, $2);
|
||||
{ $$.t = build_tree_list ($1.t, $2);
|
||||
$$.new_type_flag = 0; }
|
||||
;
|
||||
|
||||
|
20
gcc/testsuite/g++.dg/ext/attrib3.C
Normal file
20
gcc/testsuite/g++.dg/ext/attrib3.C
Normal file
@ -0,0 +1,20 @@
|
||||
// Test that attributes work in a variety of situations.
|
||||
// { dg-do run }
|
||||
|
||||
#define attrib __attribute ((mode (QI)))
|
||||
|
||||
attrib signed int a; // attributes before type are broken
|
||||
attrib unsigned int b;
|
||||
|
||||
int foo(attrib int o) // attribute arguments are broken
|
||||
{
|
||||
return (sizeof (a) != 1
|
||||
|| sizeof (b) != 1
|
||||
|| sizeof (o) != 1
|
||||
|| sizeof ((attrib signed int) b) != 1);
|
||||
}
|
||||
|
||||
int main ()
|
||||
{
|
||||
return foo (42);
|
||||
}
|
Loading…
Reference in New Issue
Block a user