From: Daniel Dunbar Date: Fri, 9 Mar 2012 01:51:51 +0000 (+0000) Subject: [AST] Reduce Decl::getASTContext() calls. X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=3d13c5a1e72ed8f8be9c083791d30643d1b1ec43;p=clang [AST] Reduce Decl::getASTContext() calls. - This function is not at all free; pass it around along some hot paths instead of recomputing it deep inside various VarDecl methods. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@152363 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/include/clang/AST/Decl.h b/include/clang/AST/Decl.h index 27a9d75f92..ccd42e6629 100644 --- a/include/clang/AST/Decl.h +++ b/include/clang/AST/Decl.h @@ -951,11 +951,17 @@ public: /// \brief 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() const; + DefinitionKind isThisDeclarationADefinition(ASTContext &) const; + DefinitionKind isThisDeclarationADefinition() const { + return isThisDeclarationADefinition(getASTContext()); + } /// \brief Check whether this variable is defined in this /// translation unit. - DefinitionKind hasDefinition() const; + DefinitionKind hasDefinition(ASTContext &) const; + DefinitionKind hasDefinition() const { + return hasDefinition(getASTContext()); + } /// \brief Get the tentative definition that acts as the real definition in /// a TU. Returns null if there is a proper definition available. @@ -969,7 +975,13 @@ public: bool isTentativeDefinitionNow() const; /// \brief Get the real (not just tentative) definition for this declaration. - VarDecl *getDefinition(); + 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(); } @@ -1068,7 +1080,7 @@ public: /// constant expression, according to the relevant language standard. /// This only checks properties of the declaration, and does not check /// whether the initializer is in fact a constant expression. - bool isUsableInConstantExpressions() const; + bool isUsableInConstantExpressions(ASTContext &C) const; EvaluatedStmt *ensureEvaluatedStmt() const; diff --git a/include/clang/AST/Expr.h b/include/clang/AST/Expr.h index 075c0a45c3..2834f6e5a0 100644 --- a/include/clang/AST/Expr.h +++ b/include/clang/AST/Expr.h @@ -804,7 +804,8 @@ class DeclRefExpr : public Expr { return const_cast(this)->getInternalFoundDecl(); } - DeclRefExpr(NestedNameSpecifierLoc QualifierLoc, + DeclRefExpr(ASTContext &Ctx, + NestedNameSpecifierLoc QualifierLoc, SourceLocation TemplateKWLoc, ValueDecl *D, const DeclarationNameInfo &NameInfo, NamedDecl *FoundD, @@ -817,7 +818,7 @@ class DeclRefExpr : public Expr { /// \brief Computes the type- and value-dependence flags for this /// declaration reference expression. - void computeDependence(); + void computeDependence(ASTContext &C); public: DeclRefExpr(ValueDecl *D, QualType T, ExprValueKind VK, SourceLocation L, @@ -828,7 +829,7 @@ public: DeclRefExprBits.HasTemplateKWAndArgsInfo = 0; DeclRefExprBits.HasFoundDecl = 0; DeclRefExprBits.HadMultipleCandidates = 0; - computeDependence(); + computeDependence(D->getASTContext()); } static DeclRefExpr *Create(ASTContext &Context, diff --git a/lib/AST/Decl.cpp b/lib/AST/Decl.cpp index 2f42607eab..ded507ef8e 100644 --- a/lib/AST/Decl.cpp +++ b/lib/AST/Decl.cpp @@ -1216,7 +1216,9 @@ VarDecl *VarDecl::getCanonicalDecl() { return getFirstDeclaration(); } -VarDecl::DefinitionKind VarDecl::isThisDeclarationADefinition() const { +VarDecl::DefinitionKind VarDecl::isThisDeclarationADefinition( + ASTContext &C) const +{ // C++ [basic.def]p2: // A declaration is a definition unless [...] it contains the 'extern' // specifier or a linkage-specification and neither an initializer [...], @@ -1258,7 +1260,7 @@ VarDecl::DefinitionKind VarDecl::isThisDeclarationADefinition() const { // and without a storage class specifier or the scs 'static', constitutes // a tentative definition. // No such thing in C++. - if (!getASTContext().getLangOptions().CPlusPlus && isFileVarDecl()) + if (!C.getLangOptions().CPlusPlus && isFileVarDecl()) return TentativeDefinition; // What's left is (in C, block-scope) declarations without initializers or @@ -1296,23 +1298,23 @@ bool VarDecl::isTentativeDefinitionNow() const { return true; } -VarDecl *VarDecl::getDefinition() { +VarDecl *VarDecl::getDefinition(ASTContext &C) { VarDecl *First = getFirstDeclaration(); for (redecl_iterator I = First->redecls_begin(), E = First->redecls_end(); I != E; ++I) { - if ((*I)->isThisDeclarationADefinition() == Definition) + if ((*I)->isThisDeclarationADefinition(C) == Definition) return *I; } return 0; } -VarDecl::DefinitionKind VarDecl::hasDefinition() const { +VarDecl::DefinitionKind VarDecl::hasDefinition(ASTContext &C) const { DefinitionKind Kind = DeclarationOnly; const VarDecl *First = getFirstDeclaration(); for (redecl_iterator I = First->redecls_begin(), E = First->redecls_end(); I != E; ++I) { - Kind = std::max(Kind, (*I)->isThisDeclarationADefinition()); + Kind = std::max(Kind, (*I)->isThisDeclarationADefinition(C)); if (Kind == Definition) break; } @@ -1370,8 +1372,8 @@ void VarDecl::setInit(Expr *I) { Init = I; } -bool VarDecl::isUsableInConstantExpressions() const { - const LangOptions &Lang = getASTContext().getLangOptions(); +bool VarDecl::isUsableInConstantExpressions(ASTContext &C) const { + const LangOptions &Lang = C.getLangOptions(); if (!Lang.CPlusPlus) return false; diff --git a/lib/AST/Expr.cpp b/lib/AST/Expr.cpp index 0fdca5a33b..18cc5b37bf 100644 --- a/lib/AST/Expr.cpp +++ b/lib/AST/Expr.cpp @@ -134,7 +134,7 @@ SourceLocation Expr::getExprLoc() const { /// \brief Compute the type-, value-, and instantiation-dependence of a /// declaration reference /// based on the declaration being referenced. -static void computeDeclRefDependence(NamedDecl *D, QualType T, +static void computeDeclRefDependence(ASTContext &Ctx, NamedDecl *D, QualType T, bool &TypeDependent, bool &ValueDependent, bool &InstantiationDependent) { @@ -191,7 +191,7 @@ static void computeDeclRefDependence(NamedDecl *D, QualType T, // - an entity with reference type and is initialized with an // expression that is value-dependent [C++11] if (VarDecl *Var = dyn_cast(D)) { - if ((D->getASTContext().getLangOptions().CPlusPlus0x ? + if ((Ctx.getLangOptions().CPlusPlus0x ? Var->getType()->isLiteralType() : Var->getType()->isIntegralOrEnumerationType()) && (Var->getType().getCVRQualifiers() == Qualifiers::Const || @@ -224,12 +224,12 @@ static void computeDeclRefDependence(NamedDecl *D, QualType T, } } -void DeclRefExpr::computeDependence() { +void DeclRefExpr::computeDependence(ASTContext &Ctx) { bool TypeDependent = false; bool ValueDependent = false; bool InstantiationDependent = false; - computeDeclRefDependence(getDecl(), getType(), TypeDependent, ValueDependent, - InstantiationDependent); + computeDeclRefDependence(Ctx, getDecl(), getType(), TypeDependent, + ValueDependent, InstantiationDependent); // (TD) C++ [temp.dep.expr]p3: // An id-expression is type-dependent if it contains: @@ -258,7 +258,8 @@ void DeclRefExpr::computeDependence() { ExprBits.ContainsUnexpandedParameterPack = true; } -DeclRefExpr::DeclRefExpr(NestedNameSpecifierLoc QualifierLoc, +DeclRefExpr::DeclRefExpr(ASTContext &Ctx, + NestedNameSpecifierLoc QualifierLoc, SourceLocation TemplateKWLoc, ValueDecl *D, const DeclarationNameInfo &NameInfo, NamedDecl *FoundD, @@ -289,7 +290,7 @@ DeclRefExpr::DeclRefExpr(NestedNameSpecifierLoc QualifierLoc, } DeclRefExprBits.HadMultipleCandidates = 0; - computeDependence(); + computeDependence(Ctx); } DeclRefExpr *DeclRefExpr::Create(ASTContext &Context, @@ -330,8 +331,8 @@ DeclRefExpr *DeclRefExpr::Create(ASTContext &Context, Size += ASTTemplateKWAndArgsInfo::sizeFor(0); void *Mem = Context.Allocate(Size, llvm::alignOf()); - return new (Mem) DeclRefExpr(QualifierLoc, TemplateKWLoc, D, NameInfo, - FoundD, TemplateArgs, T, VK); + return new (Mem) DeclRefExpr(Context, QualifierLoc, TemplateKWLoc, D, + NameInfo, FoundD, TemplateArgs, T, VK); } DeclRefExpr *DeclRefExpr::CreateEmpty(ASTContext &Context, @@ -3642,8 +3643,8 @@ BlockDeclRefExpr::BlockDeclRefExpr(VarDecl *d, QualType t, ExprValueKind VK, bool TypeDependent = false; bool ValueDependent = false; bool InstantiationDependent = false; - computeDeclRefDependence(D, getType(), TypeDependent, ValueDependent, - InstantiationDependent); + computeDeclRefDependence(D->getASTContext(), D, getType(), TypeDependent, + ValueDependent, InstantiationDependent); ExprBits.TypeDependent = TypeDependent; ExprBits.ValueDependent = ValueDependent; ExprBits.InstantiationDependent = InstantiationDependent; diff --git a/lib/AST/ExprConstant.cpp b/lib/AST/ExprConstant.cpp index 947f661c2c..5f9b0501b2 100644 --- a/lib/AST/ExprConstant.cpp +++ b/lib/AST/ExprConstant.cpp @@ -1733,7 +1733,7 @@ static bool HandleLValueToRValueConversion(EvalInfo &Info, const Expr *Conv, // parameters are constant expressions even if they're non-const. // In C, such things can also be folded, although they are not ICEs. const VarDecl *VD = dyn_cast(D); - if (const VarDecl *VDef = VD->getDefinition()) + if (const VarDecl *VDef = VD->getDefinition(Info.Ctx)) VD = VDef; if (!VD || VD->isInvalidDecl()) { Info.Diag(Loc); diff --git a/lib/CodeGen/CGExprScalar.cpp b/lib/CodeGen/CGExprScalar.cpp index 8ed36aac5f..9da493448a 100644 --- a/lib/CodeGen/CGExprScalar.cpp +++ b/lib/CodeGen/CGExprScalar.cpp @@ -217,7 +217,7 @@ public: VarDecl *VD = dyn_cast(E->getDecl()); if (!VD && !isa(E->getDecl())) return EmitLoadOfLValue(E); - if (VD && !VD->isUsableInConstantExpressions()) + if (VD && !VD->isUsableInConstantExpressions(CGF.getContext())) return EmitLoadOfLValue(E); // This is an enumerator or a variable which is usable in constant diff --git a/lib/Sema/SemaDecl.cpp b/lib/Sema/SemaDecl.cpp index 33656c9d52..062e4aa38f 100644 --- a/lib/Sema/SemaDecl.cpp +++ b/lib/Sema/SemaDecl.cpp @@ -6747,7 +6747,7 @@ void Sema::CheckCompleteVariableDeclaration(VarDecl *var) { for (unsigned I = 0, N = Notes.size(); I != N; ++I) Diag(Notes[I].first, Notes[I].second); } - } else if (var->isUsableInConstantExpressions()) { + } else if (var->isUsableInConstantExpressions(Context)) { // 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. diff --git a/lib/Sema/SemaExpr.cpp b/lib/Sema/SemaExpr.cpp index b989fac838..64008e1093 100644 --- a/lib/Sema/SemaExpr.cpp +++ b/lib/Sema/SemaExpr.cpp @@ -10145,7 +10145,7 @@ static void MarkVarDeclODRUsed(Sema &SemaRef, VarDecl *Var, SourceLocation Loc) { // Keep track of used but undefined variables. // FIXME: We shouldn't suppress this warning for static data members. - if (Var->hasDefinition() == VarDecl::DeclarationOnly && + if (Var->hasDefinition(SemaRef.Context) == VarDecl::DeclarationOnly && Var->getLinkage() != ExternalLinkage && !(Var->isStaticDataMember() && Var->hasInit())) { SourceLocation &old = SemaRef.UndefinedInternals[Var->getCanonicalDecl()]; @@ -10218,7 +10218,8 @@ static void DoMarkVarDeclReferenced(Sema &SemaRef, SourceLocation Loc, assert(MSInfo && "Missing member specialization information?"); bool AlreadyInstantiated = !MSInfo->getPointOfInstantiation().isInvalid(); if (MSInfo->getTemplateSpecializationKind() == TSK_ImplicitInstantiation && - (!AlreadyInstantiated || Var->isUsableInConstantExpressions())) { + (!AlreadyInstantiated || + Var->isUsableInConstantExpressions(SemaRef.Context))) { if (!AlreadyInstantiated) { // This is a modification of an existing AST node. Notify listeners. if (ASTMutationListener *L = SemaRef.getASTMutationListener()) @@ -10226,7 +10227,7 @@ static void DoMarkVarDeclReferenced(Sema &SemaRef, SourceLocation Loc, MSInfo->setPointOfInstantiation(Loc); } SourceLocation PointOfInstantiation = MSInfo->getPointOfInstantiation(); - if (Var->isUsableInConstantExpressions()) + if (Var->isUsableInConstantExpressions(SemaRef.Context)) // Do not defer instantiations of variables which could be used in a // constant expression. SemaRef.InstantiateStaticDataMemberDefinition(PointOfInstantiation,Var); @@ -10246,7 +10247,7 @@ static void DoMarkVarDeclReferenced(Sema &SemaRef, SourceLocation Loc, // apply to references, since they are not objects. const VarDecl *DefVD; if (E && !isa(Var) && !Var->getType()->isReferenceType() && - Var->isUsableInConstantExpressions() && + Var->isUsableInConstantExpressions(SemaRef.Context) && Var->getAnyInitializer(DefVD) && DefVD->checkInitIsICE()) SemaRef.MaybeODRUseExprs.insert(E); else