diff --git a/clang/lib/Sema/SemaDeclAttr.cpp b/clang/lib/Sema/SemaDeclAttr.cpp
index 7940670..242b81a 100644
--- a/clang/lib/Sema/SemaDeclAttr.cpp
+++ b/clang/lib/Sema/SemaDeclAttr.cpp
@@ -398,18 +398,11 @@
 /// Applies the given attribute to the Decl without performing any
 /// additional semantic checking.
 template <typename AttrType>
-static void handleSimpleAttribute(Sema &S, Decl *D, SourceRange SR,
-                                  unsigned SpellingIndex) {
-  D->addAttr(::new (S.Context) AttrType(SR, S.Context, SpellingIndex));
+static void handleSimpleAttribute(Sema &S, Decl *D,
+                                  const AttributeCommonInfo &CI) {
+  D->addAttr(::new (S.Context) AttrType(S.Context, CI));
 }
 
-template <typename AttrType>
-static void handleSimpleAttribute(Sema &S, Decl *D, const ParsedAttr &AL) {
-  handleSimpleAttribute<AttrType>(S, D, AL.getRange(),
-                                  AL.getAttributeSpellingListIndex());
-}
-
-
 template <typename... DiagnosticArgs>
 static const Sema::SemaDiagnosticBuilder&
 appendDiagnostics(const Sema::SemaDiagnosticBuilder &Bldr) {
@@ -429,28 +422,16 @@
 /// Otherwise, emit diagnostic {@code DiagID}, passing in all parameters
 /// specified in {@code ExtraArgs}.
 template <typename AttrType, typename... DiagnosticArgs>
-static void
-handleSimpleAttributeOrDiagnose(Sema &S, Decl *D, SourceRange SR,
-                               unsigned SpellingIndex,
-                               bool PassesCheck,
-                               unsigned DiagID, DiagnosticArgs&&... ExtraArgs) {
+static void handleSimpleAttributeOrDiagnose(Sema &S, Decl *D,
+                                            const AttributeCommonInfo &CI,
+                                            bool PassesCheck, unsigned DiagID,
+                                            DiagnosticArgs &&... ExtraArgs) {
   if (!PassesCheck) {
     Sema::SemaDiagnosticBuilder DB = S.Diag(D->getBeginLoc(), DiagID);
     appendDiagnostics(DB, std::forward<DiagnosticArgs>(ExtraArgs)...);
     return;
   }
-  handleSimpleAttribute<AttrType>(S, D, SR, SpellingIndex);
-}
-
-template <typename AttrType, typename... DiagnosticArgs>
-static void
-handleSimpleAttributeOrDiagnose(Sema &S, Decl *D, const ParsedAttr &AL,
-                               bool PassesCheck,
-                               unsigned DiagID,
-                               DiagnosticArgs&&... ExtraArgs) {
-  return handleSimpleAttributeOrDiagnose<AttrType>(
-      S, D, AL.getRange(), AL.getAttributeSpellingListIndex(), PassesCheck,
-      DiagID, std::forward<DiagnosticArgs>(ExtraArgs)...);
+  handleSimpleAttribute<AttrType>(S, D, CI);
 }
 
 template <typename AttrType>
@@ -745,9 +726,7 @@
   if (!threadSafetyCheckIsPointer(S, D, AL))
     return;
 
-  D->addAttr(::new (S.Context)
-             PtGuardedVarAttr(AL.getRange(), S.Context,
-                              AL.getAttributeSpellingListIndex()));
+  D->addAttr(::new (S.Context) PtGuardedVarAttr(S.Context, AL));
 }
 
 static bool checkGuardedByAttrCommon(Sema &S, Decl *D, const ParsedAttr &AL,
@@ -769,8 +748,7 @@
   if (!checkGuardedByAttrCommon(S, D, AL, Arg))
     return;
 
-  D->addAttr(::new (S.Context) GuardedByAttr(
-      AL.getRange(), S.Context, Arg, AL.getAttributeSpellingListIndex()));
+  D->addAttr(::new (S.Context) GuardedByAttr(S.Context, AL, Arg));
 }
 
 static void handlePtGuardedByAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
@@ -781,8 +759,7 @@
   if (!threadSafetyCheckIsPointer(S, D, AL))
     return;
 
-  D->addAttr(::new (S.Context) PtGuardedByAttr(
-      AL.getRange(), S.Context, Arg, AL.getAttributeSpellingListIndex()));
+  D->addAttr(::new (S.Context) PtGuardedByAttr(S.Context, AL, Arg));
 }
 
 static bool checkAcquireOrderAttrCommon(Sema &S, Decl *D, const ParsedAttr &AL,
@@ -811,9 +788,8 @@
     return;
 
   Expr **StartArg = &Args[0];
-  D->addAttr(::new (S.Context) AcquiredAfterAttr(
-      AL.getRange(), S.Context, StartArg, Args.size(),
-      AL.getAttributeSpellingListIndex()));
+  D->addAttr(::new (S.Context)
+                 AcquiredAfterAttr(S.Context, AL, StartArg, Args.size()));
 }
 
 static void handleAcquiredBeforeAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
@@ -822,9 +798,8 @@
     return;
 
   Expr **StartArg = &Args[0];
-  D->addAttr(::new (S.Context) AcquiredBeforeAttr(
-      AL.getRange(), S.Context, StartArg, Args.size(),
-      AL.getAttributeSpellingListIndex()));
+  D->addAttr(::new (S.Context)
+                 AcquiredBeforeAttr(S.Context, AL, StartArg, Args.size()));
 }
 
 static bool checkLockFunAttrCommon(Sema &S, Decl *D, const ParsedAttr &AL,
@@ -844,8 +819,7 @@
   unsigned Size = Args.size();
   Expr **StartArg = Size == 0 ? nullptr : &Args[0];
   D->addAttr(::new (S.Context)
-                 AssertSharedLockAttr(AL.getRange(), S.Context, StartArg, Size,
-                                      AL.getAttributeSpellingListIndex()));
+                 AssertSharedLockAttr(S.Context, AL, StartArg, Size));
 }
 
 static void handleAssertExclusiveLockAttr(Sema &S, Decl *D,
@@ -856,9 +830,8 @@
 
   unsigned Size = Args.size();
   Expr **StartArg = Size == 0 ? nullptr : &Args[0];
-  D->addAttr(::new (S.Context) AssertExclusiveLockAttr(
-      AL.getRange(), S.Context, StartArg, Size,
-      AL.getAttributeSpellingListIndex()));
+  D->addAttr(::new (S.Context)
+                 AssertExclusiveLockAttr(S.Context, AL, StartArg, Size));
 }
 
 /// Checks to be sure that the given parameter number is in bounds, and
@@ -919,8 +892,7 @@
   }
 
   D->addAttr(::new (S.Context)
-                 AllocSizeAttr(AL.getRange(), S.Context, SizeArgNo, NumberArgNo,
-                               AL.getAttributeSpellingListIndex()));
+                 AllocSizeAttr(S.Context, AL, SizeArgNo, NumberArgNo));
 }
 
 static bool checkTryLockFunAttrCommon(Sema &S, Decl *D, const ParsedAttr &AL,
@@ -947,8 +919,7 @@
     return;
 
   D->addAttr(::new (S.Context) SharedTrylockFunctionAttr(
-      AL.getRange(), S.Context, AL.getArgAsExpr(0), Args.data(), Args.size(),
-      AL.getAttributeSpellingListIndex()));
+      S.Context, AL, AL.getArgAsExpr(0), Args.data(), Args.size()));
 }
 
 static void handleExclusiveTrylockFunctionAttr(Sema &S, Decl *D,
@@ -958,8 +929,7 @@
     return;
 
   D->addAttr(::new (S.Context) ExclusiveTrylockFunctionAttr(
-      AL.getRange(), S.Context, AL.getArgAsExpr(0), Args.data(),
-      Args.size(), AL.getAttributeSpellingListIndex()));
+      S.Context, AL, AL.getArgAsExpr(0), Args.data(), Args.size()));
 }
 
 static void handleLockReturnedAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
@@ -970,9 +940,7 @@
   if (Size == 0)
     return;
 
-  D->addAttr(::new (S.Context)
-             LockReturnedAttr(AL.getRange(), S.Context, Args[0],
-                              AL.getAttributeSpellingListIndex()));
+  D->addAttr(::new (S.Context) LockReturnedAttr(S.Context, AL, Args[0]));
 }
 
 static void handleLocksExcludedAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
@@ -988,8 +956,7 @@
   Expr **StartArg = &Args[0];
 
   D->addAttr(::new (S.Context)
-             LocksExcludedAttr(AL.getRange(), S.Context, StartArg, Size,
-                               AL.getAttributeSpellingListIndex()));
+                 LocksExcludedAttr(S.Context, AL, StartArg, Size));
 }
 
 static bool checkFunctionConditionAttr(Sema &S, Decl *D, const ParsedAttr &AL,
@@ -1026,9 +993,7 @@
   Expr *Cond;
   StringRef Msg;
   if (checkFunctionConditionAttr(S, D, AL, Cond, Msg))
-    D->addAttr(::new (S.Context)
-                   EnableIfAttr(AL.getRange(), S.Context, Cond, Msg,
-                                AL.getAttributeSpellingListIndex()));
+    D->addAttr(::new (S.Context) EnableIfAttr(S.Context, AL, Cond, Msg));
 }
 
 namespace {
@@ -1100,8 +1065,7 @@
   if (const auto *FD = dyn_cast<FunctionDecl>(D))
     ArgDependent = ArgumentDependenceChecker(FD).referencesArgs(Cond);
   D->addAttr(::new (S.Context) DiagnoseIfAttr(
-      AL.getRange(), S.Context, Cond, Msg, DiagType, ArgDependent,
-      cast<NamedDecl>(D), AL.getAttributeSpellingListIndex()));
+      S.Context, AL, Cond, Msg, DiagType, ArgDependent, cast<NamedDecl>(D)));
 }
 
 static void handlePassObjectSizeAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
@@ -1133,8 +1097,7 @@
     return;
   }
 
-  D->addAttr(::new (S.Context) PassObjectSizeAttr(
-      AL.getRange(), S.Context, (int)Type, AL.getAttributeSpellingListIndex()));
+  D->addAttr(::new (S.Context) PassObjectSizeAttr(S.Context, AL, (int)Type));
 }
 
 static void handleConsumableAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
@@ -1154,9 +1117,7 @@
     return;
   }
 
-  D->addAttr(::new (S.Context)
-             ConsumableAttr(AL.getRange(), S.Context, DefaultState,
-                            AL.getAttributeSpellingListIndex()));
+  D->addAttr(::new (S.Context) ConsumableAttr(S.Context, AL, DefaultState));
 }
 
 static bool checkForConsumableClass(Sema &S, const CXXMethodDecl *MD,
@@ -1207,8 +1168,7 @@
   }
 
   D->addAttr(::new (S.Context)
-             CallableWhenAttr(AL.getRange(), S.Context, States.data(),
-               States.size(), AL.getAttributeSpellingListIndex()));
+                 CallableWhenAttr(S.Context, AL, States.data(), States.size()));
 }
 
 static void handleParamTypestateAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
@@ -1242,9 +1202,7 @@
   //    return;
   //}
 
-  D->addAttr(::new (S.Context)
-             ParamTypestateAttr(AL.getRange(), S.Context, ParamState,
-                                AL.getAttributeSpellingListIndex()));
+  D->addAttr(::new (S.Context) ParamTypestateAttr(S.Context, AL, ParamState));
 }
 
 static void handleReturnTypestateAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
@@ -1289,9 +1247,7 @@
   //    return;
   //}
 
-  D->addAttr(::new (S.Context)
-                 ReturnTypestateAttr(AL.getRange(), S.Context, ReturnState,
-                                     AL.getAttributeSpellingListIndex()));
+  D->addAttr(::new (S.Context) ReturnTypestateAttr(S.Context, AL, ReturnState));
 }
 
 static void handleSetTypestateAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
@@ -1313,9 +1269,7 @@
     return;
   }
 
-  D->addAttr(::new (S.Context)
-             SetTypestateAttr(AL.getRange(), S.Context, NewState,
-                              AL.getAttributeSpellingListIndex()));
+  D->addAttr(::new (S.Context) SetTypestateAttr(S.Context, AL, NewState));
 }
 
 static void handleTestTypestateAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
@@ -1337,9 +1291,7 @@
     return;
   }
 
-  D->addAttr(::new (S.Context)
-             TestTypestateAttr(AL.getRange(), S.Context, TestState,
-                                AL.getAttributeSpellingListIndex()));
+  D->addAttr(::new (S.Context) TestTypestateAttr(S.Context, AL, TestState));
 }
 
 static void handleExtVectorTypeAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
@@ -1349,8 +1301,7 @@
 
 static void handlePackedAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
   if (auto *TD = dyn_cast<TagDecl>(D))
-    TD->addAttr(::new (S.Context) PackedAttr(AL.getRange(), S.Context,
-                                        AL.getAttributeSpellingListIndex()));
+    TD->addAttr(::new (S.Context) PackedAttr(S.Context, AL));
   else if (auto *FD = dyn_cast<FieldDecl>(D)) {
     bool BitfieldByteAligned = (!FD->getType()->isDependentType() &&
                                 !FD->getType()->isIncompleteType() &&
@@ -1363,15 +1314,13 @@
         S.Diag(AL.getLoc(), diag::warn_attribute_ignored_for_field_of_type)
             << AL << FD->getType();
       else
-        FD->addAttr(::new (S.Context) PackedAttr(
-                    AL.getRange(), S.Context, AL.getAttributeSpellingListIndex()));
+        FD->addAttr(::new (S.Context) PackedAttr(S.Context, AL));
     } else {
       // Report warning about changed offset in the newer compiler versions.
       if (BitfieldByteAligned)
         S.Diag(AL.getLoc(), diag::warn_attribute_packed_for_bitfield);
 
-      FD->addAttr(::new (S.Context) PackedAttr(
-                  AL.getRange(), S.Context, AL.getAttributeSpellingListIndex()));
+      FD->addAttr(::new (S.Context) PackedAttr(S.Context, AL));
     }
 
   } else
@@ -1408,9 +1357,7 @@
   if (!checkIBOutletCommon(S, D, AL))
     return;
 
-  D->addAttr(::new (S.Context)
-             IBOutletAttr(AL.getRange(), S.Context,
-                          AL.getAttributeSpellingListIndex()));
+  D->addAttr(::new (S.Context) IBOutletAttr(S.Context, AL));
 }
 
 static void handleIBOutletCollection(Sema &S, Decl *D, const ParsedAttr &AL) {
@@ -1453,9 +1400,7 @@
     return;
   }
 
-  D->addAttr(::new (S.Context)
-             IBOutletCollectionAttr(AL.getRange(), S.Context, QTLoc,
-                                    AL.getAttributeSpellingListIndex()));
+  D->addAttr(::new (S.Context) IBOutletCollectionAttr(S.Context, AL, QTLoc));
 }
 
 bool Sema::isValidPointerAttrType(QualType T, bool RefOkay) {
@@ -1538,9 +1483,7 @@
   ParamIdx *Start = NonNullArgs.data();
   unsigned Size = NonNullArgs.size();
   llvm::array_pod_sort(Start, Start + Size);
-  D->addAttr(::new (S.Context)
-                 NonNullAttr(AL.getRange(), S.Context, Start, Size,
-                             AL.getAttributeSpellingListIndex()));
+  D->addAttr(::new (S.Context) NonNullAttr(S.Context, AL, Start, Size));
 }
 
 static void handleNonNullAttrParameter(Sema &S, ParmVarDecl *D,
@@ -1560,9 +1503,7 @@
                            D->getSourceRange()))
     return;
 
-  D->addAttr(::new (S.Context)
-                 NonNullAttr(AL.getRange(), S.Context, nullptr, 0,
-                             AL.getAttributeSpellingListIndex()));
+  D->addAttr(::new (S.Context) NonNullAttr(S.Context, AL, nullptr, 0));
 }
 
 static void handleReturnsNonNullAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
@@ -1572,9 +1513,7 @@
                            /* isReturnValue */ true))
     return;
 
-  D->addAttr(::new (S.Context)
-            ReturnsNonNullAttr(AL.getRange(), S.Context,
-                               AL.getAttributeSpellingListIndex()));
+  D->addAttr(::new (S.Context) ReturnsNonNullAttr(S.Context, AL));
 }
 
 static void handleNoEscapeAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
@@ -1589,33 +1528,30 @@
     return;
   }
 
-  D->addAttr(::new (S.Context) NoEscapeAttr(
-      AL.getRange(), S.Context, AL.getAttributeSpellingListIndex()));
+  D->addAttr(::new (S.Context) NoEscapeAttr(S.Context, AL));
 }
 
 static void handleAssumeAlignedAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
   Expr *E = AL.getArgAsExpr(0),
        *OE = AL.getNumArgs() > 1 ? AL.getArgAsExpr(1) : nullptr;
-  S.AddAssumeAlignedAttr(AL.getRange(), D, E, OE,
-                         AL.getAttributeSpellingListIndex());
+  S.AddAssumeAlignedAttr(D, AL, E, OE);
 }
 
 static void handleAllocAlignAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
-  S.AddAllocAlignAttr(AL.getRange(), D, AL.getArgAsExpr(0),
-                      AL.getAttributeSpellingListIndex());
+  S.AddAllocAlignAttr(D, AL, AL.getArgAsExpr(0));
 }
 
-void Sema::AddAssumeAlignedAttr(SourceRange AttrRange, Decl *D, Expr *E,
-                                Expr *OE, unsigned SpellingListIndex) {
+void Sema::AddAssumeAlignedAttr(Decl *D, const AttributeCommonInfo &CI, Expr *E,
+                                Expr *OE) {
   QualType ResultType = getFunctionOrMethodResultType(D);
   SourceRange SR = getFunctionOrMethodResultSourceRange(D);
 
-  AssumeAlignedAttr TmpAttr(AttrRange, Context, E, OE, SpellingListIndex);
-  SourceLocation AttrLoc = AttrRange.getBegin();
+  AssumeAlignedAttr TmpAttr(Context, CI, E, OE);
+  SourceLocation AttrLoc = TmpAttr.getLocation();
 
   if (!isValidPointerAttrType(ResultType, /* RefOkay */ true)) {
     Diag(AttrLoc, diag::warn_attribute_return_pointers_refs_only)
-      << &TmpAttr << AttrRange << SR;
+        << &TmpAttr << TmpAttr.getRange() << SR;
     return;
   }
 
@@ -1652,21 +1588,20 @@
     }
   }
 
-  D->addAttr(::new (Context)
-            AssumeAlignedAttr(AttrRange, Context, E, OE, SpellingListIndex));
+  D->addAttr(::new (Context) AssumeAlignedAttr(Context, CI, E, OE));
 }
 
-void Sema::AddAllocAlignAttr(SourceRange AttrRange, Decl *D, Expr *ParamExpr,
-                             unsigned SpellingListIndex) {
+void Sema::AddAllocAlignAttr(Decl *D, const AttributeCommonInfo &CI,
+                             Expr *ParamExpr) {
   QualType ResultType = getFunctionOrMethodResultType(D);
 
-  AllocAlignAttr TmpAttr(AttrRange, Context, ParamIdx(), SpellingListIndex);
-  SourceLocation AttrLoc = AttrRange.getBegin();
+  AllocAlignAttr TmpAttr(Context, CI, ParamIdx());
+  SourceLocation AttrLoc = CI.getLoc();
 
   if (!ResultType->isDependentType() &&
       !isValidPointerAttrType(ResultType, /* RefOkay */ true)) {
     Diag(AttrLoc, diag::warn_attribute_return_pointers_refs_only)
-        << &TmpAttr << AttrRange << getFunctionOrMethodResultSourceRange(D);
+        << &TmpAttr << CI.getRange() << getFunctionOrMethodResultSourceRange(D);
     return;
   }
 
@@ -1684,8 +1619,7 @@
     return;
   }
 
-  D->addAttr(::new (Context)
-                 AllocAlignAttr(AttrRange, Context, Idx, SpellingListIndex));
+  D->addAttr(::new (Context) AllocAlignAttr(Context, CI, Idx));
 }
 
 /// Normalize the attribute, __foo__ becomes foo.
@@ -1716,8 +1650,7 @@
 
   // Figure out our Kind.
   OwnershipAttr::OwnershipKind K =
-      OwnershipAttr(AL.getLoc(), S.Context, nullptr, nullptr, 0,
-                    AL.getAttributeSpellingListIndex()).getOwnKind();
+      OwnershipAttr(S.Context, AL, nullptr, nullptr, 0).getOwnKind();
 
   // Check arguments.
   switch (K) {
@@ -1799,8 +1732,7 @@
   unsigned Size = OwnershipArgs.size();
   llvm::array_pod_sort(Start, Start + Size);
   D->addAttr(::new (S.Context)
-                 OwnershipAttr(AL.getLoc(), S.Context, Module, Start, Size,
-                               AL.getAttributeSpellingListIndex()));
+                 OwnershipAttr(S.Context, AL, Module, Start, Size));
 }
 
 static void handleWeakRefAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
@@ -1856,12 +1788,9 @@
   if (AL.getNumArgs() && S.checkStringLiteralArgumentAttr(AL, 0, Str))
     // GCC will accept anything as the argument of weakref. Should we
     // check for an existing decl?
-    D->addAttr(::new (S.Context) AliasAttr(AL.getRange(), S.Context, Str,
-                                        AL.getAttributeSpellingListIndex()));
+    D->addAttr(::new (S.Context) AliasAttr(S.Context, AL, Str));
 
-  D->addAttr(::new (S.Context)
-             WeakRefAttr(AL.getRange(), S.Context,
-                         AL.getAttributeSpellingListIndex()));
+  D->addAttr(::new (S.Context) WeakRefAttr(S.Context, AL));
 }
 
 static void handleIFuncAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
@@ -1876,8 +1805,7 @@
     return;
   }
 
-  D->addAttr(::new (S.Context) IFuncAttr(AL.getRange(), S.Context, Str,
-                                         AL.getAttributeSpellingListIndex()));
+  D->addAttr(::new (S.Context) IFuncAttr(S.Context, AL, Str));
 }
 
 static void handleAliasAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
@@ -1918,8 +1846,7 @@
         ND->markUsed(S.Context);
   }
 
-  D->addAttr(::new (S.Context) AliasAttr(AL.getRange(), S.Context, Str,
-                                         AL.getAttributeSpellingListIndex()));
+  D->addAttr(::new (S.Context) AliasAttr(S.Context, AL, Str));
 }
 
 static void handleTLSModelAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
@@ -1936,16 +1863,13 @@
     return;
   }
 
-  D->addAttr(::new (S.Context)
-             TLSModelAttr(AL.getRange(), S.Context, Model,
-                          AL.getAttributeSpellingListIndex()));
+  D->addAttr(::new (S.Context) TLSModelAttr(S.Context, AL, Model));
 }
 
 static void handleRestrictAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
   QualType ResultType = getFunctionOrMethodResultType(D);
   if (ResultType->isAnyPointerType() || ResultType->isBlockPointerType()) {
-    D->addAttr(::new (S.Context) RestrictAttr(
-        AL.getRange(), S.Context, AL.getAttributeSpellingListIndex()));
+    D->addAttr(::new (S.Context) RestrictAttr(S.Context, AL));
     return;
   }
 
@@ -1996,13 +1920,11 @@
 
   FD->setIsMultiVersion(true);
   if (AL.getKind() == ParsedAttr::AT_CPUSpecific)
-    D->addAttr(::new (S.Context) CPUSpecificAttr(
-        AL.getRange(), S.Context, CPUs.data(), CPUs.size(),
-        AL.getAttributeSpellingListIndex()));
+    D->addAttr(::new (S.Context)
+                   CPUSpecificAttr(S.Context, AL, CPUs.data(), CPUs.size()));
   else
-    D->addAttr(::new (S.Context) CPUDispatchAttr(
-        AL.getRange(), S.Context, CPUs.data(), CPUs.size(),
-        AL.getAttributeSpellingListIndex()));
+    D->addAttr(::new (S.Context)
+                   CPUDispatchAttr(S.Context, AL, CPUs.data(), CPUs.size()));
 }
 
 static void handleCommonAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
@@ -2031,8 +1953,7 @@
     }
   }
 
-  D->addAttr(::new (S.Context) NakedAttr(AL.getRange(), S.Context,
-                                         AL.getAttributeSpellingListIndex()));
+  D->addAttr(::new (S.Context) NakedAttr(S.Context, AL));
 }
 
 static void handleNoReturnAttr(Sema &S, Decl *D, const ParsedAttr &Attrs) {
@@ -2044,8 +1965,7 @@
     return;
   }
 
-  D->addAttr(::new (S.Context) NoReturnAttr(
-      Attrs.getRange(), S.Context, Attrs.getAttributeSpellingListIndex()));
+  D->addAttr(::new (S.Context) NoReturnAttr(S.Context, Attrs));
 }
 
 static void handleNoCfCheckAttr(Sema &S, Decl *D, const ParsedAttr &Attrs) {
@@ -2091,9 +2011,7 @@
     }
   }
 
-  D->addAttr(::new (S.Context)
-             AnalyzerNoReturnAttr(AL.getRange(), S.Context,
-                                  AL.getAttributeSpellingListIndex()));
+  D->addAttr(::new (S.Context) AnalyzerNoReturnAttr(S.Context, AL));
 }
 
 // PS3 PPU-specific.
@@ -2148,8 +2066,7 @@
     count++;
   }
 
-  D->addAttr(::new (S.Context) VecReturnAttr(
-      AL.getRange(), S.Context, AL.getAttributeSpellingListIndex()));
+  D->addAttr(::new (S.Context) VecReturnAttr(S.Context, AL));
 }
 
 static void handleDependencyAttr(Sema &S, Scope *Scope, Decl *D,
@@ -2164,9 +2081,7 @@
     }
   }
 
-  D->addAttr(::new (S.Context) CarriesDependencyAttr(
-                                   AL.getRange(), S.Context,
-                                   AL.getAttributeSpellingListIndex()));
+  D->addAttr(::new (S.Context) CarriesDependencyAttr(S.Context, AL));
 }
 
 static void handleUnusedAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
@@ -2177,8 +2092,7 @@
   if (!S.getLangOpts().CPlusPlus17 && IsCXX17Attr)
     S.Diag(AL.getLoc(), diag::ext_cxx17_attr) << AL;
 
-  D->addAttr(::new (S.Context) UnusedAttr(
-      AL.getRange(), S.Context, AL.getAttributeSpellingListIndex()));
+  D->addAttr(::new (S.Context) UnusedAttr(S.Context, AL));
 }
 
 static void handleConstructorAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
@@ -2187,9 +2101,7 @@
       !checkUInt32Argument(S, AL, AL.getArgAsExpr(0), priority))
     return;
 
-  D->addAttr(::new (S.Context)
-             ConstructorAttr(AL.getRange(), S.Context, priority,
-                             AL.getAttributeSpellingListIndex()));
+  D->addAttr(::new (S.Context) ConstructorAttr(S.Context, AL, priority));
 }
 
 static void handleDestructorAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
@@ -2198,9 +2110,7 @@
       !checkUInt32Argument(S, AL, AL.getArgAsExpr(0), priority))
     return;
 
-  D->addAttr(::new (S.Context)
-             DestructorAttr(AL.getRange(), S.Context, priority,
-                            AL.getAttributeSpellingListIndex()));
+  D->addAttr(::new (S.Context) DestructorAttr(S.Context, AL, priority));
 }
 
 template <typename AttrTy>
@@ -2210,8 +2120,7 @@
   if (AL.getNumArgs() == 1 && !S.checkStringLiteralArgumentAttr(AL, 0, Str))
     return;
 
-  D->addAttr(::new (S.Context) AttrTy(AL.getRange(), S.Context, Str,
-                                      AL.getAttributeSpellingListIndex()));
+  D->addAttr(::new (S.Context) AttrTy(S.Context, AL, Str));
 }
 
 static void handleObjCSuppresProtocolAttr(Sema &S, Decl *D,
@@ -2222,9 +2131,7 @@
     return;
   }
 
-  D->addAttr(::new (S.Context)
-          ObjCExplicitProtocolImplAttr(AL.getRange(), S.Context,
-                                       AL.getAttributeSpellingListIndex()));
+  D->addAttr(::new (S.Context) ObjCExplicitProtocolImplAttr(S.Context, AL));
 }
 
 static bool checkAvailabilityAttr(Sema &S, SourceRange Range,
@@ -2285,10 +2192,11 @@
 }
 
 AvailabilityAttr *Sema::mergeAvailabilityAttr(
-    NamedDecl *D, SourceRange Range, IdentifierInfo *Platform, bool Implicit,
-    VersionTuple Introduced, VersionTuple Deprecated, VersionTuple Obsoleted,
-    bool IsUnavailable, StringRef Message, bool IsStrict, StringRef Replacement,
-    AvailabilityMergeKind AMK, int Priority, unsigned AttrSpellingListIndex) {
+    NamedDecl *D, const AttributeCommonInfo &CI, IdentifierInfo *Platform,
+    bool Implicit, VersionTuple Introduced, VersionTuple Deprecated,
+    VersionTuple Obsoleted, bool IsUnavailable, StringRef Message,
+    bool IsStrict, StringRef Replacement, AvailabilityMergeKind AMK,
+    int Priority) {
   VersionTuple MergedIntroduced = Introduced;
   VersionTuple MergedDeprecated = Deprecated;
   VersionTuple MergedObsoleted = Obsoleted;
@@ -2379,12 +2287,12 @@
               << (AMK == AMK_Override);
           }
           if (AMK == AMK_Override)
-            Diag(Range.getBegin(), diag::note_overridden_method);
+            Diag(CI.getLoc(), diag::note_overridden_method);
           else
-            Diag(Range.getBegin(), diag::note_protocol_method);
+            Diag(CI.getLoc(), diag::note_protocol_method);
         } else {
           Diag(OldAA->getLocation(), diag::warn_mismatched_availability);
-          Diag(Range.getBegin(), diag::note_previous_attribute);
+          Diag(CI.getLoc(), diag::note_previous_attribute);
         }
 
         Attrs.erase(Attrs.begin() + i);
@@ -2426,13 +2334,12 @@
 
   // Only create a new attribute if !OverrideOrImpl, but we want to do
   // the checking.
-  if (!checkAvailabilityAttr(*this, Range, Platform, MergedIntroduced,
+  if (!checkAvailabilityAttr(*this, CI.getRange(), Platform, MergedIntroduced,
                              MergedDeprecated, MergedObsoleted) &&
       !OverrideOrImpl) {
-    auto *Avail = ::new (Context)
-        AvailabilityAttr(Range, Context, Platform, Introduced, Deprecated,
-                         Obsoleted, IsUnavailable, Message, IsStrict,
-                         Replacement, Priority, AttrSpellingListIndex);
+    auto *Avail = ::new (Context) AvailabilityAttr(
+        Context, CI, Platform, Introduced, Deprecated, Obsoleted, IsUnavailable,
+        Message, IsStrict, Replacement, Priority);
     Avail->setImplicit(Implicit);
     return Avail;
   }
@@ -2443,7 +2350,6 @@
   if (!checkAttributeNumArgs(S, AL, 1))
     return;
   IdentifierLoc *Platform = AL.getArgAsIdent(0);
-  unsigned Index = AL.getAttributeSpellingListIndex();
 
   IdentifierInfo *II = Platform->Ident;
   if (AvailabilityAttr::getPrettyPlatformName(II->getName()).empty())
@@ -2479,9 +2385,9 @@
                              ? Sema::AP_PragmaClangAttribute
                              : Sema::AP_Explicit;
   AvailabilityAttr *NewAttr = S.mergeAvailabilityAttr(
-      ND, AL.getRange(), II, false /*Implicit*/, Introduced.Version,
-      Deprecated.Version, Obsoleted.Version, IsUnavailable, Str, IsStrict,
-      Replacement, Sema::AMK_None, PriorityModifier, Index);
+      ND, AL, II, false /*Implicit*/, Introduced.Version, Deprecated.Version,
+      Obsoleted.Version, IsUnavailable, Str, IsStrict, Replacement,
+      Sema::AMK_None, PriorityModifier);
   if (NewAttr)
     D->addAttr(NewAttr);
 
@@ -2519,10 +2425,10 @@
         auto NewObsoleted = adjustWatchOSVersion(Obsoleted.Version);
 
         AvailabilityAttr *NewAttr = S.mergeAvailabilityAttr(
-            ND, AL.getRange(), NewII, true /*Implicit*/, NewIntroduced,
-            NewDeprecated, NewObsoleted, IsUnavailable, Str, IsStrict,
-            Replacement, Sema::AMK_None,
-            PriorityModifier + Sema::AP_InferredFromOtherPlatform, Index);
+            ND, AL, NewII, true /*Implicit*/, NewIntroduced, NewDeprecated,
+            NewObsoleted, IsUnavailable, Str, IsStrict, Replacement,
+            Sema::AMK_None,
+            PriorityModifier + Sema::AP_InferredFromOtherPlatform);
         if (NewAttr)
           D->addAttr(NewAttr);
       }
@@ -2537,10 +2443,10 @@
 
     if (NewII) {
       AvailabilityAttr *NewAttr = S.mergeAvailabilityAttr(
-          ND, AL.getRange(), NewII, true /*Implicit*/, Introduced.Version,
+          ND, AL, NewII, true /*Implicit*/, Introduced.Version,
           Deprecated.Version, Obsoleted.Version, IsUnavailable, Str, IsStrict,
           Replacement, Sema::AMK_None,
-          PriorityModifier + Sema::AP_InferredFromOtherPlatform, Index);
+          PriorityModifier + Sema::AP_InferredFromOtherPlatform);
       if (NewAttr)
         D->addAttr(NewAttr);
       }
@@ -2563,38 +2469,34 @@
   bool IsGeneratedDeclaration = AL.getArgAsIdent(2) != nullptr;
 
   D->addAttr(::new (S.Context) ExternalSourceSymbolAttr(
-      AL.getRange(), S.Context, Language, DefinedIn, IsGeneratedDeclaration,
-      AL.getAttributeSpellingListIndex()));
+      S.Context, AL, Language, DefinedIn, IsGeneratedDeclaration));
 }
 
 template <class T>
-static T *mergeVisibilityAttr(Sema &S, Decl *D, SourceRange range,
-                              typename T::VisibilityType value,
-                              unsigned attrSpellingListIndex) {
+static T *mergeVisibilityAttr(Sema &S, Decl *D, const AttributeCommonInfo &CI,
+                              typename T::VisibilityType value) {
   T *existingAttr = D->getAttr<T>();
   if (existingAttr) {
     typename T::VisibilityType existingValue = existingAttr->getVisibility();
     if (existingValue == value)
       return nullptr;
     S.Diag(existingAttr->getLocation(), diag::err_mismatched_visibility);
-    S.Diag(range.getBegin(), diag::note_previous_attribute);
+    S.Diag(CI.getLoc(), diag::note_previous_attribute);
     D->dropAttr<T>();
   }
-  return ::new (S.Context) T(range, S.Context, value, attrSpellingListIndex);
+  return ::new (S.Context) T(S.Context, CI, value);
 }
 
-VisibilityAttr *Sema::mergeVisibilityAttr(Decl *D, SourceRange Range,
-                                          VisibilityAttr::VisibilityType Vis,
-                                          unsigned AttrSpellingListIndex) {
-  return ::mergeVisibilityAttr<VisibilityAttr>(*this, D, Range, Vis,
-                                               AttrSpellingListIndex);
+VisibilityAttr *Sema::mergeVisibilityAttr(Decl *D,
+                                          const AttributeCommonInfo &CI,
+                                          VisibilityAttr::VisibilityType Vis) {
+  return ::mergeVisibilityAttr<VisibilityAttr>(*this, D, CI, Vis);
 }
 
-TypeVisibilityAttr *Sema::mergeTypeVisibilityAttr(Decl *D, SourceRange Range,
-                                      TypeVisibilityAttr::VisibilityType Vis,
-                                      unsigned AttrSpellingListIndex) {
-  return ::mergeVisibilityAttr<TypeVisibilityAttr>(*this, D, Range, Vis,
-                                                   AttrSpellingListIndex);
+TypeVisibilityAttr *
+Sema::mergeTypeVisibilityAttr(Decl *D, const AttributeCommonInfo &CI,
+                              TypeVisibilityAttr::VisibilityType Vis) {
+  return ::mergeVisibilityAttr<TypeVisibilityAttr>(*this, D, CI, Vis);
 }
 
 static void handleVisibilityAttr(Sema &S, Decl *D, const ParsedAttr &AL,
@@ -2636,14 +2538,12 @@
     type = VisibilityAttr::Default;
   }
 
-  unsigned Index = AL.getAttributeSpellingListIndex();
   Attr *newAttr;
   if (isTypeVisibility) {
-    newAttr = S.mergeTypeVisibilityAttr(D, AL.getRange(),
-                                    (TypeVisibilityAttr::VisibilityType) type,
-                                        Index);
+    newAttr = S.mergeTypeVisibilityAttr(
+        D, AL, (TypeVisibilityAttr::VisibilityType)type);
   } else {
-    newAttr = S.mergeVisibilityAttr(D, AL.getRange(), type, Index);
+    newAttr = S.mergeVisibilityAttr(D, AL, type);
   }
   if (newAttr)
     D->addAttr(newAttr);
@@ -2672,8 +2572,7 @@
     return;
   }
 
-  D->addAttr(new (S.Context) ObjCMethodFamilyAttr(
-      AL.getRange(), S.Context, F, AL.getAttributeSpellingListIndex()));
+  D->addAttr(new (S.Context) ObjCMethodFamilyAttr(S.Context, AL, F));
 }
 
 static void handleObjCNSObject(Sema &S, Decl *D, const ParsedAttr &AL) {
@@ -2700,9 +2599,7 @@
     // case.
     S.Diag(D->getLocation(), diag::warn_nsobject_attribute);
   }
-  D->addAttr(::new (S.Context)
-             ObjCNSObjectAttr(AL.getRange(), S.Context,
-                              AL.getAttributeSpellingListIndex()));
+  D->addAttr(::new (S.Context) ObjCNSObjectAttr(S.Context, AL));
 }
 
 static void handleObjCIndependentClass(Sema &S, Decl *D, const ParsedAttr &AL) {
@@ -2716,9 +2613,7 @@
     S.Diag(D->getLocation(), diag::warn_independentclass_attribute);
     return;
   }
-  D->addAttr(::new (S.Context)
-             ObjCIndependentClassAttr(AL.getRange(), S.Context,
-                              AL.getAttributeSpellingListIndex()));
+  D->addAttr(::new (S.Context) ObjCIndependentClassAttr(S.Context, AL));
 }
 
 static void handleBlocksAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
@@ -2735,9 +2630,7 @@
     return;
   }
 
-  D->addAttr(::new (S.Context)
-             BlocksAttr(AL.getRange(), S.Context, type,
-                        AL.getAttributeSpellingListIndex()));
+  D->addAttr(::new (S.Context) BlocksAttr(S.Context, AL, type));
 }
 
 static void handleSentinelAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
@@ -2824,9 +2717,7 @@
         << AL << ExpectedFunctionMethodOrBlock;
     return;
   }
-  D->addAttr(::new (S.Context)
-             SentinelAttr(AL.getRange(), S.Context, sentinel, nullPos,
-                          AL.getAttributeSpellingListIndex()));
+  D->addAttr(::new (S.Context) SentinelAttr(S.Context, AL, sentinel, nullPos));
 }
 
 static void handleWarnUnusedResult(Sema &S, Decl *D, const ParsedAttr &AL) {
@@ -2864,9 +2755,7 @@
       S.Diag(AL.getLoc(), diag::ext_cxx17_attr) << AL;
   }
 
-  D->addAttr(::new (S.Context)
-             WarnUnusedResultAttr(AL.getRange(), S.Context, Str,
-                                  AL.getAttributeSpellingListIndex()));
+  D->addAttr(::new (S.Context) WarnUnusedResultAttr(S.Context, AL, Str));
 }
 
 static void handleWeakImportAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
@@ -2887,9 +2776,7 @@
     return;
   }
 
-  D->addAttr(::new (S.Context)
-             WeakImportAttr(AL.getRange(), S.Context,
-                            AL.getAttributeSpellingListIndex()));
+  D->addAttr(::new (S.Context) WeakImportAttr(S.Context, AL));
 }
 
 // Handles reqd_work_group_size and work_group_size_hint.
@@ -2914,9 +2801,8 @@
                     Existing->getZDim() == WGSize[2]))
     S.Diag(AL.getLoc(), diag::warn_duplicate_attribute) << AL;
 
-  D->addAttr(::new (S.Context) WorkGroupAttr(AL.getRange(), S.Context,
-                                             WGSize[0], WGSize[1], WGSize[2],
-                                       AL.getAttributeSpellingListIndex()));
+  D->addAttr(::new (S.Context)
+                 WorkGroupAttr(S.Context, AL, WGSize[0], WGSize[1], WGSize[2]));
 }
 
 // Handles intel_reqd_sub_group_size.
@@ -2936,9 +2822,8 @@
   if (Existing && Existing->getSubGroupSize() != SGSize)
     S.Diag(AL.getLoc(), diag::warn_duplicate_attribute) << AL;
 
-  D->addAttr(::new (S.Context) OpenCLIntelReqdSubGroupSizeAttr(
-      AL.getRange(), S.Context, SGSize,
-      AL.getAttributeSpellingListIndex()));
+  D->addAttr(::new (S.Context)
+                 OpenCLIntelReqdSubGroupSizeAttr(S.Context, AL, SGSize));
 }
 
 static void handleVecTypeHint(Sema &S, Decl *D, const ParsedAttr &AL) {
@@ -2965,18 +2850,15 @@
     }
   }
 
-  D->addAttr(::new (S.Context) VecTypeHintAttr(AL.getLoc(), S.Context,
-                                               ParmTSI,
-                                        AL.getAttributeSpellingListIndex()));
+  D->addAttr(::new (S.Context) VecTypeHintAttr(S.Context, AL, ParmTSI));
 }
 
-SectionAttr *Sema::mergeSectionAttr(Decl *D, SourceRange Range,
-                                    StringRef Name,
-                                    unsigned AttrSpellingListIndex) {
+SectionAttr *Sema::mergeSectionAttr(Decl *D, const AttributeCommonInfo &CI,
+                                    StringRef Name) {
   // Explicit or partial specializations do not inherit
   // the section attribute from the primary template.
   if (const auto *FD = dyn_cast<FunctionDecl>(D)) {
-    if (AttrSpellingListIndex == SectionAttr::Declspec_allocate &&
+    if (CI.getAttributeSpellingListIndex() == SectionAttr::Declspec_allocate &&
         FD->isFunctionTemplateSpecialization())
       return nullptr;
   }
@@ -2985,11 +2867,10 @@
       return nullptr;
     Diag(ExistingAttr->getLocation(), diag::warn_mismatched_section)
          << 1 /*section*/;
-    Diag(Range.getBegin(), diag::note_previous_attribute);
+    Diag(CI.getLoc(), diag::note_previous_attribute);
     return nullptr;
   }
-  return ::new (Context) SectionAttr(Range, Context, Name,
-                                     AttrSpellingListIndex);
+  return ::new (Context) SectionAttr(Context, CI, Name);
 }
 
 bool Sema::checkSectionName(SourceLocation LiteralLoc, StringRef SecName) {
@@ -3021,8 +2902,7 @@
     return;
   }
 
-  unsigned Index = AL.getAttributeSpellingListIndex();
-  SectionAttr *NewAttr = S.mergeSectionAttr(D, AL.getRange(), Str, Index);
+  SectionAttr *NewAttr = S.mergeSectionAttr(D, AL, Str);
   if (NewAttr)
     D->addAttr(NewAttr);
 }
@@ -3042,9 +2922,8 @@
   return true;
 }
 
-CodeSegAttr *Sema::mergeCodeSegAttr(Decl *D, SourceRange Range,
-                                    StringRef Name,
-                                    unsigned AttrSpellingListIndex) {
+CodeSegAttr *Sema::mergeCodeSegAttr(Decl *D, const AttributeCommonInfo &CI,
+                                    StringRef Name) {
   // Explicit or partial specializations do not inherit
   // the code_seg attribute from the primary template.
   if (const auto *FD = dyn_cast<FunctionDecl>(D)) {
@@ -3056,11 +2935,10 @@
       return nullptr;
     Diag(ExistingAttr->getLocation(), diag::warn_mismatched_section)
          << 0 /*codeseg*/;
-    Diag(Range.getBegin(), diag::note_previous_attribute);
+    Diag(CI.getLoc(), diag::note_previous_attribute);
     return nullptr;
   }
-  return ::new (Context) CodeSegAttr(Range, Context, Name,
-                                     AttrSpellingListIndex);
+  return ::new (Context) CodeSegAttr(Context, CI, Name);
 }
 
 static void handleCodeSegAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
@@ -3080,8 +2958,7 @@
     }
     D->dropAttr<CodeSegAttr>();
   }
-  if (CodeSegAttr *CSA = S.mergeCodeSegAttr(D, AL.getRange(), Str,
-                                            AL.getAttributeSpellingListIndex()))
+  if (CodeSegAttr *CSA = S.mergeCodeSegAttr(D, AL, Str))
     D->addAttr(CSA);
 }
 
@@ -3123,9 +3000,7 @@
       S.checkTargetAttr(LiteralLoc, Str))
     return;
 
-  unsigned Index = AL.getAttributeSpellingListIndex();
-  TargetAttr *NewAttr =
-      ::new (S.Context) TargetAttr(AL.getRange(), S.Context, Str, Index);
+  TargetAttr *NewAttr = ::new (S.Context) TargetAttr(S.Context, AL, Str);
   D->addAttr(NewAttr);
 }
 
@@ -3143,9 +3018,7 @@
     return;
   }
 
-  D->addAttr(::new (S.Context)
-             MinVectorWidthAttr(AL.getRange(), S.Context, VecWidth,
-                                AL.getAttributeSpellingListIndex()));
+  D->addAttr(::new (S.Context) MinVectorWidthAttr(S.Context, AL, VecWidth));
 }
 
 static void handleCleanupAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
@@ -3200,9 +3073,7 @@
     return;
   }
 
-  D->addAttr(::new (S.Context)
-             CleanupAttr(AL.getRange(), S.Context, FD,
-                         AL.getAttributeSpellingListIndex()));
+  D->addAttr(::new (S.Context) CleanupAttr(S.Context, AL, FD));
 }
 
 static void handleEnumExtensibilityAttr(Sema &S, Decl *D,
@@ -3221,9 +3092,8 @@
     return;
   }
 
-  D->addAttr(::new (S.Context) EnumExtensibilityAttr(
-      AL.getRange(), S.Context, ExtensibilityKind,
-      AL.getAttributeSpellingListIndex()));
+  D->addAttr(::new (S.Context)
+                 EnumExtensibilityAttr(S.Context, AL, ExtensibilityKind));
 }
 
 /// Handle __attribute__((format_arg((idx)))) attribute based on
@@ -3258,8 +3128,7 @@
     return;
   }
 
-  D->addAttr(::new (S.Context) FormatArgAttr(
-      AL.getRange(), S.Context, Idx, AL.getAttributeSpellingListIndex()));
+  D->addAttr(::new (S.Context) FormatArgAttr(S.Context, AL, Idx));
 }
 
 enum FormatAttrKind {
@@ -3327,15 +3196,12 @@
     AL.setInvalid();
     return;
   }
-  D->addAttr(::new (S.Context)
-             InitPriorityAttr(AL.getRange(), S.Context, prioritynum,
-                              AL.getAttributeSpellingListIndex()));
+  D->addAttr(::new (S.Context) InitPriorityAttr(S.Context, AL, prioritynum));
 }
 
-FormatAttr *Sema::mergeFormatAttr(Decl *D, SourceRange Range,
+FormatAttr *Sema::mergeFormatAttr(Decl *D, const AttributeCommonInfo &CI,
                                   IdentifierInfo *Format, int FormatIdx,
-                                  int FirstArg,
-                                  unsigned AttrSpellingListIndex) {
+                                  int FirstArg) {
   // Check whether we already have an equivalent format attribute.
   for (auto *F : D->specific_attrs<FormatAttr>()) {
     if (F->getType() == Format &&
@@ -3344,13 +3210,12 @@
       // If we don't have a valid location for this attribute, adopt the
       // location.
       if (F->getLocation().isInvalid())
-        F->setRange(Range);
+        F->setRange(CI.getRange());
       return nullptr;
     }
   }
 
-  return ::new (Context) FormatAttr(Range, Context, Format, FormatIdx,
-                                    FirstArg, AttrSpellingListIndex);
+  return ::new (Context) FormatAttr(Context, CI, Format, FormatIdx, FirstArg);
 }
 
 /// Handle __attribute__((format(type,idx,firstarg))) attributes based on
@@ -3470,9 +3335,7 @@
     return;
   }
 
-  FormatAttr *NewAttr = S.mergeFormatAttr(D, AL.getRange(), II,
-                                          Idx, FirstArg,
-                                          AL.getAttributeSpellingListIndex());
+  FormatAttr *NewAttr = S.mergeFormatAttr(D, AL, II, Idx, FirstArg);
   if (NewAttr)
     D->addAttr(NewAttr);
 }
@@ -3613,8 +3476,7 @@
   }
 
   D->addAttr(::new (S.Context) CallbackAttr(
-      AL.getRange(), S.Context, EncodingIndices.data(), EncodingIndices.size(),
-      AL.getAttributeSpellingListIndex()));
+      S.Context, AL, EncodingIndices.data(), EncodingIndices.size()));
 }
 
 static void handleTransparentUnionAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
@@ -3685,9 +3547,7 @@
     }
   }
 
-  RD->addAttr(::new (S.Context)
-              TransparentUnionAttr(AL.getRange(), S.Context,
-                                   AL.getAttributeSpellingListIndex()));
+  RD->addAttr(::new (S.Context) TransparentUnionAttr(S.Context, AL));
 }
 
 static void handleAnnotateAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
@@ -3703,20 +3563,16 @@
       return;
   }
 
-  D->addAttr(::new (S.Context)
-             AnnotateAttr(AL.getRange(), S.Context, Str,
-                          AL.getAttributeSpellingListIndex()));
+  D->addAttr(::new (S.Context) AnnotateAttr(S.Context, AL, Str));
 }
 
 static void handleAlignValueAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
-  S.AddAlignValueAttr(AL.getRange(), D, AL.getArgAsExpr(0),
-                      AL.getAttributeSpellingListIndex());
+  S.AddAlignValueAttr(D, AL, AL.getArgAsExpr(0));
 }
 
-void Sema::AddAlignValueAttr(SourceRange AttrRange, Decl *D, Expr *E,
-                             unsigned SpellingListIndex) {
-  AlignValueAttr TmpAttr(AttrRange, Context, E, SpellingListIndex);
-  SourceLocation AttrLoc = AttrRange.getBegin();
+void Sema::AddAlignValueAttr(Decl *D, const AttributeCommonInfo &CI, Expr *E) {
+  AlignValueAttr TmpAttr(Context, CI, E);
+  SourceLocation AttrLoc = CI.getLoc();
 
   QualType T;
   if (const auto *TD = dyn_cast<TypedefNameDecl>(D))
@@ -3748,14 +3604,12 @@
       return;
     }
 
-    D->addAttr(::new (Context)
-               AlignValueAttr(AttrRange, Context, ICE.get(),
-               SpellingListIndex));
+    D->addAttr(::new (Context) AlignValueAttr(Context, CI, ICE.get()));
     return;
   }
 
   // Save dependent expressions in the AST to be instantiated.
-  D->addAttr(::new (Context) AlignValueAttr(TmpAttr));
+  D->addAttr(::new (Context) AlignValueAttr(Context, CI, E));
 }
 
 static void handleAlignedAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
@@ -3766,8 +3620,7 @@
   }
 
   if (AL.getNumArgs() == 0) {
-    D->addAttr(::new (S.Context) AlignedAttr(AL.getRange(), S.Context,
-               true, nullptr, AL.getAttributeSpellingListIndex()));
+    D->addAttr(::new (S.Context) AlignedAttr(S.Context, AL, true, nullptr));
     return;
   }
 
@@ -3781,14 +3634,13 @@
   if (!AL.isPackExpansion() && S.DiagnoseUnexpandedParameterPack(E))
     return;
 
-  S.AddAlignedAttr(AL.getRange(), D, E, AL.getAttributeSpellingListIndex(),
-                   AL.isPackExpansion());
+  S.AddAlignedAttr(D, AL, E, AL.isPackExpansion());
 }
 
-void Sema::AddAlignedAttr(SourceRange AttrRange, Decl *D, Expr *E,
-                          unsigned SpellingListIndex, bool IsPackExpansion) {
-  AlignedAttr TmpAttr(AttrRange, Context, true, E, SpellingListIndex);
-  SourceLocation AttrLoc = AttrRange.getBegin();
+void Sema::AddAlignedAttr(Decl *D, const AttributeCommonInfo &CI, Expr *E,
+                          bool IsPackExpansion) {
+  AlignedAttr TmpAttr(Context, CI, true, E);
+  SourceLocation AttrLoc = CI.getLoc();
 
   // C++11 alignas(...) and C11 _Alignas(...) have additional requirements.
   if (TmpAttr.isAlignas()) {
@@ -3840,7 +3692,7 @@
     }
 
     // Save dependent expressions in the AST to be instantiated.
-    AlignedAttr *AA = ::new (Context) AlignedAttr(TmpAttr);
+    AlignedAttr *AA = ::new (Context) AlignedAttr(Context, CI, true, E);
     AA->setPackExpansion(IsPackExpansion);
     D->addAttr(AA);
     return;
@@ -3893,18 +3745,16 @@
     }
   }
 
-  AlignedAttr *AA = ::new (Context) AlignedAttr(AttrRange, Context, true,
-                                                ICE.get(), SpellingListIndex);
+  AlignedAttr *AA = ::new (Context) AlignedAttr(Context, CI, true, ICE.get());
   AA->setPackExpansion(IsPackExpansion);
   D->addAttr(AA);
 }
 
-void Sema::AddAlignedAttr(SourceRange AttrRange, Decl *D, TypeSourceInfo *TS,
-                          unsigned SpellingListIndex, bool IsPackExpansion) {
+void Sema::AddAlignedAttr(Decl *D, const AttributeCommonInfo &CI,
+                          TypeSourceInfo *TS, bool IsPackExpansion) {
   // FIXME: Cache the number on the AL object if non-dependent?
   // FIXME: Perform checking of type validity
-  AlignedAttr *AA = ::new (Context) AlignedAttr(AttrRange, Context, false, TS,
-                                                SpellingListIndex);
+  AlignedAttr *AA = ::new (Context) AlignedAttr(Context, CI, false, TS);
   AA->setPackExpansion(IsPackExpansion);
   D->addAttr(AA);
 }
@@ -4048,14 +3898,14 @@
 
   IdentifierInfo *Name = AL.getArgAsIdent(0)->Ident;
 
-  S.AddModeAttr(AL.getRange(), D, Name, AL.getAttributeSpellingListIndex());
+  S.AddModeAttr(D, AL, Name);
 }
 
-void Sema::AddModeAttr(SourceRange AttrRange, Decl *D, IdentifierInfo *Name,
-                       unsigned SpellingListIndex, bool InInstantiation) {
+void Sema::AddModeAttr(Decl *D, const AttributeCommonInfo &CI,
+                       IdentifierInfo *Name, bool InInstantiation) {
   StringRef Str = Name->getName();
   normalizeName(Str);
-  SourceLocation AttrLoc = AttrRange.getBegin();
+  SourceLocation AttrLoc = CI.getLoc();
 
   unsigned DestWidth = 0;
   bool IntegerMode = true;
@@ -4106,8 +3956,7 @@
     OldTy = cast<ValueDecl>(D)->getType();
 
   if (OldTy->isDependentType()) {
-    D->addAttr(::new (Context)
-               ModeAttr(AttrRange, Context, Name, SpellingListIndex));
+    D->addAttr(::new (Context) ModeAttr(Context, CI, Name));
     return;
   }
 
@@ -4122,7 +3971,7 @@
   // type, 'enum { A } __attribute__((mode(V4SI)))' is rejected.
   if ((isa<EnumDecl>(D) || OldElemTy->getAs<EnumType>()) &&
       VectorSize.getBoolValue()) {
-    Diag(AttrLoc, diag::err_enum_mode_vector_type) << Name << AttrRange;
+    Diag(AttrLoc, diag::err_enum_mode_vector_type) << Name << CI.getRange();
     return;
   }
   bool IntegralOrAnyEnumType =
@@ -4189,21 +4038,18 @@
   else
     cast<ValueDecl>(D)->setType(NewTy);
 
-  D->addAttr(::new (Context)
-             ModeAttr(AttrRange, Context, Name, SpellingListIndex));
+  D->addAttr(::new (Context) ModeAttr(Context, CI, Name));
 }
 
 static void handleNoDebugAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
-  D->addAttr(::new (S.Context)
-             NoDebugAttr(AL.getRange(), S.Context,
-                         AL.getAttributeSpellingListIndex()));
+  D->addAttr(::new (S.Context) NoDebugAttr(S.Context, AL));
 }
 
-AlwaysInlineAttr *Sema::mergeAlwaysInlineAttr(Decl *D, SourceRange Range,
-                                              IdentifierInfo *Ident,
-                                              unsigned AttrSpellingListIndex) {
+AlwaysInlineAttr *Sema::mergeAlwaysInlineAttr(Decl *D,
+                                              const AttributeCommonInfo &CI,
+                                              const IdentifierInfo *Ident) {
   if (OptimizeNoneAttr *Optnone = D->getAttr<OptimizeNoneAttr>()) {
-    Diag(Range.getBegin(), diag::warn_attribute_ignored) << Ident;
+    Diag(CI.getLoc(), diag::warn_attribute_ignored) << Ident;
     Diag(Optnone->getLocation(), diag::note_conflicting_attribute);
     return nullptr;
   }
@@ -4211,24 +4057,21 @@
   if (D->hasAttr<AlwaysInlineAttr>())
     return nullptr;
 
-  return ::new (Context) AlwaysInlineAttr(Range, Context,
-                                          AttrSpellingListIndex);
+  return ::new (Context) AlwaysInlineAttr(Context, CI);
 }
 
 CommonAttr *Sema::mergeCommonAttr(Decl *D, const ParsedAttr &AL) {
   if (checkAttrMutualExclusion<InternalLinkageAttr>(*this, D, AL))
     return nullptr;
 
-  return ::new (Context)
-      CommonAttr(AL.getRange(), Context, AL.getAttributeSpellingListIndex());
+  return ::new (Context) CommonAttr(Context, AL);
 }
 
 CommonAttr *Sema::mergeCommonAttr(Decl *D, const CommonAttr &AL) {
   if (checkAttrMutualExclusion<InternalLinkageAttr>(*this, D, AL))
     return nullptr;
 
-  return ::new (Context)
-      CommonAttr(AL.getRange(), Context, AL.getSpellingListIndex());
+  return ::new (Context) CommonAttr(Context, AL);
 }
 
 InternalLinkageAttr *Sema::mergeInternalLinkageAttr(Decl *D,
@@ -4252,8 +4095,7 @@
   if (checkAttrMutualExclusion<CommonAttr>(*this, D, AL))
     return nullptr;
 
-  return ::new (Context) InternalLinkageAttr(
-      AL.getRange(), Context, AL.getAttributeSpellingListIndex());
+  return ::new (Context) InternalLinkageAttr(Context, AL);
 }
 InternalLinkageAttr *
 Sema::mergeInternalLinkageAttr(Decl *D, const InternalLinkageAttr &AL) {
@@ -4276,14 +4118,12 @@
   if (checkAttrMutualExclusion<CommonAttr>(*this, D, AL))
     return nullptr;
 
-  return ::new (Context)
-      InternalLinkageAttr(AL.getRange(), Context, AL.getSpellingListIndex());
+  return ::new (Context) InternalLinkageAttr(Context, AL);
 }
 
-MinSizeAttr *Sema::mergeMinSizeAttr(Decl *D, SourceRange Range,
-                                    unsigned AttrSpellingListIndex) {
+MinSizeAttr *Sema::mergeMinSizeAttr(Decl *D, const AttributeCommonInfo &CI) {
   if (OptimizeNoneAttr *Optnone = D->getAttr<OptimizeNoneAttr>()) {
-    Diag(Range.getBegin(), diag::warn_attribute_ignored) << "'minsize'";
+    Diag(CI.getLoc(), diag::warn_attribute_ignored) << "'minsize'";
     Diag(Optnone->getLocation(), diag::note_conflicting_attribute);
     return nullptr;
   }
@@ -4291,7 +4131,7 @@
   if (D->hasAttr<MinSizeAttr>())
     return nullptr;
 
-  return ::new (Context) MinSizeAttr(Range, Context, AttrSpellingListIndex);
+  return ::new (Context) MinSizeAttr(Context, CI);
 }
 
 NoSpeculativeLoadHardeningAttr *Sema::mergeNoSpeculativeLoadHardeningAttr(
@@ -4299,28 +4139,26 @@
   if (checkAttrMutualExclusion<SpeculativeLoadHardeningAttr>(*this, D, AL))
     return nullptr;
 
-  return ::new (Context) NoSpeculativeLoadHardeningAttr(
-      AL.getRange(), Context, AL.getSpellingListIndex());
+  return ::new (Context) NoSpeculativeLoadHardeningAttr(Context, AL);
 }
 
-OptimizeNoneAttr *Sema::mergeOptimizeNoneAttr(Decl *D, SourceRange Range,
-                                              unsigned AttrSpellingListIndex) {
+OptimizeNoneAttr *Sema::mergeOptimizeNoneAttr(Decl *D,
+                                              const AttributeCommonInfo &CI) {
   if (AlwaysInlineAttr *Inline = D->getAttr<AlwaysInlineAttr>()) {
     Diag(Inline->getLocation(), diag::warn_attribute_ignored) << Inline;
-    Diag(Range.getBegin(), diag::note_conflicting_attribute);
+    Diag(CI.getLoc(), diag::note_conflicting_attribute);
     D->dropAttr<AlwaysInlineAttr>();
   }
   if (MinSizeAttr *MinSize = D->getAttr<MinSizeAttr>()) {
     Diag(MinSize->getLocation(), diag::warn_attribute_ignored) << MinSize;
-    Diag(Range.getBegin(), diag::note_conflicting_attribute);
+    Diag(CI.getLoc(), diag::note_conflicting_attribute);
     D->dropAttr<MinSizeAttr>();
   }
 
   if (D->hasAttr<OptimizeNoneAttr>())
     return nullptr;
 
-  return ::new (Context) OptimizeNoneAttr(Range, Context,
-                                          AttrSpellingListIndex);
+  return ::new (Context) OptimizeNoneAttr(Context, CI);
 }
 
 SpeculativeLoadHardeningAttr *Sema::mergeSpeculativeLoadHardeningAttr(
@@ -4328,29 +4166,25 @@
   if (checkAttrMutualExclusion<NoSpeculativeLoadHardeningAttr>(*this, D, AL))
     return nullptr;
 
-  return ::new (Context) SpeculativeLoadHardeningAttr(
-      AL.getRange(), Context, AL.getSpellingListIndex());
+  return ::new (Context) SpeculativeLoadHardeningAttr(Context, AL);
 }
 
 static void handleAlwaysInlineAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
   if (checkAttrMutualExclusion<NotTailCalledAttr>(S, D, AL))
     return;
 
-  if (AlwaysInlineAttr *Inline = S.mergeAlwaysInlineAttr(
-          D, AL.getRange(), AL.getName(),
-          AL.getAttributeSpellingListIndex()))
+  if (AlwaysInlineAttr *Inline =
+          S.mergeAlwaysInlineAttr(D, AL, AL.getAttrName()))
     D->addAttr(Inline);
 }
 
 static void handleMinSizeAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
-  if (MinSizeAttr *MinSize = S.mergeMinSizeAttr(
-          D, AL.getRange(), AL.getAttributeSpellingListIndex()))
+  if (MinSizeAttr *MinSize = S.mergeMinSizeAttr(D, AL))
     D->addAttr(MinSize);
 }
 
 static void handleOptimizeNoneAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
-  if (OptimizeNoneAttr *Optnone = S.mergeOptimizeNoneAttr(
-          D, AL.getRange(), AL.getAttributeSpellingListIndex()))
+  if (OptimizeNoneAttr *Optnone = S.mergeOptimizeNoneAttr(D, AL))
     D->addAttr(Optnone);
 }
 
@@ -4362,8 +4196,7 @@
     S.Diag(AL.getLoc(), diag::err_cuda_nonglobal_constant);
     return;
   }
-  D->addAttr(::new (S.Context) CUDAConstantAttr(
-      AL.getRange(), S.Context, AL.getAttributeSpellingListIndex()));
+  D->addAttr(::new (S.Context) CUDAConstantAttr(S.Context, AL));
 }
 
 static void handleSharedAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
@@ -4381,8 +4214,7 @@
       S.CUDADiagIfHostCode(AL.getLoc(), diag::err_cuda_host_shared)
           << S.CurrentCUDATarget())
     return;
-  D->addAttr(::new (S.Context) CUDASharedAttr(
-      AL.getRange(), S.Context, AL.getAttributeSpellingListIndex()));
+  D->addAttr(::new (S.Context) CUDASharedAttr(S.Context, AL));
 }
 
 static void handleGlobalAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
@@ -4411,9 +4243,7 @@
   if (FD->isInlineSpecified() && !S.getLangOpts().CUDAIsDevice)
     S.Diag(FD->getBeginLoc(), diag::warn_kern_is_inline) << FD;
 
-  D->addAttr(::new (S.Context)
-              CUDAGlobalAttr(AL.getRange(), S.Context,
-                             AL.getAttributeSpellingListIndex()));
+  D->addAttr(::new (S.Context) CUDAGlobalAttr(S.Context, AL));
 }
 
 static void handleGNUInlineAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
@@ -4423,9 +4253,7 @@
     return;
   }
 
-  D->addAttr(::new (S.Context)
-             GNUInlineAttr(AL.getRange(), S.Context,
-                           AL.getAttributeSpellingListIndex()));
+  D->addAttr(::new (S.Context) GNUInlineAttr(S.Context, AL));
 }
 
 static void handleCallConvAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
@@ -4445,53 +4273,34 @@
 
   switch (AL.getKind()) {
   case ParsedAttr::AT_FastCall:
-    D->addAttr(::new (S.Context)
-               FastCallAttr(AL.getRange(), S.Context,
-                            AL.getAttributeSpellingListIndex()));
+    D->addAttr(::new (S.Context) FastCallAttr(S.Context, AL));
     return;
   case ParsedAttr::AT_StdCall:
-    D->addAttr(::new (S.Context)
-               StdCallAttr(AL.getRange(), S.Context,
-                           AL.getAttributeSpellingListIndex()));
+    D->addAttr(::new (S.Context) StdCallAttr(S.Context, AL));
     return;
   case ParsedAttr::AT_ThisCall:
-    D->addAttr(::new (S.Context)
-               ThisCallAttr(AL.getRange(), S.Context,
-                            AL.getAttributeSpellingListIndex()));
+    D->addAttr(::new (S.Context) ThisCallAttr(S.Context, AL));
     return;
   case ParsedAttr::AT_CDecl:
-    D->addAttr(::new (S.Context)
-               CDeclAttr(AL.getRange(), S.Context,
-                         AL.getAttributeSpellingListIndex()));
+    D->addAttr(::new (S.Context) CDeclAttr(S.Context, AL));
     return;
   case ParsedAttr::AT_Pascal:
-    D->addAttr(::new (S.Context)
-               PascalAttr(AL.getRange(), S.Context,
-                          AL.getAttributeSpellingListIndex()));
+    D->addAttr(::new (S.Context) PascalAttr(S.Context, AL));
     return;
   case ParsedAttr::AT_SwiftCall:
-    D->addAttr(::new (S.Context)
-               SwiftCallAttr(AL.getRange(), S.Context,
-                             AL.getAttributeSpellingListIndex()));
+    D->addAttr(::new (S.Context) SwiftCallAttr(S.Context, AL));
     return;
   case ParsedAttr::AT_VectorCall:
-    D->addAttr(::new (S.Context)
-               VectorCallAttr(AL.getRange(), S.Context,
-                              AL.getAttributeSpellingListIndex()));
+    D->addAttr(::new (S.Context) VectorCallAttr(S.Context, AL));
     return;
   case ParsedAttr::AT_MSABI:
-    D->addAttr(::new (S.Context)
-               MSABIAttr(AL.getRange(), S.Context,
-                         AL.getAttributeSpellingListIndex()));
+    D->addAttr(::new (S.Context) MSABIAttr(S.Context, AL));
     return;
   case ParsedAttr::AT_SysVABI:
-    D->addAttr(::new (S.Context)
-               SysVABIAttr(AL.getRange(), S.Context,
-                           AL.getAttributeSpellingListIndex()));
+    D->addAttr(::new (S.Context) SysVABIAttr(S.Context, AL));
     return;
   case ParsedAttr::AT_RegCall:
-    D->addAttr(::new (S.Context) RegCallAttr(
-        AL.getRange(), S.Context, AL.getAttributeSpellingListIndex()));
+    D->addAttr(::new (S.Context) RegCallAttr(S.Context, AL));
     return;
   case ParsedAttr::AT_Pcs: {
     PcsAttr::PCSType PCS;
@@ -4506,28 +4315,20 @@
       llvm_unreachable("unexpected calling convention in pcs attribute");
     }
 
-    D->addAttr(::new (S.Context)
-               PcsAttr(AL.getRange(), S.Context, PCS,
-                       AL.getAttributeSpellingListIndex()));
+    D->addAttr(::new (S.Context) PcsAttr(S.Context, AL, PCS));
     return;
   }
   case ParsedAttr::AT_AArch64VectorPcs:
-    D->addAttr(::new(S.Context)
-               AArch64VectorPcsAttr(AL.getRange(), S.Context,
-                                    AL.getAttributeSpellingListIndex()));
+    D->addAttr(::new (S.Context) AArch64VectorPcsAttr(S.Context, AL));
     return;
   case ParsedAttr::AT_IntelOclBicc:
-    D->addAttr(::new (S.Context)
-               IntelOclBiccAttr(AL.getRange(), S.Context,
-                                AL.getAttributeSpellingListIndex()));
+    D->addAttr(::new (S.Context) IntelOclBiccAttr(S.Context, AL));
     return;
   case ParsedAttr::AT_PreserveMost:
-    D->addAttr(::new (S.Context) PreserveMostAttr(
-        AL.getRange(), S.Context, AL.getAttributeSpellingListIndex()));
+    D->addAttr(::new (S.Context) PreserveMostAttr(S.Context, AL));
     return;
   case ParsedAttr::AT_PreserveAll:
-    D->addAttr(::new (S.Context) PreserveAllAttr(
-        AL.getRange(), S.Context, AL.getAttributeSpellingListIndex()));
+    D->addAttr(::new (S.Context) PreserveAllAttr(S.Context, AL));
     return;
   default:
     llvm_unreachable("unexpected attribute kind");
@@ -4549,9 +4350,9 @@
     // clang-tidy knows about available rules.
     DiagnosticIdentifiers.push_back(RuleName);
   }
-  D->addAttr(::new (S.Context) SuppressAttr(
-      AL.getRange(), S.Context, DiagnosticIdentifiers.data(),
-      DiagnosticIdentifiers.size(), AL.getAttributeSpellingListIndex()));
+  D->addAttr(::new (S.Context)
+                 SuppressAttr(S.Context, AL, DiagnosticIdentifiers.data(),
+                              DiagnosticIdentifiers.size()));
 }
 
 static void handleLifetimeCategoryAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
@@ -4593,9 +4394,7 @@
       return;
     }
     for (Decl *Redecl : D->redecls()) {
-      Redecl->addAttr(::new (S.Context)
-                          OwnerAttr(AL.getRange(), S.Context, DerefTypeLoc,
-                                    AL.getAttributeSpellingListIndex()));
+      Redecl->addAttr(::new (S.Context) OwnerAttr(S.Context, AL, DerefTypeLoc));
     }
   } else {
     if (checkAttrMutualExclusion<OwnerAttr>(S, D, AL))
@@ -4613,8 +4412,7 @@
     }
     for (Decl *Redecl : D->redecls()) {
       Redecl->addAttr(::new (S.Context)
-                          PointerAttr(AL.getRange(), S.Context, DerefTypeLoc,
-                                      AL.getAttributeSpellingListIndex()));
+                          PointerAttr(S.Context, AL, DerefTypeLoc));
     }
   }
 }
@@ -4807,21 +4605,15 @@
   return isValidSwiftContextType(Ty);
 }
 
-static void handleParameterABIAttr(Sema &S, Decl *D, const ParsedAttr &Attrs,
-                                   ParameterABI Abi) {
-  S.AddParameterABIAttr(Attrs.getRange(), D, Abi,
-                        Attrs.getAttributeSpellingListIndex());
-}
-
-void Sema::AddParameterABIAttr(SourceRange range, Decl *D, ParameterABI abi,
-                               unsigned spellingIndex) {
+void Sema::AddParameterABIAttr(Decl *D, const AttributeCommonInfo &CI,
+                               ParameterABI abi) {
 
   QualType type = cast<ParmVarDecl>(D)->getType();
 
   if (auto existingAttr = D->getAttr<ParameterABIAttr>()) {
     if (existingAttr->getABI() != abi) {
-      Diag(range.getBegin(), diag::err_attributes_are_not_compatible)
-        << getParameterABISpelling(abi) << existingAttr;
+      Diag(CI.getLoc(), diag::err_attributes_are_not_compatible)
+          << getParameterABISpelling(abi) << existingAttr;
       Diag(existingAttr->getLocation(), diag::note_conflicting_attribute);
       return;
     }
@@ -4833,32 +4625,26 @@
 
   case ParameterABI::SwiftContext:
     if (!isValidSwiftContextType(type)) {
-      Diag(range.getBegin(), diag::err_swift_abi_parameter_wrong_type)
-        << getParameterABISpelling(abi)
-        << /*pointer to pointer */ 0 << type;
+      Diag(CI.getLoc(), diag::err_swift_abi_parameter_wrong_type)
+          << getParameterABISpelling(abi) << /*pointer to pointer */ 0 << type;
     }
-    D->addAttr(::new (Context)
-               SwiftContextAttr(range, Context, spellingIndex));
+    D->addAttr(::new (Context) SwiftContextAttr(Context, CI));
     return;
 
   case ParameterABI::SwiftErrorResult:
     if (!isValidSwiftErrorResultType(type)) {
-      Diag(range.getBegin(), diag::err_swift_abi_parameter_wrong_type)
-        << getParameterABISpelling(abi)
-        << /*pointer to pointer */ 1 << type;
+      Diag(CI.getLoc(), diag::err_swift_abi_parameter_wrong_type)
+          << getParameterABISpelling(abi) << /*pointer to pointer */ 1 << type;
     }
-    D->addAttr(::new (Context)
-               SwiftErrorResultAttr(range, Context, spellingIndex));
+    D->addAttr(::new (Context) SwiftErrorResultAttr(Context, CI));
     return;
 
   case ParameterABI::SwiftIndirectResult:
     if (!isValidSwiftIndirectResultType(type)) {
-      Diag(range.getBegin(), diag::err_swift_abi_parameter_wrong_type)
-        << getParameterABISpelling(abi)
-        << /*pointer*/ 0 << type;
+      Diag(CI.getLoc(), diag::err_swift_abi_parameter_wrong_type)
+          << getParameterABISpelling(abi) << /*pointer*/ 0 << type;
     }
-    D->addAttr(::new (Context)
-               SwiftIndirectResultAttr(range, Context, spellingIndex));
+    D->addAttr(::new (Context) SwiftIndirectResultAttr(Context, CI));
     return;
   }
   llvm_unreachable("bad parameter ABI attribute");
@@ -4941,10 +4727,9 @@
   return ValArg.getAs<Expr>();
 }
 
-void Sema::AddLaunchBoundsAttr(SourceRange AttrRange, Decl *D, Expr *MaxThreads,
-                               Expr *MinBlocks, unsigned SpellingListIndex) {
-  CUDALaunchBoundsAttr TmpAttr(AttrRange, Context, MaxThreads, MinBlocks,
-                               SpellingListIndex);
+void Sema::AddLaunchBoundsAttr(Decl *D, const AttributeCommonInfo &CI,
+                               Expr *MaxThreads, Expr *MinBlocks) {
+  CUDALaunchBoundsAttr TmpAttr(Context, CI, MaxThreads, MinBlocks);
   MaxThreads = makeLaunchBoundsArgExpr(*this, MaxThreads, TmpAttr, 0);
   if (MaxThreads == nullptr)
     return;
@@ -4955,8 +4740,8 @@
       return;
   }
 
-  D->addAttr(::new (Context) CUDALaunchBoundsAttr(
-      AttrRange, Context, MaxThreads, MinBlocks, SpellingListIndex));
+  D->addAttr(::new (Context)
+                 CUDALaunchBoundsAttr(Context, CI, MaxThreads, MinBlocks));
 }
 
 static void handleLaunchBoundsAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
@@ -4964,9 +4749,8 @@
       !checkAttributeAtMostNumArgs(S, AL, 2))
     return;
 
-  S.AddLaunchBoundsAttr(AL.getRange(), D, AL.getArgAsExpr(0),
-                        AL.getNumArgs() > 1 ? AL.getArgAsExpr(1) : nullptr,
-                        AL.getAttributeSpellingListIndex());
+  S.AddLaunchBoundsAttr(D, AL, AL.getArgAsExpr(0),
+                        AL.getNumArgs() > 1 ? AL.getArgAsExpr(1) : nullptr);
 }
 
 static void handleArgumentWithTypeTagAttr(Sema &S, Decl *D,
@@ -4987,7 +4771,7 @@
                                            TypeTagIdx))
     return;
 
-  bool IsPointer = AL.getName()->getName() == "pointer_with_type_tag";
+  bool IsPointer = AL.getAttrName()->getName() == "pointer_with_type_tag";
   if (IsPointer) {
     // Ensure that buffer has a pointer type.
     unsigned ArgumentIdxAST = ArgumentIdx.getASTIndex();
@@ -4997,8 +4781,8 @@
   }
 
   D->addAttr(::new (S.Context) ArgumentWithTypeTagAttr(
-      AL.getRange(), S.Context, AL.getArgAsIdent(0)->Ident, ArgumentIdx,
-      TypeTagIdx, IsPointer, AL.getAttributeSpellingListIndex()));
+      S.Context, AL, AL.getArgAsIdent(0)->Ident, ArgumentIdx, TypeTagIdx,
+      IsPointer));
 }
 
 static void handleTypeTagForDatatypeAttr(Sema &S, Decl *D,
@@ -5023,12 +4807,9 @@
   S.GetTypeFromParser(AL.getMatchingCType(), &MatchingCTypeLoc);
   assert(MatchingCTypeLoc && "no type source info for attribute argument");
 
-  D->addAttr(::new (S.Context)
-             TypeTagForDatatypeAttr(AL.getRange(), S.Context, PointerKind,
-                                    MatchingCTypeLoc,
-                                    AL.getLayoutCompatible(),
-                                    AL.getMustBeNull(),
-                                    AL.getAttributeSpellingListIndex()));
+  D->addAttr(::new (S.Context) TypeTagForDatatypeAttr(
+      S.Context, AL, PointerKind, MatchingCTypeLoc, AL.getLayoutCompatible(),
+      AL.getMustBeNull()));
 }
 
 static void handleXRayLogArgsAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
@@ -5040,9 +4821,8 @@
     return;
 
   // ArgCount isn't a parameter index [0;n), it's a count [1;n]
-  D->addAttr(::new (S.Context) XRayLogArgsAttr(
-      AL.getRange(), S.Context, ArgCount.getSourceIndex(),
-      AL.getAttributeSpellingListIndex()));
+  D->addAttr(::new (S.Context)
+                 XRayLogArgsAttr(S.Context, AL, ArgCount.getSourceIndex()));
 }
 
 //===----------------------------------------------------------------------===//
@@ -5069,20 +4849,20 @@
   return !PT.isNull() && PT->getAsCXXRecordDecl() != nullptr;
 }
 
-void Sema::AddXConsumedAttr(Decl *D, SourceRange SR, unsigned SpellingIndex,
+void Sema::AddXConsumedAttr(Decl *D, const AttributeCommonInfo &CI,
                             RetainOwnershipKind K,
                             bool IsTemplateInstantiation) {
   ValueDecl *VD = cast<ValueDecl>(D);
   switch (K) {
   case RetainOwnershipKind::OS:
     handleSimpleAttributeOrDiagnose<OSConsumedAttr>(
-        *this, VD, SR, SpellingIndex, isValidSubjectOfOSAttribute(VD->getType()),
+        *this, VD, CI, isValidSubjectOfOSAttribute(VD->getType()),
         diag::warn_ns_attribute_wrong_parameter_type,
-        /*ExtraArgs=*/SR, "os_consumed", /*pointers*/ 1);
+        /*ExtraArgs=*/CI.getRange(), "os_consumed", /*pointers*/ 1);
     return;
   case RetainOwnershipKind::NS:
     handleSimpleAttributeOrDiagnose<NSConsumedAttr>(
-        *this, VD, SR, SpellingIndex, isValidSubjectOfNSAttribute(VD->getType()),
+        *this, VD, CI, isValidSubjectOfNSAttribute(VD->getType()),
 
         // These attributes are normally just advisory, but in ARC, ns_consumed
         // is significant.  Allow non-dependent code to contain inappropriate
@@ -5091,14 +4871,13 @@
         ((IsTemplateInstantiation && getLangOpts().ObjCAutoRefCount)
              ? diag::err_ns_attribute_wrong_parameter_type
              : diag::warn_ns_attribute_wrong_parameter_type),
-        /*ExtraArgs=*/SR, "ns_consumed", /*objc pointers*/ 0);
+        /*ExtraArgs=*/CI.getRange(), "ns_consumed", /*objc pointers*/ 0);
     return;
   case RetainOwnershipKind::CF:
     handleSimpleAttributeOrDiagnose<CFConsumedAttr>(
-        *this, VD, SR, SpellingIndex,
-        isValidSubjectOfCFAttribute(VD->getType()),
+        *this, VD, CI, isValidSubjectOfCFAttribute(VD->getType()),
         diag::warn_ns_attribute_wrong_parameter_type,
-        /*ExtraArgs=*/SR, "cf_consumed", /*pointers*/1);
+        /*ExtraArgs=*/CI.getRange(), "cf_consumed", /*pointers*/ 1);
     return;
   }
 }
@@ -5301,8 +5080,7 @@
     return;
   }
 
-  D->addAttr(::new (S.Context) ObjCReturnsInnerPointerAttr(
-      Attrs.getRange(), S.Context, Attrs.getAttributeSpellingListIndex()));
+  D->addAttr(::new (S.Context) ObjCReturnsInnerPointerAttr(S.Context, Attrs));
 }
 
 static void handleObjCRequiresSuperAttr(Sema &S, Decl *D,
@@ -5322,8 +5100,7 @@
     return;
   }
 
-  D->addAttr(::new (S.Context) ObjCRequiresSuperAttr(
-      Attrs.getRange(), S.Context, Attrs.getAttributeSpellingListIndex()));
+  D->addAttr(::new (S.Context) ObjCRequiresSuperAttr(S.Context, Attrs));
 }
 
 static void handleObjCBridgeAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
@@ -5349,9 +5126,7 @@
     }
   }
 
-  D->addAttr(::new (S.Context)
-             ObjCBridgeAttr(AL.getRange(), S.Context, Parm->Ident,
-                           AL.getAttributeSpellingListIndex()));
+  D->addAttr(::new (S.Context) ObjCBridgeAttr(S.Context, AL, Parm->Ident));
 }
 
 static void handleObjCBridgeMutableAttr(Sema &S, Decl *D,
@@ -5364,8 +5139,7 @@
   }
 
   D->addAttr(::new (S.Context)
-             ObjCBridgeMutableAttr(AL.getRange(), S.Context, Parm->Ident,
-                            AL.getAttributeSpellingListIndex()));
+                 ObjCBridgeMutableAttr(S.Context, AL, Parm->Ident));
 }
 
 static void handleObjCBridgeRelatedAttr(Sema &S, Decl *D,
@@ -5380,10 +5154,8 @@
     AL.getArgAsIdent(1) ? AL.getArgAsIdent(1)->Ident : nullptr;
   IdentifierInfo *InstanceMethod =
     AL.getArgAsIdent(2) ? AL.getArgAsIdent(2)->Ident : nullptr;
-  D->addAttr(::new (S.Context)
-             ObjCBridgeRelatedAttr(AL.getRange(), S.Context, RelatedClass,
-                                   ClassMethod, InstanceMethod,
-                                   AL.getAttributeSpellingListIndex()));
+  D->addAttr(::new (S.Context) ObjCBridgeRelatedAttr(
+      S.Context, AL, RelatedClass, ClassMethod, InstanceMethod));
 }
 
 static void handleObjCDesignatedInitializer(Sema &S, Decl *D,
@@ -5409,9 +5181,7 @@
     return;
 
   IFace->setHasDesignatedInitializers();
-  D->addAttr(::new (S.Context)
-                  ObjCDesignatedInitializerAttr(AL.getRange(), S.Context,
-                                         AL.getAttributeSpellingListIndex()));
+  D->addAttr(::new (S.Context) ObjCDesignatedInitializerAttr(S.Context, AL));
 }
 
 static void handleObjCRuntimeName(Sema &S, Decl *D, const ParsedAttr &AL) {
@@ -5419,9 +5189,7 @@
   if (!S.checkStringLiteralArgumentAttr(AL, 0, MetaDataName))
     return;
   D->addAttr(::new (S.Context)
-             ObjCRuntimeNameAttr(AL.getRange(), S.Context,
-                                 MetaDataName,
-                                 AL.getAttributeSpellingListIndex()));
+                 ObjCRuntimeNameAttr(S.Context, AL, MetaDataName));
 }
 
 // When a user wants to use objc_boxable with a union or struct
@@ -5438,9 +5206,8 @@
   }
 
   if (RD) {
-    ObjCBoxableAttr *BoxableAttr = ::new (S.Context)
-                          ObjCBoxableAttr(AL.getRange(), S.Context,
-                                          AL.getAttributeSpellingListIndex());
+    ObjCBoxableAttr *BoxableAttr =
+        ::new (S.Context) ObjCBoxableAttr(S.Context, AL);
     RD->addAttr(BoxableAttr);
     if (notify) {
       // we need to notify ASTReader/ASTWriter about
@@ -5494,26 +5261,24 @@
     break;
   }
 
-  D->addAttr(::new (S.Context)
-             ObjCPreciseLifetimeAttr(AL.getRange(), S.Context,
-                                     AL.getAttributeSpellingListIndex()));
+  D->addAttr(::new (S.Context) ObjCPreciseLifetimeAttr(S.Context, AL));
 }
 
 //===----------------------------------------------------------------------===//
 // Microsoft specific attribute handlers.
 //===----------------------------------------------------------------------===//
 
-UuidAttr *Sema::mergeUuidAttr(Decl *D, SourceRange Range,
-                              unsigned AttrSpellingListIndex, StringRef Uuid) {
+UuidAttr *Sema::mergeUuidAttr(Decl *D, const AttributeCommonInfo &CI,
+                              StringRef Uuid) {
   if (const auto *UA = D->getAttr<UuidAttr>()) {
     if (UA->getGuid().equals_lower(Uuid))
       return nullptr;
     Diag(UA->getLocation(), diag::err_mismatched_uuid);
-    Diag(Range.getBegin(), diag::note_previous_uuid);
+    Diag(CI.getLoc(), diag::note_previous_uuid);
     D->dropAttr<UuidAttr>();
   }
 
-  return ::new (Context) UuidAttr(Range, Context, Uuid, AttrSpellingListIndex);
+  return ::new (Context) UuidAttr(Context, CI, Uuid);
 }
 
 static void handleUuidAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
@@ -5560,8 +5325,7 @@
   if (AL.isMicrosoftAttribute()) // Check for [uuid(...)] spelling.
     S.Diag(AL.getLoc(), diag::warn_atl_uuid_deprecated);
 
-  UuidAttr *UA = S.mergeUuidAttr(D, AL.getRange(),
-                                 AL.getAttributeSpellingListIndex(), StrRef);
+  UuidAttr *UA = S.mergeUuidAttr(D, AL, StrRef);
   if (UA)
     D->addAttr(UA);
 }
@@ -5573,8 +5337,7 @@
     return;
   }
   MSInheritanceAttr *IA = S.mergeMSInheritanceAttr(
-      D, AL.getRange(), /*BestCase=*/true,
-      AL.getAttributeSpellingListIndex(),
+      D, AL, /*BestCase=*/true,
       (MSInheritanceAttr::Spelling)AL.getSemanticSpelling());
   if (IA) {
     D->addAttr(IA);
@@ -5596,8 +5359,7 @@
     S.Diag(AL.getLoc(), diag::err_thread_non_global) << "__declspec(thread)";
     return;
   }
-  D->addAttr(::new (S.Context) ThreadAttr(AL.getRange(), S.Context,
-                                          AL.getAttributeSpellingListIndex()));
+  D->addAttr(::new (S.Context) ThreadAttr(S.Context, AL));
 }
 
 static void handleAbiTagAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
@@ -5628,8 +5390,7 @@
   Tags.erase(std::unique(Tags.begin(), Tags.end()), Tags.end());
 
   D->addAttr(::new (S.Context)
-             AbiTagAttr(AL.getRange(), S.Context, Tags.data(), Tags.size(),
-                        AL.getAttributeSpellingListIndex()));
+                 AbiTagAttr(S.Context, AL, Tags.data(), Tags.size()));
 }
 
 static void handleARMInterruptAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
@@ -5654,9 +5415,7 @@
     return;
   }
 
-  unsigned Index = AL.getAttributeSpellingListIndex();
-  D->addAttr(::new (S.Context)
-             ARMInterruptAttr(AL.getLoc(), S.Context, Kind, Index));
+  D->addAttr(::new (S.Context) ARMInterruptAttr(S.Context, AL, Kind));
 }
 
 static void handleMSP430InterruptAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
@@ -5707,9 +5466,7 @@
     return;
   }
 
-  D->addAttr(::new (S.Context)
-              MSP430InterruptAttr(AL.getLoc(), S.Context, Num,
-                                  AL.getAttributeSpellingListIndex()));
+  D->addAttr(::new (S.Context) MSP430InterruptAttr(S.Context, AL, Num));
   D->addAttr(UsedAttr::CreateImplicit(S.Context));
 }
 
@@ -5765,8 +5522,7 @@
     return;
   }
 
-  D->addAttr(::new (S.Context) MipsInterruptAttr(
-      AL.getLoc(), S.Context, Kind, AL.getAttributeSpellingListIndex()));
+  D->addAttr(::new (S.Context) MipsInterruptAttr(S.Context, AL, Kind));
 }
 
 static void handleAnyX86InterruptAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
@@ -5829,8 +5585,7 @@
         << 3 << S.Context.getIntTypeForBitwidth(TypeSize, /*Signed=*/false);
     return;
   }
-  D->addAttr(::new (S.Context) AnyX86InterruptAttr(
-      AL.getLoc(), S.Context, AL.getAttributeSpellingListIndex()));
+  D->addAttr(::new (S.Context) AnyX86InterruptAttr(S.Context, AL));
   D->addAttr(UsedAttr::CreateImplicit(S.Context));
 }
 
@@ -5878,9 +5633,8 @@
   if (!S.checkStringLiteralArgumentAttr(AL, 0, Str, &ArgLoc))
     return;
 
-  FD->addAttr(::new (S.Context) WebAssemblyImportModuleAttr(
-      AL.getRange(), S.Context, Str,
-      AL.getAttributeSpellingListIndex()));
+  FD->addAttr(::new (S.Context)
+                  WebAssemblyImportModuleAttr(S.Context, AL, Str));
 }
 
 static void handleWebAssemblyImportNameAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
@@ -5901,9 +5655,7 @@
   if (!S.checkStringLiteralArgumentAttr(AL, 0, Str, &ArgLoc))
     return;
 
-  FD->addAttr(::new (S.Context) WebAssemblyImportNameAttr(
-      AL.getRange(), S.Context, Str,
-      AL.getAttributeSpellingListIndex()));
+  FD->addAttr(::new (S.Context) WebAssemblyImportNameAttr(S.Context, AL, Str));
 }
 
 static void handleRISCVInterruptAttr(Sema &S, Decl *D,
@@ -5961,8 +5713,7 @@
     return;
   }
 
-  D->addAttr(::new (S.Context) RISCVInterruptAttr(
-    AL.getLoc(), S.Context, Kind, AL.getAttributeSpellingListIndex()));
+  D->addAttr(::new (S.Context) RISCVInterruptAttr(S.Context, AL, Kind));
 }
 
 static void handleInterruptAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
@@ -6022,17 +5773,16 @@
   return false;
 }
 
-void Sema::addAMDGPUFlatWorkGroupSizeAttr(SourceRange AttrRange, Decl *D,
-                                          Expr *MinExpr, Expr *MaxExpr,
-                                          unsigned SpellingListIndex) {
-  AMDGPUFlatWorkGroupSizeAttr TmpAttr(AttrRange, Context, MinExpr, MaxExpr,
-                                      SpellingListIndex);
+void Sema::addAMDGPUFlatWorkGroupSizeAttr(Decl *D,
+                                          const AttributeCommonInfo &CI,
+                                          Expr *MinExpr, Expr *MaxExpr) {
+  AMDGPUFlatWorkGroupSizeAttr TmpAttr(Context, CI, MinExpr, MaxExpr);
 
   if (checkAMDGPUFlatWorkGroupSizeArguments(*this, MinExpr, MaxExpr, TmpAttr))
     return;
 
-  D->addAttr(::new (Context) AMDGPUFlatWorkGroupSizeAttr(
-      AttrRange, Context, MinExpr, MaxExpr, SpellingListIndex));
+  D->addAttr(::new (Context)
+                 AMDGPUFlatWorkGroupSizeAttr(Context, CI, MinExpr, MaxExpr));
 }
 
 static void handleAMDGPUFlatWorkGroupSizeAttr(Sema &S, Decl *D,
@@ -6040,8 +5790,7 @@
   Expr *MinExpr = AL.getArgAsExpr(0);
   Expr *MaxExpr = AL.getArgAsExpr(1);
 
-  S.addAMDGPUFlatWorkGroupSizeAttr(AL.getRange(), D, MinExpr, MaxExpr,
-                                   AL.getAttributeSpellingListIndex());
+  S.addAMDGPUFlatWorkGroupSizeAttr(D, AL, MinExpr, MaxExpr);
 }
 
 static bool checkAMDGPUWavesPerEUArguments(Sema &S, Expr *MinExpr,
@@ -6078,17 +5827,15 @@
   return false;
 }
 
-void Sema::addAMDGPUWavesPerEUAttr(SourceRange AttrRange, Decl *D,
-                                   Expr *MinExpr, Expr *MaxExpr,
-                                   unsigned SpellingListIndex) {
-  AMDGPUWavesPerEUAttr TmpAttr(AttrRange, Context, MinExpr, MaxExpr,
-                               SpellingListIndex);
+void Sema::addAMDGPUWavesPerEUAttr(Decl *D, const AttributeCommonInfo &CI,
+                                   Expr *MinExpr, Expr *MaxExpr) {
+  AMDGPUWavesPerEUAttr TmpAttr(Context, CI, MinExpr, MaxExpr);
 
   if (checkAMDGPUWavesPerEUArguments(*this, MinExpr, MaxExpr, TmpAttr))
     return;
 
-  D->addAttr(::new (Context) AMDGPUWavesPerEUAttr(AttrRange, Context, MinExpr,
-                                                  MaxExpr, SpellingListIndex));
+  D->addAttr(::new (Context)
+                 AMDGPUWavesPerEUAttr(Context, CI, MinExpr, MaxExpr));
 }
 
 static void handleAMDGPUWavesPerEUAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
@@ -6099,8 +5846,7 @@
   Expr *MinExpr = AL.getArgAsExpr(0);
   Expr *MaxExpr = (AL.getNumArgs() > 1) ? AL.getArgAsExpr(1) : nullptr;
 
-  S.addAMDGPUWavesPerEUAttr(AL.getRange(), D, MinExpr, MaxExpr,
-                            AL.getAttributeSpellingListIndex());
+  S.addAMDGPUWavesPerEUAttr(D, AL, MinExpr, MaxExpr);
 }
 
 static void handleAMDGPUNumSGPRAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
@@ -6109,9 +5855,7 @@
   if (!checkUInt32Argument(S, AL, NumSGPRExpr, NumSGPR))
     return;
 
-  D->addAttr(::new (S.Context)
-             AMDGPUNumSGPRAttr(AL.getLoc(), S.Context, NumSGPR,
-                               AL.getAttributeSpellingListIndex()));
+  D->addAttr(::new (S.Context) AMDGPUNumSGPRAttr(S.Context, AL, NumSGPR));
 }
 
 static void handleAMDGPUNumVGPRAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
@@ -6120,9 +5864,7 @@
   if (!checkUInt32Argument(S, AL, NumVGPRExpr, NumVGPR))
     return;
 
-  D->addAttr(::new (S.Context)
-             AMDGPUNumVGPRAttr(AL.getLoc(), S.Context, NumVGPR,
-                               AL.getAttributeSpellingListIndex()));
+  D->addAttr(::new (S.Context) AMDGPUNumVGPRAttr(S.Context, AL, NumVGPR));
 }
 
 static void handleX86ForceAlignArgPointerAttr(Sema &S, Decl *D,
@@ -6145,9 +5887,7 @@
     return;
   }
 
-  D->addAttr(::new (S.Context)
-              X86ForceAlignArgPointerAttr(AL.getRange(), S.Context,
-                                        AL.getAttributeSpellingListIndex()));
+  D->addAttr(::new (S.Context) X86ForceAlignArgPointerAttr(S.Context, AL));
 }
 
 static void handleLayoutVersion(Sema &S, Decl *D, const ParsedAttr &AL) {
@@ -6168,26 +5908,24 @@
   // have to multiply by 100 now.
   Version *= 100;
 
-  D->addAttr(::new (S.Context)
-                 LayoutVersionAttr(AL.getRange(), S.Context, Version,
-                                   AL.getAttributeSpellingListIndex()));
+  D->addAttr(::new (S.Context) LayoutVersionAttr(S.Context, AL, Version));
 }
 
-DLLImportAttr *Sema::mergeDLLImportAttr(Decl *D, SourceRange Range,
-                                        unsigned AttrSpellingListIndex) {
+DLLImportAttr *Sema::mergeDLLImportAttr(Decl *D,
+                                        const AttributeCommonInfo &CI) {
   if (D->hasAttr<DLLExportAttr>()) {
-    Diag(Range.getBegin(), diag::warn_attribute_ignored) << "'dllimport'";
+    Diag(CI.getLoc(), diag::warn_attribute_ignored) << "'dllimport'";
     return nullptr;
   }
 
   if (D->hasAttr<DLLImportAttr>())
     return nullptr;
 
-  return ::new (Context) DLLImportAttr(Range, Context, AttrSpellingListIndex);
+  return ::new (Context) DLLImportAttr(Context, CI);
 }
 
-DLLExportAttr *Sema::mergeDLLExportAttr(Decl *D, SourceRange Range,
-                                        unsigned AttrSpellingListIndex) {
+DLLExportAttr *Sema::mergeDLLExportAttr(Decl *D,
+                                        const AttributeCommonInfo &CI) {
   if (DLLImportAttr *Import = D->getAttr<DLLImportAttr>()) {
     Diag(Import->getLocation(), diag::warn_attribute_ignored) << Import;
     D->dropAttr<DLLImportAttr>();
@@ -6196,7 +5934,7 @@
   if (D->hasAttr<DLLExportAttr>())
     return nullptr;
 
-  return ::new (Context) DLLExportAttr(Range, Context, AttrSpellingListIndex);
+  return ::new (Context) DLLExportAttr(Context, CI);
 }
 
 static void handleDLLAttr(Sema &S, Decl *D, const ParsedAttr &A) {
@@ -6224,48 +5962,46 @@
     }
   }
 
-  unsigned Index = A.getAttributeSpellingListIndex();
   Attr *NewAttr = A.getKind() == ParsedAttr::AT_DLLExport
-                      ? (Attr *)S.mergeDLLExportAttr(D, A.getRange(), Index)
-                      : (Attr *)S.mergeDLLImportAttr(D, A.getRange(), Index);
+                      ? (Attr *)S.mergeDLLExportAttr(D, A)
+                      : (Attr *)S.mergeDLLImportAttr(D, A);
   if (NewAttr)
     D->addAttr(NewAttr);
 }
 
 MSInheritanceAttr *
-Sema::mergeMSInheritanceAttr(Decl *D, SourceRange Range, bool BestCase,
-                             unsigned AttrSpellingListIndex,
+Sema::mergeMSInheritanceAttr(Decl *D, const AttributeCommonInfo &CI,
+                             bool BestCase,
                              MSInheritanceAttr::Spelling SemanticSpelling) {
   if (MSInheritanceAttr *IA = D->getAttr<MSInheritanceAttr>()) {
     if (IA->getSemanticSpelling() == SemanticSpelling)
       return nullptr;
     Diag(IA->getLocation(), diag::err_mismatched_ms_inheritance)
         << 1 /*previous declaration*/;
-    Diag(Range.getBegin(), diag::note_previous_ms_inheritance);
+    Diag(CI.getLoc(), diag::note_previous_ms_inheritance);
     D->dropAttr<MSInheritanceAttr>();
   }
 
   auto *RD = cast<CXXRecordDecl>(D);
   if (RD->hasDefinition()) {
-    if (checkMSInheritanceAttrOnDefinition(RD, Range, BestCase,
+    if (checkMSInheritanceAttrOnDefinition(RD, CI.getRange(), BestCase,
                                            SemanticSpelling)) {
       return nullptr;
     }
   } else {
     if (isa<ClassTemplatePartialSpecializationDecl>(RD)) {
-      Diag(Range.getBegin(), diag::warn_ignored_ms_inheritance)
+      Diag(CI.getLoc(), diag::warn_ignored_ms_inheritance)
           << 1 /*partial specialization*/;
       return nullptr;
     }
     if (RD->getDescribedClassTemplate()) {
-      Diag(Range.getBegin(), diag::warn_ignored_ms_inheritance)
+      Diag(CI.getLoc(), diag::warn_ignored_ms_inheritance)
           << 0 /*primary template*/;
       return nullptr;
     }
   }
 
-  return ::new (Context)
-      MSInheritanceAttr(Range, Context, BestCase, AttrSpellingListIndex);
+  return ::new (Context) MSInheritanceAttr(Context, CI, BestCase);
 }
 
 static void handleCapabilityAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
@@ -6288,8 +6024,7 @@
   if (!N.equals_lower("mutex") && !N.equals_lower("role"))
     S.Diag(LiteralLoc, diag::warn_invalid_capability_name) << N;
 
-  D->addAttr(::new (S.Context) CapabilityAttr(AL.getRange(), S.Context, N,
-                                        AL.getAttributeSpellingListIndex()));
+  D->addAttr(::new (S.Context) CapabilityAttr(S.Context, AL, N));
 }
 
 static void handleAssertCapabilityAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
@@ -6297,9 +6032,8 @@
   if (!checkLockFunAttrCommon(S, D, AL, Args))
     return;
 
-  D->addAttr(::new (S.Context) AssertCapabilityAttr(AL.getRange(), S.Context,
-                                                    Args.data(), Args.size(),
-                                        AL.getAttributeSpellingListIndex()));
+  D->addAttr(::new (S.Context)
+                 AssertCapabilityAttr(S.Context, AL, Args.data(), Args.size()));
 }
 
 static void handleAcquireCapabilityAttr(Sema &S, Decl *D,
@@ -6308,10 +6042,8 @@
   if (!checkLockFunAttrCommon(S, D, AL, Args))
     return;
 
-  D->addAttr(::new (S.Context) AcquireCapabilityAttr(AL.getRange(),
-                                                     S.Context,
-                                                     Args.data(), Args.size(),
-                                        AL.getAttributeSpellingListIndex()));
+  D->addAttr(::new (S.Context) AcquireCapabilityAttr(S.Context, AL, Args.data(),
+                                                     Args.size()));
 }
 
 static void handleTryAcquireCapabilityAttr(Sema &S, Decl *D,
@@ -6320,12 +6052,8 @@
   if (!checkTryLockFunAttrCommon(S, D, AL, Args))
     return;
 
-  D->addAttr(::new (S.Context) TryAcquireCapabilityAttr(AL.getRange(),
-                                                        S.Context,
-                                                        AL.getArgAsExpr(0),
-                                                        Args.data(),
-                                                        Args.size(),
-                                        AL.getAttributeSpellingListIndex()));
+  D->addAttr(::new (S.Context) TryAcquireCapabilityAttr(
+      S.Context, AL, AL.getArgAsExpr(0), Args.data(), Args.size()));
 }
 
 static void handleReleaseCapabilityAttr(Sema &S, Decl *D,
@@ -6334,9 +6062,8 @@
   SmallVector<Expr *, 1> Args;
   checkAttrArgsAreCapabilityObjs(S, D, AL, Args, 0, true);
 
-  D->addAttr(::new (S.Context) ReleaseCapabilityAttr(
-      AL.getRange(), S.Context, Args.data(), Args.size(),
-      AL.getAttributeSpellingListIndex()));
+  D->addAttr(::new (S.Context) ReleaseCapabilityAttr(S.Context, AL, Args.data(),
+                                                     Args.size()));
 }
 
 static void handleRequiresCapabilityAttr(Sema &S, Decl *D,
@@ -6351,8 +6078,7 @@
     return;
 
   RequiresCapabilityAttr *RCA = ::new (S.Context)
-    RequiresCapabilityAttr(AL.getRange(), S.Context, Args.data(),
-                           Args.size(), AL.getAttributeSpellingListIndex());
+      RequiresCapabilityAttr(S.Context, AL, Args.data(), Args.size());
 
   D->addAttr(RCA);
 }
@@ -6384,9 +6110,7 @@
   if (!S.getLangOpts().CPlusPlus14 && AL.isCXX11Attribute() && !AL.isGNUScope())
     S.Diag(AL.getLoc(), diag::ext_cxx14_attr) << AL;
 
-  D->addAttr(::new (S.Context)
-                 DeprecatedAttr(AL.getRange(), S.Context, Str, Replacement,
-                                AL.getAttributeSpellingListIndex()));
+  D->addAttr(::new (S.Context) DeprecatedAttr(S.Context, AL, Str, Replacement));
 }
 
 static bool isGlobalVar(const Decl *D) {
@@ -6417,14 +6141,13 @@
     Sanitizers.push_back(SanitizerName);
   }
 
-  D->addAttr(::new (S.Context) NoSanitizeAttr(
-      AL.getRange(), S.Context, Sanitizers.data(), Sanitizers.size(),
-      AL.getAttributeSpellingListIndex()));
+  D->addAttr(::new (S.Context) NoSanitizeAttr(S.Context, AL, Sanitizers.data(),
+                                              Sanitizers.size()));
 }
 
 static void handleNoSanitizeSpecificAttr(Sema &S, Decl *D,
                                          const ParsedAttr &AL) {
-  StringRef AttrName = AL.getName()->getName();
+  StringRef AttrName = AL.getAttrName()->getName();
   normalizeName(AttrName);
   StringRef SanitizerName = llvm::StringSwitch<StringRef>(AttrName)
                                 .Case("no_address_safety_analysis", "address")
@@ -6447,8 +6170,10 @@
   if (AL.isC2xAttribute() || AL.isCXX11Attribute())
     TranslatedSpellingIndex = 1;
 
-  D->addAttr(::new (S.Context) NoSanitizeAttr(
-      AL.getRange(), S.Context, &SanitizerName, 1, TranslatedSpellingIndex));
+  AttributeCommonInfo Info = AL;
+  Info.setAttributeSpellingListIndex(TranslatedSpellingIndex);
+  D->addAttr(::new (S.Context)
+                 NoSanitizeAttr(S.Context, Info, &SanitizerName, 1));
 }
 
 static void handleInternalLinkageAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
@@ -6517,7 +6242,7 @@
     if (D->getAttr<OpenCLAccessAttr>()->getSemanticSpelling() ==
         AL.getSemanticSpelling()) {
       S.Diag(AL.getLoc(), diag::warn_duplicate_declspec)
-          << AL.getName()->getName() << AL.getRange();
+          << AL.getAttrName()->getName() << AL.getRange();
     } else {
       S.Diag(AL.getLoc(), diag::err_opencl_multiple_access_qualifiers)
           << D->getSourceRange();
@@ -6533,7 +6258,7 @@
   // qualifier is a compilation error.
   if (const auto *PDecl = dyn_cast<ParmVarDecl>(D)) {
     const Type *DeclTy = PDecl->getType().getCanonicalType().getTypePtr();
-    if (AL.getName()->getName().find("read_write") != StringRef::npos) {
+    if (AL.getAttrName()->getName().find("read_write") != StringRef::npos) {
       if ((!S.getLangOpts().OpenCLCPlusPlus &&
            S.getLangOpts().OpenCLVersion < 200) ||
           DeclTy->isPipeType()) {
@@ -6545,8 +6270,7 @@
     }
   }
 
-  D->addAttr(::new (S.Context) OpenCLAccessAttr(
-      AL.getRange(), S.Context, AL.getAttributeSpellingListIndex()));
+  D->addAttr(::new (S.Context) OpenCLAccessAttr(S.Context, AL));
 }
 
 static void handleDestroyAttr(Sema &S, Decl *D, const ParsedAttr &A) {
@@ -6565,9 +6289,7 @@
 static void handleUninitializedAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
   assert(cast<VarDecl>(D)->getStorageDuration() == SD_Automatic &&
          "uninitialized is only valid on automatic duration variables");
-  unsigned Index = AL.getAttributeSpellingListIndex();
-  D->addAttr(::new (S.Context)
-                 UninitializedAttr(AL.getLoc(), S.Context, Index));
+  D->addAttr(::new (S.Context) UninitializedAttr(S.Context, AL));
 }
 
 static bool tryMakeVariablePseudoStrong(Sema &S, VarDecl *VD,
@@ -7018,9 +6740,8 @@
   case ParsedAttr::AT_CFConsumed:
   case ParsedAttr::AT_NSConsumed:
   case ParsedAttr::AT_OSConsumed:
-    S.AddXConsumedAttr(D, AL.getRange(), AL.getAttributeSpellingListIndex(),
-                     parsedAttrToRetainOwnershipKind(AL),
-                     /*IsTemplateInstantiation=*/false);
+    S.AddXConsumedAttr(D, AL, parsedAttrToRetainOwnershipKind(AL),
+                       /*IsTemplateInstantiation=*/false);
     break;
   case ParsedAttr::AT_NSConsumesSelf:
     handleSimpleAttribute<NSConsumesSelfAttr>(S, D, AL);
@@ -7239,13 +6960,13 @@
     handleOpenCLNoSVMAttr(S, D, AL);
     break;
   case ParsedAttr::AT_SwiftContext:
-    handleParameterABIAttr(S, D, AL, ParameterABI::SwiftContext);
+    S.AddParameterABIAttr(D, AL, ParameterABI::SwiftContext);
     break;
   case ParsedAttr::AT_SwiftErrorResult:
-    handleParameterABIAttr(S, D, AL, ParameterABI::SwiftErrorResult);
+    S.AddParameterABIAttr(D, AL, ParameterABI::SwiftErrorResult);
     break;
   case ParsedAttr::AT_SwiftIndirectResult:
-    handleParameterABIAttr(S, D, AL, ParameterABI::SwiftIndirectResult);
+    S.AddParameterABIAttr(D, AL, ParameterABI::SwiftIndirectResult);
     break;
   case ParsedAttr::AT_InternalLinkage:
     handleInternalLinkageAttr(S, D, AL);
@@ -7619,9 +7340,10 @@
   if (W.getAlias()) { // clone decl, impersonate __attribute(weak,alias(...))
     IdentifierInfo *NDId = ND->getIdentifier();
     NamedDecl *NewD = DeclClonePragmaWeak(ND, W.getAlias(), W.getLocation());
-    NewD->addAttr(AliasAttr::CreateImplicit(Context, NDId->getName(),
-                                            W.getLocation()));
-    NewD->addAttr(WeakAttr::CreateImplicit(Context, W.getLocation()));
+    NewD->addAttr(
+        AliasAttr::CreateImplicit(Context, NDId->getName(), W.getLocation()));
+    NewD->addAttr(WeakAttr::CreateImplicit(Context, W.getLocation(),
+                                           AttributeCommonInfo::AS_Pragma));
     WeakTopLevelDecl.push_back(NewD);
     // FIXME: "hideous" code from Sema::LazilyCreateBuiltin
     // to insert Decl at TU scope, sorry.
@@ -7632,7 +7354,8 @@
     PushOnScopeChains(NewD, S);
     CurContext = SavedContext;
   } else { // just add weak to existing
-    ND->addAttr(WeakAttr::CreateImplicit(Context, W.getLocation()));
+    ND->addAttr(WeakAttr::CreateImplicit(Context, W.getLocation(),
+                                         AttributeCommonInfo::AS_Pragma));
   }
 }
 
