diff --git a/clang/lib/Sema/SemaDeclAttr.cpp b/clang/lib/Sema/SemaDeclAttr.cpp index f2d1d19d22da..47acdf9456f3 100644 --- a/clang/lib/Sema/SemaDeclAttr.cpp +++ b/clang/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 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/clang/lib/Sema/TargetAttributesSema.cpp b/clang/lib/Sema/TargetAttributesSema.cpp index 8b19be74dd43..c0746388e595 100644 --- a/clang/lib/Sema/TargetAttributesSema.cpp +++ b/clang/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()) { 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()) { + S.Diag(Import->getLocation(), diag::warn_attribute_ignored) << "dllimport"; + D->dropAttr(); + } + D->addAttr(::new (S.Context) DLLExportAttr(Attr.getLoc(), S.Context)); } diff --git a/clang/test/Index/complete-with-annotations.cpp b/clang/test/Index/complete-with-annotations.cpp index afa8d9ed6607..3b37e380f3bd 100644 --- a/clang/test/Index/complete-with-annotations.cpp +++ b/clang/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/clang/test/Sema/attr-availability.c b/clang/test/Sema/attr-availability.c index 89252a6cc40b..a13e351a6e95 100644 --- a/clang/test/Sema/attr-availability.c +++ b/clang/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/clang/test/Sema/attr-visibility.c b/clang/test/Sema/attr-visibility.c index 4996dca5be77..cb549921abe2 100644 --- a/clang/test/Sema/attr-visibility.c +++ b/clang/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/clang/test/Sema/dllimport-dllexport.c b/clang/test/Sema/dllimport-dllexport.c index 610059ec9f6b..4c049026978b 100644 --- a/clang/test/Sema/dllimport-dllexport.c +++ b/clang/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();