diff options
author | Richard Smith <richard-llvm@metafoo.co.uk> | 2015-02-27 23:05:10 +0000 |
---|---|---|
committer | Richard Smith <richard-llvm@metafoo.co.uk> | 2015-02-27 23:05:10 +0000 |
commit | 509fc85b4ee7216178e3945c37de89f3482484a1 (patch) | |
tree | c9e569228c17b9ad2ecc8828cea63ec5dd0a88d4 /clang | |
parent | 86ee1737122a486aadb2862b977175f65b4a3aa5 (diff) | |
download | bcm5719-llvm-509fc85b4ee7216178e3945c37de89f3482484a1.tar.gz bcm5719-llvm-509fc85b4ee7216178e3945c37de89f3482484a1.zip |
[modules] When writing out a list of specializations for a template, if we have
undeserialized specializations (because we merged an imported declaration of
the same template since we last added one), don't bother reading in the
specializations themselves just so we can write out their IDs again.
llvm-svn: 230805
Diffstat (limited to 'clang')
-rw-r--r-- | clang/lib/Serialization/ASTReaderDecl.cpp | 6 | ||||
-rw-r--r-- | clang/lib/Serialization/ASTWriterDecl.cpp | 109 |
2 files changed, 58 insertions, 57 deletions
diff --git a/clang/lib/Serialization/ASTReaderDecl.cpp b/clang/lib/Serialization/ASTReaderDecl.cpp index 97e43b700b9..ab0f00b7b98 100644 --- a/clang/lib/Serialization/ASTReaderDecl.cpp +++ b/clang/lib/Serialization/ASTReaderDecl.cpp @@ -1748,9 +1748,6 @@ void ASTDeclReader::VisitClassTemplateDecl(ClassTemplateDecl *D) { // This ClassTemplateDecl owns a CommonPtr; read it to keep track of all of // the specializations. SmallVector<serialization::DeclID, 32> SpecIDs; - // Specializations. - ReadDeclIDList(SpecIDs); - // Partial specializations. ReadDeclIDList(SpecIDs); if (!SpecIDs.empty()) { @@ -1779,9 +1776,6 @@ void ASTDeclReader::VisitVarTemplateDecl(VarTemplateDecl *D) { // This VarTemplateDecl owns a CommonPtr; read it to keep track of all of // the specializations. SmallVector<serialization::DeclID, 32> SpecIDs; - // Specializations. - ReadDeclIDList(SpecIDs); - // Partial specializations. ReadDeclIDList(SpecIDs); if (!SpecIDs.empty()) { diff --git a/clang/lib/Serialization/ASTWriterDecl.cpp b/clang/lib/Serialization/ASTWriterDecl.cpp index 7f2e80583e5..e4353cd41d0 100644 --- a/clang/lib/Serialization/ASTWriterDecl.cpp +++ b/clang/lib/Serialization/ASTWriterDecl.cpp @@ -138,6 +138,58 @@ namespace clang { CD->NumCtorInitializers, Record); Writer.AddStmt(FD->getBody()); } + + /// Get the specialization decl from an entry in the specialization list. + template <typename EntryType> + typename RedeclarableTemplateDecl::SpecEntryTraits<EntryType>::DeclType * + getSpecializationDecl(EntryType &T) { + return RedeclarableTemplateDecl::SpecEntryTraits<EntryType>::getDecl(&T); + } + + /// Get the list of partial specializations from a template's common ptr. + template<typename T> + decltype(T::PartialSpecializations) &getPartialSpecializations(T *Common) { + return Common->PartialSpecializations; + } + ArrayRef<Decl> getPartialSpecializations(FunctionTemplateDecl::Common *) { + return None; + } + + template<typename Decl> + void AddTemplateSpecializations(Decl *D) { + auto *Common = D->getCommonPtr(); + + // If we have any lazy specializations, and the external AST source is + // our chained AST reader, we can just write out the DeclIDs. Otherwise, + // we need to resolve them to actual declarations. + if (Writer.Chain != Writer.Context->getExternalSource() && + Common->LazySpecializations) { + D->LoadLazySpecializations(); + assert(!Common->LazySpecializations); + } + + auto &Specializations = Common->Specializations; + auto &&PartialSpecializations = getPartialSpecializations(Common); + ArrayRef<DeclID> LazySpecializations; + if (auto *LS = Common->LazySpecializations) + LazySpecializations = ArrayRef<DeclID>(LS + 1, LS + 1 + LS[0]); + + Record.push_back(Specializations.size() + + PartialSpecializations.size() + + LazySpecializations.size()); + for (auto &Entry : Specializations) { + auto *D = getSpecializationDecl(Entry); + assert(D->isCanonicalDecl() && "non-canonical decl in set"); + Writer.AddDeclRef(D, Record); + } + for (auto &Entry : PartialSpecializations) { + auto *D = getSpecializationDecl(Entry); + assert(D->isCanonicalDecl() && "non-canonical decl in set"); + Writer.AddDeclRef(D, Record); + } + for (DeclID ID : LazySpecializations) + Record.push_back(ID); + } }; } @@ -1172,24 +1224,8 @@ void ASTDeclWriter::VisitRedeclarableTemplateDecl(RedeclarableTemplateDecl *D) { void ASTDeclWriter::VisitClassTemplateDecl(ClassTemplateDecl *D) { VisitRedeclarableTemplateDecl(D); - if (D->isFirstDecl()) { - typedef llvm::FoldingSetVector<ClassTemplateSpecializationDecl> CTSDSetTy; - CTSDSetTy &CTSDSet = D->getSpecializations(); - Record.push_back(CTSDSet.size()); - for (CTSDSetTy::iterator I=CTSDSet.begin(), E = CTSDSet.end(); I!=E; ++I) { - assert(I->isCanonicalDecl() && "Expected only canonical decls in set"); - Writer.AddDeclRef(&*I, Record); - } - - typedef llvm::FoldingSetVector<ClassTemplatePartialSpecializationDecl> - CTPSDSetTy; - CTPSDSetTy &CTPSDSet = D->getPartialSpecializations(); - Record.push_back(CTPSDSet.size()); - for (CTPSDSetTy::iterator I=CTPSDSet.begin(), E=CTPSDSet.end(); I!=E; ++I) { - assert(I->isCanonicalDecl() && "Expected only canonical decls in set"); - Writer.AddDeclRef(&*I, Record); - } - } + if (D->isFirstDecl()) + AddTemplateSpecializations(D); Code = serialization::DECL_CLASS_TEMPLATE; } @@ -1247,26 +1283,8 @@ void ASTDeclWriter::VisitClassTemplatePartialSpecializationDecl( void ASTDeclWriter::VisitVarTemplateDecl(VarTemplateDecl *D) { VisitRedeclarableTemplateDecl(D); - if (D->isFirstDecl()) { - typedef llvm::FoldingSetVector<VarTemplateSpecializationDecl> VTSDSetTy; - VTSDSetTy &VTSDSet = D->getSpecializations(); - Record.push_back(VTSDSet.size()); - for (VTSDSetTy::iterator I = VTSDSet.begin(), E = VTSDSet.end(); I != E; - ++I) { - assert(I->isCanonicalDecl() && "Expected only canonical decls in set"); - Writer.AddDeclRef(&*I, Record); - } - - typedef llvm::FoldingSetVector<VarTemplatePartialSpecializationDecl> - VTPSDSetTy; - VTPSDSetTy &VTPSDSet = D->getPartialSpecializations(); - Record.push_back(VTPSDSet.size()); - for (VTPSDSetTy::iterator I = VTPSDSet.begin(), E = VTPSDSet.end(); I != E; - ++I) { - assert(I->isCanonicalDecl() && "Expected only canonical decls in set"); - Writer.AddDeclRef(&*I, Record); - } - } + if (D->isFirstDecl()) + AddTemplateSpecializations(D); Code = serialization::DECL_VAR_TEMPLATE; } @@ -1331,19 +1349,8 @@ void ASTDeclWriter::VisitClassScopeFunctionSpecializationDecl( void ASTDeclWriter::VisitFunctionTemplateDecl(FunctionTemplateDecl *D) { VisitRedeclarableTemplateDecl(D); - if (D->isFirstDecl()) { - // This FunctionTemplateDecl owns the CommonPtr; write it. - - // Write the function specialization declarations. - Record.push_back(D->getSpecializations().size()); - for (llvm::FoldingSetVector<FunctionTemplateSpecializationInfo>::iterator - I = D->getSpecializations().begin(), - E = D->getSpecializations().end() ; I != E; ++I) { - assert(I->Function->isCanonicalDecl() && - "Expected only canonical decls in set"); - Writer.AddDeclRef(I->Function, Record); - } - } + if (D->isFirstDecl()) + AddTemplateSpecializations(D); Code = serialization::DECL_FUNCTION_TEMPLATE; } |