diff options
Diffstat (limited to 'clang/lib')
| -rw-r--r-- | clang/lib/AST/DeclTemplate.cpp | 17 | ||||
| -rw-r--r-- | clang/lib/Serialization/ASTReaderDecl.cpp | 30 |
2 files changed, 37 insertions, 10 deletions
diff --git a/clang/lib/AST/DeclTemplate.cpp b/clang/lib/AST/DeclTemplate.cpp index d764d2bedb1..ac0d54f5011 100644 --- a/clang/lib/AST/DeclTemplate.cpp +++ b/clang/lib/AST/DeclTemplate.cpp @@ -245,6 +245,23 @@ FunctionTemplateDecl::newCommon(ASTContext &C) const { return CommonPtr; } +void FunctionTemplateDecl::LoadLazySpecializations() const { + Common *CommonPtr = getCommonPtr(); + if (CommonPtr->LazySpecializations) { + ASTContext &Context = getASTContext(); + uint32_t *Specs = CommonPtr->LazySpecializations; + CommonPtr->LazySpecializations = 0; + for (uint32_t I = 0, N = *Specs++; I != N; ++I) + (void)Context.getExternalSource()->GetExternalDecl(Specs[I]); + } +} + +llvm::FoldingSetVector<FunctionTemplateSpecializationInfo> & +FunctionTemplateDecl::getSpecializations() const { + LoadLazySpecializations(); + return getCommonPtr()->Specializations; +} + FunctionDecl * FunctionTemplateDecl::findSpecialization(const TemplateArgument *Args, unsigned NumArgs, void *&InsertPos) { diff --git a/clang/lib/Serialization/ASTReaderDecl.cpp b/clang/lib/Serialization/ASTReaderDecl.cpp index e93eae81127..84a8b09e4e5 100644 --- a/clang/lib/Serialization/ASTReaderDecl.cpp +++ b/clang/lib/Serialization/ASTReaderDecl.cpp @@ -606,11 +606,16 @@ void ASTDeclReader::VisitFunctionDecl(FunctionDecl *FD) { FunctionTemplateSpecializationInfo::Profile(ID, TemplArgs.data(), TemplArgs.size(), C); void *InsertPos = 0; - CanonTemplate->getSpecializations().FindNodeOrInsertPos(ID, InsertPos); + FunctionTemplateDecl::Common *CommonPtr = CanonTemplate->getCommonPtr(); + CommonPtr->Specializations.FindNodeOrInsertPos(ID, InsertPos); if (InsertPos) - CanonTemplate->getSpecializations().InsertNode(FTInfo, InsertPos); - else - assert(0 && "Another specialization already inserted!"); + CommonPtr->Specializations.InsertNode(FTInfo, InsertPos); + else { + assert(Reader.getContext().getLangOpts().Modules && + "already deserialized this template specialization"); + // FIXME: This specialization is a redeclaration of one from another + // module. Merge it. + } } break; } @@ -1508,12 +1513,17 @@ void ASTDeclReader::VisitFunctionTemplateDecl(FunctionTemplateDecl *D) { if (ThisDeclID == Redecl.getFirstID()) { // This FunctionTemplateDecl owns a CommonPtr; read it. - // Read the function specialization declarations. - // FunctionTemplateDecl's FunctionTemplateSpecializationInfos are filled - // when reading the specialized FunctionDecl. - unsigned NumSpecs = Record[Idx++]; - while (NumSpecs--) - (void)ReadDecl(Record, Idx); + // Read the function specialization declaration IDs. The specializations + // themselves will be loaded if they're needed. + if (unsigned NumSpecs = Record[Idx++]) { + // FIXME: Append specializations! + FunctionTemplateDecl::Common *CommonPtr = D->getCommonPtr(); + CommonPtr->LazySpecializations = new (Reader.getContext()) + serialization::DeclID[NumSpecs + 1]; + CommonPtr->LazySpecializations[0] = NumSpecs; + for (unsigned I = 0; I != NumSpecs; ++I) + CommonPtr->LazySpecializations[I + 1] = ReadDeclID(Record, Idx); + } } } |

