Index: include/clang/AST/DeclTemplate.h =================================================================== --- include/clang/AST/DeclTemplate.h +++ include/clang/AST/DeclTemplate.h @@ -800,6 +800,8 @@ return SpecIterator(isEnd ? Specs.end() : Specs.begin()); } + void loadLazySpecializationsImpl() const; + template typename SpecEntryTraits::DeclType* findSpecializationImpl(llvm::FoldingSetVector &Specs, ArrayRef Args, void *&InsertPos); @@ -818,6 +820,13 @@ /// was explicitly specialized. llvm::PointerIntPair InstantiatedFromMember; + + /// \brief If non-null, points to an array of specializations (including + /// partial specializations) known only by their external declaration IDs. + /// + /// The first value in the array is the number of specializations/partial + /// specializations that follow. + uint32_t *LazySpecializations = nullptr; }; /// \brief Pointer to the common data shared by all declarations of this @@ -985,13 +994,6 @@ /// require the use of this information. TemplateArgument *InjectedArgs = nullptr; - /// \brief If non-null, points to an array of specializations known only - /// by their external declaration IDs. - /// - /// The first value in the array is the number of of specializations - /// that follow. - uint32_t *LazySpecializations = nullptr; - Common() = default; }; @@ -2075,13 +2077,6 @@ /// \brief The injected-class-name type for this class template. QualType InjectedClassNameType; - /// \brief If non-null, points to an array of specializations (including - /// partial specializations) known only by their external declaration IDs. - /// - /// The first value in the array is the number of of specializations/ - /// partial specializations that follow. - uint32_t *LazySpecializations = nullptr; - Common() = default; }; @@ -2895,13 +2890,6 @@ llvm::FoldingSetVector PartialSpecializations; - /// \brief If non-null, points to an array of specializations (including - /// partial specializations) known ownly by their external declaration IDs. - /// - /// The first value in the array is the number of of specializations/ - /// partial specializations that follow. - uint32_t *LazySpecializations = nullptr; - Common() = default; }; Index: lib/AST/DeclTemplate.cpp =================================================================== --- lib/AST/DeclTemplate.cpp +++ lib/AST/DeclTemplate.cpp @@ -182,6 +182,21 @@ return Common; } +void RedeclarableTemplateDecl::loadLazySpecializationsImpl() const { + // Grab the most recent declaration to ensure we've loaded any lazy + // redeclarations of this template. + // + // FIXME: Avoid walking the entire redeclaration chain here. + CommonBase *CommonBasePtr = getMostRecentDecl()->getCommonPtr(); + if (CommonBasePtr->LazySpecializations) { + ASTContext &Context = getASTContext(); + uint32_t *Specs = CommonBasePtr->LazySpecializations; + CommonBasePtr->LazySpecializations = nullptr; + for (uint32_t I = 0, N = *Specs++; I != N; ++I) + (void)Context.getExternalSource()->GetExternalDecl(Specs[I]); + } +} + template typename RedeclarableTemplateDecl::SpecEntryTraits::DeclType * RedeclarableTemplateDecl::findSpecializationImpl( @@ -190,7 +205,7 @@ using SETraits = SpecEntryTraits; llvm::FoldingSetNodeID ID; - EntryType::Profile(ID,Args, getASTContext()); + EntryType::Profile(ID, Args, getASTContext()); EntryType *Entry = Specs.FindNodeOrInsertPos(ID, InsertPos); return Entry ? SETraits::getDecl(Entry)->getMostRecentDecl() : nullptr; } @@ -251,18 +266,7 @@ } void FunctionTemplateDecl::LoadLazySpecializations() const { - // Grab the most recent declaration to ensure we've loaded any lazy - // redeclarations of this template. - // - // FIXME: Avoid walking the entire redeclaration chain here. - Common *CommonPtr = getMostRecentDecl()->getCommonPtr(); - if (CommonPtr->LazySpecializations) { - ASTContext &Context = getASTContext(); - uint32_t *Specs = CommonPtr->LazySpecializations; - CommonPtr->LazySpecializations = nullptr; - for (uint32_t I = 0, N = *Specs++; I != N; ++I) - (void)Context.getExternalSource()->GetExternalDecl(Specs[I]); - } + loadLazySpecializationsImpl(); } llvm::FoldingSetVector & @@ -330,18 +334,7 @@ } void ClassTemplateDecl::LoadLazySpecializations() const { - // Grab the most recent declaration to ensure we've loaded any lazy - // redeclarations of this template. - // - // FIXME: Avoid walking the entire redeclaration chain here. - Common *CommonPtr = getMostRecentDecl()->getCommonPtr(); - if (CommonPtr->LazySpecializations) { - ASTContext &Context = getASTContext(); - uint32_t *Specs = CommonPtr->LazySpecializations; - CommonPtr->LazySpecializations = nullptr; - for (uint32_t I = 0, N = *Specs++; I != N; ++I) - (void)Context.getExternalSource()->GetExternalDecl(Specs[I]); - } + loadLazySpecializationsImpl(); } llvm::FoldingSetVector & @@ -941,21 +934,8 @@ DeclarationName(), nullptr, nullptr); } -// TODO: Unify across class, function and variable templates? -// May require moving this and Common to RedeclarableTemplateDecl. void VarTemplateDecl::LoadLazySpecializations() const { - // Grab the most recent declaration to ensure we've loaded any lazy - // redeclarations of this template. - // - // FIXME: Avoid walking the entire redeclaration chain here. - Common *CommonPtr = getMostRecentDecl()->getCommonPtr(); - if (CommonPtr->LazySpecializations) { - ASTContext &Context = getASTContext(); - uint32_t *Specs = CommonPtr->LazySpecializations; - CommonPtr->LazySpecializations = nullptr; - for (uint32_t I = 0, N = *Specs++; I != N; ++I) - (void)Context.getExternalSource()->GetExternalDecl(Specs[I]); - } + loadLazySpecializationsImpl(); } llvm::FoldingSetVector &