diff options
Diffstat (limited to 'lib/AST/Decl.cpp')
-rw-r--r-- | lib/AST/Decl.cpp | 83 |
1 files changed, 43 insertions, 40 deletions
diff --git a/lib/AST/Decl.cpp b/lib/AST/Decl.cpp index bf5bfaaef1..986430595b 100644 --- a/lib/AST/Decl.cpp +++ b/lib/AST/Decl.cpp @@ -104,14 +104,8 @@ getLVForTemplateParameterList(const TemplateParameterList *Params) { return LV; } -/// Compute the linkage and visibility for the given declaration. -static LinkageInfo computeLVForDecl(const NamedDecl *D, bool OnlyTemplate); - -static LinkageInfo getLVForDecl(const NamedDecl *D, bool OnlyTemplate) { - if (!OnlyTemplate) - return D->getLinkageAndVisibility(); - return computeLVForDecl(D, OnlyTemplate); -} +/// getLVForDecl - Get the linkage and visibility for the given declaration. +static LinkageInfo getLVForDecl(const NamedDecl *D, bool OnlyTemplate); /// \brief Get the most restrictive linkage for the types and /// declarations in the given template argument list. @@ -575,18 +569,18 @@ static void clearLinkageForClass(const CXXRecordDecl *record) { i = record->decls_begin(), e = record->decls_end(); i != e; ++i) { Decl *child = *i; if (isa<NamedDecl>(child)) - cast<NamedDecl>(child)->ClearLVCache(); + cast<NamedDecl>(child)->ClearLinkageCache(); } } void NamedDecl::anchor() { } -void NamedDecl::ClearLVCache() { +void NamedDecl::ClearLinkageCache() { // Note that we can't skip clearing the linkage of children just // because the parent doesn't have cached linkage: we don't cache // when computing linkage for parent contexts. - CacheValidAndVisibility = 0; + HasCachedLinkage = 0; // If we're changing the linkage of a class, we need to reset the // linkage of child declarations, too. @@ -597,51 +591,66 @@ void NamedDecl::ClearLVCache() { dyn_cast<ClassTemplateDecl>(const_cast<NamedDecl*>(this))) { // Clear linkage for the template pattern. CXXRecordDecl *record = temp->getTemplatedDecl(); - record->CacheValidAndVisibility = 0; + record->HasCachedLinkage = 0; clearLinkageForClass(record); // We need to clear linkage for specializations, too. for (ClassTemplateDecl::spec_iterator i = temp->spec_begin(), e = temp->spec_end(); i != e; ++i) - i->ClearLVCache(); + i->ClearLinkageCache(); } // Clear cached linkage for function template decls, too. if (FunctionTemplateDecl *temp = dyn_cast<FunctionTemplateDecl>(const_cast<NamedDecl*>(this))) { - temp->getTemplatedDecl()->ClearLVCache(); + temp->getTemplatedDecl()->ClearLinkageCache(); for (FunctionTemplateDecl::spec_iterator i = temp->spec_begin(), e = temp->spec_end(); i != e; ++i) - i->ClearLVCache(); + i->ClearLinkageCache(); } } Linkage NamedDecl::getLinkage() const { - return getLinkageAndVisibility().linkage(); + if (HasCachedLinkage) { + assert(Linkage(CachedLinkage) == + getLVForDecl(this, true).linkage()); + return Linkage(CachedLinkage); + } + + CachedLinkage = getLVForDecl(this, true).linkage(); + HasCachedLinkage = 1; + +#ifndef NDEBUG + verifyLinkage(); +#endif + + return Linkage(CachedLinkage); } LinkageInfo NamedDecl::getLinkageAndVisibility() const { - if (CacheValidAndVisibility) { - Linkage L = static_cast<Linkage>(CachedLinkage); - Visibility V = static_cast<Visibility>(CacheValidAndVisibility - 1); - bool Explicit = CachedVisibilityExplicit; - LinkageInfo LV(L, V, Explicit); - assert(LV == computeLVForDecl(this, false)); - return LV; + LinkageInfo LI = getLVForDecl(this, false); + if (HasCachedLinkage) { + assert(Linkage(CachedLinkage) == LI.linkage()); + return LI; } - LinkageInfo LV = computeLVForDecl(this, false); - CachedLinkage = LV.linkage(); - CacheValidAndVisibility = LV.visibility() + 1; - CachedVisibilityExplicit = LV.visibilityExplicit(); + HasCachedLinkage = 1; + CachedLinkage = LI.linkage(); #ifndef NDEBUG + verifyLinkage(); +#endif + + return LI; +} + +void NamedDecl::verifyLinkage() const { // In C (because of gnu inline) and in c++ with microsoft extensions an // static can follow an extern, so we can have two decls with different // linkages. const LangOptions &Opts = getASTContext().getLangOpts(); if (!Opts.CPlusPlus || Opts.MicrosoftExt) - return LV; + return; // We have just computed the linkage for this decl. By induction we know // that all other computed linkages match, check that the one we just computed @@ -651,15 +660,12 @@ LinkageInfo NamedDecl::getLinkageAndVisibility() const { NamedDecl *T = cast<NamedDecl>(*I); if (T == this) continue; - if (T->CacheValidAndVisibility != 0) { + if (T->HasCachedLinkage != 0) { D = T; break; } } assert(!D || D->CachedLinkage == CachedLinkage); -#endif - - return LV; } llvm::Optional<Visibility> NamedDecl::getExplicitVisibility() const { @@ -723,7 +729,7 @@ llvm::Optional<Visibility> NamedDecl::getExplicitVisibility() const { return llvm::Optional<Visibility>(); } -static LinkageInfo computeLVForDecl(const NamedDecl *D, bool OnlyTemplate) { +static LinkageInfo getLVForDecl(const NamedDecl *D, bool OnlyTemplate) { // Objective-C: treat all Objective-C declarations as having external // linkage. switch (D->getKind()) { @@ -1192,7 +1198,7 @@ VarDecl *VarDecl::CreateDeserialized(ASTContext &C, unsigned ID) { void VarDecl::setStorageClass(StorageClass SC) { assert(isLegalForVariable(SC)); if (getStorageClass() != SC) - ClearLVCache(); + ClearLinkageCache(); VarDeclBits.SClass = SC; } @@ -1714,9 +1720,6 @@ void FunctionDecl::setBody(Stmt *B) { Body = B; if (B) EndRangeLoc = B->getLocEnd(); - for (redecl_iterator R = redecls_begin(), REnd = redecls_end(); R != REnd; - ++R) - R->ClearLVCache(); } void FunctionDecl::setPure(bool P) { @@ -1825,7 +1828,7 @@ FunctionDecl *FunctionDecl::getCanonicalDecl() { void FunctionDecl::setStorageClass(StorageClass SC) { assert(isLegalForFunction(SC)); if (getStorageClass() != SC) - ClearLVCache(); + ClearLinkageCache(); SClass = SC; } @@ -2595,8 +2598,8 @@ TagDecl* TagDecl::getCanonicalDecl() { void TagDecl::setTypedefNameForAnonDecl(TypedefNameDecl *TDD) { TypedefNameDeclOrQualifier = TDD; if (TypeForDecl) - const_cast<Type*>(TypeForDecl)->ClearLVCache(); - ClearLVCache(); + const_cast<Type*>(TypeForDecl)->ClearLinkageCache(); + ClearLinkageCache(); } void TagDecl::startDefinition() { |