Index: lib/Serialization/ASTReaderDecl.cpp =================================================================== --- lib/Serialization/ASTReaderDecl.cpp +++ lib/Serialization/ASTReaderDecl.cpp @@ -206,6 +206,30 @@ DeclContext *DC); FindExistingResult findExisting(NamedDecl *D); + template + void AddLazySpecializations(T *D, + SmallVectorImpl& IDs) { + assert(!IDs.empty() && "no IDs to add to list"); + assert(isa(D) || + isa(D) && + "Decl doesn't have specializations."); + + auto *CommonPtr = D->getCommonPtr(); + ASTContext &C = Reader.getContext(); + + if (auto &Old = CommonPtr->LazySpecializations) { + IDs.insert(IDs.end(), Old + 1, Old + 1 + Old[0]); + std::sort(IDs.begin(), IDs.end()); + IDs.erase(std::unique(IDs.begin(), IDs.end()), IDs.end()); + } + + auto *Result = new (C) DeclID[1 + IDs.size()]; + *Result = IDs.size(); + std::copy(IDs.begin(), IDs.end(), Result + 1); + + CommonPtr->LazySpecializations = Result; + } + public: ASTDeclReader(ASTReader &Reader, ASTRecordReader &Record, ASTReader::RecordLocation Loc, @@ -1951,21 +1975,6 @@ return Redecl; } -static DeclID *newDeclIDList(ASTContext &Context, DeclID *Old, - SmallVectorImpl &IDs) { - assert(!IDs.empty() && "no IDs to add to list"); - if (Old) { - IDs.insert(IDs.end(), Old + 1, Old + 1 + Old[0]); - std::sort(IDs.begin(), IDs.end()); - IDs.erase(std::unique(IDs.begin(), IDs.end()), IDs.end()); - } - - auto *Result = new (Context) DeclID[1 + IDs.size()]; - *Result = IDs.size(); - std::copy(IDs.begin(), IDs.end(), Result + 1); - return Result; -} - void ASTDeclReader::VisitClassTemplateDecl(ClassTemplateDecl *D) { RedeclarableResult Redecl = VisitRedeclarableTemplateDecl(D); @@ -1975,11 +1984,8 @@ SmallVector SpecIDs; ReadDeclIDList(SpecIDs); - if (!SpecIDs.empty()) { - auto *CommonPtr = D->getCommonPtr(); - CommonPtr->LazySpecializations = newDeclIDList( - Reader.getContext(), CommonPtr->LazySpecializations, SpecIDs); - } + if (!SpecIDs.empty()) + AddLazySpecializations(D, SpecIDs); } if (D->getTemplatedDecl()->TemplateOrInstantiation) { @@ -2007,11 +2013,8 @@ SmallVector SpecIDs; ReadDeclIDList(SpecIDs); - if (!SpecIDs.empty()) { - auto *CommonPtr = D->getCommonPtr(); - CommonPtr->LazySpecializations = newDeclIDList( - Reader.getContext(), CommonPtr->LazySpecializations, SpecIDs); - } + if (!SpecIDs.empty()) + AddLazySpecializations(D, SpecIDs); } } @@ -2118,11 +2121,8 @@ SmallVector SpecIDs; ReadDeclIDList(SpecIDs); - if (!SpecIDs.empty()) { - auto *CommonPtr = D->getCommonPtr(); - CommonPtr->LazySpecializations = newDeclIDList( - Reader.getContext(), CommonPtr->LazySpecializations, SpecIDs); - } + if (!SpecIDs.empty()) + AddLazySpecializations(D, SpecIDs); } } @@ -3908,9 +3908,19 @@ break; } - case UPD_CXX_ADDED_TEMPLATE_SPECIALIZATION: - // It will be added to the template's specializations set when loaded. - (void)Record.readDecl(); + case UPD_CXX_ADDED_TEMPLATE_SPECIALIZATION: { + // It will be added to the template's lazy specialization set when loaded. + SmallVector SpecID; + SpecID.push_back(ReadDeclID()); + if (auto *CTD = dyn_cast(D)) + AddLazySpecializations(CTD, SpecID); + else if (auto *FTD = dyn_cast(D)) + AddLazySpecializations(FTD, SpecID); + else if (auto *VTD = dyn_cast(D)) + AddLazySpecializations(VTD, SpecID); + else // TypeAliasTemplateDecl + llvm_unreachable("TypeAliasTemplateDecl doesn't have specs!"); + } break; case UPD_CXX_ADDED_ANONYMOUS_NAMESPACE: {