]> granicus.if.org Git - clang/commitdiff
Add inherited attributes before parsed attributes.
authorMichael Kruse <llvm@meinersbur.de>
Mon, 24 Sep 2018 06:31:37 +0000 (06:31 +0000)
committerMichael Kruse <llvm@meinersbur.de>
Mon, 24 Sep 2018 06:31:37 +0000 (06:31 +0000)
Currently, attributes from previous declarations ('inherited attributes')
are added to the end of a declaration's list of attributes. Before
r338800, the attribute list was in reverse. r338800 changed the order
of non-inherited (parsed from the current declaration) attributes, but
inherited attributes are still appended to the end of the list.

This patch appends inherited attributes after other inherited
attributes, but before any non-inherited attribute. This is to make the
order of attributes in the AST correspond to the order in the source
code.

Differential Revision: https://reviews.llvm.org/D50214

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

include/clang/AST/DeclBase.h
lib/AST/DeclBase.cpp
test/Misc/ast-dump-attr.cpp
test/Sema/attr-availability-ios.c
test/Sema/attr-availability-tvos.c
test/Sema/attr-availability-watchos.c

index c174242a9068fbe561a5d215ca8fc384de067e3b..23870400a321b10633899d0b8b03369e4262578c 100644 (file)
@@ -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>;
index 6bb2034a9ea95965666cc97cc209f2d46f6ac7f4..b706e504a3ad1457c4b549139776363bf8865dfc 100644 (file)
@@ -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);
index 1e4eb7c31955e11e2fd39f89d0ba3991b2aef284..5ed3c73aa2370bf93f1a2d257c95ab7e835e5290 100644 (file)
@@ -209,3 +209,24 @@ namespace TestSuppress {
       }\r
     }\r
 }\r
+\r
+// Verify the order of attributes in the Ast. It must reflect the order\r
+// in the parsed source.\r
+int mergeAttrTest() __attribute__((deprecated)) __attribute__((warn_unused_result));\r
+int mergeAttrTest() __attribute__((annotate("test")));\r
+int mergeAttrTest() __attribute__((unused,no_thread_safety_analysis));\r
+// CHECK: FunctionDecl{{.*}} mergeAttrTest\r
+// CHECK-NEXT: DeprecatedAttr\r
+// CHECK-NEXT: WarnUnusedResultAttr\r
+\r
+// CHECK: FunctionDecl{{.*}} mergeAttrTest\r
+// CHECK-NEXT: DeprecatedAttr{{.*}} Inherited\r
+// CHECK-NEXT: WarnUnusedResultAttr{{.*}} Inherited\r
+// CHECK-NEXT: AnnotateAttr{{.*}}\r
+\r
+// CHECK: FunctionDecl{{.*}} mergeAttrTest\r
+// CHECK-NEXT: DeprecatedAttr{{.*}} Inherited\r
+// CHECK-NEXT: WarnUnusedResultAttr{{.*}} Inherited\r
+// CHECK-NEXT: AnnotateAttr{{.*}} Inherited\r
+// CHECK-NEXT: UnusedAttr\r
+// CHECK-NEXT: NoThreadSafetyAnalysisAttr\r
index 3f901bb33cb5a08e57d52edbcb6eb6c928dd4b7a..f418c7dcfd5f805a71a0791bcf4970ca7737062c 100644 (file)
@@ -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}}
index 4f8c4588ec989f98d3c94801d17e7b53369b0d4d..b940a9ad3a998a017ea2b2f1ad6664b20b838505 100644 (file)
@@ -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}}
index 59233986ee4601ac0ce74a57044daafaf9e861b9..866efac6a04faecb503600956b6b4cc04f0a4bae 100644 (file)
@@ -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}}