Skip to content

Commit 493cb7c

Browse files
committed
[Serialization] Code cleanups and polish 83233
1 parent 1172643 commit 493cb7c

24 files changed

+616
-287
lines changed

clang/include/clang/AST/DeclTemplate.h

Lines changed: 7 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -262,9 +262,6 @@ class TemplateArgumentList final
262262
TemplateArgumentList(const TemplateArgumentList &) = delete;
263263
TemplateArgumentList &operator=(const TemplateArgumentList &) = delete;
264264

265-
/// Create hash for the given arguments.
266-
static unsigned ComputeODRHash(ArrayRef<TemplateArgument> Args);
267-
268265
/// Create a new template argument list that copies the given set of
269266
/// template arguments.
270267
static TemplateArgumentList *CreateCopy(ASTContext &Context,
@@ -738,25 +735,6 @@ class RedeclarableTemplateDecl : public TemplateDecl,
738735
}
739736

740737
void anchor() override;
741-
struct LazySpecializationInfo {
742-
GlobalDeclID DeclID = GlobalDeclID();
743-
unsigned ODRHash = ~0U;
744-
bool IsPartial = false;
745-
LazySpecializationInfo(GlobalDeclID ID, unsigned Hash = ~0U,
746-
bool Partial = false)
747-
: DeclID(ID), ODRHash(Hash), IsPartial(Partial) {}
748-
LazySpecializationInfo() {}
749-
bool operator<(const LazySpecializationInfo &Other) const {
750-
return DeclID < Other.DeclID;
751-
}
752-
bool operator==(const LazySpecializationInfo &Other) const {
753-
assert((DeclID != Other.DeclID || ODRHash == Other.ODRHash) &&
754-
"Hashes differ!");
755-
assert((DeclID != Other.DeclID || IsPartial == Other.IsPartial) &&
756-
"Both must be the same kinds!");
757-
return DeclID == Other.DeclID;
758-
}
759-
};
760738

761739
protected:
762740
template <typename EntryType> struct SpecEntryTraits {
@@ -800,16 +778,20 @@ class RedeclarableTemplateDecl : public TemplateDecl,
800778

801779
void loadLazySpecializationsImpl(bool OnlyPartial = false) const;
802780

803-
void loadLazySpecializationsImpl(llvm::ArrayRef<TemplateArgument> Args,
781+
bool loadLazySpecializationsImpl(llvm::ArrayRef<TemplateArgument> Args,
804782
TemplateParameterList *TPL = nullptr) const;
805783

806-
Decl *loadLazySpecializationImpl(LazySpecializationInfo &LazySpecInfo) const;
807-
808784
template <class EntryType, typename ...ProfileArguments>
809785
typename SpecEntryTraits<EntryType>::DeclType*
810786
findSpecializationImpl(llvm::FoldingSetVector<EntryType> &Specs,
811787
void *&InsertPos, ProfileArguments &&...ProfileArgs);
812788

789+
template <class EntryType, typename... ProfileArguments>
790+
typename SpecEntryTraits<EntryType>::DeclType *
791+
findSpecializationLocally(llvm::FoldingSetVector<EntryType> &Specs,
792+
void *&InsertPos,
793+
ProfileArguments &&...ProfileArgs);
794+
813795
template <class Derived, class EntryType>
814796
void addSpecializationImpl(llvm::FoldingSetVector<EntryType> &Specs,
815797
EntryType *Entry, void *InsertPos);

clang/include/clang/AST/ExternalASTSource.h

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -155,11 +155,15 @@ class ExternalASTSource : public RefCountedBase<ExternalASTSource> {
155155
/// Load all the external specializations for the Decl \param D if \param
156156
/// OnlyPartial is false. Otherwise, load all the external **partial**
157157
/// specializations for the \param D.
158-
virtual void LoadExternalSpecializations(const Decl *D, bool OnlyPartial);
158+
///
159+
/// Return true if any new specializations get loaded. Return false otherwise.
160+
virtual bool LoadExternalSpecializations(const Decl *D, bool OnlyPartial);
159161

160162
/// Load all the specializations for the Decl \param D with the same template
161163
/// args specified by \param TemplateArgs.
162-
virtual void
164+
///
165+
/// Return true if any new specializations get loaded. Return false otherwise.
166+
virtual bool
163167
LoadExternalSpecializations(const Decl *D,
164168
ArrayRef<TemplateArgument> TemplateArgs);
165169

clang/include/clang/Sema/MultiplexExternalSemaSource.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -97,9 +97,9 @@ class MultiplexExternalSemaSource : public ExternalSemaSource {
9797
bool FindExternalVisibleDeclsByName(const DeclContext *DC,
9898
DeclarationName Name) override;
9999

100-
void LoadExternalSpecializations(const Decl *D, bool OnlyPartial) override;
100+
bool LoadExternalSpecializations(const Decl *D, bool OnlyPartial) override;
101101

102-
void
102+
bool
103103
LoadExternalSpecializations(const Decl *D,
104104
ArrayRef<TemplateArgument> TemplateArgs) override;
105105

clang/include/clang/Serialization/ASTBitCodes.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -737,6 +737,8 @@ enum ASTRecordTypes {
737737

738738
/// Record code for updated specialization
739739
UPDATE_SPECIALIZATION = 73,
740+
741+
CXX_ADDED_TEMPLATE_SPECIALIZATION = 74,
740742
};
741743

742744
/// Record types used within a source manager block.

clang/include/clang/Serialization/ASTReader.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2098,9 +2098,9 @@ class ASTReader
20982098
unsigned BlockID,
20992099
uint64_t *StartOfBlockOffset = nullptr);
21002100

2101-
void LoadExternalSpecializations(const Decl *D, bool OnlyPartial) override;
2101+
bool LoadExternalSpecializations(const Decl *D, bool OnlyPartial) override;
21022102

2103-
void
2103+
bool
21042104
LoadExternalSpecializations(const Decl *D,
21052105
ArrayRef<TemplateArgument> TemplateArgs) override;
21062106

clang/lib/AST/DeclTemplate.cpp

Lines changed: 31 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -362,63 +362,30 @@ void RedeclarableTemplateDecl::loadLazySpecializationsImpl(
362362
ExternalSource->LoadExternalSpecializations(this->getCanonicalDecl(),
363363
OnlyPartial);
364364
return;
365-
366-
// Grab the most recent declaration to ensure we've loaded any lazy
367-
// redeclarations of this template.
368-
CommonBase *CommonBasePtr = getMostRecentDecl()->getCommonPtr();
369-
if (auto *Specs = CommonBasePtr->LazySpecializations) {
370-
if (!OnlyPartial)
371-
CommonBasePtr->LazySpecializations = nullptr;
372-
unsigned N = Specs[0].DeclID.getRawValue();
373-
for (unsigned I = 0; I != N; ++I) {
374-
// Skip over already loaded specializations.
375-
if (!Specs[I + 1].ODRHash)
376-
continue;
377-
if (!OnlyPartial || Specs[I + 1].IsPartial)
378-
(void)loadLazySpecializationImpl(Specs[I + 1]);
379-
}
380-
}
381-
}
382-
383-
Decl *RedeclarableTemplateDecl::loadLazySpecializationImpl(
384-
LazySpecializationInfo &LazySpecInfo) const {
385-
llvm_unreachable("We don't use LazySpecializationInfo any more");
386-
387-
GlobalDeclID ID = LazySpecInfo.DeclID;
388-
assert(ID.isValid() && "Loading already loaded specialization!");
389-
// Note that we loaded the specialization.
390-
LazySpecInfo.DeclID = GlobalDeclID();
391-
LazySpecInfo.ODRHash = LazySpecInfo.IsPartial = 0;
392-
return getASTContext().getExternalSource()->GetExternalDecl(ID);
393365
}
394366

395-
void RedeclarableTemplateDecl::loadLazySpecializationsImpl(
367+
bool RedeclarableTemplateDecl::loadLazySpecializationsImpl(
396368
ArrayRef<TemplateArgument> Args, TemplateParameterList *TPL) const {
397369
auto *ExternalSource = getASTContext().getExternalSource();
398370
if (!ExternalSource)
399-
return;
371+
return false;
400372

401-
ExternalSource->LoadExternalSpecializations(this->getCanonicalDecl(), Args);
402-
return;
373+
// If TPL is not null, it implies that we're loading specializations for
374+
// partial templates. We need to load all specializations in such cases.
375+
if (TPL)
376+
return ExternalSource->LoadExternalSpecializations(this->getCanonicalDecl(),
377+
/*OnlyPartial=*/false);
403378

404-
CommonBase *CommonBasePtr = getMostRecentDecl()->getCommonPtr();
405-
if (auto *Specs = CommonBasePtr->LazySpecializations) {
406-
unsigned Hash = TemplateArgumentList::ComputeODRHash(Args);
407-
unsigned N = Specs[0].DeclID.getRawValue();
408-
for (unsigned I = 0; I != N; ++I)
409-
if (Specs[I + 1].ODRHash && Specs[I + 1].ODRHash == Hash)
410-
(void)loadLazySpecializationImpl(Specs[I + 1]);
411-
}
379+
return ExternalSource->LoadExternalSpecializations(this->getCanonicalDecl(),
380+
Args);
412381
}
413382

414-
template<class EntryType, typename... ProfileArguments>
383+
template <class EntryType, typename... ProfileArguments>
415384
typename RedeclarableTemplateDecl::SpecEntryTraits<EntryType>::DeclType *
416-
RedeclarableTemplateDecl::findSpecializationImpl(
385+
RedeclarableTemplateDecl::findSpecializationLocally(
417386
llvm::FoldingSetVector<EntryType> &Specs, void *&InsertPos,
418-
ProfileArguments&&... ProfileArgs) {
419-
using SETraits = SpecEntryTraits<EntryType>;
420-
421-
loadLazySpecializationsImpl(std::forward<ProfileArguments>(ProfileArgs)...);
387+
ProfileArguments &&...ProfileArgs) {
388+
using SETraits = RedeclarableTemplateDecl::SpecEntryTraits<EntryType>;
422389

423390
llvm::FoldingSetNodeID ID;
424391
EntryType::Profile(ID, std::forward<ProfileArguments>(ProfileArgs)...,
@@ -427,6 +394,24 @@ RedeclarableTemplateDecl::findSpecializationImpl(
427394
return Entry ? SETraits::getDecl(Entry)->getMostRecentDecl() : nullptr;
428395
}
429396

397+
template <class EntryType, typename... ProfileArguments>
398+
typename RedeclarableTemplateDecl::SpecEntryTraits<EntryType>::DeclType *
399+
RedeclarableTemplateDecl::findSpecializationImpl(
400+
llvm::FoldingSetVector<EntryType> &Specs, void *&InsertPos,
401+
ProfileArguments &&...ProfileArgs) {
402+
403+
if (auto *Found = findSpecializationLocally(
404+
Specs, InsertPos, std::forward<ProfileArguments>(ProfileArgs)...))
405+
return Found;
406+
407+
if (!loadLazySpecializationsImpl(
408+
std::forward<ProfileArguments>(ProfileArgs)...))
409+
return nullptr;
410+
411+
return findSpecializationLocally(
412+
Specs, InsertPos, std::forward<ProfileArguments>(ProfileArgs)...);
413+
}
414+
430415
template<class Derived, class EntryType>
431416
void RedeclarableTemplateDecl::addSpecializationImpl(
432417
llvm::FoldingSetVector<EntryType> &Specializations, EntryType *Entry,
@@ -955,14 +940,6 @@ TemplateArgumentList::CreateCopy(ASTContext &Context,
955940
return new (Mem) TemplateArgumentList(Args);
956941
}
957942

958-
unsigned TemplateArgumentList::ComputeODRHash(ArrayRef<TemplateArgument> Args) {
959-
ODRHash Hasher;
960-
for (TemplateArgument TA : Args)
961-
Hasher.AddTemplateArgument(TA);
962-
963-
return Hasher.CalculateHash();
964-
}
965-
966943
FunctionTemplateSpecializationInfo *FunctionTemplateSpecializationInfo::Create(
967944
ASTContext &C, FunctionDecl *FD, FunctionTemplateDecl *Template,
968945
TemplateSpecializationKind TSK, TemplateArgumentList *TemplateArgs,

clang/lib/AST/ExternalASTSource.cpp

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -98,10 +98,14 @@ ExternalASTSource::FindExternalVisibleDeclsByName(const DeclContext *DC,
9898
return false;
9999
}
100100

101-
void ExternalASTSource::LoadExternalSpecializations(const Decl *D, bool) {}
101+
bool ExternalASTSource::LoadExternalSpecializations(const Decl *D, bool) {
102+
return false;
103+
}
102104

103-
void ExternalASTSource::LoadExternalSpecializations(
104-
const Decl *D, ArrayRef<TemplateArgument>) {}
105+
bool ExternalASTSource::LoadExternalSpecializations(
106+
const Decl *D, ArrayRef<TemplateArgument>) {
107+
return false;
108+
}
105109

106110
void ExternalASTSource::completeVisibleDeclsMap(const DeclContext *DC) {}
107111

clang/lib/AST/ODRHash.cpp

Lines changed: 0 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -819,16 +819,6 @@ void ODRHash::AddDecl(const Decl *D) {
819819

820820
AddDeclarationName(ND->getDeclName());
821821

822-
const auto *Specialization =
823-
dyn_cast<ClassTemplateSpecializationDecl>(D);
824-
AddBoolean(Specialization);
825-
if (Specialization) {
826-
const TemplateArgumentList &List = Specialization->getTemplateArgs();
827-
ID.AddInteger(List.size());
828-
for (const TemplateArgument &TA : List.asArray())
829-
AddTemplateArgument(TA);
830-
}
831-
832822
// If this was a specialization we should take into account its template
833823
// arguments. This helps to reduce collisions coming when visiting template
834824
// specialization types (eg. when processing type template arguments).

clang/lib/Sema/MultiplexExternalSemaSource.cpp

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -115,16 +115,21 @@ FindExternalVisibleDeclsByName(const DeclContext *DC, DeclarationName Name) {
115115
return AnyDeclsFound;
116116
}
117117

118-
void MultiplexExternalSemaSource::LoadExternalSpecializations(
118+
bool MultiplexExternalSemaSource::LoadExternalSpecializations(
119119
const Decl *D, bool OnlyPartial) {
120+
bool Loaded = false;
120121
for (size_t i = 0; i < Sources.size(); ++i)
121-
Sources[i]->LoadExternalSpecializations(D, OnlyPartial);
122+
Loaded |= Sources[i]->LoadExternalSpecializations(D, OnlyPartial);
123+
return Loaded;
122124
}
123125

124-
void MultiplexExternalSemaSource::LoadExternalSpecializations(
126+
bool MultiplexExternalSemaSource::LoadExternalSpecializations(
125127
const Decl *D, ArrayRef<TemplateArgument> TemplateArgs) {
128+
bool AnyNewSpecsLoaded = false;
126129
for (size_t i = 0; i < Sources.size(); ++i)
127-
Sources[i]->LoadExternalSpecializations(D, TemplateArgs);
130+
AnyNewSpecsLoaded |=
131+
Sources[i]->LoadExternalSpecializations(D, TemplateArgs);
132+
return AnyNewSpecsLoaded;
128133
}
129134

130135
void MultiplexExternalSemaSource::completeVisibleDeclsMap(const DeclContext *DC){

clang/lib/Serialization/ASTCommon.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,6 @@ namespace serialization {
2424

2525
enum DeclUpdateKind {
2626
UPD_CXX_ADDED_IMPLICIT_MEMBER,
27-
UPD_CXX_ADDED_TEMPLATE_SPECIALIZATION,
2827
UPD_CXX_ADDED_ANONYMOUS_NAMESPACE,
2928
UPD_CXX_ADDED_FUNCTION_DEFINITION,
3029
UPD_CXX_ADDED_VAR_DEFINITION,

clang/lib/Serialization/ASTReader.cpp

Lines changed: 31 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212

1313
#include "ASTCommon.h"
1414
#include "ASTReaderInternals.h"
15+
#include "TemplateArgumentHasher.h"
1516
#include "clang/AST/ASTConsumer.h"
1617
#include "clang/AST/ASTContext.h"
1718
#include "clang/AST/ASTMutationListener.h"
@@ -3542,7 +3543,7 @@ llvm::Error ASTReader::ReadASTBlock(ModuleFile &F,
35423543
break;
35433544
}
35443545

3545-
case UPDATE_SPECIALIZATION: {
3546+
case CXX_ADDED_TEMPLATE_SPECIALIZATION: {
35463547
unsigned Idx = 0;
35473548
GlobalDeclID ID = ReadDeclID(F, Record, Idx);
35483549
auto *Data = (const unsigned char *)Blob.data();
@@ -7747,8 +7748,14 @@ void ASTReader::CompleteRedeclChain(const Decl *D) {
77477748
}
77487749
}
77497750

7750-
if (Template)
7751-
Template->loadLazySpecializationsImpl(Args);
7751+
if (Template) {
7752+
// For partitial specialization, load all the specializations for safety.
7753+
if (isa<ClassTemplatePartialSpecializationDecl,
7754+
VarTemplatePartialSpecializationDecl>(D))
7755+
Template->loadLazySpecializationsImpl();
7756+
else
7757+
Template->loadLazySpecializationsImpl(Args);
7758+
}
77527759
}
77537760

77547761
CXXCtorInitializer **
@@ -8129,12 +8136,12 @@ Stmt *ASTReader::GetExternalDeclStmt(uint64_t Offset) {
81298136
return ReadStmtFromStream(*Loc.F);
81308137
}
81318138

8132-
void ASTReader::LoadExternalSpecializations(const Decl *D, bool OnlyPartial) {
8139+
bool ASTReader::LoadExternalSpecializations(const Decl *D, bool OnlyPartial) {
81338140
assert(D);
81348141

81358142
auto It = SpecializationsLookups.find(D);
81368143
if (It == SpecializationsLookups.end())
8137-
return;
8144+
return false;
81388145

81398146
// Get Decl may violate the iterator from SpecializationsLookups so we store
81408147
// the DeclIDs in ahead.
@@ -8146,29 +8153,43 @@ void ASTReader::LoadExternalSpecializations(const Decl *D, bool OnlyPartial) {
81468153
if (!OnlyPartial)
81478154
SpecializationsLookups.erase(It);
81488155

8156+
bool NewSpecsFound = false;
81498157
Deserializing LookupResults(this);
81508158
for (auto &Info : Infos)
8151-
if (!OnlyPartial || Info.IsPartial)
8159+
if (!OnlyPartial || Info.IsPartial) {
8160+
if (GetExistingDecl(Info.ID))
8161+
continue;
8162+
NewSpecsFound = true;
81528163
GetDecl(Info.ID);
8164+
}
8165+
8166+
return NewSpecsFound;
81538167
}
81548168

8155-
void ASTReader::LoadExternalSpecializations(
8169+
bool ASTReader::LoadExternalSpecializations(
81568170
const Decl *D, ArrayRef<TemplateArgument> TemplateArgs) {
81578171
assert(D);
81588172

81598173
auto It = SpecializationsLookups.find(D);
81608174
if (It == SpecializationsLookups.end())
8161-
return;
8175+
return false;
81628176

81638177
Deserializing LookupResults(this);
8164-
auto HashValue = TemplateArgumentList::ComputeODRHash(TemplateArgs);
8178+
auto HashValue = StableHashForTemplateArguments(TemplateArgs);
81658179

81668180
// Get Decl may violate the iterator from SpecializationsLookups
81678181
llvm::SmallVector<serialization::reader::LazySpecializationInfo, 8> Infos =
81688182
It->second.Table.find(HashValue);
81698183

8170-
for (auto &Info : Infos)
8184+
bool NewSpecsFound = false;
8185+
for (auto &Info : Infos) {
8186+
if (GetExistingDecl(Info.ID))
8187+
continue;
8188+
NewSpecsFound = true;
81718189
GetDecl(Info.ID);
8190+
}
8191+
8192+
return NewSpecsFound;
81728193
}
81738194

81748195
void ASTReader::FindExternalLexicalDecls(

0 commit comments

Comments
 (0)