summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--clang/include/clang/AST/DeclBase.h8
-rw-r--r--clang/lib/AST/DeclBase.cpp23
-rw-r--r--clang/test/Misc/ast-dump-attr.cpp21
-rw-r--r--clang/test/Sema/attr-availability-ios.c4
-rw-r--r--clang/test/Sema/attr-availability-tvos.c8
-rw-r--r--clang/test/Sema/attr-availability-watchos.c4
6 files changed, 53 insertions, 15 deletions
diff --git a/clang/include/clang/AST/DeclBase.h b/clang/include/clang/AST/DeclBase.h
index c174242a906..23870400a32 100644
--- a/clang/include/clang/AST/DeclBase.h
+++ b/clang/include/clang/AST/DeclBase.h
@@ -482,13 +482,7 @@ public:
const AttrVec &getAttrs() const;
void dropAttrs();
-
- void addAttr(Attr *A) {
- if (hasAttrs())
- getAttrs().push_back(A);
- else
- setAttrs(AttrVec(1, A));
- }
+ void addAttr(Attr *A);
using attr_iterator = AttrVec::const_iterator;
using attr_range = llvm::iterator_range<attr_iterator>;
diff --git a/clang/lib/AST/DeclBase.cpp b/clang/lib/AST/DeclBase.cpp
index 6bb2034a9ea..b706e504a3a 100644
--- a/clang/lib/AST/DeclBase.cpp
+++ b/clang/lib/AST/DeclBase.cpp
@@ -836,6 +836,29 @@ void Decl::dropAttrs() {
getASTContext().eraseDeclAttrs(this);
}
+void Decl::addAttr(Attr *A) {
+ if (!hasAttrs()) {
+ setAttrs(AttrVec(1, A));
+ return;
+ }
+
+ AttrVec &Attrs = getAttrs();
+ if (!A->isInherited()) {
+ Attrs.push_back(A);
+ return;
+ }
+
+ // Attribute inheritance is processed after attribute parsing. To keep the
+ // order as in the source code, add inherited attributes before non-inherited
+ // ones.
+ auto I = Attrs.begin(), E = Attrs.end();
+ for (; I != E; ++I) {
+ if (!(*I)->isInherited())
+ break;
+ }
+ Attrs.insert(I, A);
+}
+
const AttrVec &Decl::getAttrs() const {
assert(HasAttrs && "No attrs to get!");
return getASTContext().getDeclAttrs(this);
diff --git a/clang/test/Misc/ast-dump-attr.cpp b/clang/test/Misc/ast-dump-attr.cpp
index 1e4eb7c3195..5ed3c73aa23 100644
--- a/clang/test/Misc/ast-dump-attr.cpp
+++ b/clang/test/Misc/ast-dump-attr.cpp
@@ -209,3 +209,24 @@ namespace TestSuppress {
}
}
}
+
+// Verify the order of attributes in the Ast. It must reflect the order
+// in the parsed source.
+int mergeAttrTest() __attribute__((deprecated)) __attribute__((warn_unused_result));
+int mergeAttrTest() __attribute__((annotate("test")));
+int mergeAttrTest() __attribute__((unused,no_thread_safety_analysis));
+// CHECK: FunctionDecl{{.*}} mergeAttrTest
+// CHECK-NEXT: DeprecatedAttr
+// CHECK-NEXT: WarnUnusedResultAttr
+
+// CHECK: FunctionDecl{{.*}} mergeAttrTest
+// CHECK-NEXT: DeprecatedAttr{{.*}} Inherited
+// CHECK-NEXT: WarnUnusedResultAttr{{.*}} Inherited
+// CHECK-NEXT: AnnotateAttr{{.*}}
+
+// CHECK: FunctionDecl{{.*}} mergeAttrTest
+// CHECK-NEXT: DeprecatedAttr{{.*}} Inherited
+// CHECK-NEXT: WarnUnusedResultAttr{{.*}} Inherited
+// CHECK-NEXT: AnnotateAttr{{.*}} Inherited
+// CHECK-NEXT: UnusedAttr
+// CHECK-NEXT: NoThreadSafetyAnalysisAttr
diff --git a/clang/test/Sema/attr-availability-ios.c b/clang/test/Sema/attr-availability-ios.c
index 3f901bb33cb..f418c7dcfd5 100644
--- a/clang/test/Sema/attr-availability-ios.c
+++ b/clang/test/Sema/attr-availability-ios.c
@@ -7,8 +7,8 @@ void f3(int) __attribute__((availability(ios,introduced=3.0)));
void f4(int) __attribute__((availability(macosx,introduced=10.1,deprecated=10.3,obsoleted=10.5), availability(ios,introduced=2.0,deprecated=2.1,obsoleted=3.0))); // expected-note{{explicitly marked unavailable}}
void f5(int) __attribute__((availability(ios,introduced=2.0))) __attribute__((availability(ios,deprecated=3.0))); // expected-note {{'f5' has been explicitly marked deprecated here}}
-void f6(int) __attribute__((availability(ios,deprecated=3.0)));
-void f6(int) __attribute__((availability(iOS,introduced=2.0))); // expected-note {{'f6' has been explicitly marked deprecated here}}
+void f6(int) __attribute__((availability(ios,deprecated=3.0))); // expected-note {{'f6' has been explicitly marked deprecated here}}
+void f6(int) __attribute__((availability(iOS,introduced=2.0)));
void test() {
f0(0); // expected-warning{{'f0' is deprecated: first deprecated in iOS 2.1}}
diff --git a/clang/test/Sema/attr-availability-tvos.c b/clang/test/Sema/attr-availability-tvos.c
index 4f8c4588ec9..b940a9ad3a9 100644
--- a/clang/test/Sema/attr-availability-tvos.c
+++ b/clang/test/Sema/attr-availability-tvos.c
@@ -7,8 +7,8 @@ void f3(int) __attribute__((availability(tvos,introduced=3.0)));
void f4(int) __attribute__((availability(macosx,introduced=10.1,deprecated=10.3,obsoleted=10.5), availability(tvos,introduced=2.0,deprecated=2.1,obsoleted=3.0))); // expected-note{{explicitly marked unavailable}}
void f5(int) __attribute__((availability(tvos,introduced=2.0))) __attribute__((availability(tvos,deprecated=3.0))); // expected-note {{'f5' has been explicitly marked deprecated here}}
-void f6(int) __attribute__((availability(tvos,deprecated=3.0)));
-void f6(int) __attribute__((availability(tvos,introduced=2.0))); // expected-note {{'f6' has been explicitly marked deprecated here}}
+void f6(int) __attribute__((availability(tvos,deprecated=3.0))); // expected-note {{'f6' has been explicitly marked deprecated here}}
+void f6(int) __attribute__((availability(tvos,introduced=2.0)));
void test() {
f0(0); // expected-warning{{'f0' is deprecated: first deprecated in tvOS 2.1}}
@@ -41,8 +41,8 @@ void f5_tvos(int) __attribute__((availability(tvos,introduced=2.0))) __attribute
void f5_attr_reversed_tvos(int) __attribute__((availability(ios, deprecated=3.0))) __attribute__((availability(tvos,introduced=2.0)));
void f5b_tvos(int) __attribute__((availability(tvos,introduced=2.0))) __attribute__((availability(tvos,deprecated=3.0))); // expected-note {{'f5b_tvos' has been explicitly marked deprecated here}}
void f5c_tvos(int) __attribute__((availability(ios,introduced=2.0))) __attribute__((availability(ios,deprecated=3.0))); // expected-note {{'f5c_tvos' has been explicitly marked deprecated here}}
-void f6_tvos(int) __attribute__((availability(tvos,deprecated=3.0)));
-void f6_tvos(int) __attribute__((availability(tvOS,introduced=2.0))); // expected-note {{'f6_tvos' has been explicitly marked deprecated here}}
+void f6_tvos(int) __attribute__((availability(tvos,deprecated=3.0))); // expected-note {{'f6_tvos' has been explicitly marked deprecated here}}
+void f6_tvos(int) __attribute__((availability(tvOS,introduced=2.0)));
void test_tvos() {
f0_tvos(0); // expected-warning{{'f0_tvos' is deprecated: first deprecated in tvOS 2.1}}
diff --git a/clang/test/Sema/attr-availability-watchos.c b/clang/test/Sema/attr-availability-watchos.c
index 59233986ee4..866efac6a04 100644
--- a/clang/test/Sema/attr-availability-watchos.c
+++ b/clang/test/Sema/attr-availability-watchos.c
@@ -32,8 +32,8 @@ void f5_watchos(int) __attribute__((availability(watchos,introduced=2.0))) __att
void f5_attr_reversed_watchos(int) __attribute__((availability(ios, deprecated=3.0))) __attribute__((availability(watchos,introduced=2.0)));
void f5b_watchos(int) __attribute__((availability(watchos,introduced=2.0))) __attribute__((availability(watchos,deprecated=3.0))); // expected-note {{'f5b_watchos' has been explicitly marked deprecated here}}
void f5c_watchos(int) __attribute__((availability(ios,introduced=2.0))) __attribute__((availability(ios,deprecated=3.0))); // expected-note {{'f5c_watchos' has been explicitly marked deprecated here}}
-void f6_watchos(int) __attribute__((availability(watchos,deprecated=3.0)));
-void f6_watchos(int) __attribute__((availability(watchOS,introduced=2.0))); // expected-note {{'f6_watchos' has been explicitly marked deprecated here}}
+void f6_watchos(int) __attribute__((availability(watchos,deprecated=3.0))); // expected-note {{'f6_watchos' has been explicitly marked deprecated here}}
+void f6_watchos(int) __attribute__((availability(watchOS,introduced=2.0)));
void test_watchos() {
f0_watchos(0); // expected-warning{{'f0_watchos' is deprecated: first deprecated in watchOS 2.1}}
OpenPOWER on IntegriCloud