Don't call getMostRecentDecl when we know we have it.

On a Release build this takes the testcase in pr18055 from 0m3.892s to 0m1.452s.

llvm-svn: 195768
This commit is contained in:
Rafael Espindola 2013-11-26 16:09:08 +00:00
parent 8ef7f6828c
commit 9ad6112772
1 changed files with 22 additions and 11 deletions

View File

@ -949,15 +949,19 @@ LinkageInfo NamedDecl::getLinkageAndVisibility() const {
return getLVForDecl(this, computation);
}
Optional<Visibility>
NamedDecl::getExplicitVisibility(ExplicitVisibilityKind kind) const {
static Optional<Visibility>
getExplicitVisibilityAux(const NamedDecl *ND,
NamedDecl::ExplicitVisibilityKind kind,
bool IsMostRecent) {
assert(!IsMostRecent || ND == ND->getMostRecentDecl());
// Check the declaration itself first.
if (Optional<Visibility> V = getVisibilityOf(this, kind))
if (Optional<Visibility> V = getVisibilityOf(ND, kind))
return V;
// If this is a member class of a specialization of a class template
// and the corresponding decl has explicit visibility, use that.
if (const CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(this)) {
if (const CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(ND)) {
CXXRecordDecl *InstantiatedFrom = RD->getInstantiatedFromMemberClass();
if (InstantiatedFrom)
return getVisibilityOf(InstantiatedFrom, kind);
@ -967,16 +971,18 @@ NamedDecl::getExplicitVisibility(ExplicitVisibilityKind kind) const {
// specialization of a class template, check for visibility
// on the pattern.
if (const ClassTemplateSpecializationDecl *spec
= dyn_cast<ClassTemplateSpecializationDecl>(this))
= dyn_cast<ClassTemplateSpecializationDecl>(ND))
return getVisibilityOf(spec->getSpecializedTemplate()->getTemplatedDecl(),
kind);
// Use the most recent declaration.
const NamedDecl *MostRecent = getMostRecentDecl();
if (MostRecent != this)
return MostRecent->getExplicitVisibility(kind);
if (!IsMostRecent) {
const NamedDecl *MostRecent = ND->getMostRecentDecl();
if (MostRecent != ND)
return getExplicitVisibilityAux(MostRecent, kind, true);
}
if (const VarDecl *Var = dyn_cast<VarDecl>(this)) {
if (const VarDecl *Var = dyn_cast<VarDecl>(ND)) {
if (Var->isStaticDataMember()) {
VarDecl *InstantiatedFrom = Var->getInstantiatedFromStaticDataMember();
if (InstantiatedFrom)
@ -986,7 +992,7 @@ NamedDecl::getExplicitVisibility(ExplicitVisibilityKind kind) const {
return None;
}
// Also handle function template specializations.
if (const FunctionDecl *fn = dyn_cast<FunctionDecl>(this)) {
if (const FunctionDecl *fn = dyn_cast<FunctionDecl>(ND)) {
// If the function is a specialization of a template with an
// explicit visibility attribute, use that.
if (FunctionTemplateSpecializationInfo *templateInfo
@ -1004,12 +1010,17 @@ NamedDecl::getExplicitVisibility(ExplicitVisibilityKind kind) const {
}
// The visibility of a template is stored in the templated decl.
if (const TemplateDecl *TD = dyn_cast<TemplateDecl>(this))
if (const TemplateDecl *TD = dyn_cast<TemplateDecl>(ND))
return getVisibilityOf(TD->getTemplatedDecl(), kind);
return None;
}
Optional<Visibility>
NamedDecl::getExplicitVisibility(ExplicitVisibilityKind kind) const {
return getExplicitVisibilityAux(this, kind, false);
}
static LinkageInfo getLVForClosure(const DeclContext *DC, Decl *ContextDecl,
LVComputationKind computation) {
// This lambda has its linkage/visibility determined by its owner.