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; } 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(this)->getActingDefinition(); + VarDecl *getActingDefinition(const ASTContext &Context); + const VarDecl *getActingDefinition(const ASTContext &Context) const { + return const_cast(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(this)->getDefinition(C); - } - VarDecl *getDefinition() { - return getDefinition(getASTContext()); - } - const VarDecl *getDefinition() const { - return const_cast(this)->getDefinition(); + VarDecl *getDefinition(const ASTContext &Context); + const VarDecl *getDefinition(const ASTContext &Context) const { + return const_cast(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(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/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/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/ASTMatchers/ASTMatchers.h =================================================================== --- include/clang/ASTMatchers/ASTMatchers.h +++ include/clang/ASTMatchers/ASTMatchers.h @@ -4501,7 +4501,15 @@ AST_POLYMORPHIC_SUPPORTED_TYPES(TagDecl, VarDecl, ObjCMethodDecl, FunctionDecl)) { - return Node.isThisDeclarationADefinition(); + if (auto *TD = dyn_cast(&Node)) + return TD->isThisDeclarationADefinition(); + if (auto *VD = dyn_cast(&Node)) + return VD->isThisDeclarationADefinition(Finder->getASTContext()); + if (auto *ObjCMD = dyn_cast(&Node)) + return ObjCMD->isThisDeclarationADefinition(); + if (auto *FD = dyn_cast(&Node)) + return FD->isThisDeclarationADefinition(); + llvm_unreachable("unexpected node kind in isDefinition matcher!"); } /// Matches if a function declaration is variadic. 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(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: 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: 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(D->getTemplatedDecl()->getDefinition()); + auto *Definition = cast_or_null( + 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/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/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()->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 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; @@ -2371,6 +2372,14 @@ return D; } +template +static DeclT *getDefinitionOrSelf(const ASTContext &Context, DeclT *D) { + assert(D); + if (auto *Def = D->getDefinition(Context)) + return Def; + return D; +} + bool VarDecl::isEscapingByref() const { return hasAttr() && NonParmVarDeclBits.EscapingByref; } @@ -2379,7 +2388,8 @@ return hasAttr() && !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(this)) { @@ -2390,7 +2400,7 @@ break; VTD = NewVTD; } - return getDefinitionOrSelf(VTD->getTemplatedDecl()); + return getDefinitionOrSelf(Context, VTD->getTemplatedDecl()); } if (auto *VTPSD = From.dyn_cast()) { @@ -2399,7 +2409,7 @@ break; VTPSD = NewVTPSD; } - return getDefinitionOrSelf(VTPSD); + return getDefinitionOrSelf(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(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(I) || isa(I)) return true; - return isWeakImported(); + return isWeakImported(Context); } void ImplicitParamDecl::anchor() {} 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(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(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(A)) { - if (CheckAvailability(getASTContext(), Availability, nullptr, - VersionTuple()) == AR_NotYetIntroduced) + if (CheckAvailability(Context, Availability, nullptr, VersionTuple()) == + AR_NotYetIntroduced) return true; } } 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/ExprConstant.cpp =================================================================== --- lib/AST/ExprConstant.cpp +++ lib/AST/ExprConstant.cpp @@ -1757,9 +1757,9 @@ return E && !isa(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(); - 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 @@ -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(E)->getLocation()); Index: lib/CodeGen/CGExpr.cpp =================================================================== --- lib/CodeGen/CGExpr.cpp +++ lib/CodeGen/CGExpr.cpp @@ -2452,7 +2452,7 @@ const auto *BD = dyn_cast_or_null(CurCodeDecl); if (Init && !isa(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/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/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(Value)) CGM.setGVProperties(ClassSymbol, OID); return Value; 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()); + isForDefinition, ID->isWeakImported(CGM.getContext()), + !isForDefinition && + CGM.getTriple().isOSBinFormatCOFF() && + ID->hasAttr()); } 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(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/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() || ND->isWeakImported())) + (ND->hasAttr() || 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()) @@ -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() || - VD->hasAttr()); + bool MustEmitForCuda = + LangOpts.CUDA && !LangOpts.CUDAIsDevice && + !VD->hasDefinition(Context) && + (VD->hasAttr() || VD->hasAttr()); 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(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()) { + !D->hasDefinition(Context) && D->hasInit() && + !D->hasAttr()) { 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()) 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()) 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() || D->hasAttr() || - D->isWeakImported()) { + D->isWeakImported(getContext())) { GA->setLinkage(llvm::Function::WeakAnyLinkage); } 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/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(D)) { return SD->getTemplateInstantiationPattern(); } else if (const FunctionDecl *FD = dyn_cast(D)) { return FD->getTemplateInstantiationPattern(); } else if (auto *VD = dyn_cast(D)) { - return VD->getTemplateInstantiationPattern(); + return VD->getTemplateInstantiationPattern(Context); } else if (const auto *RD = dyn_cast(D)) { return RD->getInstantiatedFromMemberClass(); } else if (const auto *ED = dyn_cast(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/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(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(*I)->getDefinition(); + const VarDecl *DiagD = cast(*I)->getDefinition(Context); if (!DiagD) DiagD = cast(*I); if (DiagD->isReferenced()) { 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/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(D)) - return VD->isThisDeclarationADefinition(); + return VD->isThisDeclarationADefinition(S.Context); if (TagDecl *TD = dyn_cast(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(D)) return TD->getDefinition(); if (const VarDecl *VD = dyn_cast(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(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(New); - unsigned Diag = cast(Def)->isThisDeclarationADefinition() == - VarDecl::TentativeDefinition + unsigned Diag = cast(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(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() && !Old->hasAttr()) { if (auto *VD = dyn_cast(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); } @@ -2843,6 +2844,23 @@ return std::make_pair(PrevDiag, OldLocation); } +template +static std::pair +getNoteDiagForInvalidRedeclaration(const ASTContext &Context, const T *Old, + const T *New) { + diag::kind PrevDiag; + SourceLocation OldLocation = Old->getLocation(); + if (Old->isThisDeclarationADefinition(Context)) + PrevDiag = diag::note_previous_definition; + else if (Old->isImplicit()) { + PrevDiag = diag::note_previous_implicit_declaration; + if (OldLocation.isInvalid()) + OldLocation = New->getLocation(); + } else + PrevDiag = diag::note_previous_declaration; + return std::make_pair(PrevDiag, OldLocation); +} + /// canRedefineFunction - checks if a function can be redefined. Currently, /// only extern inline functions can be redefined, and even then only in /// GNU89 mode. @@ -3017,7 +3035,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(); @@ -3634,15 +3652,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 +3889,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 +3956,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 +3968,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 +3993,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 +5962,7 @@ if (auto *VD = dyn_cast(&ND)) { if (VD->hasInit()) { if (const auto *Attr = VD->getAttr()) { - 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(); @@ -7490,7 +7509,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 +11071,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 +11477,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 +11506,7 @@ return; } - switch (Var->isThisDeclarationADefinition()) { + switch (Var->isThisDeclarationADefinition(Context)) { case VarDecl::Definition: if (!Var->isStaticDataMember() || !Var->getAnyInitializer()) break; @@ -11772,7 +11792,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 +11801,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 +11842,7 @@ // Apply section attributes and pragmas to global variables. bool GlobalStorage = var->hasGlobalStorage(); - if (GlobalStorage && var->isThisDeclarationADefinition() && + if (GlobalStorage && var->isThisDeclarationADefinition(Context) && !inTemplateInstantiation()) { PragmaStack *Stack = nullptr; int SectionFlags = ASTContext::PSF_Implicit | ASTContext::PSF_Read; @@ -11895,7 +11915,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 +11923,8 @@ if (!var->isConstexpr() && GlobalStorage && var->hasAttr()) { // 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(); Diag(var->getLocation(), diag::err_require_constant_init_failed) @@ -12013,7 +12033,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()) { if (PragmaClangBSSSection.Valid) VD->addAttr(PragmaClangBSSSectionAttr::CreateImplicit(Context, @@ -12094,7 +12114,7 @@ // Imported static data members cannot be defined out-of-line. if (const auto *IA = dyn_cast_or_null(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 +12150,7 @@ } if (UsedAttr *Attr = VD->getAttr()) { - if (!Attr->isInherited() && !VD->isThisDeclarationADefinition()) { + if (!Attr->isInherited() && !VD->isThisDeclarationADefinition(Context)) { Diag(Attr->getLocation(), diag::warn_attribute_ignored) << Attr; VD->dropAttr(); } Index: lib/Sema/SemaDeclAttr.cpp =================================================================== --- lib/Sema/SemaDeclAttr.cpp +++ lib/Sema/SemaDeclAttr.cpp @@ -1885,7 +1885,8 @@ } } else { const auto *VD = cast(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/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(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/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/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(Eval->Value); 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(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(D)) - return VD->getDefinition(); + return VD->getDefinition(Context); if (FunctionDecl *FD = dyn_cast(D)) return FD->getDefinition(); if (TagDecl *TD = dyn_cast(D)) @@ -5041,7 +5042,7 @@ if (ObjCProtocolDecl *PD = dyn_cast(D)) return PD->getDefinition(); if (TemplateDecl *TD = dyn_cast(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/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/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/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(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/SemaType.cpp =================================================================== --- lib/Sema/SemaType.cpp +++ lib/Sema/SemaType.cpp @@ -7491,11 +7491,11 @@ if (DeclRefExpr *DRE = dyn_cast(E->IgnoreParens())) { if (VarDecl *Var = dyn_cast(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(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/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(D)) return Var->isFileVarDecl() && - (Var->isThisDeclarationADefinition() == VarDecl::Definition || + (Var->isThisDeclarationADefinition(Ctx) == VarDecl::Definition || OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(Var)); if (const auto *Func = dyn_cast(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/StaticAnalyzer/Core/SimpleSValBuilder.cpp =================================================================== --- lib/StaticAnalyzer/Core/SimpleSValBuilder.cpp +++ lib/StaticAnalyzer/Core/SimpleSValBuilder.cpp @@ -152,7 +152,7 @@ const MemRegion *R = val.castAs().getRegion(); if (const FunctionCodeRegion *FTR = dyn_cast(R)) if (const FunctionDecl *FD = dyn_cast(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: 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(D)->getDefinition()) + if (const VarDecl *Def = + cast(D)->getDefinition(D->getASTContext())) return MakeCXCursor(Def, TU); return clang_getNullCursor(); } @@ -6312,7 +6313,8 @@ case Decl::VarTemplate: { if (VarDecl *Def = - cast(D)->getTemplatedDecl()->getDefinition()) + cast(D)->getTemplatedDecl()->getDefinition( + D->getASTContext())) return MakeCXCursor(cast(Def)->getDescribedVarTemplate(), TU); return clang_getNullCursor(); } 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: 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().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(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().match( ToTU, varDecl(hasName("a"))); ASSERT_FALSE(ToD->getInit()); - ASSERT_FALSE(ToD->getDefinition()); + ASSERT_FALSE(ToD->getDefinition(ToD->getASTContext())); auto *ImportedD = cast(Import(FromDWithDef, Lang_CXX11)); EXPECT_TRUE(ImportedD->getAnyInitializer()); - EXPECT_TRUE(ImportedD->getDefinition()); + EXPECT_TRUE(ImportedD->getDefinition(ImportedD->getASTContext())); } struct DeclContextTest : ASTImporterTestBase {};