aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRafael Espindola <rafael.espindola@gmail.com>2012-05-07 23:58:18 +0000
committerRafael Espindola <rafael.espindola@gmail.com>2012-05-07 23:58:18 +0000
commit9b79fc9c57dc9d541c2a5737c3e2c24cc68d485d (patch)
treeef1106603d82a8c98672f7b6986a2054ed60e8e5
parentca11510d399ae0493bcb3daf24e3c1df399d75f2 (diff)
Process attributes in the order they appear in the source code. This make clang
match gcc behavior for two conflicting visibilities in the same decl. It also makes handling of dllimport/dllexport more natural. As a bonus we now warn on the dllimport in void __attribute__((dllimport)) foo13(); void __attribute__((dllexport)) foo13(); as does gcc. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@156343 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--lib/Sema/SemaDeclAttr.cpp6
-rw-r--r--lib/Sema/TargetAttributesSema.cpp15
-rw-r--r--test/Index/complete-with-annotations.cpp2
-rw-r--r--test/Sema/attr-availability.c4
-rw-r--r--test/Sema/attr-visibility.c3
-rw-r--r--test/Sema/dllimport-dllexport.c3
6 files changed, 19 insertions, 14 deletions
diff --git a/lib/Sema/SemaDeclAttr.cpp b/lib/Sema/SemaDeclAttr.cpp
index f2d1d19d22..47acdf9456 100644
--- a/lib/Sema/SemaDeclAttr.cpp
+++ b/lib/Sema/SemaDeclAttr.cpp
@@ -3986,8 +3986,12 @@ static void ProcessDeclAttribute(Sema &S, Scope *scope, Decl *D,
void Sema::ProcessDeclAttributeList(Scope *S, Decl *D,
const AttributeList *AttrList,
bool NonInheritable, bool Inheritable) {
+ SmallVector<const AttributeList*, 4> attrs;
for (const AttributeList* l = AttrList; l; l = l->getNext()) {
- ProcessDeclAttribute(*this, S, D, *l, NonInheritable, Inheritable);
+ attrs.push_back(l);
+ }
+ for (int i = attrs.size() - 1; i >= 0; --i) {
+ ProcessDeclAttribute(*this, S, D, *attrs[i], NonInheritable, Inheritable);
}
// GCC accepts
diff --git a/lib/Sema/TargetAttributesSema.cpp b/lib/Sema/TargetAttributesSema.cpp
index 8b19be74dd..c0746388e5 100644
--- a/lib/Sema/TargetAttributesSema.cpp
+++ b/lib/Sema/TargetAttributesSema.cpp
@@ -182,16 +182,6 @@ static void HandleDLLImportAttr(Decl *D, const AttributeList &Attr, Sema &S) {
return;
}
- // The attribute is also overridden by a subsequent declaration as dllexport.
- // Warning is emitted.
- for (AttributeList *nextAttr = Attr.getNext(); nextAttr;
- nextAttr = nextAttr->getNext()) {
- if (nextAttr->getKind() == AttributeList::AT_dllexport) {
- S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "dllimport";
- return;
- }
- }
-
if (D->getAttr<DLLExportAttr>()) {
S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "dllimport";
return;
@@ -228,6 +218,11 @@ static void HandleDLLExportAttr(Decl *D, const AttributeList &Attr, Sema &S) {
return;
}
+ if (DLLImportAttr *Import = D->getAttr<DLLImportAttr>()) {
+ S.Diag(Import->getLocation(), diag::warn_attribute_ignored) << "dllimport";
+ D->dropAttr<DLLImportAttr>();
+ }
+
D->addAttr(::new (S.Context) DLLExportAttr(Attr.getLoc(), S.Context));
}
diff --git a/test/Index/complete-with-annotations.cpp b/test/Index/complete-with-annotations.cpp
index afa8d9ed66..3b37e380f3 100644
--- a/test/Index/complete-with-annotations.cpp
+++ b/test/Index/complete-with-annotations.cpp
@@ -14,7 +14,7 @@ void X::doSomething() {
}
// CHECK: CXXMethod:{ResultType void}{TypedText doSomething}{LeftParen (}{RightParen )} (34)
-// CHECK: FieldDecl:{ResultType int}{TypedText field} (35) ("three", "two", "one")
+// CHECK: FieldDecl:{ResultType int}{TypedText field} (35) ("one", "two", "three")
// CHECK: CXXMethod:{ResultType void}{TypedText func2}{LeftParen (}{RightParen )} (34) ("some annotation")
// CHECK: FieldDecl:{ResultType int}{TypedText member2} (35) ("another annotation", "some annotation")
// CHECK: CXXMethod:{ResultType X &}{TypedText operator=}{LeftParen (}{Placeholder const X &}{RightParen )} (34)
diff --git a/test/Sema/attr-availability.c b/test/Sema/attr-availability.c
index 89252a6cc4..a13e351a6e 100644
--- a/test/Sema/attr-availability.c
+++ b/test/Sema/attr-availability.c
@@ -28,8 +28,8 @@ enum {
void f4(int) __attribute__((availability(ios,deprecated=3.0)));
void f4(int) __attribute__((availability(ios,introduced=4.0))); // expected-warning {{feature cannot be deprecated in iOS version 3.0 before it was introduced in version 4.0; attribute ignored}}
-void f5(int) __attribute__((availability(ios,deprecated=3.0), // expected-warning {{feature cannot be deprecated in iOS version 3.0 before it was introduced in version 4.0; attribute ignored}}
- availability(ios,introduced=4.0)));
+void f5(int) __attribute__((availability(ios,deprecated=3.0),
+ availability(ios,introduced=4.0))); // expected-warning {{feature cannot be deprecated in iOS version 3.0 before it was introduced in version 4.0; attribute ignored}}
void f6(int) __attribute__((availability(ios,deprecated=3.0))); // expected-note {{previous attribute is here}}
void f6(int) __attribute__((availability(ios,deprecated=4.0))); // expected-warning {{availability does not match previous declaration}}
diff --git a/test/Sema/attr-visibility.c b/test/Sema/attr-visibility.c
index 4996dca5be..cb549921ab 100644
--- a/test/Sema/attr-visibility.c
+++ b/test/Sema/attr-visibility.c
@@ -14,3 +14,6 @@ struct __attribute__((visibility("default"))) test4; // expected-error {{visibil
struct test5;
struct __attribute__((visibility("hidden"))) test5; // expected-note {{previous attribute is here}}
struct __attribute__((visibility("default"))) test5; // expected-error {{visibility does not match previous declaration}}
+
+void test6() __attribute__((visibility("hidden"), // expected-note {{previous attribute is here}}
+ visibility("default"))); // expected-error {{visibility does not match previous declaration}}
diff --git a/test/Sema/dllimport-dllexport.c b/test/Sema/dllimport-dllexport.c
index 610059ec9f..4c04902697 100644
--- a/test/Sema/dllimport-dllexport.c
+++ b/test/Sema/dllimport-dllexport.c
@@ -35,3 +35,6 @@ typedef int __declspec(dllimport) type2; // expected-warning{{'dllimport' attrib
void __declspec(dllimport) foo12();
void foo12(){} // expected-warning {{'foo12' redeclared without dllimport attribute: previous dllimport ignored}}
+
+void __attribute__((dllimport)) foo13(); // expected-warning{{dllimport attribute ignored}}
+void __attribute__((dllexport)) foo13();