This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
C++ PATCH to attribute handling
- From: Jason Merrill <jason at redhat dot com>
- To: gcc-patches at gcc dot gnu dot org
- Date: Thu, 31 Jan 2002 20:11:56 +0000
- Subject: C++ PATCH to attribute handling
This is pretty much a quick hack to allow attributes to apply to types in
casts and to parameter declarations; a more thorough attribute overhaul
should wait for the new parser.
Tested i686-pc-linux-gnu; test in g++.dg/ext/attrib3.C.
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.
*** parse.y.~1~ Thu Jan 31 16:59:01 2002
--- parse.y Thu Jan 31 17:48:58 2002
*************** cp_parse_init ()
*** 301,307 ****
%nonassoc IF
%nonassoc ELSE
! %left IDENTIFIER PFUNCNAME TYPENAME SELFNAME PTYPENAME SCSPEC TYPESPEC CV_QUALIFIER ENUM AGGR ELLIPSIS TYPEOF SIGOF OPERATOR NSNAME TYPENAME_KEYWORD
%left '{' ',' ';'
--- 301,307 ----
%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 '{' ',' ';'
*************** declmods:
*** 1938,1948 ****
}
| 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
--- 1938,1943 ----
*************** nonempty_cv_qualifiers:
*** 2819,2824 ****
--- 2814,2825 ----
| 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
*************** named_parm:
*** 3718,3726 ****
/* 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); }
| typed_typespecs declarator
{ $$.t = build_tree_list ($1.t, $2);
$$.new_type_flag = $1.new_type_flag; }
--- 3719,3726 ----
/* Here we expand typed_declspecs inline to avoid mis-parsing of
TYPESPEC IDENTIFIER. */
typed_declspecs1 declarator
! { $$.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; }
*************** named_parm:
*** 3729,3744 ****
$2);
$$.new_type_flag = $1.new_type_flag; }
| typed_declspecs1 absdcl
! { tree specs = strip_attrs ($1.t);
! $$.t = build_tree_list (specs, $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);
$$.new_type_flag = $1.new_type_flag; }
| declmods notype_declarator
! { tree specs = strip_attrs ($1.t);
! $$.t = build_tree_list (specs, $2);
$$.new_type_flag = 0; }
;
--- 3729,3741 ----
$2);
$$.new_type_flag = $1.new_type_flag; }
| typed_declspecs1 absdcl
! { $$.t = build_tree_list ($1.t, $2);
$$.new_type_flag = $1.new_type_flag; }
| typed_declspecs1 %prec EMPTY
! { $$.t = build_tree_list ($1.t, NULL_TREE);
$$.new_type_flag = $1.new_type_flag; }
| declmods notype_declarator
! { $$.t = build_tree_list ($1.t, $2);
$$.new_type_flag = 0; }
;
*** decl.c.~1~ Thu Jan 31 16:59:01 2002
--- decl.c Thu Jan 31 18:51:32 2002
*************** tree
*** 7127,7137 ****
groktypename (typename)
tree typename;
{
if (TREE_CODE (typename) != TREE_LIST)
return typename;
! return grokdeclarator (TREE_VALUE (typename),
! TREE_PURPOSE (typename),
! TYPENAME, 0, NULL);
}
/* Decode a declarator in an ordinary declaration or data definition.
--- 7127,7142 ----
groktypename (typename)
tree typename;
{
+ tree specs, attrs;
+ tree type;
if (TREE_CODE (typename) != TREE_LIST)
return typename;
! 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.
*************** grokparms (first_parm)
*** 11997,12004 ****
for (parm = first_parm; parm != NULL_TREE; parm = chain)
{
tree type = NULL_TREE;
! register tree decl = TREE_VALUE (parm);
tree init = TREE_PURPOSE (parm);
chain = TREE_CHAIN (parm);
/* @@ weak defense against parse errors. */
--- 12002,12010 ----
for (parm = first_parm; parm != NULL_TREE; parm = chain)
{
tree type = NULL_TREE;
! tree decl = TREE_VALUE (parm);
tree init = TREE_PURPOSE (parm);
+ tree specs, attrs;
chain = TREE_CHAIN (parm);
/* @@ weak defense against parse errors. */
*************** grokparms (first_parm)
*** 12016,12026 ****
if (parm == void_list_node)
break;
! decl = grokdeclarator (TREE_VALUE (decl), TREE_PURPOSE (decl),
! PARM, init != NULL_TREE, NULL);
if (! decl || TREE_TYPE (decl) == error_mark_node)
continue;
type = TREE_TYPE (decl);
if (VOID_TYPE_P (type))
{
--- 12022,12036 ----
if (parm == void_list_node)
break;
! 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))
{