Allow attributes in parms and casts.
authorjason <jason@138bc75d-0d04-0410-961f-82ee72b054a4>
Thu, 31 Jan 2002 20:14:37 +0000 (20:14 +0000)
committerjason <jason@138bc75d-0d04-0410-961f-82ee72b054a4>
Thu, 31 Jan 2002 20:14:37 +0000 (20:14 +0000)
        * 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.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@49373 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/cp/ChangeLog
gcc/cp/decl.c
gcc/cp/parse.y
gcc/testsuite/g++.dg/ext/attrib3.C [new file with mode: 0644]

index 92f5a4a..f259c96 100644 (file)
@@ -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
index 0bb5dfd..e5d1a47 100644 (file)
@@ -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))
         {
index 83a1cd0..7941a89 100644 (file)
@@ -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 (file)
index 0000000..aabb8d1
--- /dev/null
@@ -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);
+}