Quellcode durchsuchen

Revert "Append new attributes to the end of an AttributeList."

This reverts commit r335084 as requested by David Jones and
Eric Christopher because of differences of emitted warnings.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@335516 91177308-0d34-0410-b5e6-96231b3b80d8
Michael Kruse vor 7 Jahren
Ursprung
Commit
f479c70eb4

+ 2 - 5
include/clang/Sema/AttributeList.h

@@ -764,11 +764,8 @@ public:
   void add(AttributeList *newAttr) {
     assert(newAttr);
     assert(newAttr->getNext() == nullptr);
-
-    // FIXME: AttributeList is a singly linked list, i.e. appending to the end
-    // requires walking to the last element. For adding n attributes, this
-    // requires O(n^2) time. However, AttributeLists should be very short.
-    addAllAtEnd(newAttr);
+    newAttr->setNext(list);
+    list = newAttr;
   }
 
   void addAll(AttributeList *newList) {

+ 4 - 2
lib/AST/ItaniumMangle.cpp

@@ -707,8 +707,10 @@ void CXXNameMangler::mangleFunctionEncodingBareType(const FunctionDecl *FD) {
   if (FD->hasAttr<EnableIfAttr>()) {
     FunctionTypeDepthState Saved = FunctionTypeDepth.push();
     Out << "Ua9enable_ifI";
-    for (AttrVec::const_iterator I = FD->getAttrs().begin(),
-                                 E = FD->getAttrs().end();
+    // FIXME: specific_attr_iterator iterates in reverse order. Fix that and use
+    // it here.
+    for (AttrVec::const_reverse_iterator I = FD->getAttrs().rbegin(),
+                                         E = FD->getAttrs().rend();
          I != E; ++I) {
       EnableIfAttr *EIA = dyn_cast<EnableIfAttr>(*I);
       if (!EIA)

+ 3 - 1
lib/Parse/ParseDecl.cpp

@@ -1649,7 +1649,9 @@ void Parser::stripTypeAttributesOffDeclSpec(ParsedAttributesWithRange &Attrs,
   }
 
   // Find end of type attributes Attrs and add NewTypeAttributes in the same
-  // order they were in originally.
+  // order they were in originally.  (Remember, in AttributeList things earlier
+  // in source order are later in the list, since new attributes are added to
+  // the front of the list.)
   Attrs.addAllAtEnd(TypeAttrHead);
 }
 

+ 34 - 13
lib/Sema/SemaOverload.cpp

@@ -6189,6 +6189,24 @@ Sema::SelectBestMethod(Selector Sel, MultiExprArg Args, bool IsInstance,
   return nullptr;
 }
 
+// specific_attr_iterator iterates over enable_if attributes in reverse, and
+// enable_if is order-sensitive. As a result, we need to reverse things
+// sometimes. Size of 4 elements is arbitrary.
+static SmallVector<EnableIfAttr *, 4>
+getOrderedEnableIfAttrs(const FunctionDecl *Function) {
+  SmallVector<EnableIfAttr *, 4> Result;
+  if (!Function->hasAttrs())
+    return Result;
+
+  const auto &FuncAttrs = Function->getAttrs();
+  for (Attr *Attr : FuncAttrs)
+    if (auto *EnableIf = dyn_cast<EnableIfAttr>(Attr))
+      Result.push_back(EnableIf);
+
+  std::reverse(Result.begin(), Result.end());
+  return Result;
+}
+
 static bool
 convertArgsForAvailabilityChecks(Sema &S, FunctionDecl *Function, Expr *ThisArg,
                                  ArrayRef<Expr *> Args, Sema::SFINAETrap &Trap,
@@ -6262,9 +6280,9 @@ convertArgsForAvailabilityChecks(Sema &S, FunctionDecl *Function, Expr *ThisArg,
 
 EnableIfAttr *Sema::CheckEnableIf(FunctionDecl *Function, ArrayRef<Expr *> Args,
                                   bool MissingImplicitThis) {
-  auto EnableIfAttrs = Function->specific_attrs<EnableIfAttr>();
-
-  if (EnableIfAttrs.begin() == EnableIfAttrs.end())
+  SmallVector<EnableIfAttr *, 4> EnableIfAttrs =
+      getOrderedEnableIfAttrs(Function);
+  if (EnableIfAttrs.empty())
     return nullptr;
 
   SFINAETrap Trap(*this);
@@ -6274,7 +6292,7 @@ EnableIfAttr *Sema::CheckEnableIf(FunctionDecl *Function, ArrayRef<Expr *> Args,
   if (!convertArgsForAvailabilityChecks(
           *this, Function, /*ThisArg=*/nullptr, Args, Trap,
           /*MissingImplicitThis=*/true, DiscardedThis, ConvertedArgs))
-    return *EnableIfAttrs.begin();
+    return EnableIfAttrs[0];
 
   for (auto *EIA : EnableIfAttrs) {
     APValue Result;
@@ -8923,21 +8941,24 @@ static Comparison compareEnableIfAttrs(const Sema &S, const FunctionDecl *Cand1,
     return Cand1Attr ? Comparison::Better : Comparison::Worse;
   }
 
-  auto Cand1Attrs = Cand1->specific_attrs<EnableIfAttr>();
-  auto Cand2Attrs = Cand2->specific_attrs<EnableIfAttr>();
+  // FIXME: The next several lines are just
+  // specific_attr_iterator<EnableIfAttr> but going in declaration order,
+  // instead of reverse order which is how they're stored in the AST.
+  auto Cand1Attrs = getOrderedEnableIfAttrs(Cand1);
+  auto Cand2Attrs = getOrderedEnableIfAttrs(Cand2);
+
+  // It's impossible for Cand1 to be better than (or equal to) Cand2 if Cand1
+  // has fewer enable_if attributes than Cand2.
+  if (Cand1Attrs.size() < Cand2Attrs.size())
+    return Comparison::Worse;
 
   auto Cand1I = Cand1Attrs.begin();
   llvm::FoldingSetNodeID Cand1ID, Cand2ID;
-  for (auto Cand2A : Cand2Attrs) {
+  for (auto &Cand2A : Cand2Attrs) {
     Cand1ID.clear();
     Cand2ID.clear();
 
-    // It's impossible for Cand1 to be better than (or equal to) Cand2 if Cand1
-    // has fewer enable_if attributes than Cand2.
-    if (Cand1I == Cand1Attrs.end())
-      return Comparison::Worse;
-    auto Cand1A = Cand1I++;
-
+    auto &Cand1A = *Cand1I++;
     Cand1A->getCond()->Profile(Cand1ID, S.getASTContext(), true);
     Cand2A->getCond()->Profile(Cand2ID, S.getASTContext(), true);
     if (Cand1ID != Cand2ID)

+ 22 - 11
lib/Serialization/ASTReaderDecl.cpp

@@ -2804,25 +2804,36 @@ static bool hasSameOverloadableAttrs(const FunctionDecl *A,
   // Note that pass_object_size attributes are represented in the function's
   // ExtParameterInfo, so we don't need to check them here.
 
-  // Return false if any of the enable_if expressions of A and B are different.
+  SmallVector<const EnableIfAttr *, 4> AEnableIfs;
+  // Since this is an equality check, we can ignore that enable_if attrs show up
+  // in reverse order.
+  for (const auto *EIA : A->specific_attrs<EnableIfAttr>())
+    AEnableIfs.push_back(EIA);
+
+  SmallVector<const EnableIfAttr *, 4> BEnableIfs;
+  for (const auto *EIA : B->specific_attrs<EnableIfAttr>())
+    BEnableIfs.push_back(EIA);
+
+  // Two very common cases: either we have 0 enable_if attrs, or we have an
+  // unequal number of enable_if attrs.
+  if (AEnableIfs.empty() && BEnableIfs.empty())
+    return true;
+
+  if (AEnableIfs.size() != BEnableIfs.size())
+    return false;
+
   llvm::FoldingSetNodeID Cand1ID, Cand2ID;
-  auto AEnableIfAttrs = A->specific_attrs<EnableIfAttr>();
-  auto BEnableIfAttrs = B->specific_attrs<EnableIfAttr>();
-  auto AEnableIf = AEnableIfAttrs.begin();
-  auto BEnableIf = BEnableIfAttrs.begin();
-  for (; AEnableIf != AEnableIfAttrs.end() && BEnableIf != BEnableIfAttrs.end();
-       ++BEnableIf, ++AEnableIf) {
+  for (unsigned I = 0, E = AEnableIfs.size(); I != E; ++I) {
     Cand1ID.clear();
     Cand2ID.clear();
 
-    AEnableIf->getCond()->Profile(Cand1ID, A->getASTContext(), true);
-    BEnableIf->getCond()->Profile(Cand2ID, B->getASTContext(), true);
+    AEnableIfs[I]->getCond()->Profile(Cand1ID, A->getASTContext(), true);
+    BEnableIfs[I]->getCond()->Profile(Cand2ID, B->getASTContext(), true);
     if (Cand1ID != Cand2ID)
       return false;
   }
 
-  // Return false if the number of enable_if attributes was different.
-  return AEnableIf == AEnableIfAttrs.end() && BEnableIf == BEnableIfAttrs.end();
+  return true;
 }
 
 /// Determine whether the two declarations refer to the same entity.

+ 1 - 1
test/Index/annotate-comments-availability-attrs.cpp

@@ -13,7 +13,7 @@
 void attr_availability_1() __attribute__((availability(macosx,obsoleted=10.0,introduced=8.0,deprecated=9.0, message="use availability_test in <foo.h>")))
                            __attribute__((availability(ios,unavailable, message="not for iOS")));
 
-// CHECK: FullCommentAsXML=[<Function file="{{[^"]+}}annotate-comments-availability-attrs.cpp" line="[[@LINE-3]]" column="6"><Name>attr_availability_1</Name><USR>c:@F@attr_availability_1#</USR><Declaration>void attr_availability_1()</Declaration><Abstract><Para> Aaa.</Para></Abstract><Availability distribution="macOS"><IntroducedInVersion>8.0</IntroducedInVersion><DeprecatedInVersion>9.0</DeprecatedInVersion><RemovedAfterVersion>10.0</RemovedAfterVersion><DeprecationSummary>use availability_test in &lt;foo.h&gt;</DeprecationSummary></Availability><Availability distribution="iOS"><DeprecationSummary>not for iOS</DeprecationSummary><Unavailable/></Availability></Function>]
+// CHECK: FullCommentAsXML=[<Function file="{{[^"]+}}annotate-comments-availability-attrs.cpp" line="[[@LINE-3]]" column="6"><Name>attr_availability_1</Name><USR>c:@F@attr_availability_1#</USR><Declaration>void attr_availability_1()</Declaration><Abstract><Para> Aaa.</Para></Abstract><Availability distribution="iOS"><DeprecationSummary>not for iOS</DeprecationSummary><Unavailable/></Availability><Availability distribution="macOS"><IntroducedInVersion>8.0</IntroducedInVersion><DeprecatedInVersion>9.0</DeprecatedInVersion><RemovedAfterVersion>10.0</RemovedAfterVersion><DeprecationSummary>use availability_test in &lt;foo.h&gt;</DeprecationSummary></Availability></Function>]
 
 /// Aaa.
 void attr_availability_2() __attribute__((availability(macosx,obsoleted=10.0.1,introduced=8.0.1,deprecated=9.0.1)));

+ 1 - 1
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) ("one", "two", "three")
+// CHECK: FieldDecl:{ResultType int}{TypedText field} (35) ("three", "two", "one")
 // 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 )} (79)

+ 10 - 7
test/Misc/ast-print-pragmas.cpp

@@ -1,8 +1,11 @@
 // RUN: %clang_cc1 -ast-print %s -o - | FileCheck %s
 // RUN: %clang_cc1 -DMS_EXT -fsyntax-only -fms-extensions %s -triple x86_64-pc-win32 -ast-print | FileCheck %s --check-prefix=MS-EXT
 
-// CHECK: #pragma clang loop vectorize_width(4)
-// CHECK-NEXT: #pragma clang loop interleave_count(8){{$}}
+// FIXME: A bug in ParsedAttributes causes the order of the attributes to be
+// reversed. The checks are consequently in the reverse order below.
+
+// CHECK: #pragma clang loop interleave_count(8){{$}}
+// CHECK-NEXT: #pragma clang loop vectorize_width(4)
 
 void test(int *List, int Length) {
   int i = 0;
@@ -14,9 +17,9 @@ void test(int *List, int Length) {
     i++;
   }
 
-// CHECK: #pragma clang loop distribute(disable)
+// CHECK: #pragma clang loop interleave(disable)
 // CHECK-NEXT: #pragma clang loop vectorize(enable)
-// CHECK-NEXT: #pragma clang loop interleave(disable)
+// CHECK-NEXT: #pragma clang loop distribute(disable)
 
 #pragma clang loop distribute(disable)
 #pragma clang loop vectorize(enable)
@@ -27,9 +30,9 @@ void test(int *List, int Length) {
     i++;
   }
 
-// CHECK: #pragma clang loop distribute(enable)
+// CHECK: #pragma clang loop interleave(enable)
 // CHECK-NEXT: #pragma clang loop vectorize(disable)
-// CHECK-NEXT: #pragma clang loop interleave(enable)
+// CHECK-NEXT: #pragma clang loop distribute(enable)
 
 #pragma clang loop distribute(enable)
 #pragma clang loop vectorize(disable)
@@ -49,8 +52,8 @@ void test_nontype_template_param(int *List, int Length) {
   }
 }
 
-// CHECK: #pragma clang loop vectorize_width(V)
 // CHECK: #pragma clang loop interleave_count(I)
+// CHECK: #pragma clang loop vectorize_width(V)
 
 void test_templates(int *List, int Length) {
   test_nontype_template_param<2, 4>(List, Length);

+ 12 - 9
test/PCH/pragma-loop.cpp

@@ -1,23 +1,26 @@
 // RUN: %clang_cc1 -emit-pch -o %t.a %s
 // RUN: %clang_cc1 -include-pch %t.a %s -ast-print -o - | FileCheck %s
 
-// CHECK: #pragma clang loop vectorize_width(4)
-// CHECK: #pragma clang loop interleave_count(8)
+// FIXME: A bug in ParsedAttributes causes the order of the attributes to be
+// reversed. The checks are consequently in the reverse order below.
+
 // CHECK: #pragma clang loop unroll_count(16){{$}}
-// CHECK: #pragma clang loop vectorize(enable)
-// CHECK: #pragma clang loop interleave(disable)
-// CHECK: #pragma clang loop unroll(disable)
+// CHECK: #pragma clang loop interleave_count(8)
+// CHECK: #pragma clang loop vectorize_width(4)
 // CHECK: #pragma clang loop distribute(enable)
-// CHECK: #pragma clang loop vectorize(disable)
-// CHECK: #pragma clang loop interleave(enable)
-// CHECK: #pragma clang loop unroll(full)
+// CHECK: #pragma clang loop unroll(disable)
+// CHECK: #pragma clang loop interleave(disable)
+// CHECK: #pragma clang loop vectorize(enable)
 // CHECK: #pragma clang loop distribute(disable)
+// CHECK: #pragma clang loop unroll(full)
+// CHECK: #pragma clang loop interleave(enable)
+// CHECK: #pragma clang loop vectorize(disable)
 // FIXME: "#pragma unroll (enable)" is invalid and is not the input source.
 // CHECK: #pragma unroll (enable){{$}}
 // CHECK: #pragma unroll (32){{$}}
 // CHECK: #pragma nounroll{{$}}
-// CHECK: #pragma clang loop vectorize_width(V)
 // CHECK: #pragma clang loop interleave_count(I)
+// CHECK: #pragma clang loop vectorize_width(V)
 
 #ifndef HEADER
 #define HEADER

+ 4 - 4
test/Parser/pragma-loop-safety.cpp

@@ -25,10 +25,10 @@ void test(int *List, int Length) {
     List[i] = i;
   }
 
-#pragma clang loop vectorize(enable)
-/* expected-error {{duplicate directives 'vectorize(enable)' and 'vectorize(assume_safety)'}} */ #pragma clang loop vectorize(assume_safety)
-#pragma clang loop interleave(enable)
-/* expected-error {{duplicate directives 'interleave(enable)' and 'interleave(assume_safety)'}} */ #pragma clang loop interleave(assume_safety)
+/* expected-error {{duplicate directives 'vectorize(assume_safety)' and 'vectorize(enable)'}} */ #pragma clang loop vectorize(enable)
+#pragma clang loop vectorize(assume_safety)
+/* expected-error {{duplicate directives 'interleave(assume_safety)' and 'interleave(enable)'}} */ #pragma clang loop interleave(enable)
+#pragma clang loop interleave(assume_safety)
   while (i-9 < Length) {
     List[i] = i;
   }

+ 29 - 28
test/Parser/pragma-loop.cpp

@@ -231,50 +231,51 @@ const int VV = 4;
 // of the next three tests rather than the last, and the order of the kinds
 // is also reversed.
 
-#pragma clang loop vectorize_width(4)
-/* expected-error {{incompatible directives 'vectorize(disable)' and 'vectorize_width(4)'}} */ #pragma clang loop vectorize(disable)
-#pragma clang loop interleave_count(4)
-/* expected-error {{incompatible directives 'interleave(disable)' and 'interleave_count(4)'}} */ #pragma clang loop interleave(disable)
-#pragma clang loop unroll_count(4)
-/* expected-error {{incompatible directives 'unroll(disable)' and 'unroll_count(4)'}} */ #pragma clang loop unroll(disable)
+/* expected-error {{incompatible directives 'vectorize(disable)' and 'vectorize_width(4)'}} */ #pragma clang loop vectorize_width(4)
+#pragma clang loop vectorize(disable)
+/* expected-error {{incompatible directives 'interleave(disable)' and 'interleave_count(4)'}} */ #pragma clang loop interleave_count(4)
+#pragma clang loop interleave(disable)
+/* expected-error {{incompatible directives 'unroll(disable)' and 'unroll_count(4)'}} */ #pragma clang loop unroll_count(4)
+#pragma clang loop unroll(disable)
   while (i-8 < Length) {
     List[i] = i;
   }
 
-#pragma clang loop vectorize(enable)
-/* expected-error {{duplicate directives 'vectorize(enable)' and 'vectorize(disable)'}} */ #pragma clang loop vectorize(disable)
-#pragma clang loop interleave(enable)
-/* expected-error {{duplicate directives 'interleave(enable)' and 'interleave(disable)'}} */ #pragma clang loop interleave(disable)
-#pragma clang loop unroll(full)
-/* expected-error {{duplicate directives 'unroll(full)' and 'unroll(disable)'}} */ #pragma clang loop unroll(disable)
-#pragma clang loop distribute(enable)
-/* expected-error {{duplicate directives 'distribute(enable)' and 'distribute(disable)'}} */ #pragma clang loop distribute(disable)
+/* expected-error {{duplicate directives 'vectorize(disable)' and 'vectorize(enable)'}} */ #pragma clang loop vectorize(enable)
+#pragma clang loop vectorize(disable)
+/* expected-error {{duplicate directives 'interleave(disable)' and 'interleave(enable)'}} */ #pragma clang loop interleave(enable)
+#pragma clang loop interleave(disable)
+/* expected-error {{duplicate directives 'unroll(disable)' and 'unroll(full)'}} */ #pragma clang loop unroll(full)
+#pragma clang loop unroll(disable)
+/* expected-error {{duplicate directives 'distribute(disable)' and 'distribute(enable)'}} */ #pragma clang loop distribute(enable)
+#pragma clang loop distribute(disable)
   while (i-9 < Length) {
     List[i] = i;
   }
 
-#pragma clang loop vectorize(disable)
-/* expected-error {{incompatible directives 'vectorize(disable)' and 'vectorize_width(4)'}} */ #pragma clang loop vectorize_width(4)
-#pragma clang loop interleave(disable)
-/* expected-error {{incompatible directives 'interleave(disable)' and 'interleave_count(4)'}} */ #pragma clang loop interleave_count(4)
-#pragma clang loop unroll(disable)
-/* expected-error {{incompatible directives 'unroll(disable)' and 'unroll_count(4)'}} */ #pragma clang loop unroll_count(4)
+/* expected-error {{incompatible directives 'vectorize(disable)' and 'vectorize_width(4)'}} */ #pragma clang loop vectorize(disable)
+#pragma clang loop vectorize_width(4)
+/* expected-error {{incompatible directives 'interleave(disable)' and 'interleave_count(4)'}} */ #pragma clang loop interleave(disable)
+#pragma clang loop interleave_count(4)
+/* expected-error {{incompatible directives 'unroll(disable)' and 'unroll_count(4)'}} */ #pragma clang loop unroll(disable)
+#pragma clang loop unroll_count(4)
   while (i-10 < Length) {
     List[i] = i;
   }
 
-#pragma clang loop vectorize_width(8)
-/* expected-error {{duplicate directives 'vectorize_width(8)' and 'vectorize_width(4)'}} */ #pragma clang loop vectorize_width(4)
-#pragma clang loop interleave_count(8)
-/* expected-error {{duplicate directives 'interleave_count(8)' and 'interleave_count(4)'}} */ #pragma clang loop interleave_count(4)
-#pragma clang loop unroll_count(8)
-/* expected-error {{duplicate directives 'unroll_count(8)' and 'unroll_count(4)'}} */ #pragma clang loop unroll_count(4)
+/* expected-error {{duplicate directives 'vectorize_width(4)' and 'vectorize_width(8)'}} */ #pragma clang loop vectorize_width(8)
+#pragma clang loop vectorize_width(4)
+/* expected-error {{duplicate directives 'interleave_count(4)' and 'interleave_count(8)'}} */ #pragma clang loop interleave_count(8)
+#pragma clang loop interleave_count(4)
+/* expected-error {{duplicate directives 'unroll_count(4)' and 'unroll_count(8)'}} */ #pragma clang loop unroll_count(8)
+#pragma clang loop unroll_count(4)
   while (i-11 < Length) {
     List[i] = i;
   }
 
-#pragma clang loop unroll(full)
-/* expected-error {{incompatible directives 'unroll(full)' and 'unroll_count(4)'}} */ #pragma clang loop unroll_count(4)
+
+/* expected-error {{incompatible directives 'unroll(full)' and 'unroll_count(4)'}} */ #pragma clang loop unroll(full)
+#pragma clang loop unroll_count(4)
   while (i-11 < Length) {
     List[i] = i;
   }

+ 16 - 16
test/Parser/pragma-unroll.cpp

@@ -55,56 +55,56 @@ void test(int *List, int Length) {
 #pragma nounroll
 /* expected-error {{expected a for, while, or do-while loop to follow '#pragma nounroll'}} */ int l = Length;
 
-#pragma unroll 4
-/* expected-error {{incompatible directives 'unroll(disable)' and '#pragma unroll(4)'}} */ #pragma clang loop unroll(disable)
+/* expected-error {{incompatible directives 'unroll(disable)' and '#pragma unroll(4)'}} */ #pragma unroll 4
+#pragma clang loop unroll(disable)
   while (i-10 < Length) {
     List[i] = i;
   }
 
-#pragma unroll(4)
-/* expected-error {{incompatible directives 'unroll(full)' and '#pragma unroll(4)'}} */ #pragma clang loop unroll(full)
+/* expected-error {{incompatible directives 'unroll(full)' and '#pragma unroll(4)'}} */ #pragma unroll(4)
+#pragma clang loop unroll(full)
   while (i-11 < Length) {
     List[i] = i;
   }
 
-#pragma unroll(4)
-/* expected-error {{incompatible directives 'unroll(enable)' and '#pragma unroll(4)'}} */ #pragma clang loop unroll(enable)
+/* expected-error {{incompatible directives 'unroll(enable)' and '#pragma unroll(4)'}} */ #pragma unroll(4)
+#pragma clang loop unroll(enable)
   while (i-11 < Length) {
     List[i] = i;
   }
 
-#pragma unroll(4)
-/* expected-error {{incompatible directives '#pragma unroll' and '#pragma unroll(4)'}} */ #pragma unroll
+/* expected-error {{incompatible directives '#pragma unroll' and '#pragma unroll(4)'}} */ #pragma unroll(4)
+#pragma unroll
   while (i-11 < Length) {
     List[i] = i;
   }
 
-#pragma clang loop unroll_count(4)
-/* expected-error {{incompatible directives '#pragma nounroll' and 'unroll_count(4)'}} */ #pragma nounroll
+/* expected-error {{incompatible directives '#pragma nounroll' and 'unroll_count(4)'}} */ #pragma clang loop unroll_count(4)
+#pragma nounroll
   while (i-12 < Length) {
     List[i] = i;
   }
 
-#pragma nounroll
 /* expected-error {{duplicate directives '#pragma nounroll' and '#pragma nounroll'}} */ #pragma nounroll
+#pragma nounroll
   while (i-13 < Length) {
     List[i] = i;
   }
 
-#pragma unroll
 /* expected-error {{duplicate directives '#pragma unroll' and '#pragma unroll'}} */ #pragma unroll
+#pragma unroll
   while (i-14 < Length) {
     List[i] = i;
   }
 
-#pragma unroll
-/* expected-error {{duplicate directives '#pragma unroll' and 'unroll(full)'}} */ #pragma clang loop unroll(full)
+/* expected-error {{duplicate directives 'unroll(full)' and '#pragma unroll'}} */ #pragma unroll
+#pragma clang loop unroll(full)
   while (i-15 < Length) {
     List[i] = i;
   }
 
-#pragma unroll 4
-/* expected-error {{duplicate directives '#pragma unroll(4)' and '#pragma unroll(4)'}} */ #pragma unroll(4)
+/* expected-error {{duplicate directives '#pragma unroll(4)' and '#pragma unroll(4)'}} */ #pragma unroll 4
+#pragma unroll(4)
   while (i-16 < Length) {
     List[i] = i;
   }

+ 4 - 2
test/Sema/attr-availability-tvos.c

@@ -27,8 +27,10 @@ void test_transcribed_availability() {
   f9(0);
 }
 
-__attribute__((availability(ios,introduced=9_0,deprecated=9_0,message="" ))) // expected-warning 2{{availability does not match previous declaration}}
-__attribute__((availability(ios,introduced=7_0)))                            // expected-note 2{{previous attribute is here}}
+__attribute__((availability(ios,introduced=9_0,deprecated=9_0,message="" ))) // expected-note{{previous attribute is here}} \
+  // expected-note{{previous attribute is here}}
+__attribute__((availability(ios,introduced=7_0))) // expected-warning{{availability does not match previous declaration}} \
+  // expected-warning{{availability does not match previous declaration}}
 void f10(int);
 
 // Test tvOS specific attributes.

+ 2 - 2
test/Sema/attr-availability.c

@@ -64,8 +64,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}}

+ 2 - 2
test/Sema/attr-coldhot.c

@@ -6,7 +6,7 @@ int bar() __attribute__((__cold__));
 int var1 __attribute__((__cold__)); // expected-warning{{'__cold__' attribute only applies to functions}}
 int var2 __attribute__((__hot__)); // expected-warning{{'__hot__' attribute only applies to functions}}
 
-int qux() __attribute__((__hot__)) __attribute__((__cold__)); // expected-error{{'__cold__' and 'hot' attributes are not compatible}} \
+int qux() __attribute__((__hot__)) __attribute__((__cold__)); // expected-error{{'__hot__' and 'cold' attributes are not compatible}} \
 // expected-note{{conflicting attribute is here}}
-int baz() __attribute__((__cold__)) __attribute__((__hot__)); // expected-error{{'__hot__' and 'cold' attributes are not compatible}} \
+int baz() __attribute__((__cold__)) __attribute__((__hot__)); // expected-error{{'__cold__' and 'hot' attributes are not compatible}} \
 // expected-note{{conflicting attribute is here}}

+ 2 - 2
test/Sema/attr-disable-tail-calls.c

@@ -1,10 +1,10 @@
 // RUN: %clang_cc1 -fsyntax-only -verify %s
 
-void __attribute__((disable_tail_calls,naked)) foo1(int a) { // expected-error {{'naked' and 'disable_tail_calls' attributes are not compatible}} expected-note {{conflicting attribute is here}}
+void __attribute__((disable_tail_calls,naked)) foo1(int a) { // expected-error {{'disable_tail_calls' and 'naked' attributes are not compatible}} expected-note {{conflicting attribute is here}}
   __asm__("");
 }
 
-void __attribute__((naked,disable_tail_calls)) foo2(int a) { // expected-error {{'disable_tail_calls' and 'naked' attributes are not compatible}} expected-note {{conflicting attribute is here}}
+void __attribute__((naked,disable_tail_calls)) foo2(int a) { // expected-error {{'naked' and 'disable_tail_calls' attributes are not compatible}} expected-note {{conflicting attribute is here}}
   __asm__("");
 }
 

+ 2 - 2
test/Sema/attr-long-call.c

@@ -19,8 +19,8 @@ __attribute((near)) void foo6();
 __attribute((long_call, far)) void foo7();
 __attribute((short_call, near)) void foo11();
 
-__attribute((far, near)) void foo8(); // expected-error {{'near' and 'far' attributes are not compatible}} \
+__attribute((far, near)) void foo8(); // expected-error {{'far' and 'near' attributes are not compatible}} \
                                       // expected-note {{conflicting attribute is here}}
 
-__attribute((short_call, long_call)) void foo12(); // expected-error {{'long_call' and 'short_call' attributes are not compatible}} \
+__attribute((short_call, long_call)) void foo12(); // expected-error {{'short_call' and 'long_call' attributes are not compatible}} \
                                                    // expected-note {{conflicting attribute is here}}

+ 2 - 2
test/Sema/attr-micromips.c

@@ -6,9 +6,9 @@ __attribute__((micromips(1))) void foo2();    // expected-error {{'micromips' at
 __attribute((nomicromips)) int a; // expected-error {{attribute only applies to functions}}
 __attribute((micromips)) int b;   // expected-error {{attribute only applies to functions}}
 
-__attribute__((micromips,mips16)) void foo5();  // expected-error {{'mips16' and 'micromips' attributes are not compatible}} \
+__attribute__((micromips,mips16)) void foo5();  // expected-error {{'micromips' and 'mips16' attributes are not compatible}} \
                                                 // expected-note {{conflicting attribute is here}}
-__attribute__((mips16,micromips)) void foo6();  // expected-error {{'micromips' and 'mips16' attributes are not compatible}} \
+__attribute__((mips16,micromips)) void foo6();  // expected-error {{'mips16' and 'micromips' attributes are not compatible}} \
                                                 // expected-note {{conflicting attribute is here}}
 
 __attribute((micromips)) void foo7();

+ 2 - 2
test/Sema/attr-notail.c

@@ -1,8 +1,8 @@
 // RUN: %clang_cc1 -fsyntax-only -verify %s
 
-int callee0() __attribute__((not_tail_called,always_inline)); // expected-error{{'always_inline' and 'not_tail_called' attributes are not compatible}} \
+int callee0() __attribute__((not_tail_called,always_inline)); // expected-error{{'not_tail_called' and 'always_inline' attributes are not compatible}} \
 // expected-note{{conflicting attribute is here}}
-int callee1() __attribute__((always_inline,not_tail_called)); // expected-error{{'not_tail_called' and 'always_inline' attributes are not compatible}} \
+int callee1() __attribute__((always_inline,not_tail_called)); // expected-error{{'always_inline' and 'not_tail_called' attributes are not compatible}} \
 // expected-note{{conflicting attribute is here}}
 
 int foo(int a) {

+ 3 - 3
test/Sema/attr-ownership.c

@@ -16,11 +16,11 @@ void *f11(float i) __attribute__((ownership_returns(foo, 1)));  // expected-erro
 void *f12(float i, int k, int f, int *j) __attribute__((ownership_returns(foo, 4)));  // expected-error {{'ownership_returns' attribute only applies to integer arguments}}
 
 void f13(int *i, int *j) __attribute__((ownership_holds(foo, 1))) __attribute__((ownership_takes(foo, 2)));
-void f14(int i, int j, int *k) __attribute__((ownership_holds(foo, 3))) __attribute__((ownership_takes(foo, 3)));  // expected-error {{'ownership_takes' and 'ownership_holds' attributes are not compatible}}
+void f14(int i, int j, int *k) __attribute__((ownership_holds(foo, 3))) __attribute__((ownership_takes(foo, 3)));  // expected-error {{'ownership_holds' and 'ownership_takes' attributes are not compatible}}
 
 void f15(int, int)
-  __attribute__((ownership_returns(foo, 1)))  // expected-error {{'ownership_returns' attribute index does not match; here it is 1}}
-  __attribute__((ownership_returns(foo, 2))); // expected-note {{declared with index 2 here}}
+  __attribute__((ownership_returns(foo, 1)))  // expected-note {{declared with index 1 here}}
+  __attribute__((ownership_returns(foo, 2))); // expected-error {{'ownership_returns' attribute index does not match; here it is 2}}
 void f16(int *i, int *j) __attribute__((ownership_holds(foo, 1))) __attribute__((ownership_holds(foo, 1))); // OK, same index
 void f17(void*) __attribute__((ownership_takes(__, 1)));
 void f18() __attribute__((ownership_takes(foo, 1)));  // expected-warning {{'ownership_takes' attribute only applies to non-K&R-style functions}}

+ 2 - 2
test/Sema/attr-ownership.cpp

@@ -2,6 +2,6 @@
 
 class C {
   void f(int, int)
-      __attribute__((ownership_returns(foo, 2)))  // expected-error {{'ownership_returns' attribute index does not match; here it is 2}}
-      __attribute__((ownership_returns(foo, 3))); // expected-note {{declared with index 3 here}}
+      __attribute__((ownership_returns(foo, 2)))  // expected-note {{declared with index 2 here}}
+      __attribute__((ownership_returns(foo, 3))); // expected-error {{'ownership_returns' attribute index does not match; here it is 3}}
 };

+ 3 - 3
test/Sema/attr-print.c

@@ -24,13 +24,13 @@ int * __ptr64 p64;
 
 // TODO: the Type Printer has no way to specify the order to print attributes
 // in, and so it currently always prints them in reverse order. Fix this.
-// CHECK: int * __uptr __ptr32 p32_2;
+// CHECK: int * __ptr32 __uptr p32_2;
 int * __uptr __ptr32 p32_2;
 
-// CHECK: int * __sptr __ptr64 p64_2;
+// CHECK: int * __ptr64 __sptr p64_2;
 int * __sptr __ptr64 p64_2;
 
-// CHECK: int * __uptr __ptr32 p32_3;
+// CHECK: int * __ptr32 __uptr p32_3;
 int * __uptr __ptr32 p32_3;
 
 // CHECK: int * __sptr * __ptr32 ppsp32;

+ 1 - 1
test/Sema/attr-swiftcall.c

@@ -9,7 +9,7 @@
 int notAFunction SWIFTCALL; // expected-warning {{'swiftcall' only applies to function types; type here is 'int'}}
 void variadic(int x, ...) SWIFTCALL; // expected-error {{variadic function cannot use swiftcall calling convention}}
 void unprototyped() SWIFTCALL; // expected-error {{function with no prototype cannot use the swiftcall calling convention}}
-void multiple_ccs(int x) SWIFTCALL __attribute__((vectorcall)); // expected-error {{swiftcall and vectorcall attributes are not compatible}}
+void multiple_ccs(int x) SWIFTCALL __attribute__((vectorcall)); // expected-error {{vectorcall and swiftcall attributes are not compatible}}
 void (*functionPointer)(void) SWIFTCALL;
 
 void indirect_result_nonswift(INDIRECT_RESULT void *out); // expected-error {{'swift_indirect_result' parameter can only be used with swiftcall calling convention}}

+ 1 - 1
test/Sema/attr-target-mv.c

@@ -95,7 +95,7 @@ void __attribute__((target("arch=sandybridge")))  addtl_attrs4(void);
 void __attribute__((used,target("arch=ivybridge")))  addtl_attrs4(void);
 
 int __attribute__((target("sse4.2"))) diff_cc(void);
-// expected-error@+1 {{attribute 'target' multiversioning cannot be combined with other attributes}}
+// expected-error@+1 {{multiversioned function declaration has a different calling convention}}
 __vectorcall int __attribute__((target("arch=sandybridge")))  diff_cc(void);
 
 int __attribute__((target("sse4.2"))) diff_ret(void);

+ 2 - 2
test/Sema/attr-visibility.c

@@ -15,8 +15,8 @@ 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("default"), // expected-error {{visibility does not match previous declaration}}
-                            visibility("hidden"))); // expected-note {{previous attribute is here}}
+void test6() __attribute__((visibility("hidden"), // expected-note {{previous attribute is here}}
+                            visibility("default"))); // expected-error {{visibility does not match previous declaration}}
 
 extern int test7 __attribute__((visibility("default"))); // expected-note {{previous attribute is here}}
 extern int test7 __attribute__((visibility("hidden"))); // expected-error {{visibility does not match previous declaration}}

+ 2 - 2
test/Sema/internal_linkage.c

@@ -1,9 +1,9 @@
 // RUN: %clang_cc1 -fsyntax-only -verify -fdouble-square-bracket-attributes %s
 
 int var __attribute__((internal_linkage));
-int var2 __attribute__((internal_linkage,common)); // expected-error{{'common' and 'internal_linkage' attributes are not compatible}} \
+int var2 __attribute__((internal_linkage,common)); // expected-error{{'internal_linkage' and 'common' attributes are not compatible}} \
                                                    // expected-note{{conflicting attribute is here}}
-int var3 __attribute__((common,internal_linkage)); // expected-error{{'internal_linkage' and 'common' attributes are not compatible}} \
+int var3 __attribute__((common,internal_linkage)); // expected-error{{'common' and 'internal_linkage' attributes are not compatible}} \
                                                    // expected-note{{conflicting attribute is here}}
 
 int var4 __attribute__((common)); // expected-error{{'common' and 'internal_linkage' attributes are not compatible}} \

+ 4 - 4
test/Sema/mips-interrupt-attr.c

@@ -19,11 +19,11 @@ __attribute__((interrupt(""))) void food() {}
 
 __attribute__((interrupt)) int foob() {return 0;} // expected-warning {{MIPS 'interrupt' attribute only applies to functions that have a 'void' return type}}
 __attribute__((interrupt())) void fooc(int a) {} // expected-warning {{MIPS 'interrupt' attribute only applies to functions that have no parameters}}
-__attribute__((interrupt,mips16)) void fooe() {} // expected-error {{'mips16' and 'interrupt' attributes are not compatible}} \
+__attribute__((interrupt,mips16)) void fooe() {} // expected-error {{'interrupt' and 'mips16' attributes are not compatible}} \
                                                  // expected-note {{conflicting attribute is here}}
-__attribute__((mips16,interrupt)) void foof() {} // expected-error {{'interrupt' and 'mips16' attributes are not compatible}} \
+__attribute__((mips16,interrupt)) void foof() {} // expected-error {{'mips16' and 'interrupt' attributes are not compatible}} \
                                                  // expected-note {{conflicting attribute is here}}
-__attribute__((interrupt)) __attribute__ ((mips16)) void foo10() {} // expected-error {{'mips16' and 'interrupt' attributes are not compatible}} \
+__attribute__((interrupt)) __attribute__ ((mips16)) void foo10() {} // expected-error {{'interrupt' and 'mips16' attributes are not compatible}} \
                                                                     // expected-note {{conflicting attribute is here}}
-__attribute__((mips16)) __attribute ((interrupt)) void foo11() {} // expected-error {{'interrupt' and 'mips16' attributes are not compatible}} \
+__attribute__((mips16)) __attribute ((interrupt)) void foo11() {} // expected-error {{'mips16' and 'interrupt' attributes are not compatible}} \
                                                                   // expected-note {{conflicting attribute is here}}

+ 2 - 2
test/Sema/ms_abi-sysv_abi.c

@@ -6,9 +6,9 @@ int __attribute__((sysv_abi)) var2; // expected-warning{{'sysv_abi' only applies
 
 // Different CC qualifiers are not compatible
 // FIXME: Should say 'sysv_abi' instead of 'cdecl'
-void __attribute__((ms_abi, sysv_abi)) foo3(void); // expected-error{{ms_abi and cdecl attributes are not compatible}}
+void __attribute__((ms_abi, sysv_abi)) foo3(void); // expected-error{{cdecl and ms_abi attributes are not compatible}}
 void __attribute__((ms_abi)) foo4(); // expected-note{{previous declaration is here}}
 void __attribute__((sysv_abi)) foo4(void); // expected-error{{function declared 'cdecl' here was previously declared 'ms_abi'}}
 
-void bar(int i, int j) __attribute__((ms_abi, cdecl)); // expected-error{{ms_abi and cdecl attributes are not compatible}}
+void bar(int i, int j) __attribute__((ms_abi, cdecl)); // expected-error{{cdecl and ms_abi attributes are not compatible}}
 void bar2(int i, int j) __attribute__((sysv_abi, cdecl)); // no-error

+ 2 - 2
test/Sema/nullability.c

@@ -20,8 +20,8 @@ typedef int * _Null_unspecified null_unspecified_int_ptr;
 typedef int * _Nonnull _Nonnull redundant_1; // expected-warning{{duplicate nullability specifier '_Nonnull'}}
 
 // Conflicting nullability type specifiers.
-typedef int *_Nonnull _Nullable conflicting_1; // expected-error{{nullability specifier '_Nullable' conflicts with existing specifier '_Nonnull'}}
-typedef int *_Null_unspecified _Nonnull conflicting_2; // expected-error{{nullability specifier '_Nonnull' conflicts with existing specifier '_Null_unspecified'}}
+typedef int * _Nonnull _Nullable conflicting_1; // expected-error{{nullability specifier '_Nonnull' conflicts with existing specifier '_Nullable'}}
+typedef int * _Null_unspecified _Nonnull conflicting_2; // expected-error{{nullability specifier '_Null_unspecified' conflicts with existing specifier '_Nonnull'}}
 
 // Redundant nullability specifiers via a typedef are okay.
 typedef nonnull_int_ptr _Nonnull redundant_okay_1;

+ 1 - 1
test/Sema/stdcall-fastcall.c

@@ -5,7 +5,7 @@ int __attribute__((stdcall)) var1; // expected-warning{{'stdcall' only applies t
 int __attribute__((fastcall)) var2; // expected-warning{{'fastcall' only applies to function types; type here is 'int'}}
 
 // Different CC qualifiers are not compatible
-void __attribute__((stdcall, fastcall)) foo3(void); // expected-error{{stdcall and fastcall attributes are not compatible}}
+void __attribute__((stdcall, fastcall)) foo3(void); // expected-error{{fastcall and stdcall attributes are not compatible}}
 void __attribute__((stdcall)) foo4(); // expected-note{{previous declaration is here}} expected-warning{{function with no prototype cannot use the stdcall calling convention}}
 void __attribute__((fastcall)) foo4(void); // expected-error{{function declared 'fastcall' here was previously declared 'stdcall'}}
 

+ 1 - 1
test/SemaCXX/attr-print.cpp

@@ -14,7 +14,7 @@ void foo() __attribute__((const));
 void bar() __attribute__((__const));
 
 // FIXME: Print this with correct format and order.
-// CHECK: void foo1() __attribute__((noinline)) __attribute__((pure));
+// CHECK: void foo1() __attribute__((pure)) __attribute__((noinline));
 void foo1() __attribute__((noinline, pure));
 
 // CHECK: typedef int Small1 __attribute__((mode(byte)));

+ 1 - 1
test/SemaCXX/attr-swiftcall.cpp

@@ -7,7 +7,7 @@
 
 int notAFunction SWIFTCALL; // expected-warning {{'swiftcall' only applies to function types; type here is 'int'}}
 void variadic(int x, ...) SWIFTCALL; // expected-error {{variadic function cannot use swiftcall calling convention}}
-void multiple_ccs(int x) SWIFTCALL __attribute__((vectorcall)); // expected-error {{swiftcall and vectorcall attributes are not compatible}}
+void multiple_ccs(int x) SWIFTCALL __attribute__((vectorcall)); // expected-error {{vectorcall and swiftcall attributes are not compatible}}
 void (*functionPointer)(void) SWIFTCALL;
 
 void indirect_result_nonswift(INDIRECT_RESULT void *out); // expected-error {{'swift_indirect_result' parameter can only be used with swiftcall calling convention}}

+ 1 - 1
test/SemaCXX/decl-microsoft-call-conv.cpp

@@ -161,7 +161,7 @@ void multi_attribute(int x) { __builtin_unreachable(); }
 // expected-error@+3 {{vectorcall and cdecl attributes are not compatible}}
 // expected-error@+2 {{stdcall and cdecl attributes are not compatible}}
 // expected-error@+1 {{fastcall and cdecl attributes are not compatible}}
-void __vectorcall __fastcall __cdecl __stdcall __cdecl __cdecl multi_cc(int x);
+void __cdecl __cdecl __stdcall __cdecl __fastcall __vectorcall multi_cc(int x);
 
 template <typename T> void __stdcall StdcallTemplate(T) {}
 template <> void StdcallTemplate<int>(int) {}

+ 4 - 4
test/SemaCXX/ms-uuid.cpp

@@ -62,14 +62,14 @@ class __declspec(uuid("110000A0-0000-0000-C000-000000000049")) C2_2;
 [uuid("220000A0-0000-0000-C000-000000000049")] class C4 {};
 
 // Both cl and clang-cl error out on this:
-// expected-error@+1 {{uuid does not match previous declaration}}
-class __declspec(uuid("000000A0-0000-0000-C000-000000000049"))
 // expected-note@+1 {{previous uuid specified here}}
+class __declspec(uuid("000000A0-0000-0000-C000-000000000049"))
+// expected-error@+1 {{uuid does not match previous declaration}}
       __declspec(uuid("110000A0-0000-0000-C000-000000000049")) C5;
 
-// expected-error@+1 {{uuid does not match previous declaration}}
-[uuid("000000A0-0000-0000-C000-000000000049"),
 // expected-note@+1 {{previous uuid specified here}}
+[uuid("000000A0-0000-0000-C000-000000000049"),
+// expected-error@+1 {{uuid does not match previous declaration}}
  uuid("110000A0-0000-0000-C000-000000000049")] class C6;
 
 // cl doesn't diagnose having one uuid each as []-style attributes and as

+ 2 - 2
test/SemaOpenCL/address-spaces.cl

@@ -61,8 +61,8 @@ __generic int func_return_generic(void);    //expected-error {{return value cann
 
 void func_multiple_addr(void) {
   typedef __private int private_int_t;
-  __private __local int var1;   // expected-error {{multiple address spaces specified for type}}
-  __private __local int *var2;  // expected-error {{multiple address spaces specified for type}}
+  __local __private int var1;   // expected-error {{multiple address spaces specified for type}}
+  __local __private int *var2;  // expected-error {{multiple address spaces specified for type}}
   __local private_int_t var3;   // expected-error {{multiple address spaces specified for type}}
   __local private_int_t *var4;  // expected-error {{multiple address spaces specified for type}}
   __private private_int_t var5; // expected-warning {{multiple identical address spaces specified for type}}

+ 2 - 2
test/SemaTemplate/attributes.cpp

@@ -55,11 +55,11 @@ namespace PR9049 {
 }
 
 // CHECK: FunctionTemplateDecl {{.*}} HasAnnotations
-// CHECK:   AnnotateAttr {{.*}} "ANNOTATE_FOO"
 // CHECK:   AnnotateAttr {{.*}} "ANNOTATE_BAR"
+// CHECK:   AnnotateAttr {{.*}} "ANNOTATE_FOO"
 // CHECK: FunctionDecl {{.*}} HasAnnotations
 // CHECK:   TemplateArgument type 'int'
-// CHECK:   AnnotateAttr {{.*}} "ANNOTATE_FOO"
 // CHECK:   AnnotateAttr {{.*}} "ANNOTATE_BAR"
+// CHECK:   AnnotateAttr {{.*}} "ANNOTATE_FOO"
 template<typename T> [[clang::annotate("ANNOTATE_FOO"), clang::annotate("ANNOTATE_BAR")]] void HasAnnotations();
 void UseAnnotations() { HasAnnotations<int>(); }