Add inherited attributes before parsed attributes.

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

llvm-svn: 342861
This commit is contained in:
Michael Kruse
2018-09-24 06:31:37 +00:00
parent 2b8107614c
commit 4c99f5fe2b
6 changed files with 53 additions and 15 deletions

View 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>;

View 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);

View File

@@ -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

View 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}}

View 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}}

View 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}}