riccibruno updated this revision to Diff 178259.
riccibruno marked 3 inline comments as done.
riccibruno added a comment.

Addressed inline comments


Repository:
  rC Clang

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D55658/new/

https://reviews.llvm.org/D55658

Files:
  include/clang/AST/ComparisonCategories.h
  include/clang/AST/Decl.h
  include/clang/AST/DeclBase.h
  include/clang/AST/DeclTemplate.h
  include/clang/ASTMatchers/ASTMatchers.h
  include/clang/ASTMatchers/ASTMatchersInternal.h
  include/clang/Sema/SemaInternal.h
  lib/AST/ASTContext.cpp
  lib/AST/ASTImporter.cpp
  lib/AST/ComparisonCategories.cpp
  lib/AST/Decl.cpp
  lib/AST/DeclBase.cpp
  lib/AST/DeclTemplate.cpp
  lib/AST/ExprConstant.cpp
  lib/CodeGen/CGExpr.cpp
  lib/CodeGen/CGExprAgg.cpp
  lib/CodeGen/CGObjCGNU.cpp
  lib/CodeGen/CGObjCMac.cpp
  lib/CodeGen/CodeGenModule.cpp
  lib/CodeGen/ItaniumCXXABI.cpp
  lib/Index/IndexingContext.cpp
  lib/Sema/Sema.cpp
  lib/Sema/SemaChecking.cpp
  lib/Sema/SemaDecl.cpp
  lib/Sema/SemaDeclAttr.cpp
  lib/Sema/SemaDeclCXX.cpp
  lib/Sema/SemaExpr.cpp
  lib/Sema/SemaExprCXX.cpp
  lib/Sema/SemaLookup.cpp
  lib/Sema/SemaOpenMP.cpp
  lib/Sema/SemaTemplateInstantiate.cpp
  lib/Sema/SemaTemplateInstantiateDecl.cpp
  lib/Sema/SemaType.cpp
  lib/Serialization/ASTReaderDecl.cpp
  lib/StaticAnalyzer/Core/SimpleSValBuilder.cpp
  tools/libclang/CIndex.cpp
  tools/libclang/CXIndexDataConsumer.cpp
  unittests/AST/ASTImporterTest.cpp

Index: unittests/AST/ASTImporterTest.cpp
===================================================================
--- unittests/AST/ASTImporterTest.cpp
+++ unittests/AST/ASTImporterTest.cpp
@@ -3336,18 +3336,20 @@
       FromTU, varDecl(hasName("a"))); // Decl with definition
   ASSERT_EQ(FromDWithInit, FromDWithDef->getPreviousDecl());
   ASSERT_TRUE(FromDWithInit->getInit());
-  ASSERT_FALSE(FromDWithInit->isThisDeclarationADefinition());
-  ASSERT_TRUE(FromDWithDef->isThisDeclarationADefinition());
+  ASSERT_FALSE(FromDWithInit->isThisDeclarationADefinition(
+      FromDWithInit->getASTContext()));
+  ASSERT_TRUE(FromDWithDef->isThisDeclarationADefinition(
+      FromDWithDef->getASTContext()));
   ASSERT_FALSE(FromDWithDef->getInit());
 
   auto *ToD = FirstDeclMatcher<VarDecl>().match(
       ToTU, varDecl(hasName("a"))); // Decl with init
   ASSERT_TRUE(ToD->getInit());
-  ASSERT_FALSE(ToD->getDefinition());
+  ASSERT_FALSE(ToD->getDefinition(ToD->getASTContext()));
 
   auto *ImportedD = cast<VarDecl>(Import(FromDWithDef, Lang_CXX11));
   EXPECT_TRUE(ImportedD->getAnyInitializer());
-  EXPECT_TRUE(ImportedD->getDefinition());
+  EXPECT_TRUE(ImportedD->getDefinition(ImportedD->getASTContext()));
 }
 
 TEST_P(ImportVariables, InitAndDefinitionAreInTheFromContext) {
@@ -3367,18 +3369,20 @@
       FromTU, varDecl(hasName("a"))); // Decl with definition and with init.
   ASSERT_EQ(FromDDeclarationOnly, FromDWithDef->getPreviousDecl());
   ASSERT_FALSE(FromDDeclarationOnly->getInit());
-  ASSERT_FALSE(FromDDeclarationOnly->isThisDeclarationADefinition());
-  ASSERT_TRUE(FromDWithDef->isThisDeclarationADefinition());
+  ASSERT_FALSE(FromDDeclarationOnly->isThisDeclarationADefinition(
+      FromDDeclarationOnly->getASTContext()));
+  ASSERT_TRUE(FromDWithDef->isThisDeclarationADefinition(
+      FromDWithDef->getASTContext()));
   ASSERT_TRUE(FromDWithDef->getInit());
 
   auto *ToD = FirstDeclMatcher<VarDecl>().match(
       ToTU, varDecl(hasName("a")));
   ASSERT_FALSE(ToD->getInit());
-  ASSERT_FALSE(ToD->getDefinition());
+  ASSERT_FALSE(ToD->getDefinition(ToD->getASTContext()));
 
   auto *ImportedD = cast<VarDecl>(Import(FromDWithDef, Lang_CXX11));
   EXPECT_TRUE(ImportedD->getAnyInitializer());
-  EXPECT_TRUE(ImportedD->getDefinition());
+  EXPECT_TRUE(ImportedD->getDefinition(ImportedD->getASTContext()));
 }
 
 struct DeclContextTest : ASTImporterTestBase {};
Index: tools/libclang/CXIndexDataConsumer.cpp
===================================================================
--- tools/libclang/CXIndexDataConsumer.cpp
+++ tools/libclang/CXIndexDataConsumer.cpp
@@ -623,7 +623,8 @@
 }
 
 bool CXIndexDataConsumer::handleVar(const VarDecl *D) {
-  DeclInfo DInfo(!D->isFirstDecl(), D->isThisDeclarationADefinition(),
+  DeclInfo DInfo(!D->isFirstDecl(),
+                 D->isThisDeclarationADefinition(getASTContext()),
                  /*isContainer=*/false);
   return handleDecl(D, D->getLocation(), getCursor(D), DInfo);
 }
Index: tools/libclang/CIndex.cpp
===================================================================
--- tools/libclang/CIndex.cpp
+++ tools/libclang/CIndex.cpp
@@ -6290,7 +6290,8 @@
   case Decl::VarTemplatePartialSpecialization:
   case Decl::Decomposition: {
     // Ask the variable if it has a definition.
-    if (const VarDecl *Def = cast<VarDecl>(D)->getDefinition())
+    if (const VarDecl *Def =
+            cast<VarDecl>(D)->getDefinition(D->getASTContext()))
       return MakeCXCursor(Def, TU);
     return clang_getNullCursor();
   }
@@ -6312,7 +6313,8 @@
 
   case Decl::VarTemplate: {
     if (VarDecl *Def =
-            cast<VarTemplateDecl>(D)->getTemplatedDecl()->getDefinition())
+            cast<VarTemplateDecl>(D)->getTemplatedDecl()->getDefinition(
+                D->getASTContext()))
       return MakeCXCursor(cast<VarDecl>(Def)->getDescribedVarTemplate(), TU);
     return clang_getNullCursor();
   }
Index: lib/StaticAnalyzer/Core/SimpleSValBuilder.cpp
===================================================================
--- lib/StaticAnalyzer/Core/SimpleSValBuilder.cpp
+++ lib/StaticAnalyzer/Core/SimpleSValBuilder.cpp
@@ -152,7 +152,7 @@
         const MemRegion *R = val.castAs<loc::MemRegionVal>().getRegion();
         if (const FunctionCodeRegion *FTR = dyn_cast<FunctionCodeRegion>(R))
           if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(FTR->getDecl()))
-            if (FD->isWeak())
+            if (FD->isWeak(getContext()))
               // FIXME: Currently we are using an extent symbol here,
               // because there are no generic region address metadata
               // symbols to use, only content metadata.
Index: lib/Serialization/ASTReaderDecl.cpp
===================================================================
--- lib/Serialization/ASTReaderDecl.cpp
+++ lib/Serialization/ASTReaderDecl.cpp
@@ -2782,7 +2782,7 @@
     return !D->getDeclContext()->isFunctionOrMethod();
   if (const auto *Var = dyn_cast<VarDecl>(D))
     return Var->isFileVarDecl() &&
-           (Var->isThisDeclarationADefinition() == VarDecl::Definition ||
+           (Var->isThisDeclarationADefinition(Ctx) == VarDecl::Definition ||
             OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(Var));
   if (const auto *Func = dyn_cast<FunctionDecl>(D))
     return Func->doesThisDeclarationHaveABody() || HasBody;
@@ -3432,9 +3432,11 @@
   // We should keep at most one definition on the chain.
   // FIXME: Cache the definition once we've found it. Building a chain with
   // N definitions currently takes O(N^2) time here.
-  if (VD->isThisDeclarationADefinition() == VarDecl::Definition) {
+  if (VD->isThisDeclarationADefinition(Reader.getContext()) ==
+      VarDecl::Definition) {
     for (VarDecl *CurD = PrevVD; CurD; CurD = CurD->getPreviousDecl()) {
-      if (CurD->isThisDeclarationADefinition() == VarDecl::Definition) {
+      if (CurD->isThisDeclarationADefinition(Reader.getContext()) ==
+          VarDecl::Definition) {
         Reader.mergeDefinitionVisibility(CurD, VD);
         VD->demoteThisDefinitionToDeclaration();
         break;
Index: lib/Sema/SemaType.cpp
===================================================================
--- lib/Sema/SemaType.cpp
+++ lib/Sema/SemaType.cpp
@@ -7491,11 +7491,11 @@
   if (DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(E->IgnoreParens())) {
     if (VarDecl *Var = dyn_cast<VarDecl>(DRE->getDecl())) {
       if (isTemplateInstantiation(Var->getTemplateSpecializationKind())) {
-        auto *Def = Var->getDefinition();
+        auto *Def = Var->getDefinition(Context);
         if (!Def) {
           SourceLocation PointOfInstantiation = E->getExprLoc();
           InstantiateVariableDefinition(PointOfInstantiation, Var);
-          Def = Var->getDefinition();
+          Def = Var->getDefinition(Context);
 
           // If we don't already have a point of instantiation, and we managed
           // to instantiate a definition, this is the point of instantiation.
@@ -7659,9 +7659,9 @@
       FD = Pattern;
     D = FD->getDefinition();
   } else if (auto *VD = dyn_cast<VarDecl>(D)) {
-    if (auto *Pattern = VD->getTemplateInstantiationPattern())
+    if (auto *Pattern = VD->getTemplateInstantiationPattern(Context))
       VD = Pattern;
-    D = VD->getDefinition();
+    D = VD->getDefinition(Context);
   }
   assert(D && "missing definition for pattern of instantiated definition");
 
Index: lib/Sema/SemaTemplateInstantiateDecl.cpp
===================================================================
--- lib/Sema/SemaTemplateInstantiateDecl.cpp
+++ lib/Sema/SemaTemplateInstantiateDecl.cpp
@@ -4073,7 +4073,7 @@
 VarTemplateSpecializationDecl *Sema::CompleteVarTemplateSpecializationDecl(
     VarTemplateSpecializationDecl *VarSpec, VarDecl *PatternDecl,
     const MultiLevelTemplateArgumentList &TemplateArgs) {
-  assert(PatternDecl->isThisDeclarationADefinition() &&
+  assert(PatternDecl->isThisDeclarationADefinition(Context) &&
          "don't have a definition to instantiate from");
 
   // Do substitution on the type of the declaration
@@ -4179,8 +4179,8 @@
   // it right away if the type contains 'auto'.
   if ((!isa<VarTemplateSpecializationDecl>(NewVar) &&
        !InstantiatingVarTemplate &&
-       !(OldVar->isInline() && OldVar->isThisDeclarationADefinition() &&
-         !NewVar->isThisDeclarationADefinition())) ||
+       !(OldVar->isInline() && OldVar->isThisDeclarationADefinition(Context) &&
+         !NewVar->isThisDeclarationADefinition(Context))) ||
       NewVar->getType()->isUndeducedType())
     InstantiateVariableInitializer(NewVar, OldVar, TemplateArgs);
 
@@ -4374,7 +4374,7 @@
     }
 
     // Find actual definition
-    Def = PatternDecl->getDefinition(getASTContext());
+    Def = PatternDecl->getDefinition(Context);
   } else {
     // If this is a static data member, find its out-of-line definition.
     assert(Var->isStaticDataMember() && "not a static data member?");
@@ -4382,7 +4382,7 @@
 
     assert(PatternDecl && "data member was not instantiated from a template?");
     assert(PatternDecl->isStaticDataMember() && "not a static data member?");
-    Def = PatternDecl->getDefinition();
+    Def = PatternDecl->getDefinition(Context);
   }
 
   TemplateSpecializationKind TSK = Var->getTemplateSpecializationKind();
@@ -4447,7 +4447,7 @@
   } PassToConsumerRAII(Consumer, Var);
 
   // If we already have a definition, we're done.
-  if (VarDecl *Def = Var->getDefinition()) {
+  if (VarDecl *Def = Var->getDefinition(Context)) {
     // We may be explicitly instantiating something we've already implicitly
     // instantiated.
     Def->setTemplateSpecializationKind(Var->getTemplateSpecializationKind(),
Index: lib/Sema/SemaTemplateInstantiate.cpp
===================================================================
--- lib/Sema/SemaTemplateInstantiate.cpp
+++ lib/Sema/SemaTemplateInstantiate.cpp
@@ -2646,7 +2646,8 @@
           //   specialization and is only an explicit instantiation definition
           //   of members whose definition is visible at the point of
           //   instantiation.
-          if (!Var->getInstantiatedFromStaticDataMember()->getDefinition())
+          if (!Var->getInstantiatedFromStaticDataMember()->getDefinition(
+                  Context))
             continue;
 
           Var->setTemplateSpecializationKind(TSK, PointOfInstantiation);
Index: lib/Sema/SemaOpenMP.cpp
===================================================================
--- lib/Sema/SemaOpenMP.cpp
+++ lib/Sema/SemaOpenMP.cpp
@@ -10905,7 +10905,7 @@
     //  for all threads of the team.
     if (!ASE && !OASE) {
       if (VD) {
-        VarDecl *VDDef = VD->getDefinition();
+        VarDecl *VDDef = VD->getDefinition(S.Context);
         if (VD->getType()->isReferenceType() && VDDef && VDDef->hasInit()) {
           DSARefChecker Check(Stack);
           if (Check.Visit(VDDef->getInit())) {
Index: lib/Sema/SemaLookup.cpp
===================================================================
--- lib/Sema/SemaLookup.cpp
+++ lib/Sema/SemaLookup.cpp
@@ -1366,7 +1366,7 @@
     if (auto *Pattern = ED->getTemplateInstantiationPattern())
       Entity = Pattern;
   } else if (VarDecl *VD = dyn_cast<VarDecl>(Entity)) {
-    if (VarDecl *Pattern = VD->getTemplateInstantiationPattern())
+    if (VarDecl *Pattern = VD->getTemplateInstantiationPattern(S.Context))
       Entity = Pattern;
   }
 
@@ -5029,9 +5029,10 @@
 
 /// Find which declaration we should import to provide the definition of
 /// the given declaration.
-static NamedDecl *getDefinitionToImport(NamedDecl *D) {
+static NamedDecl *getDefinitionToImport(const ASTContext &Context,
+                                        NamedDecl *D) {
   if (VarDecl *VD = dyn_cast<VarDecl>(D))
-    return VD->getDefinition();
+    return VD->getDefinition(Context);
   if (FunctionDecl *FD = dyn_cast<FunctionDecl>(D))
     return FD->getDefinition();
   if (TagDecl *TD = dyn_cast<TagDecl>(D))
@@ -5041,7 +5042,7 @@
   if (ObjCProtocolDecl *PD = dyn_cast<ObjCProtocolDecl>(D))
     return PD->getDefinition();
   if (TemplateDecl *TD = dyn_cast<TemplateDecl>(D))
-    return getDefinitionToImport(TD->getTemplatedDecl());
+    return getDefinitionToImport(Context, TD->getTemplatedDecl());
   return nullptr;
 }
 
@@ -5049,7 +5050,7 @@
                                  MissingImportKind MIK, bool Recover) {
   // Suggest importing a module providing the definition of this entity, if
   // possible.
-  NamedDecl *Def = getDefinitionToImport(Decl);
+  NamedDecl *Def = getDefinitionToImport(Context, Decl);
   if (!Def)
     Def = Decl;
 
Index: lib/Sema/SemaExprCXX.cpp
===================================================================
--- lib/Sema/SemaExprCXX.cpp
+++ lib/Sema/SemaExprCXX.cpp
@@ -7368,7 +7368,8 @@
   // If there is no initializer - this can not be a constant expression.
   if (!Var->getAnyInitializer(DefVD)) return true;
   assert(DefVD);
-  if (DefVD->isWeak()) return false;
+  if (DefVD->isWeak(Context))
+    return false;
   EvaluatedStmt *Eval = DefVD->ensureEvaluatedStmt();
 
   Expr *Init = cast<Expr>(Eval->Value);
Index: lib/Sema/SemaExpr.cpp
===================================================================
--- lib/Sema/SemaExpr.cpp
+++ lib/Sema/SemaExpr.cpp
@@ -9998,9 +9998,9 @@
                           S.PDiag(diag::warn_comparison_always)
                               << 0 /*self-comparison*/ << !Result.empty()
                               << Result);
-  } else if (DL && DR &&
-             DL->getType()->isArrayType() && DR->getType()->isArrayType() &&
-             !DL->isWeak() && !DR->isWeak()) {
+  } else if (DL && DR && DL->getType()->isArrayType() &&
+             DR->getType()->isArrayType() && !DL->isWeak(S.Context) &&
+             !DR->isWeak(S.Context)) {
     // What is it always going to evaluate to?
     StringRef Result;
     switch(Opc) {
Index: lib/Sema/SemaDeclCXX.cpp
===================================================================
--- lib/Sema/SemaDeclCXX.cpp
+++ lib/Sema/SemaDeclCXX.cpp
@@ -1209,7 +1209,7 @@
     if (E.isInvalid())
       return true;
     RefVD->setInit(E.get());
-    RefVD->checkInitIsICE();
+    RefVD->checkInitIsICE(S.Context);
 
     E = S.BuildDeclarationNameExpr(CXXScopeSpec(),
                                    DeclarationNameInfo(B->getDeclName(), Loc),
@@ -1706,7 +1706,7 @@
       //   a definition of a variable of non-literal type or of static or
       //   thread storage duration or for which no initialization is performed.
       const auto *VD = cast<VarDecl>(DclIt);
-      if (VD->isThisDeclarationADefinition()) {
+      if (VD->isThisDeclarationADefinition(SemaRef.Context)) {
         if (VD->isStaticLocal()) {
           SemaRef.Diag(VD->getLocation(),
                        diag::err_constexpr_local_var_static)
@@ -9135,13 +9135,13 @@
     // might be foobar, including it failing to be a constant expression.
     // TODO Handle more ways the lookup or result can be invalid.
     if (!VD->isStaticDataMember() || !VD->isConstexpr() || !VD->hasInit() ||
-        !VD->checkInitIsICE())
+        !VD->checkInitIsICE(Context))
       return UnsupportedSTLError(USS_InvalidMember, MemName, VD);
 
     // Attempt to evaluate the var decl as a constant expression and extract
     // the value of its first field as a ICE. If this fails, the STL
     // implementation is not supported.
-    if (!ValInfo->hasValidIntValue())
+    if (!ValInfo->hasValidIntValue(Context))
       return UnsupportedSTLError();
 
     MarkVariableReferenced(Loc, VD);
Index: lib/Sema/SemaDeclAttr.cpp
===================================================================
--- lib/Sema/SemaDeclAttr.cpp
+++ lib/Sema/SemaDeclAttr.cpp
@@ -1885,7 +1885,8 @@
     }
   } else {
     const auto *VD = cast<VarDecl>(D);
-    if (VD->isThisDeclarationADefinition() && VD->isExternallyVisible()) {
+    if (VD->isThisDeclarationADefinition(S.Context) &&
+        VD->isExternallyVisible()) {
       S.Diag(AL.getLoc(), diag::err_alias_is_definition) << VD << 0;
       return;
     }
@@ -2854,7 +2855,7 @@
 static void handleWeakImportAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
   // weak_import only applies to variable & function declarations.
   bool isDef = false;
-  if (!D->canBeWeakImported(isDef)) {
+  if (!D->canBeWeakImported(S.Context, isDef)) {
     if (isDef)
       S.Diag(AL.getLoc(), diag::warn_attribute_invalid_on_definition)
         << "weak_import";
Index: lib/Sema/SemaDecl.cpp
===================================================================
--- lib/Sema/SemaDecl.cpp
+++ lib/Sema/SemaDecl.cpp
@@ -2295,9 +2295,9 @@
   return false;
 }
 
-static bool isAttributeTargetADefinition(Decl *D) {
+static bool isAttributeTargetADefinition(Sema &S, Decl *D) {
   if (VarDecl *VD = dyn_cast<VarDecl>(D))
-    return VD->isThisDeclarationADefinition();
+    return VD->isThisDeclarationADefinition(S.Context);
   if (TagDecl *TD = dyn_cast<TagDecl>(D))
     return TD->isCompleteDefinition() || TD->isBeingDefined();
   return true;
@@ -2377,7 +2377,8 @@
     }
   }
 
-  if (OldAlignasAttr && !NewAlignasAttr && isAttributeTargetADefinition(New)) {
+  if (OldAlignasAttr && !NewAlignasAttr &&
+      isAttributeTargetADefinition(S, New)) {
     // C++11 [dcl.align]p6:
     //   if any declaration of an entity has an alignment-specifier,
     //   every defining declaration of that entity shall specify an
@@ -2503,14 +2504,14 @@
   return false;
 }
 
-static const NamedDecl *getDefinition(const Decl *D) {
+static const NamedDecl *getDefinition(Sema &SemaRef, const Decl *D) {
   if (const TagDecl *TD = dyn_cast<TagDecl>(D))
     return TD->getDefinition();
   if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
-    const VarDecl *Def = VD->getDefinition();
+    const VarDecl *Def = VD->getDefinition(SemaRef.Context);
     if (Def)
       return Def;
-    return VD->getActingDefinition();
+    return VD->getActingDefinition(SemaRef.Context);
   }
   if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D))
     return FD->getDefinition();
@@ -2530,7 +2531,7 @@
   if (!New->hasAttrs())
     return;
 
-  const NamedDecl *Def = getDefinition(Old);
+  const NamedDecl *Def = getDefinition(S, Old);
   if (!Def || Def == New)
     return;
 
@@ -2551,8 +2552,8 @@
         }
       } else {
         VarDecl *VD = cast<VarDecl>(New);
-        unsigned Diag = cast<VarDecl>(Def)->isThisDeclarationADefinition() ==
-                                VarDecl::TentativeDefinition
+        unsigned Diag = cast<VarDecl>(Def)->isThisDeclarationADefinition(
+                            S.Context) == VarDecl::TentativeDefinition
                             ? diag::err_alias_after_tentative
                             : diag::err_redefinition;
         S.Diag(VD->getLocation(), Diag) << VD->getDeclName();
@@ -2568,7 +2569,7 @@
 
     if (const VarDecl *VD = dyn_cast<VarDecl>(Def)) {
       // Tentative definitions are only interesting for the alias check above.
-      if (VD->isThisDeclarationADefinition() != VarDecl::Definition) {
+      if (VD->isThisDeclarationADefinition(S.Context) != VarDecl::Definition) {
         ++I;
         continue;
       }
@@ -2662,7 +2663,7 @@
   // This redeclaration adds a section attribute.
   if (New->hasAttr<SectionAttr>() && !Old->hasAttr<SectionAttr>()) {
     if (auto *VD = dyn_cast<VarDecl>(New)) {
-      if (VD->isThisDeclarationADefinition() == VarDecl::DeclarationOnly) {
+      if (VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly) {
         Diag(New->getLocation(), diag::warn_attribute_section_on_redeclaration);
         Diag(Old->getLocation(), diag::note_previous_declaration);
       }
@@ -2825,14 +2826,25 @@
   return Sema::CXXInvalid;
 }
 
+template <typename DeclT>
+static bool isThisDeclarationADefinition(const ASTContext &, const DeclT *D) {
+  return D->isThisDeclarationADefinition();
+}
+
+static bool isThisDeclarationADefinition(const ASTContext &Context,
+                                         const VarDecl *VD) {
+  return VD->isThisDeclarationADefinition(Context);
+}
+
 // Determine whether the previous declaration was a definition, implicit
 // declaration, or a declaration.
 template <typename T>
 static std::pair<diag::kind, SourceLocation>
-getNoteDiagForInvalidRedeclaration(const T *Old, const T *New) {
+getNoteDiagForInvalidRedeclaration(const ASTContext &Context, const T *Old,
+                                   const T *New) {
   diag::kind PrevDiag;
   SourceLocation OldLocation = Old->getLocation();
-  if (Old->isThisDeclarationADefinition())
+  if (isThisDeclarationADefinition(Context, Old))
     PrevDiag = diag::note_previous_definition;
   else if (Old->isImplicit()) {
     PrevDiag = diag::note_previous_implicit_declaration;
@@ -3017,7 +3029,7 @@
     return true;
 
   // Disallow redeclaration of some builtins.
-  if (!getASTContext().canBuiltinBeRedeclared(Old)) {
+  if (!Context.canBuiltinBeRedeclared(Old)) {
     Diag(New->getLocation(), diag::err_builtin_redeclare) << Old->getDeclName();
     Diag(Old->getLocation(), diag::note_previous_builtin_declaration)
         << Old << Old->getType();
@@ -3027,7 +3039,7 @@
   diag::kind PrevDiag;
   SourceLocation OldLocation;
   std::tie(PrevDiag, OldLocation) =
-      getNoteDiagForInvalidRedeclaration(Old, New);
+      getNoteDiagForInvalidRedeclaration(Context, Old, New);
 
   // Don't complain about this if we're in GNU89 mode and the old function
   // is an extern inline function.
@@ -3634,15 +3646,15 @@
 static void diagnoseVarDeclTypeMismatch(Sema &S, VarDecl *New, VarDecl* Old) {
   assert(!S.Context.hasSameType(New->getType(), Old->getType()));
 
-  S.Diag(New->getLocation(), New->isThisDeclarationADefinition()
+  S.Diag(New->getLocation(), New->isThisDeclarationADefinition(S.Context)
          ? diag::err_redefinition_different_type
          : diag::err_redeclaration_different_type)
     << New->getDeclName() << New->getType() << Old->getType();
 
   diag::kind PrevDiag;
   SourceLocation OldLocation;
-  std::tie(PrevDiag, OldLocation)
-    = getNoteDiagForInvalidRedeclaration(Old, New);
+  std::tie(PrevDiag, OldLocation) =
+      getNoteDiagForInvalidRedeclaration(S.Context, Old, New);
   S.Diag(OldLocation, PrevDiag);
   New->setInvalidDecl();
 }
@@ -3871,7 +3883,7 @@
   diag::kind PrevDiag;
   SourceLocation OldLocation;
   std::tie(PrevDiag, OldLocation) =
-      getNoteDiagForInvalidRedeclaration(Old, New);
+      getNoteDiagForInvalidRedeclaration(Context, Old, New);
 
   // [dcl.stc]p8: Check if we have a non-static decl followed by a static.
   if (New->getStorageClass() == SC_Static &&
@@ -3938,7 +3950,7 @@
   }
 
   if (New->isInline() && !Old->getMostRecentDecl()->isInline()) {
-    if (VarDecl *Def = Old->getDefinition()) {
+    if (VarDecl *Def = Old->getDefinition(Context)) {
       // C++1z [dcl.fcn.spec]p4:
       //   If the definition of a variable appears in a translation unit before
       //   its first declaration as inline, the program is ill-formed.
@@ -3950,7 +3962,8 @@
   // If this redeclaration makes the variable inline, we may need to add it to
   // UndefinedButUsed.
   if (!Old->isInline() && New->isInline() && Old->isUsed(false) &&
-      !Old->getDefinition() && !New->isThisDeclarationADefinition())
+      !Old->getDefinition(Context) &&
+      !New->isThisDeclarationADefinition(Context))
     UndefinedButUsed.insert(std::make_pair(Old->getCanonicalDecl(),
                                            SourceLocation()));
 
@@ -3974,13 +3987,13 @@
 
   // C++ doesn't have tentative definitions, so go right ahead and check here.
   if (getLangOpts().CPlusPlus &&
-      New->isThisDeclarationADefinition() == VarDecl::Definition) {
+      New->isThisDeclarationADefinition(Context) == VarDecl::Definition) {
     if (Old->isStaticDataMember() && Old->getCanonicalDecl()->isInline() &&
         Old->getCanonicalDecl()->isConstexpr()) {
       // This definition won't be a definition any more once it's been merged.
       Diag(New->getLocation(),
            diag::warn_deprecated_redundant_constexpr_static_def);
-    } else if (VarDecl *Def = Old->getDefinition()) {
+    } else if (VarDecl *Def = Old->getDefinition(Context)) {
       if (checkVarDeclRedefinition(Def, New))
         return;
     }
@@ -5943,7 +5956,7 @@
   if (auto *VD = dyn_cast<VarDecl>(&ND)) {
     if (VD->hasInit()) {
       if (const auto *Attr = VD->getAttr<AliasAttr>()) {
-        assert(VD->isThisDeclarationADefinition() &&
+        assert(VD->isThisDeclarationADefinition(S.Context) &&
                !VD->isExternallyVisible() && "Broken AliasAttr handled late!");
         S.Diag(Attr->getLocation(), diag::err_alias_is_definition) << VD << 0;
         VD->dropAttr<AliasAttr>();
@@ -7490,7 +7503,8 @@
   if (T->isVoidType()) {
     // C++98 [dcl.stc]p5: The extern specifier can be applied only to the names
     //                    of objects and functions.
-    if (NewVD->isThisDeclarationADefinition() || getLangOpts().CPlusPlus) {
+    if (NewVD->isThisDeclarationADefinition(Context) ||
+        getLangOpts().CPlusPlus) {
       Diag(NewVD->getLocation(), diag::err_typecheck_decl_incomplete_type)
         << T;
       NewVD->setInvalidDecl();
@@ -11051,7 +11065,7 @@
   // and we already have a definition for this variable, diagnose or otherwise
   // handle the situation.
   VarDecl *Def;
-  if ((Def = VDecl->getDefinition()) && Def != VDecl &&
+  if ((Def = VDecl->getDefinition(Context)) && Def != VDecl &&
       (!VDecl->isStaticDataMember() || VDecl->isOutOfLine()) &&
       !VDecl->isThisDeclarationADemotedDefinition() &&
       checkVarDeclRedefinition(Def, VDecl))
@@ -11457,7 +11471,7 @@
     // C++11 [dcl.constexpr]p1: The constexpr specifier shall be applied only to
     // the definition of a variable [...] or the declaration of a static data
     // member.
-    if (Var->isConstexpr() && !Var->isThisDeclarationADefinition() &&
+    if (Var->isConstexpr() && !Var->isThisDeclarationADefinition(Context) &&
         !Var->isThisDeclarationADemotedDefinition()) {
       if (Var->isStaticDataMember()) {
         // C++1z removes the relevant rule; the in-class declaration is always
@@ -11486,7 +11500,7 @@
       return;
     }
 
-    switch (Var->isThisDeclarationADefinition()) {
+    switch (Var->isThisDeclarationADefinition(Context)) {
     case VarDecl::Definition:
       if (!Var->isStaticDataMember() || !Var->getAnyInitializer())
         break;
@@ -11772,7 +11786,7 @@
   // declarations, but we also specifically need to avoid doing it for
   // class members because the linkage of an anonymous class can
   // change if it's later given a typedef name.
-  if (var->isThisDeclarationADefinition() &&
+  if (var->isThisDeclarationADefinition(Context) &&
       var->getDeclContext()->getRedeclContext()->isFileContext() &&
       var->isExternallyVisible() && var->hasLinkage() &&
       !var->isInline() && !var->getDescribedVarTemplate() &&
@@ -11781,7 +11795,7 @@
                                   var->getLocation())) {
     // Find a previous declaration that's not a definition.
     VarDecl *prev = var->getPreviousDecl();
-    while (prev && prev->isThisDeclarationADefinition())
+    while (prev && prev->isThisDeclarationADefinition(Context))
       prev = prev->getPreviousDecl();
 
     if (!prev)
@@ -11822,7 +11836,7 @@
 
   // Apply section attributes and pragmas to global variables.
   bool GlobalStorage = var->hasGlobalStorage();
-  if (GlobalStorage && var->isThisDeclarationADefinition() &&
+  if (GlobalStorage && var->isThisDeclarationADefinition(Context) &&
       !inTemplateInstantiation()) {
     PragmaStack<StringLiteral *> *Stack = nullptr;
     int SectionFlags = ASTContext::PSF_Implicit | ASTContext::PSF_Read;
@@ -11895,7 +11909,7 @@
       // Check whether the initializer of a const variable of integral or
       // enumeration type is an ICE now, since we can't tell whether it was
       // initialized by a constant expression if we check later.
-      var->checkInitIsICE();
+      var->checkInitIsICE(Context);
     }
 
     // Don't emit further diagnostics about constexpr globals since they
@@ -11903,8 +11917,8 @@
     if (!var->isConstexpr() && GlobalStorage &&
             var->hasAttr<RequireConstantInitAttr>()) {
       // FIXME: Need strict checking in C++03 here.
-      bool DiagErr = getLangOpts().CPlusPlus11
-          ? !var->checkInitIsICE() : !checkConstInit();
+      bool DiagErr = getLangOpts().CPlusPlus11 ? !var->checkInitIsICE(Context)
+                                               : !checkConstInit();
       if (DiagErr) {
         auto attr = var->getAttr<RequireConstantInitAttr>();
         Diag(var->getLocation(), diag::err_require_constant_init_failed)
@@ -12013,7 +12027,7 @@
     return;
 
   // Apply an implicit SectionAttr if '#pragma clang section bss|data|rodata' is active
-  if (VD->hasGlobalStorage() && VD->isThisDeclarationADefinition() &&
+  if (VD->hasGlobalStorage() && VD->isThisDeclarationADefinition(Context) &&
       !inTemplateInstantiation() && !VD->hasAttr<SectionAttr>()) {
     if (PragmaClangBSSSection.Valid)
       VD->addAttr(PragmaClangBSSSectionAttr::CreateImplicit(Context,
@@ -12094,7 +12108,7 @@
   // Imported static data members cannot be defined out-of-line.
   if (const auto *IA = dyn_cast_or_null<DLLImportAttr>(DLLAttr)) {
     if (VD->isStaticDataMember() && VD->isOutOfLine() &&
-        VD->isThisDeclarationADefinition()) {
+        VD->isThisDeclarationADefinition(Context)) {
       // We allow definitions of dllimport class template static data members
       // with a warning.
       CXXRecordDecl *Context =
@@ -12130,7 +12144,7 @@
   }
 
   if (UsedAttr *Attr = VD->getAttr<UsedAttr>()) {
-    if (!Attr->isInherited() && !VD->isThisDeclarationADefinition()) {
+    if (!Attr->isInherited() && !VD->isThisDeclarationADefinition(Context)) {
       Diag(Attr->getLocation(), diag::warn_attribute_ignored) << Attr;
       VD->dropAttr<UsedAttr>();
     }
Index: lib/Sema/SemaChecking.cpp
===================================================================
--- lib/Sema/SemaChecking.cpp
+++ lib/Sema/SemaChecking.cpp
@@ -11365,7 +11365,7 @@
   }
 
   // Weak Decls can be null.
-  if (!D || D->isWeak())
+  if (!D || D->isWeak(Context))
     return;
 
   // Check for parameter decl with nonnull attribute
Index: lib/Sema/Sema.cpp
===================================================================
--- lib/Sema/Sema.cpp
+++ lib/Sema/Sema.cpp
@@ -590,7 +590,7 @@
 
     // UnusedFileScopedDecls stores the first declaration.
     // The declaration may have become definition so check again.
-    const VarDecl *DeclToCheck = VD->getDefinition();
+    const VarDecl *DeclToCheck = VD->getDefinition(SemaRef->Context);
     if (DeclToCheck)
       return !SemaRef->ShouldWarnIfUnusedFileScopedDecl(DeclToCheck);
 
@@ -656,7 +656,7 @@
         continue;
     } else {
       auto *VD = cast<VarDecl>(ND);
-      if (VD->hasDefinition() != VarDecl::DeclarationOnly)
+      if (VD->hasDefinition(Context) != VarDecl::DeclarationOnly)
         continue;
       if (VD->isExternallyVisible() &&
           !isExternalWithNoLinkageType(VD) &&
@@ -666,7 +666,7 @@
 
       // Skip VarDecls that lack formal definitions but which we know are in
       // fact defined somewhere.
-      if (VD->isKnownToBeDefined())
+      if (VD->isKnownToBeDefined(Context))
         continue;
     }
 
@@ -1038,7 +1038,7 @@
             T = TentativeDefinitions.begin(ExternalSource),
          TEnd = TentativeDefinitions.end();
        T != TEnd; ++T) {
-    VarDecl *VD = (*T)->getActingDefinition();
+    VarDecl *VD = (*T)->getActingDefinition(Context);
 
     // If the tentative definition was completed, getActingDefinition() returns
     // null. If we've already seen this variable before, insert()'s second
@@ -1111,7 +1111,7 @@
               << DiagD->getDeclName();
         }
       } else {
-        const VarDecl *DiagD = cast<VarDecl>(*I)->getDefinition();
+        const VarDecl *DiagD = cast<VarDecl>(*I)->getDefinition(Context);
         if (!DiagD)
           DiagD = cast<VarDecl>(*I);
         if (DiagD->isReferenced()) {
Index: lib/Index/IndexingContext.cpp
===================================================================
--- lib/Index/IndexingContext.cpp
+++ lib/Index/IndexingContext.cpp
@@ -193,14 +193,15 @@
   return nullptr;
 }
 
-static const Decl *adjustTemplateImplicitInstantiation(const Decl *D) {
+static const Decl *
+adjustTemplateImplicitInstantiation(const ASTContext &Context, const Decl *D) {
   if (const ClassTemplateSpecializationDecl *
       SD = dyn_cast<ClassTemplateSpecializationDecl>(D)) {
     return SD->getTemplateInstantiationPattern();
   } else if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
     return FD->getTemplateInstantiationPattern();
   } else if (auto *VD = dyn_cast<VarDecl>(D)) {
-    return VD->getTemplateInstantiationPattern();
+    return VD->getTemplateInstantiationPattern(Context);
   } else if (const auto *RD = dyn_cast<CXXRecordDecl>(D)) {
     return RD->getInstantiatedFromMemberClass();
   } else if (const auto *ED = dyn_cast<EnumDecl>(D)) {
@@ -378,7 +379,7 @@
   if (isTemplateImplicitInstantiation(D)) {
     if (!IsRef)
       return true;
-    D = adjustTemplateImplicitInstantiation(D);
+    D = adjustTemplateImplicitInstantiation(*Ctx, D);
     if (!D)
       return true;
     assert(!isTemplateImplicitInstantiation(D));
Index: lib/CodeGen/ItaniumCXXABI.cpp
===================================================================
--- lib/CodeGen/ItaniumCXXABI.cpp
+++ lib/CodeGen/ItaniumCXXABI.cpp
@@ -2459,7 +2459,7 @@
 
   CGM.SetLLVMFunctionAttributes(GlobalDecl(), FI, Wrapper);
 
-  if (VD->hasDefinition())
+  if (VD->hasDefinition(CGM.getContext()))
     CGM.SetLLVMFunctionAttributesForDefinition(nullptr, Wrapper);
 
   // Always resolve references to the wrapper at link time.
@@ -2529,7 +2529,8 @@
     // Some targets require that all access to thread local variables go through
     // the thread wrapper.  This means that we cannot attempt to create a thread
     // wrapper or a thread helper.
-    if (isThreadWrapperReplaceable(VD, CGM) && !VD->hasDefinition()) {
+    if (isThreadWrapperReplaceable(VD, CGM) &&
+        !VD->hasDefinition(CGM.getContext())) {
       Wrapper->setLinkage(llvm::Function::ExternalLinkage);
       continue;
     }
@@ -2546,7 +2547,7 @@
     // produce a declaration of the initialization function.
     llvm::GlobalValue *Init = nullptr;
     bool InitIsInitFunc = false;
-    if (VD->hasDefinition()) {
+    if (VD->hasDefinition(CGM.getContext())) {
       InitIsInitFunc = true;
       llvm::Function *InitFuncToUse = InitFunc;
       if (isTemplateInstantiation(VD->getTemplateSpecializationKind()))
Index: lib/CodeGen/CodeGenModule.cpp
===================================================================
--- lib/CodeGen/CodeGenModule.cpp
+++ lib/CodeGen/CodeGenModule.cpp
@@ -1488,14 +1488,15 @@
   setNonAliasAttributes(GD, F);
 }
 
-static void setLinkageForGV(llvm::GlobalValue *GV, const NamedDecl *ND) {
+static void setLinkageForGV(const CodeGenModule &CGM, llvm::GlobalValue *GV,
+                            const NamedDecl *ND) {
   // Set linkage and visibility in case we never see a definition.
   LinkageInfo LV = ND->getLinkageAndVisibility();
   // Don't set internal linkage on declarations.
   // "extern_weak" is overloaded in LLVM; we probably should have
   // separate linkage types for this.
   if (isExternallyVisible(LV.getLinkage()) &&
-      (ND->hasAttr<WeakAttr>() || ND->isWeakImported()))
+      (ND->hasAttr<WeakAttr>() || ND->isWeakImported(CGM.getContext())))
     GV->setLinkage(llvm::GlobalValue::ExternalWeakLinkage);
 }
 
@@ -1563,7 +1564,7 @@
   // Only a few attributes are set on declarations; these may later be
   // overridden by a definition.
 
-  setLinkageForGV(F, FD);
+  setLinkageForGV(*this, F, FD);
   setGVProperties(F, FD);
 
   if (const auto *CSA = FD->getAttr<CodeSegAttr>())
@@ -2188,12 +2189,12 @@
     // We need to emit device-side global CUDA variables even if a
     // variable does not have a definition -- we still need to define
     // host-side shadow for it.
-    bool MustEmitForCuda = LangOpts.CUDA && !LangOpts.CUDAIsDevice &&
-                           !VD->hasDefinition() &&
-                           (VD->hasAttr<CUDAConstantAttr>() ||
-                            VD->hasAttr<CUDADeviceAttr>());
+    bool MustEmitForCuda =
+        LangOpts.CUDA && !LangOpts.CUDAIsDevice &&
+        !VD->hasDefinition(Context) &&
+        (VD->hasAttr<CUDAConstantAttr>() || VD->hasAttr<CUDADeviceAttr>());
     if (!MustEmitForCuda &&
-        VD->isThisDeclarationADefinition() != VarDecl::Definition &&
+        VD->isThisDeclarationADefinition(Context) != VarDecl::Definition &&
         !Context.isMSStaticDataMemberInlineDefinition(VD)) {
       if (LangOpts.OpenMP) {
         // Emit declaration of the must-be-emitted declare target variable.
@@ -2309,7 +2310,7 @@
       }
 
       // A variable definition might imply a destructor call.
-      if (VD->isThisDeclarationADefinition())
+      if (VD->isThisDeclarationADefinition(VD->getASTContext()))
         SafeToInline = !HasNonDllImportDtor(VD->getType());
 
       return SafeToInline;
@@ -2468,7 +2469,7 @@
   }
 
   if (const auto *VD = dyn_cast<VarDecl>(D))
-    return EmitGlobalVarDefinition(VD, !VD->hasDefinition());
+    return EmitGlobalVarDefinition(VD, !VD->hasDefinition(Context));
 
   llvm_unreachable("Invalid argument to EmitGlobalDefinition()");
 }
@@ -3115,7 +3116,7 @@
 
     GV->setAlignment(getContext().getDeclAlign(D).getQuantity());
 
-    setLinkageForGV(GV, D);
+    setLinkageForGV(*this, GV, D);
 
     if (D->getTLSKind()) {
       if (D->getTLSKind() == VarDecl::TLS_Dynamic)
@@ -3149,7 +3150,8 @@
     // optimizer.
     if (Context.getLangOpts().CPlusPlus && GV->hasExternalLinkage() &&
         D->getType().isConstQualified() && !GV->hasInitializer() &&
-        !D->hasDefinition() && D->hasInit() && !D->hasAttr<DLLImportAttr>()) {
+        !D->hasDefinition(Context) && D->hasInit() &&
+        !D->hasAttr<DLLImportAttr>()) {
       const auto *Record =
           Context.getBaseElementType(D->getType())->getAsCXXRecordDecl();
       bool HasMutableFields = Record && Record->hasMutableFields();
@@ -3602,7 +3604,7 @@
         // Shadow variables and their properties must be registered
         // with CUDA runtime.
         unsigned Flags = 0;
-        if (!D->hasDefinition())
+        if (!D->hasDefinition(Context))
           Flags |= CGCUDARuntime::ExternDeviceVar;
         if (D->hasAttr<CUDAConstantAttr>())
           Flags |= CGCUDARuntime::ConstantDeviceVar;
@@ -3947,14 +3949,15 @@
 }
 
 void CodeGenModule::HandleCXXStaticMemberVarInstantiation(VarDecl *VD) {
-  auto DK = VD->isThisDeclarationADefinition();
+  auto DK = VD->isThisDeclarationADefinition(Context);
   if (DK == VarDecl::Definition && VD->hasAttr<DLLImportAttr>())
     return;
 
   TemplateSpecializationKind TSK = VD->getTemplateSpecializationKind();
   // If we have a definition, this might be a deferred decl. If the
   // instantiation is explicit, make sure we emit it at the end.
-  if (VD->getDefinition() && TSK == TSK_ExplicitInstantiationDefinition)
+  if (VD->getDefinition(getContext()) &&
+      TSK == TSK_ExplicitInstantiationDefinition)
     GetAddrOfGlobalVar(VD);
 
   EmitTopLevelDecl(VD);
@@ -4071,7 +4074,7 @@
   // specialization of the attributes which may be set on a global
   // variable/function.
   if (D->hasAttr<WeakAttr>() || D->hasAttr<WeakRefAttr>() ||
-      D->isWeakImported()) {
+      D->isWeakImported(getContext())) {
     GA->setLinkage(llvm::Function::WeakAnyLinkage);
   }
 
Index: lib/CodeGen/CGObjCMac.cpp
===================================================================
--- lib/CodeGen/CGObjCMac.cpp
+++ lib/CodeGen/CGObjCMac.cpp
@@ -2064,9 +2064,10 @@
                          false, CallArgs, Method, Class, ObjCTypes);
 }
 
-static bool isWeakLinkedClass(const ObjCInterfaceDecl *ID) {
+static bool isWeakLinkedClass(CodeGen::CodeGenFunction &CGF,
+                              const ObjCInterfaceDecl *ID) {
   do {
-    if (ID->isWeakImported())
+    if (ID->isWeakImported(CGF.getContext()))
       return true;
   } while ((ID = ID->getSuperClass()));
 
@@ -2110,7 +2111,7 @@
   // If this is a direct dispatch of a class method, check whether the class,
   // or anything in its hierarchy, was weak-linked.
   } else if (ClassReceiver && Method && Method->isClassMethod()) {
-    ReceiverCanBeNull = isWeakLinkedClass(ClassReceiver);
+    ReceiverCanBeNull = isWeakLinkedClass(CGF, ClassReceiver);
 
   // If we're emitting a method, and self is const (meaning just ARC, for now),
   // and the receiver is a load of self, then self is a valid object.
@@ -4995,7 +4996,8 @@
     assert(ID);
     if (ObjCImplementationDecl *IMP = ID->getImplementation())
       // We are implementing a weak imported interface. Give it external linkage
-      if (ID->isWeakImported() && !IMP->isWeakImported())
+      if (ID->isWeakImported(CGM.getContext()) &&
+          !IMP->isWeakImported(CGM.getContext()))
         DefinedClasses[i]->setLinkage(llvm::GlobalVariable::ExternalLinkage);
 
     array.addBitCast(DefinedClasses[i], ObjCTypes.Int8PtrTy);
@@ -6015,7 +6017,8 @@
     assert(ID);
     if (ObjCImplementationDecl *IMP = ID->getImplementation())
       // We are implementing a weak imported interface. Give it external linkage
-      if (ID->isWeakImported() && !IMP->isWeakImported()) {
+      if (ID->isWeakImported(CGM.getContext()) &&
+          !IMP->isWeakImported(CGM.getContext())) {
         DefinedClasses[i]->setLinkage(llvm::GlobalVariable::ExternalLinkage);
         DefinedMetaClasses[i]->setLinkage(llvm::GlobalVariable::ExternalLinkage);
       }
@@ -7173,11 +7176,10 @@
   auto prefix =
     (metaclass ? getMetaclassSymbolPrefix() : getClassSymbolPrefix());
   return GetClassGlobal((prefix + ID->getObjCRuntimeNameAsString()).str(),
-                        isForDefinition,
-                        ID->isWeakImported(),
-                        !isForDefinition
-                          && CGM.getTriple().isOSBinFormatCOFF()
-                          && ID->hasAttr<DLLImportAttr>());
+                        isForDefinition, ID->isWeakImported(CGM.getContext()),
+                        !isForDefinition &&
+                            CGM.getTriple().isOSBinFormatCOFF() &&
+                            ID->hasAttr<DLLImportAttr>());
 }
 
 llvm::Constant *
@@ -7299,7 +7301,7 @@
 /// decl.
 llvm::Value *CGObjCNonFragileABIMac::GetClass(CodeGenFunction &CGF,
                                               const ObjCInterfaceDecl *ID) {
-  if (ID->isWeakImported()) {
+  if (ID->isWeakImported(CGM.getContext())) {
     auto ClassGV = GetClassGlobal(ID, /*metaclass*/ false, NotForDefinition);
     (void)ClassGV;
     assert(!isa<llvm::GlobalVariable>(ClassGV) ||
@@ -7339,7 +7341,8 @@
   // If this is a class message the metaclass is passed as the target.
   llvm::Value *Target;
   if (IsClassMessage)
-      Target = EmitMetaClassRef(CGF, Class, Class->isWeakImported());
+    Target =
+        EmitMetaClassRef(CGF, Class, Class->isWeakImported(CGM.getContext()));
   else
     Target = EmitSuperClassRef(CGF, Class);
 
Index: lib/CodeGen/CGObjCGNU.cpp
===================================================================
--- lib/CodeGen/CGObjCGNU.cpp
+++ lib/CodeGen/CGObjCGNU.cpp
@@ -2173,8 +2173,8 @@
 // techniques can modify the name -> class mapping.
 llvm::Value *CGObjCGNU::GetClass(CodeGenFunction &CGF,
                                  const ObjCInterfaceDecl *OID) {
-  auto *Value =
-      GetClassNamed(CGF, OID->getNameAsString(), OID->isWeakImported());
+  auto *Value = GetClassNamed(CGF, OID->getNameAsString(),
+                              OID->isWeakImported(CGF.getContext()));
   if (auto *ClassSymbol = dyn_cast<llvm::GlobalVariable>(Value))
     CGM.setGVProperties(ClassSymbol, OID);
   return Value;
Index: lib/CodeGen/CGExprAgg.cpp
===================================================================
--- lib/CodeGen/CGExprAgg.cpp
+++ lib/CodeGen/CGExprAgg.cpp
@@ -991,7 +991,7 @@
     return Builder.CreateAnd(Cmp, CmpImag, "and.eq");
   };
   auto EmitCmpRes = [&](const ComparisonCategoryInfo::ValueInfo *VInfo) {
-    return Builder.getInt(VInfo->getIntValue());
+    return Builder.getInt(VInfo->getIntValue(CGF.getContext()));
   };
 
   Value *Select;
Index: lib/CodeGen/CGExpr.cpp
===================================================================
--- lib/CodeGen/CGExpr.cpp
+++ lib/CodeGen/CGExpr.cpp
@@ -2452,7 +2452,7 @@
     const auto *BD = dyn_cast_or_null<BlockDecl>(CurCodeDecl);
     if (Init && !isa<ParmVarDecl>(VD) && VD->getType()->isReferenceType() &&
         VD->isUsableInConstantExpressions(getContext()) &&
-        VD->checkInitIsICE() &&
+        VD->checkInitIsICE(getContext()) &&
         // Do not emit if it is private OpenMP variable.
         !(E->refersToEnclosingVariableOrCapture() &&
           ((CapturedStmtInfo &&
Index: lib/AST/ExprConstant.cpp
===================================================================
--- lib/AST/ExprConstant.cpp
+++ lib/AST/ExprConstant.cpp
@@ -1757,9 +1757,9 @@
   return E && !isa<MaterializeTemporaryExpr>(E);
 }
 
-static bool IsWeakLValue(const LValue &Value) {
+static bool IsWeakLValue(const ASTContext &Context, const LValue &Value) {
   const ValueDecl *Decl = GetLValueBaseDecl(Value);
-  return Decl && Decl->isWeak();
+  return Decl && Decl->isWeak(Context);
 }
 
 static bool isZeroSized(const LValue &Value) {
@@ -2005,7 +2005,8 @@
   return true;
 }
 
-static bool EvalPointerValueAsBool(const APValue &Value, bool &Result) {
+static bool EvalPointerValueAsBool(const ASTContext &Context,
+                                   const APValue &Value, bool &Result) {
   // A null base expression indicates a null pointer.  These are always
   // evaluatable, and they are false unless the offset is zero.
   if (!Value.getLValueBase()) {
@@ -2017,10 +2018,11 @@
   // a weak declaration it can be null at runtime.
   Result = true;
   const ValueDecl *Decl = Value.getLValueBase().dyn_cast<const ValueDecl*>();
-  return !Decl || !Decl->isWeak();
+  return !Decl || !Decl->isWeak(Context);
 }
 
-static bool HandleConversionToBool(const APValue &Val, bool &Result) {
+static bool HandleConversionToBool(const ASTContext &Context,
+                                   const APValue &Val, bool &Result) {
   switch (Val.getKind()) {
   case APValue::Uninitialized:
     return false;
@@ -2039,7 +2041,7 @@
              !Val.getComplexFloatImag().isZero();
     return true;
   case APValue::LValue:
-    return EvalPointerValueAsBool(Val, Result);
+    return EvalPointerValueAsBool(Context, Val, Result);
   case APValue::MemberPointer:
     Result = Val.getMemberPointerDecl();
     return true;
@@ -2060,7 +2062,7 @@
   APValue Val;
   if (!Evaluate(Val, Info, E))
     return false;
-  return HandleConversionToBool(Val, Result);
+  return HandleConversionToBool(Info.Ctx, Val, Result);
 }
 
 template<typename T>
@@ -2595,7 +2597,7 @@
 
   // Never evaluate the initializer of a weak variable. We can't be sure that
   // this is the definition which will be used.
-  if (VD->isWeak()) {
+  if (VD->isWeak(Info.Ctx)) {
     Info.FFDiag(E, diag::note_invalid_subexpr_in_const_expr);
     return false;
   }
@@ -2609,7 +2611,7 @@
     Info.Note(VD->getLocation(), diag::note_declared_at);
     Info.addNotes(Notes);
     return false;
-  } else if (!VD->checkInitIsICE()) {
+  } else if (!VD->checkInitIsICE(Info.Ctx)) {
     Info.CCEDiag(E, diag::note_constexpr_var_init_non_constant,
                  Notes.size() + 1) << VD;
     Info.Note(VD->getLocation(), diag::note_declared_at);
@@ -8862,7 +8864,8 @@
 
   if (E->isLogicalOp()) {
     bool LHSAsBool;
-    if (!LHSResult.Failed && HandleConversionToBool(LHSResult.Val, LHSAsBool)) {
+    if (!LHSResult.Failed &&
+        HandleConversionToBool(Info.Ctx, LHSResult.Val, LHSAsBool)) {
       // We were able to evaluate the LHS, see if we can get away with not
       // evaluating the RHS: 0 && X -> 0, 1 || X -> 1
       if (LHSAsBool == (E->getOpcode() == BO_LOr)) {
@@ -8920,8 +8923,9 @@
 
   if (E->isLogicalOp()) {
     bool lhsResult, rhsResult;
-    bool LHSIsOK = HandleConversionToBool(LHSResult.Val, lhsResult);
-    bool RHSIsOK = HandleConversionToBool(RHSResult.Val, rhsResult);
+    const ASTContext &Context = Info.Ctx;
+    bool LHSIsOK = HandleConversionToBool(Context, LHSResult.Val, lhsResult);
+    bool RHSIsOK = HandleConversionToBool(Context, RHSResult.Val, rhsResult);
 
     if (LHSIsOK) {
       if (RHSIsOK) {
@@ -9212,7 +9216,7 @@
         return Error(E);
       // We can't tell whether weak symbols will end up pointing to the same
       // object.
-      if (IsWeakLValue(LHSValue) || IsWeakLValue(RHSValue))
+      if (IsWeakLValue(Info.Ctx, LHSValue) || IsWeakLValue(Info.Ctx, RHSValue))
         return Error(E);
       // We can't compare the address of the start of one object with the
       // past-the-end address of another object, per C++ DR1652.
@@ -10932,7 +10936,7 @@
                                       const ASTContext &Ctx) const {
   EvalResult Scratch;
   return EvaluateAsRValue(Scratch, Ctx) &&
-         HandleConversionToBool(Scratch.Val, Result);
+         HandleConversionToBool(Ctx, Scratch.Val, Result);
 }
 
 bool Expr::EvaluateAsInt(EvalResult &Result, const ASTContext &Ctx,
@@ -11288,7 +11292,7 @@
         const VarDecl *VD;
         // Look for a declaration of this variable that has an initializer, and
         // check whether it is an ICE.
-        if (Dcl->getAnyInitializer(VD) && VD->checkInitIsICE())
+        if (Dcl->getAnyInitializer(VD) && VD->checkInitIsICE(Ctx))
           return NoDiag();
         else
           return ICEDiag(IK_NotICE, cast<DeclRefExpr>(E)->getLocation());
Index: lib/AST/DeclTemplate.cpp
===================================================================
--- lib/AST/DeclTemplate.cpp
+++ lib/AST/DeclTemplate.cpp
@@ -941,10 +941,10 @@
 // VarTemplateDecl Implementation
 //===----------------------------------------------------------------------===//
 
-VarTemplateDecl *VarTemplateDecl::getDefinition() {
+VarTemplateDecl *VarTemplateDecl::getDefinition(const ASTContext &Context) {
   VarTemplateDecl *CurD = this;
   while (CurD) {
-    if (CurD->isThisDeclarationADefinition())
+    if (CurD->isThisDeclarationADefinition(Context))
       return CurD;
     CurD = CurD->getPreviousDecl();
   }
Index: lib/AST/DeclBase.cpp
===================================================================
--- lib/AST/DeclBase.cpp
+++ lib/AST/DeclBase.cpp
@@ -508,7 +508,7 @@
 ///
 /// FIXME: Make these strings localizable, since they end up in
 /// diagnostics.
-static AvailabilityResult CheckAvailability(ASTContext &Context,
+static AvailabilityResult CheckAvailability(const ASTContext &Context,
                                             const AvailabilityAttr *A,
                                             std::string *Message,
                                             VersionTuple EnclosingVersion) {
@@ -658,12 +658,13 @@
   return {};
 }
 
-bool Decl::canBeWeakImported(bool &IsDefinition) const {
+bool Decl::canBeWeakImported(const ASTContext &Context,
+                             bool &IsDefinition) const {
   IsDefinition = false;
 
   // Variables, if they aren't definitions.
   if (const auto *Var = dyn_cast<VarDecl>(this)) {
-    if (Var->isThisDeclarationADefinition()) {
+    if (Var->isThisDeclarationADefinition(Context)) {
       IsDefinition = true;
       return false;
     }
@@ -679,7 +680,7 @@
 
   // Objective-C classes, if this is the non-fragile runtime.
   } else if (isa<ObjCInterfaceDecl>(this) &&
-             getASTContext().getLangOpts().ObjCRuntime.hasWeakClassImport()) {
+             Context.getLangOpts().ObjCRuntime.hasWeakClassImport()) {
     return true;
 
   // Nothing else.
@@ -688,9 +689,9 @@
   }
 }
 
-bool Decl::isWeakImported() const {
+bool Decl::isWeakImported(const ASTContext &Context) const {
   bool IsDefinition;
-  if (!canBeWeakImported(IsDefinition))
+  if (!canBeWeakImported(Context, IsDefinition))
     return false;
 
   for (const auto *A : attrs()) {
@@ -698,8 +699,8 @@
       return true;
 
     if (const auto *Availability = dyn_cast<AvailabilityAttr>(A)) {
-      if (CheckAvailability(getASTContext(), Availability, nullptr,
-                            VersionTuple()) == AR_NotYetIntroduced)
+      if (CheckAvailability(Context, Availability, nullptr, VersionTuple()) ==
+          AR_NotYetIntroduced)
         return true;
     }
   }
Index: lib/AST/Decl.cpp
===================================================================
--- lib/AST/Decl.cpp
+++ lib/AST/Decl.cpp
@@ -2026,7 +2026,7 @@
 VarDecl *VarDecl::getCanonicalDecl() { return getFirstDecl(); }
 
 VarDecl::DefinitionKind
-VarDecl::isThisDeclarationADefinition(ASTContext &C) const {
+VarDecl::isThisDeclarationADefinition(const ASTContext &Context) const {
   if (isThisDeclarationADemotedDefinition())
     return DeclarationOnly;
 
@@ -2104,7 +2104,7 @@
   //   and without a storage class specifier or the scs 'static', constitutes
   //   a tentative definition.
   // No such thing in C++.
-  if (!C.getLangOpts().CPlusPlus && isFileVarDecl())
+  if (!Context.getLangOpts().CPlusPlus && isFileVarDecl())
     return TentativeDefinition;
 
   // What's left is (in C, block-scope) declarations without initializers or
@@ -2112,15 +2112,15 @@
   return Definition;
 }
 
-VarDecl *VarDecl::getActingDefinition() {
-  DefinitionKind Kind = isThisDeclarationADefinition();
+VarDecl *VarDecl::getActingDefinition(const ASTContext &Context) {
+  DefinitionKind Kind = isThisDeclarationADefinition(Context);
   if (Kind != TentativeDefinition)
     return nullptr;
 
   VarDecl *LastTentative = nullptr;
   VarDecl *First = getFirstDecl();
   for (auto I : First->redecls()) {
-    Kind = I->isThisDeclarationADefinition();
+    Kind = I->isThisDeclarationADefinition(Context);
     if (Kind == Definition)
       return nullptr;
     else if (Kind == TentativeDefinition)
@@ -2129,21 +2129,22 @@
   return LastTentative;
 }
 
-VarDecl *VarDecl::getDefinition(ASTContext &C) {
+VarDecl *VarDecl::getDefinition(const ASTContext &Context) {
   VarDecl *First = getFirstDecl();
   for (auto I : First->redecls()) {
-    if (I->isThisDeclarationADefinition(C) == Definition)
+    if (I->isThisDeclarationADefinition(Context) == Definition)
       return I;
   }
   return nullptr;
 }
 
-VarDecl::DefinitionKind VarDecl::hasDefinition(ASTContext &C) const {
+VarDecl::DefinitionKind
+VarDecl::hasDefinition(const ASTContext &Context) const {
   DefinitionKind Kind = DeclarationOnly;
 
   const VarDecl *First = getFirstDecl();
   for (auto I : First->redecls()) {
-    Kind = std::max(Kind, I->isThisDeclarationADefinition(C));
+    Kind = std::max(Kind, I->isThisDeclarationADefinition(Context));
     if (Kind == Definition)
       break;
   }
@@ -2327,9 +2328,9 @@
   return Init.get<EvaluatedStmt *>()->IsICE;
 }
 
-bool VarDecl::checkInitIsICE() const {
+bool VarDecl::checkInitIsICE(const ASTContext &Context) const {
   // Initializers of weak variables are never ICEs.
-  if (isWeak())
+  if (isWeak(Context))
     return false;
 
   EvaluatedStmt *Eval = ensureEvaluatedStmt();
@@ -2343,7 +2344,7 @@
 
   // In C++11, evaluate the initializer to check whether it's a constant
   // expression.
-  if (getASTContext().getLangOpts().CPlusPlus11) {
+  if (Context.getLangOpts().CPlusPlus11) {
     SmallVector<PartialDiagnosticAt, 8> Notes;
     evaluateValue(Notes);
     return Eval->IsICE;
@@ -2357,7 +2358,7 @@
     return false;
   Eval->CheckingICE = true;
 
-  Eval->IsICE = Init->isIntegerConstantExpr(getASTContext());
+  Eval->IsICE = Init->isIntegerConstantExpr(Context);
   Eval->CheckingICE = false;
   Eval->CheckedICE = true;
   return Eval->IsICE;
@@ -2366,7 +2367,15 @@
 template<typename DeclT>
 static DeclT *getDefinitionOrSelf(DeclT *D) {
   assert(D);
-  if (auto *Def = D->getDefinition())
+  if (DeclT *Def = D->getDefinition())
+    return Def;
+  return D;
+}
+
+template <typename DeclT>
+static DeclT *getDefinitionOrSelf(const ASTContext &Context, DeclT *D) {
+  assert(D);
+  if (DeclT *Def = D->getDefinition(Context))
     return Def;
   return D;
 }
@@ -2379,7 +2388,8 @@
   return hasAttr<BlocksAttr>() && !NonParmVarDeclBits.EscapingByref;
 }
 
-VarDecl *VarDecl::getTemplateInstantiationPattern() const {
+VarDecl *
+VarDecl::getTemplateInstantiationPattern(const ASTContext &Context) const {
   // If it's a variable template specialization, find the template or partial
   // specialization from which it was instantiated.
   if (auto *VDTemplSpec = dyn_cast<VarTemplateSpecializationDecl>(this)) {
@@ -2390,7 +2400,7 @@
           break;
         VTD = NewVTD;
       }
-      return getDefinitionOrSelf(VTD->getTemplatedDecl());
+      return getDefinitionOrSelf(Context, VTD->getTemplatedDecl());
     }
     if (auto *VTPSD =
             From.dyn_cast<VarTemplatePartialSpecializationDecl *>()) {
@@ -2399,7 +2409,7 @@
           break;
         VTPSD = NewVTPSD;
       }
-      return getDefinitionOrSelf<VarDecl>(VTPSD);
+      return getDefinitionOrSelf<VarDecl>(Context, VTPSD);
     }
   }
 
@@ -2408,7 +2418,7 @@
       VarDecl *VD = getInstantiatedFromStaticDataMember();
       while (auto *NewVD = VD->getInstantiatedFromStaticDataMember())
         VD = NewVD;
-      return getDefinitionOrSelf(VD);
+      return getDefinitionOrSelf(Context, VD);
     }
   }
 
@@ -2419,7 +2429,7 @@
       VarTemplate = VarTemplate->getInstantiatedFromMemberTemplate();
     }
 
-    return getDefinitionOrSelf(VarTemplate->getTemplatedDecl());
+    return getDefinitionOrSelf(Context, VarTemplate->getTemplatedDecl());
   }
   return nullptr;
 }
@@ -2460,8 +2470,8 @@
   getASTContext().setTemplateOrSpecializationInfo(this, Template);
 }
 
-bool VarDecl::isKnownToBeDefined() const {
-  const auto &LangOpts = getASTContext().getLangOpts();
+bool VarDecl::isKnownToBeDefined(const ASTContext &Context) const {
+  const auto &LangOpts = Context.getLangOpts();
   // In CUDA mode without relocatable device code, variables of form 'extern
   // __shared__ Foo foo[]' are pointers to the base of the GPU core's shared
   // memory pool.  These are never undefined variables, even if they appear
@@ -2474,7 +2484,7 @@
       isa<IncompleteArrayType>(getType()))
     return true;
 
-  return hasDefinition();
+  return hasDefinition(Context);
 }
 
 bool VarDecl::isNoDestroy(const ASTContext &Ctx) const {
@@ -4405,12 +4415,12 @@
 
 void ValueDecl::anchor() {}
 
-bool ValueDecl::isWeak() const {
+bool ValueDecl::isWeak(const ASTContext &Context) const {
   for (const auto *I : attrs())
     if (isa<WeakAttr>(I) || isa<WeakRefAttr>(I))
       return true;
 
-  return isWeakImported();
+  return isWeakImported(Context);
 }
 
 void ImplicitParamDecl::anchor() {}
Index: lib/AST/ComparisonCategories.cpp
===================================================================
--- lib/AST/ComparisonCategories.cpp
+++ lib/AST/ComparisonCategories.cpp
@@ -20,9 +20,10 @@
 
 using namespace clang;
 
-bool ComparisonCategoryInfo::ValueInfo::hasValidIntValue() const {
+bool ComparisonCategoryInfo::ValueInfo::hasValidIntValue(
+    const ASTContext &Context) const {
   assert(VD && "must have var decl");
-  if (!VD->checkInitIsICE())
+  if (!VD->checkInitIsICE(Context))
     return false;
 
   // Before we attempt to get the value of the first field, ensure that we
@@ -43,8 +44,9 @@
 /// Note: The STL types are expected to have the form:
 ///    struct X { T value; };
 /// where T is an integral or enumeration type.
-llvm::APSInt ComparisonCategoryInfo::ValueInfo::getIntValue() const {
-  assert(hasValidIntValue() && "must have a valid value");
+llvm::APSInt ComparisonCategoryInfo::ValueInfo::getIntValue(
+    const ASTContext &Context) const {
+  assert(hasValidIntValue(Context) && "must have a valid value");
   return VD->evaluateValue()->getStructField(0).getInt();
 }
 
Index: lib/AST/ASTImporter.cpp
===================================================================
--- lib/AST/ASTImporter.cpp
+++ lib/AST/ASTImporter.cpp
@@ -3639,8 +3639,9 @@
 
             // The VarDecl in the "From" context has a definition, but in the
             // "To" context we already have a definition.
-            VarDecl *FoundDef = FoundVar->getDefinition();
-            if (D->isThisDeclarationADefinition() && FoundDef)
+            VarDecl *FoundDef =
+                FoundVar->getDefinition(FoundVar->getASTContext());
+            if (D->isThisDeclarationADefinition(D->getASTContext()) && FoundDef)
               // FIXME Check for ODR error if the two definitions have
               // different initializers?
               return Importer.MapImported(D, FoundDef);
@@ -5291,8 +5292,8 @@
   // from,
   // but this particular declaration is not that definition, import the
   // definition and map to that.
-  auto *Definition =
-      cast_or_null<VarDecl>(D->getTemplatedDecl()->getDefinition());
+  auto *Definition = cast_or_null<VarDecl>(
+      D->getTemplatedDecl()->getDefinition(D->getASTContext()));
   if (Definition && Definition != D->getTemplatedDecl()) {
     if (ExpectedDecl ImportedDefOrErr = import(
         Definition->getDescribedVarTemplate()))
@@ -5375,8 +5376,9 @@
   ToVarTD->setLexicalDeclContext(LexicalDC);
   LexicalDC->addDeclInternal(ToVarTD);
 
-  if (DTemplated->isThisDeclarationADefinition() &&
-      !ToTemplated->isThisDeclarationADefinition()) {
+  if (DTemplated->isThisDeclarationADefinition(DTemplated->getASTContext()) &&
+      !ToTemplated->isThisDeclarationADefinition(
+          ToTemplated->getASTContext())) {
     // FIXME: Import definition!
   }
 
@@ -5388,7 +5390,7 @@
   // If this record has a definition in the translation unit we're coming from,
   // but this particular declaration is not that definition, import the
   // definition and map to that.
-  VarDecl *Definition = D->getDefinition();
+  VarDecl *Definition = D->getDefinition(D->getASTContext());
   if (Definition && Definition != D) {
     if (ExpectedDecl ImportedDefOrErr = import(Definition))
       return Importer.MapImported(D, *ImportedDefOrErr);
@@ -5430,8 +5432,8 @@
 
     // FIXME: Check for specialization vs. instantiation errors.
 
-    if (VarDecl *FoundDef = D2->getDefinition()) {
-      if (!D->isThisDeclarationADefinition() ||
+    if (VarDecl *FoundDef = D2->getDefinition(D2->getASTContext())) {
+      if (!D->isThisDeclarationADefinition(D->getASTContext()) ||
           IsStructuralMatch(D, FoundDef)) {
         // The record types structurally match, or the "from" translation
         // unit only had a forward declaration anyway; call it the same
Index: lib/AST/ASTContext.cpp
===================================================================
--- lib/AST/ASTContext.cpp
+++ lib/AST/ASTContext.cpp
@@ -9878,7 +9878,7 @@
       OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD))
     return true;
 
-  if (VD->isThisDeclarationADefinition() == VarDecl::DeclarationOnly &&
+  if (VD->isThisDeclarationADefinition(*this) == VarDecl::DeclarationOnly &&
       !isMSStaticDataMemberInlineDefinition(VD))
     return false;
 
Index: include/clang/Sema/SemaInternal.h
===================================================================
--- include/clang/Sema/SemaInternal.h
+++ include/clang/Sema/SemaInternal.h
@@ -44,8 +44,8 @@
 inline bool IsVariableAConstantExpression(VarDecl *Var, ASTContext &Context) {
   const VarDecl *DefVD = nullptr;
   return !isa<ParmVarDecl>(Var) &&
-    Var->isUsableInConstantExpressions(Context) &&
-    Var->getAnyInitializer(DefVD) && DefVD->checkInitIsICE();
+         Var->isUsableInConstantExpressions(Context) &&
+         Var->getAnyInitializer(DefVD) && DefVD->checkInitIsICE(Context);
 }
 
 // Helper function to check whether D's attributes match current CUDA mode.
Index: include/clang/ASTMatchers/ASTMatchersInternal.h
===================================================================
--- include/clang/ASTMatchers/ASTMatchersInternal.h
+++ include/clang/ASTMatchers/ASTMatchersInternal.h
@@ -1815,6 +1815,18 @@
   return Node.getSubStmt();
 }
 
+template <typename Ty> struct IsDefinitionMatcher {
+  static bool get(const ASTContext &, const Ty &Node) {
+    return Node.isThisDeclarationADefinition();
+  }
+};
+
+template <>
+inline bool IsDefinitionMatcher<VarDecl>::get(const ASTContext &Context,
+                                              const VarDecl &Node) {
+  return Node.isThisDeclarationADefinition(Context);
+}
+
 } // namespace internal
 
 } // namespace ast_matchers
Index: include/clang/ASTMatchers/ASTMatchers.h
===================================================================
--- include/clang/ASTMatchers/ASTMatchers.h
+++ include/clang/ASTMatchers/ASTMatchers.h
@@ -4501,7 +4501,7 @@
                         AST_POLYMORPHIC_SUPPORTED_TYPES(TagDecl, VarDecl,
                                                         ObjCMethodDecl,
                                                         FunctionDecl)) {
-  return Node.isThisDeclarationADefinition();
+  return IsDefinitionMatcher<NodeType>::get(Finder->getASTContext(), Node);
 }
 
 /// Matches if a function declaration is variadic.
Index: include/clang/AST/DeclTemplate.h
===================================================================
--- include/clang/AST/DeclTemplate.h
+++ include/clang/AST/DeclTemplate.h
@@ -2909,11 +2909,11 @@
 
   /// Returns whether this template declaration defines the primary
   /// variable pattern.
-  bool isThisDeclarationADefinition() const {
-    return getTemplatedDecl()->isThisDeclarationADefinition();
+  bool isThisDeclarationADefinition(const ASTContext &Context) const {
+    return getTemplatedDecl()->isThisDeclarationADefinition(Context);
   }
 
-  VarTemplateDecl *getDefinition();
+  VarTemplateDecl *getDefinition(const ASTContext &Context);
 
   /// Create a variable template node.
   static VarTemplateDecl *Create(ASTContext &C, DeclContext *DC,
Index: include/clang/AST/DeclBase.h
===================================================================
--- include/clang/AST/DeclBase.h
+++ include/clang/AST/DeclBase.h
@@ -680,7 +680,7 @@
   /// 'weak_import' attribute, but may also be marked with an
   /// 'availability' attribute where we're targing a platform prior to
   /// the introduction of this feature.
-  bool isWeakImported() const;
+  bool isWeakImported(const ASTContext &Context) const;
 
   /// Determines whether this symbol can be weak-imported,
   /// e.g., whether it would be well-formed to add the weak_import
@@ -688,7 +688,7 @@
   ///
   /// \param IsDefinition Set to \c true to indicate that this
   /// declaration cannot be weak-imported because it has a definition.
-  bool canBeWeakImported(bool &IsDefinition) const;
+  bool canBeWeakImported(const ASTContext &Context, bool &IsDefinition) const;
 
   /// Determine whether this declaration came from an AST file (such as
   /// a precompiled header or module) rather than having been parsed.
Index: include/clang/AST/Decl.h
===================================================================
--- include/clang/AST/Decl.h
+++ include/clang/AST/Decl.h
@@ -649,7 +649,7 @@
 
   /// Determine whether this symbol is weakly-imported,
   ///        or declared with the weak or weak-ref attr.
-  bool isWeak() const;
+  bool isWeak(const ASTContext &Context) const;
 
   // Implement isa/cast/dyncast/etc.
   static bool classof(const Decl *D) { return classofKind(D->getKind()); }
@@ -1155,34 +1155,22 @@
   /// Check whether this declaration is a definition. If this could be
   /// a tentative definition (in C), don't check whether there's an overriding
   /// definition.
-  DefinitionKind isThisDeclarationADefinition(ASTContext &) const;
-  DefinitionKind isThisDeclarationADefinition() const {
-    return isThisDeclarationADefinition(getASTContext());
-  }
+  DefinitionKind isThisDeclarationADefinition(const ASTContext &Context) const;
 
   /// Check whether this variable is defined in this translation unit.
-  DefinitionKind hasDefinition(ASTContext &) const;
-  DefinitionKind hasDefinition() const {
-    return hasDefinition(getASTContext());
-  }
+  DefinitionKind hasDefinition(const ASTContext &Context) const;
 
   /// Get the tentative definition that acts as the real definition in a TU.
   /// Returns null if there is a proper definition available.
-  VarDecl *getActingDefinition();
-  const VarDecl *getActingDefinition() const {
-    return const_cast<VarDecl*>(this)->getActingDefinition();
+  VarDecl *getActingDefinition(const ASTContext &Context);
+  const VarDecl *getActingDefinition(const ASTContext &Context) const {
+    return const_cast<VarDecl *>(this)->getActingDefinition(Context);
   }
 
   /// Get the real (not just tentative) definition for this declaration.
-  VarDecl *getDefinition(ASTContext &);
-  const VarDecl *getDefinition(ASTContext &C) const {
-    return const_cast<VarDecl*>(this)->getDefinition(C);
-  }
-  VarDecl *getDefinition() {
-    return getDefinition(getASTContext());
-  }
-  const VarDecl *getDefinition() const {
-    return const_cast<VarDecl*>(this)->getDefinition();
+  VarDecl *getDefinition(const ASTContext &Context);
+  const VarDecl *getDefinition(const ASTContext &Context) const {
+    return const_cast<VarDecl *>(this)->getDefinition(Context);
   }
 
   /// Determine whether this is or was instantiated from an out-of-line
@@ -1259,7 +1247,7 @@
 
   /// Determine whether the value of the initializer attached to this
   /// declaration is an integral constant expression.
-  bool checkInitIsICE() const;
+  bool checkInitIsICE(const ASTContext &Context) const;
 
   void setInitStyle(InitializationStyle Style) {
     VarDeclBits.InitStyle = Style;
@@ -1296,7 +1284,8 @@
   /// definitions one of which needs to be demoted to a declaration to keep
   /// the AST invariants.
   void demoteThisDefinitionToDeclaration() {
-    assert(isThisDeclarationADefinition() && "Not a definition!");
+    assert(isThisDeclarationADefinition(getASTContext()) &&
+           "Not a definition!");
     assert(!isa<ParmVarDecl>(this) && "Cannot demote ParmVarDecls!");
     NonParmVarDeclBits.IsThisDeclarationADemotedDefinition = 1;
   }
@@ -1424,7 +1413,7 @@
 
   /// Retrieve the variable declaration from which this variable could
   /// be instantiated, if it is an instantiation (rather than a non-template).
-  VarDecl *getTemplateInstantiationPattern() const;
+  VarDecl *getTemplateInstantiationPattern(const ASTContext &Context) const;
 
   /// If this variable is an instantiated static data member of a
   /// class template specialization, returns the templated static data member
@@ -1474,7 +1463,7 @@
   // Is this variable known to have a definition somewhere in the complete
   // program? This may be true even if the declaration has internal linkage and
   // has no definition within this source file.
-  bool isKnownToBeDefined() const;
+  bool isKnownToBeDefined(const ASTContext &Context) const;
 
   /// Do we need to emit an exit-time destructor for this variable?
   bool isNoDestroy(const ASTContext &) const;
Index: include/clang/AST/ComparisonCategories.h
===================================================================
--- include/clang/AST/ComparisonCategories.h
+++ include/clang/AST/ComparisonCategories.h
@@ -83,11 +83,11 @@
 
     /// True iff we've successfully evaluated the variable as a constant
     /// expression and extracted its integer value.
-    bool hasValidIntValue() const;
+    bool hasValidIntValue(const ASTContext &Context) const;
 
     /// Get the constant integer value used by this variable to represent
     /// the comparison category result type.
-    llvm::APSInt getIntValue() const;
+    llvm::APSInt getIntValue(const ASTContext &Context) const;
   };
 private:
   const ASTContext &Ctx;
@@ -121,7 +121,7 @@
     ValueInfo *Info = lookupValueInfo(ValueKind);
     assert(Info &&
            "comparison category does not contain the specified result kind");
-    assert(Info->hasValidIntValue() &&
+    assert(Info->hasValidIntValue(Ctx) &&
            "couldn't determine the integer constant for this value");
     return Info;
   }
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to