mirror of
https://github.com/capstone-engine/llvm-capstone.git
synced 2024-11-27 15:41:46 +00:00
[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:
parent
8aff411add
commit
9d35581907
@ -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;
|
||||
|
||||
|
@ -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,
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
|
@ -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
|
||||
|
@ -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.
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user