summaryrefslogtreecommitdiffstats
path: root/clang
diff options
context:
space:
mode:
authorChris Lattner <sabre@nondot.org>2008-10-20 04:57:38 +0000
committerChris Lattner <sabre@nondot.org>2008-10-20 04:57:38 +0000
commit29e6f2b674bd463bdba4e26d175eacd27f97b31c (patch)
treed99b23797e012808dbf5364da76a89931af67c3b /clang
parent8ff2c6c9f060b30f31c88d79d76a5c665157cbe3 (diff)
downloadbcm5719-llvm-29e6f2b674bd463bdba4e26d175eacd27f97b31c.tar.gz
bcm5719-llvm-29e6f2b674bd463bdba4e26d175eacd27f97b31c.zip
Support attributes in *yet another* place. Is there any place you
can't stick an attributes? llvm-svn: 57795
Diffstat (limited to 'clang')
-rw-r--r--clang/include/clang/Parse/DeclSpec.h13
-rw-r--r--clang/lib/Parse/ParseDecl.cpp11
-rw-r--r--clang/test/Parser/attributes.c12
3 files changed, 31 insertions, 5 deletions
diff --git a/clang/include/clang/Parse/DeclSpec.h b/clang/include/clang/Parse/DeclSpec.h
index c929f087677..22d75a61512 100644
--- a/clang/include/clang/Parse/DeclSpec.h
+++ b/clang/include/clang/Parse/DeclSpec.h
@@ -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; }
diff --git a/clang/lib/Parse/ParseDecl.cpp b/clang/lib/Parse/ParseDecl.cpp
index 78793cef1ee..041d876f567 100644
--- a/clang/lib/Parse/ParseDecl.cpp
+++ b/clang/lib/Parse/ParseDecl.cpp
@@ -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);
}
diff --git a/clang/test/Parser/attributes.c b/clang/test/Parser/attributes.c
index 0746517daa5..d7fc35d92b3 100644
--- a/clang/test/Parser/attributes.c
+++ b/clang/test/Parser/attributes.c
@@ -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);
+
OpenPOWER on IntegriCloud