From 98884b267644fd8cc217c77d820e490fb7ce8625 Mon Sep 17 00:00:00 2001 From: Jason Merrill Date: Thu, 31 Jan 2002 15:14:37 -0500 Subject: [PATCH] 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 --- gcc/cp/ChangeLog | 10 ++++++++++ gcc/cp/decl.c | 22 ++++++++++++++++------ gcc/cp/parse.y | 27 ++++++++++++--------------- gcc/testsuite/g++.dg/ext/attrib3.C | 20 ++++++++++++++++++++ 4 files changed, 58 insertions(+), 21 deletions(-) create mode 100644 gcc/testsuite/g++.dg/ext/attrib3.C diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 92f5a4a..f259c96 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,13 @@ +2002-01-31 Jason Merrill + + 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 * decl2.c (cxx_decode_option): Pass 0 as last argument to diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c index 0bb5dfd..e5d1a47 100644 --- a/gcc/cp/decl.c +++ b/gcc/cp/decl.c @@ -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)) { diff --git a/gcc/cp/parse.y b/gcc/cp/parse.y index 83a1cd0..7941a89 100644 --- a/gcc/cp/parse.y +++ b/gcc/cp/parse.y @@ -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; } ; diff --git a/gcc/testsuite/g++.dg/ext/attrib3.C b/gcc/testsuite/g++.dg/ext/attrib3.C new file mode 100644 index 0000000..aabb8d1 --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/attrib3.C @@ -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); +} -- 2.7.4