diff --git a/clang/include/clang/AST/Decl.h b/clang/include/clang/AST/Decl.h index f2cb672bb866..bdc91a168ee6 100644 --- a/clang/include/clang/AST/Decl.h +++ b/clang/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/clang/include/clang/AST/DeclBase.h b/clang/include/clang/AST/DeclBase.h index 699950ef6b42..0aa60ce9782e 100644 --- a/clang/include/clang/AST/DeclBase.h +++ b/clang/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/clang/include/clang/AST/DeclTemplate.h b/clang/include/clang/AST/DeclTemplate.h index a7d0f51d6ab7..bde2e24e198f 100644 --- a/clang/include/clang/AST/DeclTemplate.h +++ b/clang/include/clang/AST/DeclTemplate.h @@ -1241,8 +1241,6 @@ public: } void setSpecializationKind(TemplateSpecializationKind TSK) { - if (getSpecializationKind() != TSK) - ClearLinkageAndVisibilityCache(); SpecializationKind = TSK; } diff --git a/clang/include/clang/AST/Redeclarable.h b/clang/include/clang/AST/Redeclarable.h index 4a1c1d0018fe..ba778293ba2d 100644 --- a/clang/include/clang/AST/Redeclarable.h +++ b/clang/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/clang/lib/AST/Decl.cpp b/clang/lib/AST/Decl.cpp index a8959b8d91c4..71bda4156f9e 100644 --- a/clang/lib/AST/Decl.cpp +++ b/clang/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/clang/lib/AST/DeclBase.cpp b/clang/lib/AST/DeclBase.cpp index 3758ca10651e..843e907dea9a 100644 --- a/clang/lib/AST/DeclBase.cpp +++ b/clang/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/clang/lib/AST/DeclCXX.cpp b/clang/lib/AST/DeclCXX.cpp index 58cc50b97add..35c89971eaed 100644 --- a/clang/lib/AST/DeclCXX.cpp +++ b/clang/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/clang/lib/Serialization/ASTReaderDecl.cpp b/clang/lib/Serialization/ASTReaderDecl.cpp index 7053f404e436..adbf3bff3c36 100644 --- a/clang/lib/Serialization/ASTReaderDecl.cpp +++ b/clang/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++]);