[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.

llvm-svn: 152363
This commit is contained in:
Daniel Dunbar 2012-03-09 01:51:51 +00:00
parent 8aff411add
commit 9d35581907
8 changed files with 50 additions and 33 deletions

View File

@ -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<VarDecl*>(this)->getDefinition(C);
}
VarDecl *getDefinition() {
return getDefinition(getASTContext());
}
const VarDecl *getDefinition() const {
return const_cast<VarDecl*>(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;

View File

@ -804,7 +804,8 @@ class DeclRefExpr : public Expr {
return const_cast<DeclRefExpr *>(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,

View File

@ -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;

View File

@ -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<VarDecl>(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<DeclRefExpr>());
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;

View File

@ -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<VarDecl>(D);
if (const VarDecl *VDef = VD->getDefinition())
if (const VarDecl *VDef = VD->getDefinition(Info.Ctx))
VD = VDef;
if (!VD || VD->isInvalidDecl()) {
Info.Diag(Loc);

View File

@ -217,7 +217,7 @@ public:
VarDecl *VD = dyn_cast<VarDecl>(E->getDecl());
if (!VD && !isa<EnumConstantDecl>(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

View File

@ -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.

View File

@ -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<ParmVarDecl>(Var) && !Var->getType()->isReferenceType() &&
Var->isUsableInConstantExpressions() &&
Var->isUsableInConstantExpressions(SemaRef.Context) &&
Var->getAnyInitializer(DefVD) && DefVD->checkInitIsICE())
SemaRef.MaybeODRUseExprs.insert(E);
else