From b5f35bae05f1ce3ae62ca52b266a086fd019e89b Mon Sep 17 00:00:00 2001 From: Douglas Gregor Date: Mon, 6 Dec 2010 17:49:01 +0000 Subject: [PATCH] Revert r120808, my previous implementation of caching for the linkage and visibility of declarations, because it was extremely messy and it increased the size of NamedDecl. An improved implementation is forthcoming. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@121012 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/clang/AST/Decl.h | 95 +++-------------------------- include/clang/AST/DeclBase.h | 9 ++- include/clang/AST/DeclTemplate.h | 2 - include/clang/AST/Redeclarable.h | 22 ++++++- lib/AST/Decl.cpp | 75 +---------------------- lib/AST/DeclBase.cpp | 32 ---------- lib/AST/DeclCXX.cpp | 2 - lib/Serialization/ASTReaderDecl.cpp | 4 +- 8 files changed, 41 insertions(+), 200 deletions(-) diff --git a/include/clang/AST/Decl.h b/include/clang/AST/Decl.h index f2cb672bb8..bdc91a168e 100644 --- a/include/clang/AST/Decl.h +++ b/include/clang/AST/Decl.h @@ -99,25 +99,10 @@ class NamedDecl : public Decl { /// constructor, Objective-C selector, etc.) DeclarationName Name; - /// \brief Whether we have already cached linkage and visibility. - mutable unsigned HasLinkageAndVisibilityCached : 1; - - /// \brief The cached visibility, if \c HasLinkageAndVisibilityCached is - /// non-zero. - mutable unsigned CachedVisibility : 2; - - /// \brief Whether the cached visibility was explicitly placed on this - /// declaration. - mutable unsigned CachedVisibilityIsExplicit : 1; - - /// \brief The cached linkage, if \c HasLinkageAndVisibilityCached is - /// non-zero. - mutable unsigned CachedLinkage : 2; - protected: NamedDecl(Kind DK, DeclContext *DC, SourceLocation L, DeclarationName N) - : Decl(DK, DC, L), Name(N), HasLinkageAndVisibilityCached(0) { } - + : Decl(DK, DC, L), Name(N) { } + public: /// getIdentifier - Get the identifier that names this declaration, /// if there is one. This will return NULL if this declaration has @@ -287,13 +272,6 @@ public: /// \brief Determines the linkage and visibility of this entity. LinkageInfo getLinkageAndVisibility() const; - /// \brief Clear the linkage and visibility cache in response to a change - /// to the declaration. - /// - /// \param Redeclarations When true, we also have to clear out the linkage - /// and visibility cache for all redeclarations. - void ClearLinkageAndVisibilityCache(); - /// \brief Looks through UsingDecls and ObjCCompatibleAliasDecls for /// the underlying named decl. NamedDecl *getUnderlyingDecl(); @@ -647,8 +625,6 @@ private: bool NRVOVariable : 1; friend class StmtIteratorBase; - friend class ASTDeclReader; - protected: VarDecl(Kind DK, DeclContext *DC, SourceLocation L, IdentifierInfo *Id, QualType T, TypeSourceInfo *TInfo, StorageClass SC, @@ -684,7 +660,10 @@ public: StorageClass getStorageClassAsWritten() const { return (StorageClass) SClassAsWritten; } - void setStorageClass(StorageClass SC); + void setStorageClass(StorageClass SC) { + assert(isLegalForVariable(SC)); + SClass = SC; + } void setStorageClassAsWritten(StorageClass SC) { assert(isLegalForVariable(SC)); SClassAsWritten = SC; @@ -1499,7 +1478,10 @@ public: } StorageClass getStorageClass() const { return StorageClass(SClass); } - void setStorageClass(StorageClass SC); + void setStorageClass(StorageClass SC) { + assert(isLegalForFunction(SC)); + SClass = SC; + } StorageClass getStorageClassAsWritten() const { return StorageClass(SClassAsWritten); @@ -2576,63 +2558,6 @@ inline const DiagnosticBuilder &operator<<(const DiagnosticBuilder &DB, return DB; } -template -void Redeclarable::setPreviousDeclaration(decl_type *PrevDecl) { - // Note: This routine is implemented here because we need both NamedDecl - // and Redeclarable to be defined. - decl_type *First; - - if (PrevDecl) { - // Point to previous. Make sure that this is actually the most recent - // redeclaration, or we can build invalid chains. If the most recent - // redeclaration is invalid, it won't be PrevDecl, but we want it anyway. - RedeclLink = PreviousDeclLink(llvm::cast( - PrevDecl->getMostRecentDeclaration())); - First = PrevDecl->getFirstDeclaration(); - assert(First->RedeclLink.NextIsLatest() && "Expected first"); - } else { - // Make this first. - First = static_cast(this); - } - - // First one will point to this one as latest. - First->RedeclLink = LatestDeclLink(static_cast(this)); - - // If this declaration has a visibility attribute that differs from the - // previous visibility attribute, or has private extern storage while the - // previous declaration merely had extern storage, clear out the linkage and - ///visibility cache. This is required because declarations after the first - // declaration can change the visibility for all previous and future - // declarations. - if (NamedDecl *ND = dyn_cast(static_cast(this))) { - bool MustClear = false; - if (VisibilityAttr *Visibility = ND->getAttr()) { - VisibilityAttr *PrevVisibility - = PrevDecl->template getAttr(); - if (!PrevVisibility || - PrevVisibility->getVisibility() != Visibility->getVisibility()) - MustClear = true; - } - - if (!MustClear) { - if (VarDecl *VD = dyn_cast(ND)) { - if (VD->getStorageClass() != cast(PrevDecl)->getStorageClass()) - MustClear = true; - } else if (FunctionDecl *FD = dyn_cast(ND)) { - FunctionDecl *PrevFD = cast(PrevDecl); - if (FD->getStorageClass() != PrevFD->getStorageClass()) - MustClear = true; - else if (FD->isInlineSpecified() && !PrevFD->isInlined()) - MustClear = true; - } - } - - if (MustClear) - ND->ClearLinkageAndVisibilityCache(); - } -} - - } // end namespace clang #endif diff --git a/include/clang/AST/DeclBase.h b/include/clang/AST/DeclBase.h index 699950ef6b..0aa60ce978 100644 --- a/include/clang/AST/DeclBase.h +++ b/include/clang/AST/DeclBase.h @@ -198,7 +198,7 @@ private: return DeclCtx.get(); } - /// Loc - The location of this decl. + /// Loc - The location that this decl. SourceLocation Loc; /// DeclKind - This indicates which class this is. @@ -316,7 +316,12 @@ public: void swapAttrs(Decl *D); void dropAttrs(); - void addAttr(Attr *A); + void addAttr(Attr *A) { + if (hasAttrs()) + getAttrs().push_back(A); + else + setAttrs(AttrVec(1, A)); + } typedef AttrVec::const_iterator attr_iterator; diff --git a/include/clang/AST/DeclTemplate.h b/include/clang/AST/DeclTemplate.h index a7d0f51d6a..bde2e24e19 100644 --- a/include/clang/AST/DeclTemplate.h +++ b/include/clang/AST/DeclTemplate.h @@ -1241,8 +1241,6 @@ public: } void setSpecializationKind(TemplateSpecializationKind TSK) { - if (getSpecializationKind() != TSK) - ClearLinkageAndVisibilityCache(); SpecializationKind = TSK; } diff --git a/include/clang/AST/Redeclarable.h b/include/clang/AST/Redeclarable.h index 4a1c1d0018..ba778293ba 100644 --- a/include/clang/AST/Redeclarable.h +++ b/include/clang/AST/Redeclarable.h @@ -109,8 +109,26 @@ public: /// \brief Set the previous declaration. If PrevDecl is NULL, set this as the /// first and only declaration. - void setPreviousDeclaration(decl_type *PrevDecl); - + void setPreviousDeclaration(decl_type *PrevDecl) { + decl_type *First; + + if (PrevDecl) { + // Point to previous. Make sure that this is actually the most recent + // redeclaration, or we can build invalid chains. If the most recent + // redeclaration is invalid, it won't be PrevDecl, but we want it anyway. + RedeclLink = PreviousDeclLink(llvm::cast( + PrevDecl->getMostRecentDeclaration())); + First = PrevDecl->getFirstDeclaration(); + assert(First->RedeclLink.NextIsLatest() && "Expected first"); + } else { + // Make this first. + First = static_cast(this); + } + + // First one will point to this one as latest. + First->RedeclLink = LatestDeclLink(static_cast(this)); + } + /// \brief Iterates through all the redeclarations of the same decl. class redecl_iterator { /// Current - The current declaration. diff --git a/lib/AST/Decl.cpp b/lib/AST/Decl.cpp index a8959b8d91..71bda4156f 100644 --- a/lib/AST/Decl.cpp +++ b/lib/AST/Decl.cpp @@ -526,57 +526,7 @@ static LinkageInfo getLVForClassMember(const NamedDecl *D, LVFlags F) { } LinkageInfo NamedDecl::getLinkageAndVisibility() const { - // If we have already cached linkage and visibility, just return the - // cached information. - if (HasLinkageAndVisibilityCached) { -#ifndef NDEBUG - LinkageInfo LI = getLVForDecl(this, LVFlags()); - assert(LI.visibility() == Visibility(CachedVisibility)); - assert(LI.visibilityExplicit() == CachedVisibilityIsExplicit); - assert(LI.linkage() == Linkage(CachedLinkage)); -#endif - return LinkageInfo(Linkage(CachedLinkage), Visibility(CachedVisibility), - CachedVisibilityIsExplicit); - } - - LinkageInfo LI = getLVForDecl(this, LVFlags()); - HasLinkageAndVisibilityCached = 1; - CachedVisibility = LI.visibility(); - CachedVisibilityIsExplicit = LI.visibilityExplicit(); - CachedLinkage = LI.linkage(); - return LI; -} - -void NamedDecl::ClearLinkageAndVisibilityCache() { - HasLinkageAndVisibilityCached = 0; - - if (VarDecl *VD = dyn_cast(this)) { - for (VarDecl::redecl_iterator R = VD->redecls_begin(), - REnd = VD->redecls_end(); - R != REnd; ++R) - R->HasLinkageAndVisibilityCached = 0; - - return; - } - - if (FunctionDecl *FD = dyn_cast(this)) { - for (FunctionDecl::redecl_iterator R = FD->redecls_begin(), - REnd = FD->redecls_end(); - R != REnd; ++R) - R->HasLinkageAndVisibilityCached = 0; - - return; - } - - // Changing the linkage or visibility of a C++ class affect the linkage and - // visibility of all of its members. Clear their caches, too. - if (CXXRecordDecl *RD = dyn_cast(this)) { - for (DeclContext::decl_iterator D = RD->decls_begin(), - DEnd = RD->decls_end(); - D != DEnd; ++D) - if (NamedDecl *ND = dyn_cast(*D)) - ND->ClearLinkageAndVisibilityCache(); - } + return getLVForDecl(this, LVFlags()); } static LinkageInfo getLVForDecl(const NamedDecl *D, LVFlags Flags) { @@ -928,14 +878,6 @@ VarDecl *VarDecl::Create(ASTContext &C, DeclContext *DC, SourceLocation L, return new (C) VarDecl(Var, DC, L, Id, T, TInfo, S, SCAsWritten); } -void VarDecl::setStorageClass(StorageClass SC) { - assert(isLegalForVariable(SC)); - if (getStorageClass() != SC) - ClearLinkageAndVisibilityCache(); - - SClass = SC; -} - SourceLocation VarDecl::getInnerLocStart() const { SourceLocation Start = getTypeSpecStartLoc(); if (Start.isInvalid()) @@ -1154,7 +1096,6 @@ void VarDecl::setTemplateSpecializationKind(TemplateSpecializationKind TSK, PointOfInstantiation.isValid() && MSI->getPointOfInstantiation().isInvalid()) MSI->setPointOfInstantiation(PointOfInstantiation); - ClearLinkageAndVisibilityCache(); } //===----------------------------------------------------------------------===// @@ -1254,10 +1195,8 @@ Stmt *FunctionDecl::getBody(const FunctionDecl *&Definition) const { void FunctionDecl::setBody(Stmt *B) { Body = B; - if (B) { + if (B) EndRangeLoc = B->getLocEnd(); - ClearLinkageAndVisibilityCache(); - } } void FunctionDecl::setPure(bool P) { @@ -1338,14 +1277,6 @@ FunctionDecl *FunctionDecl::getCanonicalDecl() { return getFirstDeclaration(); } -void FunctionDecl::setStorageClass(StorageClass SC) { - assert(isLegalForFunction(SC)); - if (getStorageClass() != SC) - ClearLinkageAndVisibilityCache(); - - SClass = SC; -} - /// \brief Returns a value indicating whether this function /// corresponds to a builtin function. /// @@ -1778,7 +1709,6 @@ FunctionDecl::setTemplateSpecializationKind(TemplateSpecializationKind TSK, MSInfo->setPointOfInstantiation(PointOfInstantiation); } else assert(false && "Function cannot have a template specialization kind"); - ClearLinkageAndVisibilityCache(); } SourceLocation FunctionDecl::getPointOfInstantiation() const { @@ -1857,7 +1787,6 @@ void TagDecl::setTypedefForAnonDecl(TypedefDecl *TDD) { TypedefDeclOrQualifier = TDD; if (TypeForDecl) TypeForDecl->ClearLinkageCache(); - ClearLinkageAndVisibilityCache(); } void TagDecl::startDefinition() { diff --git a/lib/AST/DeclBase.cpp b/lib/AST/DeclBase.cpp index 3758ca1065..843e907dea 100644 --- a/lib/AST/DeclBase.cpp +++ b/lib/AST/DeclBase.cpp @@ -337,38 +337,6 @@ void Decl::dropAttrs() { getASTContext().eraseDeclAttrs(this); } -void Decl::addAttr(Attr *A) { - if (NamedDecl *ND = dyn_cast(this)) - if (VisibilityAttr *Visibility = dyn_cast(A)) { - bool ClearVisibility = true; - if (VarDecl *VD = dyn_cast(this)) { - if (VD->getPreviousDeclaration()) { - VisibilityAttr *PrevVisibility - = VD->getPreviousDeclaration()->getAttr(); - if (PrevVisibility && - PrevVisibility->getVisibility() == Visibility->getVisibility()) - ClearVisibility = false; - } - } else if (FunctionDecl *FD = dyn_cast(this)) { - if (FD->getPreviousDeclaration()) { - VisibilityAttr *PrevVisibility - = FD->getPreviousDeclaration()->getAttr(); - if (PrevVisibility && - PrevVisibility->getVisibility() == Visibility->getVisibility()) - ClearVisibility = false; - } - } - - if (ClearVisibility) - ND->ClearLinkageAndVisibilityCache(); - } - - if (hasAttrs()) - getAttrs().push_back(A); - else - setAttrs(AttrVec(1, A)); -} - const AttrVec &Decl::getAttrs() const { assert(HasAttrs && "No attrs to get!"); return getASTContext().getDeclAttrs(this); diff --git a/lib/AST/DeclCXX.cpp b/lib/AST/DeclCXX.cpp index 58cc50b97a..35c89971ea 100644 --- a/lib/AST/DeclCXX.cpp +++ b/lib/AST/DeclCXX.cpp @@ -792,8 +792,6 @@ CXXRecordDecl::setTemplateSpecializationKind(TemplateSpecializationKind TSK) { } if (MemberSpecializationInfo *MSInfo = getMemberSpecializationInfo()) { - if (MSInfo->getTemplateSpecializationKind() != TSK) - ClearLinkageAndVisibilityCache(); MSInfo->setTemplateSpecializationKind(TSK); return; } diff --git a/lib/Serialization/ASTReaderDecl.cpp b/lib/Serialization/ASTReaderDecl.cpp index 7053f404e4..adbf3bff3c 100644 --- a/lib/Serialization/ASTReaderDecl.cpp +++ b/lib/Serialization/ASTReaderDecl.cpp @@ -384,7 +384,7 @@ void ASTDeclReader::VisitFunctionDecl(FunctionDecl *FD) { // FunctionDecl's body is handled last at ASTDeclReader::Visit, // after everything else is read. - FD->SClass = (StorageClass)Record[Idx++]; + FD->setStorageClass((StorageClass)Record[Idx++]); FD->setStorageClassAsWritten((StorageClass)Record[Idx++]); FD->setInlineSpecified(Record[Idx++]); FD->setVirtualAsWritten(Record[Idx++]); @@ -651,7 +651,7 @@ void ASTDeclReader::VisitIndirectFieldDecl(IndirectFieldDecl *FD) { void ASTDeclReader::VisitVarDecl(VarDecl *VD) { VisitDeclaratorDecl(VD); VisitRedeclarable(VD); - VD->SClass = (StorageClass)Record[Idx++]; + VD->setStorageClass((StorageClass)Record[Idx++]); VD->setStorageClassAsWritten((StorageClass)Record[Idx++]); VD->setThreadSpecified(Record[Idx++]); VD->setCXXDirectInitializer(Record[Idx++]); -- 2.40.0