]> granicus.if.org Git - clang/commitdiff
Support attributes in *yet another* place. Is there any place you
authorChris Lattner <sabre@nondot.org>
Mon, 20 Oct 2008 04:57:38 +0000 (04:57 +0000)
committerChris Lattner <sabre@nondot.org>
Mon, 20 Oct 2008 04:57:38 +0000 (04:57 +0000)
can't stick an attributes?

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@57795 91177308-0d34-0410-b5e6-96231b3b80d8

include/clang/Parse/DeclSpec.h
lib/Parse/ParseDecl.cpp
test/Parser/attributes.c

index c929f08767735f1bd7a715fd976d32d27354ced5..22d75a61512232e1003ff1ea58c38d0e560b4b97 100644 (file)
@@ -718,17 +718,20 @@ public:
   }
   
   /// AddAttributes - simply adds the attribute list to the Declarator.
-  /// Unlike AddAttributes on DeclSpec, this routine should never have to
-  /// concatenate two lists. The following syntax adds 3 attributes to "var":
-  ///
-  /// short int var __attribute__((aligned(16),common,deprecated));
+  /// These examples both add 3 attributes to "var":
+  ///  short int var __attribute__((aligned(16),common,deprecated));
+  ///  short int x, __attribute__((aligned(16)) var
+  ///                                 __attribute__((common,deprecated));
   ///
   void AddAttributes(AttributeList *alist) { 
     if (!alist)
       return; // we parsed __attribute__(()) or had a syntax error
-    assert((AttrList == 0) && "Declarator already has an attribute list");
+    
+    if (AttrList) 
+      alist->addAttributeList(AttrList); 
     AttrList = alist;
   }
+  
   const AttributeList *getAttributes() const { return AttrList; }
   AttributeList *getAttributes() { return AttrList; }
 
index 78793cef1eec70da5c3cd218c8af79f4a897e95c..041d876f56709480de35b8e3767420c868ebaa44 100644 (file)
@@ -321,6 +321,17 @@ ParseInitDeclaratorListAfterFirstDeclarator(Declarator &D) {
     
     // Parse the next declarator.
     D.clear();
+    
+    // Accept attributes in an init-declarator.  In the first declarator in a
+    // declaration, these would be part of the declspec.  In subsequent
+    // declarators, they become part of the declarator itself, so that they
+    // don't apply to declarators after *this* one.  Examples:
+    //    short __attribute__((common)) var;    -> declspec
+    //    short var __attribute__((common));    -> declarator
+    //    short x, __attribute__((common)) var;    -> declarator
+    if (Tok.is(tok::kw___attribute))
+      D.AddAttributes(ParseAttributes());
+    
     ParseDeclarator(D);
   }
   
index 0746517daa5b6fea148c218dafb38e686581b57f..d7fc35d92b3a483df5a427635c2ad4aa7555fe2d 100644 (file)
@@ -43,3 +43,15 @@ void (*h2)(int (*f2)(y, attribute(()) x));    // expected-error {{expected ident
 
 void (*h3)(void (*f3)(attribute(()) x));   // expected-warning {{defaults to 'int'}}
 void (*h4)(void (*f4)(attribute(())));  // expected-error {{expected parameter declarator}}
+
+
+
+// rdar://6131260
+int foo42(void) {
+  int x, attribute((unused)) y, z;
+  return 0;
+}
+
+// rdar://6096491
+void attribute((noreturn)) d0(void), attribute((noreturn)) d1(void);
+