From: Sebastian Redl Date: Tue, 24 Aug 2010 22:50:19 +0000 (+0000) Subject: AST reader support for having specializations of templates from earlier in the chain. X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=6e50e00c2fe6a04b2c35592588a4b10a2c269416;p=clang AST reader support for having specializations of templates from earlier in the chain. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@111985 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/include/clang/Serialization/ASTBitCodes.h b/include/clang/Serialization/ASTBitCodes.h index 3341679965..d879fdf402 100644 --- a/include/clang/Serialization/ASTBitCodes.h +++ b/include/clang/Serialization/ASTBitCodes.h @@ -316,7 +316,11 @@ namespace clang { /// \brief Record code for an update to a decl context's lookup table. /// /// In practice, this should only be used for the TU and namespaces. - UPDATE_VISIBLE = 34 + UPDATE_VISIBLE = 34, + + /// \brief Record code for template specializations introduced after + /// serializations of the original template decl. + ADDITIONAL_TEMPLATE_SPECIALIZATIONS = 35 }; /// \brief Record types used within a source manager block. diff --git a/include/clang/Serialization/ASTReader.h b/include/clang/Serialization/ASTReader.h index 889605e34d..12fb3163f8 100644 --- a/include/clang/Serialization/ASTReader.h +++ b/include/clang/Serialization/ASTReader.h @@ -372,6 +372,16 @@ 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/lib/Serialization/ASTReader.cpp b/lib/Serialization/ASTReader.cpp index 46448fff0c..9acc759fc9 100644 --- a/lib/Serialization/ASTReader.cpp +++ b/lib/Serialization/ASTReader.cpp @@ -1972,6 +1972,13 @@ 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 d2fb408e56..d5649ad7be 100644 --- a/lib/Serialization/ASTReaderDecl.cpp +++ b/lib/Serialization/ASTReaderDecl.cpp @@ -1424,6 +1424,20 @@ 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()); // If we have deserialized a declaration that has a definition the