@@ -342,60 +342,24 @@ void RedeclarableTemplateDecl::loadLazySpecializationsImpl(
342
342
ExternalSource->LoadExternalSpecializations (this ->getCanonicalDecl (),
343
343
OnlyPartial);
344
344
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);
371
345
}
372
346
373
- void RedeclarableTemplateDecl::loadLazySpecializationsImpl (
347
+ bool RedeclarableTemplateDecl::loadLazySpecializationsImpl (
374
348
ArrayRef<TemplateArgument> Args, TemplateParameterList *TPL) const {
375
349
auto *ExternalSource = getASTContext ().getExternalSource ();
376
350
if (!ExternalSource)
377
- return ;
378
-
379
- ExternalSource->LoadExternalSpecializations (this ->getCanonicalDecl (), Args);
380
- return ;
351
+ return false ;
381
352
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 (),
354
+ Args);
389
355
}
390
356
391
- template <class EntryType , typename ... ProfileArguments>
357
+ template <class EntryType , typename ... ProfileArguments>
392
358
typename RedeclarableTemplateDecl::SpecEntryTraits<EntryType>::DeclType *
393
- RedeclarableTemplateDecl::findSpecializationImpl (
359
+ RedeclarableTemplateDecl::findSpecializationLocally (
394
360
llvm::FoldingSetVector<EntryType> &Specs, void *&InsertPos,
395
- ProfileArguments&&... ProfileArgs) {
396
- using SETraits = SpecEntryTraits<EntryType>;
397
-
398
- loadLazySpecializationsImpl (std::forward<ProfileArguments>(ProfileArgs)...);
361
+ ProfileArguments &&...ProfileArgs) {
362
+ using SETraits = RedeclarableTemplateDecl::SpecEntryTraits<EntryType>;
399
363
400
364
llvm::FoldingSetNodeID ID;
401
365
EntryType::Profile (ID, std::forward<ProfileArguments>(ProfileArgs)...,
@@ -404,6 +368,24 @@ RedeclarableTemplateDecl::findSpecializationImpl(
404
368
return Entry ? SETraits::getDecl (Entry)->getMostRecentDecl () : nullptr ;
405
369
}
406
370
371
+ template <class EntryType , typename ... ProfileArguments>
372
+ typename RedeclarableTemplateDecl::SpecEntryTraits<EntryType>::DeclType *
373
+ RedeclarableTemplateDecl::findSpecializationImpl (
374
+ llvm::FoldingSetVector<EntryType> &Specs, void *&InsertPos,
375
+ ProfileArguments &&...ProfileArgs) {
376
+
377
+ if (auto *Found = findSpecializationLocally (
378
+ Specs, InsertPos, std::forward<ProfileArguments>(ProfileArgs)...))
379
+ return Found;
380
+
381
+ if (!loadLazySpecializationsImpl (
382
+ std::forward<ProfileArguments>(ProfileArgs)...))
383
+ return nullptr ;
384
+
385
+ return findSpecializationLocally (
386
+ Specs, InsertPos, std::forward<ProfileArguments>(ProfileArgs)...);
387
+ }
388
+
407
389
template <class Derived , class EntryType >
408
390
void RedeclarableTemplateDecl::addSpecializationImpl (
409
391
llvm::FoldingSetVector<EntryType> &Specializations, EntryType *Entry,
@@ -939,7 +921,20 @@ TemplateArgumentList::CreateCopy(ASTContext &Context,
939
921
return new (Mem) TemplateArgumentList (Args);
940
922
}
941
923
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.
943
938
ODRHash Hasher;
944
939
for (TemplateArgument TA : Args)
945
940
Hasher.AddTemplateArgument (TA);
0 commit comments