@@ -342,68 +342,50 @@ void RedeclarableTemplateDecl::loadLazySpecializationsImpl(
342342 ExternalSource->LoadExternalSpecializations (this ->getCanonicalDecl (),
343343 OnlyPartial);
344344 return ;
345-
346- // Grab the most recent declaration to ensure we've loaded any lazy
347- // redeclarations of this template.
348- CommonBase *CommonBasePtr = getMostRecentDecl ()->getCommonPtr ();
349- if (auto *Specs = CommonBasePtr->LazySpecializations ) {
350- if (!OnlyPartial)
351- CommonBasePtr->LazySpecializations = nullptr ;
352- for (uint32_t I = 0 , N = Specs[0 ].DeclID ; I != N; ++I) {
353- // Skip over already loaded specializations.
354- if (!Specs[I + 1 ].ODRHash )
355- continue ;
356- if (!OnlyPartial || Specs[I + 1 ].IsPartial )
357- (void )loadLazySpecializationImpl (Specs[I + 1 ]);
358- }
359- }
360- }
361-
362- Decl *RedeclarableTemplateDecl::loadLazySpecializationImpl (
363- LazySpecializationInfo &LazySpecInfo) const {
364- llvm_unreachable (" We don't use LazySpecializationInfo any more" );
365-
366- uint32_t ID = LazySpecInfo.DeclID ;
367- assert (ID && " Loading already loaded specialization!" );
368- // Note that we loaded the specialization.
369- LazySpecInfo.DeclID = LazySpecInfo.ODRHash = LazySpecInfo.IsPartial = 0 ;
370- return getASTContext ().getExternalSource ()->GetExternalDecl (ID);
371345}
372346
373- void RedeclarableTemplateDecl::loadLazySpecializationsImpl (
347+ bool RedeclarableTemplateDecl::loadLazySpecializationsImpl (
374348 ArrayRef<TemplateArgument> Args, TemplateParameterList *TPL) const {
375349 auto *ExternalSource = getASTContext ().getExternalSource ();
376350 if (!ExternalSource)
377- return ;
378-
379- ExternalSource->LoadExternalSpecializations (this ->getCanonicalDecl (), Args);
380- return ;
351+ return false ;
381352
382- CommonBase *CommonBasePtr = getMostRecentDecl ()->getCommonPtr ();
383- if (auto *Specs = CommonBasePtr->LazySpecializations ) {
384- unsigned Hash = TemplateArgumentList::ComputeODRHash (Args);
385- for (uint32_t I = 0 , N = Specs[0 ].DeclID ; I != N; ++I)
386- if (Specs[I + 1 ].ODRHash && Specs[I + 1 ].ODRHash == Hash)
387- (void )loadLazySpecializationImpl (Specs[I + 1 ]);
388- }
353+ return ExternalSource->LoadExternalSpecializations (this ->getCanonicalDecl (), Args);
389354}
390355
391356template <class EntryType , typename ... ProfileArguments>
357+ static
392358typename RedeclarableTemplateDecl::SpecEntryTraits<EntryType>::DeclType *
393- RedeclarableTemplateDecl::findSpecializationImpl (
394- llvm::FoldingSetVector<EntryType> &Specs, void *&InsertPos ,
359+ findSpecializationLocally (llvm::FoldingSetVector<EntryType> &Specs, void *&InsertPos,
360+ ASTContext &Context ,
395361 ProfileArguments&&... ProfileArgs) {
396- using SETraits = SpecEntryTraits<EntryType>;
397-
398- loadLazySpecializationsImpl (std::forward<ProfileArguments>(ProfileArgs)...);
362+ using SETraits = RedeclarableTemplateDecl::SpecEntryTraits<EntryType>;
399363
400364 llvm::FoldingSetNodeID ID;
401365 EntryType::Profile (ID, std::forward<ProfileArguments>(ProfileArgs)...,
402- getASTContext () );
366+ Context );
403367 EntryType *Entry = Specs.FindNodeOrInsertPos (ID, InsertPos);
404368 return Entry ? SETraits::getDecl (Entry)->getMostRecentDecl () : nullptr ;
405369}
406370
371+
372+ template <class EntryType , typename ... ProfileArguments>
373+ typename RedeclarableTemplateDecl::SpecEntryTraits<EntryType>::DeclType *
374+ RedeclarableTemplateDecl::findSpecializationImpl (
375+ llvm::FoldingSetVector<EntryType> &Specs, void *&InsertPos,
376+ ProfileArguments&&... ProfileArgs) {
377+
378+ if (auto *Found = findSpecializationLocally (Specs, InsertPos, getASTContext (),
379+ std::forward<ProfileArguments>(ProfileArgs)...))
380+ return Found;
381+
382+ if (!loadLazySpecializationsImpl (std::forward<ProfileArguments>(ProfileArgs)...))
383+ return nullptr ;
384+
385+ return findSpecializationLocally (Specs, InsertPos, getASTContext (),
386+ std::forward<ProfileArguments>(ProfileArgs)...);
387+ }
388+
407389template <class Derived , class EntryType >
408390void RedeclarableTemplateDecl::addSpecializationImpl (
409391 llvm::FoldingSetVector<EntryType> &Specializations, EntryType *Entry,
@@ -939,7 +921,20 @@ TemplateArgumentList::CreateCopy(ASTContext &Context,
939921 return new (Mem) TemplateArgumentList (Args);
940922}
941923
942- unsigned TemplateArgumentList::ComputeODRHash (ArrayRef<TemplateArgument> Args) {
924+ unsigned
925+ TemplateArgumentList::ComputeStableHash (ArrayRef<TemplateArgument> Args) {
926+ // FIXME: ODR hashing may not be the best mechanism to hash the template
927+ // arguments. ODR hashing is (or perhaps, should be) about determining whether
928+ // two things are spelled the same way and have the same meaning (as required
929+ // by the C++ ODR), whereas what we want here is whether they have the same
930+ // meaning regardless of spelling. Maybe we can get away with reusing ODR
931+ // hashing anyway, on the basis that any canonical, non-dependent template
932+ // argument should have the same (invented) spelling in every translation
933+ // unit, but it is not sure that's true in all cases. There may still be cases
934+ // where the canonical type includes some aspect of "whatever we saw first",
935+ // in which case the ODR hash can differ across translation units for
936+ // non-dependent, canonical template arguments that are spelled differently
937+ // but have the same meaning. But it is not easy to raise examples.
943938 ODRHash Hasher;
944939 for (TemplateArgument TA : Args)
945940 Hasher.AddTemplateArgument (TA);
0 commit comments