From 162ab3200fb02522f07c2b51f8d87b7fd473b72d Mon Sep 17 00:00:00 2001 From: Argiris Kirtzidis Date: Thu, 28 Oct 2010 07:38:42 +0000 Subject: [PATCH] Use the ASTMutationListener to track added template specializations in a chained PCH. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@117533 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/clang/AST/ASTMutationListener.h | 9 ++++++++- include/clang/AST/DeclTemplate.h | 8 ++------ include/clang/Serialization/ASTBitCodes.h | 8 ++------ include/clang/Serialization/ASTReader.h | 10 ---------- include/clang/Serialization/ASTWriter.h | 20 ++------------------ lib/AST/DeclTemplate.cpp | 16 ++++++++++++++++ lib/Serialization/ASTCommon.h | 3 ++- lib/Serialization/ASTReader.cpp | 7 ------- lib/Serialization/ASTReaderDecl.cpp | 18 ++++-------------- lib/Serialization/ASTWriter.cpp | 29 ++++++++++------------------- lib/Serialization/ASTWriterDecl.cpp | 4 ---- 11 files changed, 46 insertions(+), 86 deletions(-) diff --git a/include/clang/AST/ASTMutationListener.h b/include/clang/AST/ASTMutationListener.h index de8cef5f5..dd0c2019d 100644 --- a/include/clang/AST/ASTMutationListener.h +++ b/include/clang/AST/ASTMutationListener.h @@ -14,9 +14,11 @@ #define LLVM_CLANG_AST_ASTMUTATIONLISTENER_H namespace clang { + class Decl; class TagDecl; class CXXRecordDecl; - class CXXMethodDecl; + class ClassTemplateDecl; + class ClassTemplateSpecializationDecl; /// \brief An abstract interface that should be implemented by listeners /// that want to be notified when an AST entity gets modified after its @@ -30,6 +32,11 @@ public: /// \brief An implicit member was added after the definition was completed. virtual void AddedCXXImplicitMember(const CXXRecordDecl *RD, const Decl *D) {} + + /// \brief A template specialization (or partial one) was added to the + /// template declaration. + virtual void AddedCXXTemplateSpecialization(const ClassTemplateDecl *TD, + const ClassTemplateSpecializationDecl *D) {} }; } // end namespace clang diff --git a/include/clang/AST/DeclTemplate.h b/include/clang/AST/DeclTemplate.h index 0217d5389..96ab4a8a1 100644 --- a/include/clang/AST/DeclTemplate.h +++ b/include/clang/AST/DeclTemplate.h @@ -1697,9 +1697,7 @@ public: /// \brief Insert the specified specialization knowing that it is not already /// in. InsertPos must be obtained from findSpecialization. - void AddSpecialization(ClassTemplateSpecializationDecl *D, void *InsertPos) { - getSpecializations().InsertNode(D, InsertPos); - } + void AddSpecialization(ClassTemplateSpecializationDecl *D, void *InsertPos); ClassTemplateDecl *getCanonicalDecl() { return redeclarable_base::getCanonicalDecl(); @@ -1733,9 +1731,7 @@ public: /// \brief Insert the specified partial specialization knowing that it is not /// already in. InsertPos must be obtained from findPartialSpecialization. void AddPartialSpecialization(ClassTemplatePartialSpecializationDecl *D, - void *InsertPos) { - getPartialSpecializations().InsertNode(D, InsertPos); - } + void *InsertPos); /// \brief Return the next partial specialization sequence number. unsigned getNextPartialSpecSequenceNumber() { diff --git a/include/clang/Serialization/ASTBitCodes.h b/include/clang/Serialization/ASTBitCodes.h index 7370db1fc..d8e04214b 100644 --- a/include/clang/Serialization/ASTBitCodes.h +++ b/include/clang/Serialization/ASTBitCodes.h @@ -327,17 +327,13 @@ namespace clang { /// In practice, this should only be used for the TU and namespaces. UPDATE_VISIBLE = 34, - /// \brief Record code for template specializations introduced after - /// serializations of the original template decl. - ADDITIONAL_TEMPLATE_SPECIALIZATIONS = 35, - /// \brief Record for offsets of DECL_UPDATES records for declarations /// that were modified after being deserialized and need updates. - DECL_UPDATE_OFFSETS = 36, + DECL_UPDATE_OFFSETS = 35, /// \brief Record of updates for a declaration that was modified after /// being deserialized. - DECL_UPDATES = 37 + DECL_UPDATES = 36 }; /// \brief Record types used within a source manager block. diff --git a/include/clang/Serialization/ASTReader.h b/include/clang/Serialization/ASTReader.h index 324e093e7..abe84cac2 100644 --- a/include/clang/Serialization/ASTReader.h +++ b/include/clang/Serialization/ASTReader.h @@ -458,16 +458,6 @@ private: /// most recent declarations in another AST file. FirstLatestDeclIDMap FirstLatestDeclIDs; - typedef llvm::SmallVector - AdditionalTemplateSpecializations; - typedef llvm::DenseMap - AdditionalTemplateSpecializationsMap; - - /// \brief Additional specializations (including partial) of templates that - /// were introduced after the template was serialized. - AdditionalTemplateSpecializationsMap AdditionalTemplateSpecializationsPending; - /// \brief Read the records that describe the contents of declcontexts. bool ReadDeclContextStorage(llvm::BitstreamCursor &Cursor, const std::pair &Offsets, diff --git a/include/clang/Serialization/ASTWriter.h b/include/clang/Serialization/ASTWriter.h index da47e159e..45edd360b 100644 --- a/include/clang/Serialization/ASTWriter.h +++ b/include/clang/Serialization/ASTWriter.h @@ -236,16 +236,6 @@ private: llvm::SmallVector, 16> ReplacedDecls; - typedef llvm::SmallVector - AdditionalTemplateSpecializationsList; - typedef llvm::DenseMap - AdditionalTemplateSpecializationsMap; - - /// \brief Additional specializations (including partial) of templates that - /// were introduced after the template was serialized. - AdditionalTemplateSpecializationsMap AdditionalTemplateSpecializations; - /// \brief Statements that we've encountered while serializing a /// declaration or type. llvm::SmallVector StmtsToEmit; @@ -296,7 +286,6 @@ private: void WriteDeclUpdatesBlocks(); void WriteDeclReplacementsBlock(); void WriteDeclContextVisibleUpdate(const DeclContext *DC); - void WriteAdditionalTemplateSpecializations(); unsigned ParmVarDeclAbbrev; unsigned DeclContextLexicalAbbrev; @@ -459,13 +448,6 @@ public: UpdatedNamespaces.insert(NS); } - /// \brief Record a template specialization or partial specialization of - /// a template from a previous PCH file. - void AddAdditionalTemplateSpecialization(serialization::DeclID Templ, - serialization::DeclID Spec) { - AdditionalTemplateSpecializations[Templ].push_back(Spec); - } - /// \brief Note that the identifier II occurs at the given offset /// within the identifier table. void SetIdentifierOffset(const IdentifierInfo *II, uint32_t Offset); @@ -515,6 +497,8 @@ public: // ASTMutationListener implementation. virtual void CompletedTagDefinition(const TagDecl *D); virtual void AddedCXXImplicitMember(const CXXRecordDecl *RD, const Decl *D); + virtual void AddedCXXTemplateSpecialization(const ClassTemplateDecl *TD, + const ClassTemplateSpecializationDecl *D); }; /// \brief AST and semantic-analysis consumer that generates a diff --git a/lib/AST/DeclTemplate.cpp b/lib/AST/DeclTemplate.cpp index 36b92fa02..c07d83207 100644 --- a/lib/AST/DeclTemplate.cpp +++ b/lib/AST/DeclTemplate.cpp @@ -16,6 +16,7 @@ #include "clang/AST/Expr.h" #include "clang/AST/ASTContext.h" #include "clang/AST/TypeLoc.h" +#include "clang/AST/ASTMutationListener.h" #include "clang/Basic/IdentifierTable.h" #include "llvm/ADT/STLExtras.h" using namespace clang; @@ -225,6 +226,13 @@ ClassTemplateDecl::findSpecialization(const TemplateArgument *Args, return findSpecializationImpl(getSpecializations(), Args, NumArgs, InsertPos); } +void ClassTemplateDecl::AddSpecialization(ClassTemplateSpecializationDecl *D, + void *InsertPos) { + getSpecializations().InsertNode(D, InsertPos); + if (ASTMutationListener *L = getASTMutationListener()) + L->AddedCXXTemplateSpecialization(this, D); +} + ClassTemplatePartialSpecializationDecl * ClassTemplateDecl::findPartialSpecialization(const TemplateArgument *Args, unsigned NumArgs, @@ -233,6 +241,14 @@ ClassTemplateDecl::findPartialSpecialization(const TemplateArgument *Args, InsertPos); } +void ClassTemplateDecl::AddPartialSpecialization( + ClassTemplatePartialSpecializationDecl *D, + void *InsertPos) { + getPartialSpecializations().InsertNode(D, InsertPos); + if (ASTMutationListener *L = getASTMutationListener()) + L->AddedCXXTemplateSpecialization(this, D); +} + void ClassTemplateDecl::getPartialSpecializations( llvm::SmallVectorImpl &PS) { llvm::FoldingSet &PartialSpecs diff --git a/lib/Serialization/ASTCommon.h b/lib/Serialization/ASTCommon.h index 5ed607a86..5ded8057e 100644 --- a/lib/Serialization/ASTCommon.h +++ b/lib/Serialization/ASTCommon.h @@ -22,7 +22,8 @@ namespace serialization { enum DeclUpdateKind { UPD_CXX_SET_DEFINITIONDATA, - UPD_CXX_ADDED_IMPLICIT_MEMBER + UPD_CXX_ADDED_IMPLICIT_MEMBER, + UPD_CXX_ADDED_TEMPLATE_SPECIALIZATION }; TypeIdx TypeIdxFromBuiltin(const BuiltinType *BT); diff --git a/lib/Serialization/ASTReader.cpp b/lib/Serialization/ASTReader.cpp index c0aff9afd..f09873a07 100644 --- a/lib/Serialization/ASTReader.cpp +++ b/lib/Serialization/ASTReader.cpp @@ -2069,13 +2069,6 @@ ASTReader::ReadASTBlock(PerFileData &F) { std::make_pair(&F, Record[I+1]); break; } - - case ADDITIONAL_TEMPLATE_SPECIALIZATIONS: { - AdditionalTemplateSpecializations &ATS = - AdditionalTemplateSpecializationsPending[Record[0]]; - ATS.insert(ATS.end(), Record.begin()+1, Record.end()); - break; - } } First = false; } diff --git a/lib/Serialization/ASTReaderDecl.cpp b/lib/Serialization/ASTReaderDecl.cpp index b815878a6..ea995af7f 100644 --- a/lib/Serialization/ASTReaderDecl.cpp +++ b/lib/Serialization/ASTReaderDecl.cpp @@ -1553,20 +1553,6 @@ Decl *ASTReader::ReadDeclRecord(unsigned Index, DeclID ID) { } } } - - // If this is a template, read additional specializations that may be in a - // different part of the chain. - if (isa(D)) { - AdditionalTemplateSpecializationsMap::iterator F = - AdditionalTemplateSpecializationsPending.find(ID); - if (F != AdditionalTemplateSpecializationsPending.end()) { - for (AdditionalTemplateSpecializations::iterator I = F->second.begin(), - E = F->second.end(); - I != E; ++I) - GetDecl(*I); - AdditionalTemplateSpecializationsPending.erase(F); - } - } assert(Idx == Record.size()); // The declaration may have been modified by files later in the chain. @@ -1617,6 +1603,10 @@ void ASTDeclReader::UpdateDecl(Decl *D, const RecordData &Record) { case UPD_CXX_ADDED_IMPLICIT_MEMBER: cast(D)->addedMember(Reader.GetDecl(Record[Idx++])); break; + + case UPD_CXX_ADDED_TEMPLATE_SPECIALIZATION: + // It will be added to the template's specializations set when loaded. + Reader.GetDecl(Record[Idx++]); } } } diff --git a/lib/Serialization/ASTWriter.cpp b/lib/Serialization/ASTWriter.cpp index 340f0cc55..3589b9bd9 100644 --- a/lib/Serialization/ASTWriter.cpp +++ b/lib/Serialization/ASTWriter.cpp @@ -2181,21 +2181,6 @@ void ASTWriter::WriteDeclContextVisibleUpdate(const DeclContext *DC) { Stream.EmitRecordWithBlob(UpdateVisibleAbbrev, Record, LookupTable.str()); } -/// \brief Write ADDITIONAL_TEMPLATE_SPECIALIZATIONS blocks for all templates -/// that have new specializations in the current AST file. -void ASTWriter::WriteAdditionalTemplateSpecializations() { - RecordData Record; - for (AdditionalTemplateSpecializationsMap::iterator - I = AdditionalTemplateSpecializations.begin(), - E = AdditionalTemplateSpecializations.end(); - I != E; ++I) { - Record.clear(); - Record.push_back(I->first); - Record.insert(Record.end(), I->second.begin(), I->second.end()); - Stream.EmitRecord(ADDITIONAL_TEMPLATE_SPECIALIZATIONS, Record); - } -} - //===----------------------------------------------------------------------===// // General Serialization Routines //===----------------------------------------------------------------------===// @@ -2697,10 +2682,6 @@ void ASTWriter::WriteASTChain(Sema &SemaRef, MemorizeStatCalls *StatCalls, I != E; ++I) WriteDeclContextVisibleUpdate(*I); - // Write the updates to C++ template specialization lists. - if (!AdditionalTemplateSpecializations.empty()) - WriteAdditionalTemplateSpecializations(); - WriteDeclUpdatesBlocks(); Record.clear(); @@ -3340,3 +3321,13 @@ void ASTWriter::AddedCXXImplicitMember(const CXXRecordDecl *RD, const Decl *D) { Record.push_back(UPD_CXX_ADDED_IMPLICIT_MEMBER); AddDeclRef(D, Record); } + +void ASTWriter::AddedCXXTemplateSpecialization(const ClassTemplateDecl *TD, + const ClassTemplateSpecializationDecl *D) { + if (!(D->getPCHLevel() == 0 && TD->getPCHLevel() > 0)) + return; // Not a source specialization added to a template from PCH. + + UpdateRecord &Record = DeclUpdates[TD]; + Record.push_back(UPD_CXX_ADDED_TEMPLATE_SPECIALIZATION); + AddDeclRef(D, Record); +} diff --git a/lib/Serialization/ASTWriterDecl.cpp b/lib/Serialization/ASTWriterDecl.cpp index 46f62b7d8..5b403cf71 100644 --- a/lib/Serialization/ASTWriterDecl.cpp +++ b/lib/Serialization/ASTWriterDecl.cpp @@ -905,10 +905,6 @@ void ASTDeclWriter::VisitClassTemplateSpecializationDecl( InstFromD = cast(InstFromD)-> getSpecializedTemplate(); } - // Is this a specialization of an already-serialized template? - if (InstFromD->getCanonicalDecl()->getPCHLevel() != 0) - Writer.AddAdditionalTemplateSpecialization(Writer.getDeclID(InstFromD), - Writer.getDeclID(D)); // Explicit info. Writer.AddTypeSourceInfo(D->getTypeAsWritten(), Record); -- 2.11.4.GIT