From 9ad61127721a42ca7487cfc6791e3dd92fecf459 Mon Sep 17 00:00:00 2001 From: Rafael Espindola Date: Tue, 26 Nov 2013 16:09:08 +0000 Subject: [PATCH] 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 --- clang/lib/AST/Decl.cpp | 33 ++++++++++++++++++++++----------- 1 file changed, 22 insertions(+), 11 deletions(-) diff --git a/clang/lib/AST/Decl.cpp b/clang/lib/AST/Decl.cpp index 75fa27bed60a..db3ab9536eb3 100644 --- a/clang/lib/AST/Decl.cpp +++ b/clang/lib/AST/Decl.cpp @@ -949,15 +949,19 @@ LinkageInfo NamedDecl::getLinkageAndVisibility() const { return getLVForDecl(this, computation); } -Optional -NamedDecl::getExplicitVisibility(ExplicitVisibilityKind kind) const { +static Optional +getExplicitVisibilityAux(const NamedDecl *ND, + NamedDecl::ExplicitVisibilityKind kind, + bool IsMostRecent) { + assert(!IsMostRecent || ND == ND->getMostRecentDecl()); + // Check the declaration itself first. - if (Optional V = getVisibilityOf(this, kind)) + if (Optional 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(this)) { + if (const CXXRecordDecl *RD = dyn_cast(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(this)) + = dyn_cast(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(this)) { + if (const VarDecl *Var = dyn_cast(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(this)) { + if (const FunctionDecl *fn = dyn_cast(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(this)) + if (const TemplateDecl *TD = dyn_cast(ND)) return getVisibilityOf(TD->getTemplatedDecl(), kind); return None; } +Optional +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.