Skip to content

Commit 1172643

Browse files
committed
[Serialization] Introduce OnDiskHashTable for specializations
1 parent a526580 commit 1172643

15 files changed

+855
-13
lines changed

clang/include/clang/AST/ExternalASTSource.h

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -152,6 +152,17 @@ class ExternalASTSource : public RefCountedBase<ExternalASTSource> {
152152
virtual bool
153153
FindExternalVisibleDeclsByName(const DeclContext *DC, DeclarationName Name);
154154

155+
/// Load all the external specializations for the Decl \param D if \param
156+
/// OnlyPartial is false. Otherwise, load all the external **partial**
157+
/// specializations for the \param D.
158+
virtual void LoadExternalSpecializations(const Decl *D, bool OnlyPartial);
159+
160+
/// Load all the specializations for the Decl \param D with the same template
161+
/// args specified by \param TemplateArgs.
162+
virtual void
163+
LoadExternalSpecializations(const Decl *D,
164+
ArrayRef<TemplateArgument> TemplateArgs);
165+
155166
/// Ensures that the table of all visible declarations inside this
156167
/// context is up to date.
157168
///

clang/include/clang/Sema/MultiplexExternalSemaSource.h

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

100+
void LoadExternalSpecializations(const Decl *D, bool OnlyPartial) override;
101+
102+
void
103+
LoadExternalSpecializations(const Decl *D,
104+
ArrayRef<TemplateArgument> TemplateArgs) override;
105+
100106
/// Ensures that the table of all visible declarations inside this
101107
/// context is up to date.
102108
void completeVisibleDeclsMap(const DeclContext *DC) override;

clang/include/clang/Serialization/ASTBitCodes.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -734,6 +734,9 @@ enum ASTRecordTypes {
734734
/// Record code for Sema's vector of functions/blocks with effects to
735735
/// be verified.
736736
DECLS_WITH_EFFECTS_TO_VERIFY = 72,
737+
738+
/// Record code for updated specialization
739+
UPDATE_SPECIALIZATION = 73,
737740
};
738741

739742
/// Record types used within a source manager block.
@@ -1500,6 +1503,9 @@ enum DeclCode {
15001503
/// A HLSLBufferDecl record.
15011504
DECL_HLSL_BUFFER,
15021505

1506+
// A decls specilization record.
1507+
DECL_SPECIALIZATIONS,
1508+
15031509
/// An ImplicitConceptSpecializationDecl record.
15041510
DECL_IMPLICIT_CONCEPT_SPECIALIZATION,
15051511

clang/include/clang/Serialization/ASTReader.h

Lines changed: 31 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -354,6 +354,9 @@ class ASTIdentifierLookupTrait;
354354
/// The on-disk hash table(s) used for DeclContext name lookup.
355355
struct DeclContextLookupTable;
356356

357+
/// The on-disk hash table(s) used for specialization decls.
358+
struct LazySpecializationInfoLookupTable;
359+
357360
} // namespace reader
358361

359362
} // namespace serialization
@@ -632,20 +635,29 @@ class ASTReader
632635
llvm::DenseMap<const DeclContext *,
633636
serialization::reader::DeclContextLookupTable> Lookups;
634637

638+
/// Map from decls to specialized decls.
639+
llvm::DenseMap<const Decl *,
640+
serialization::reader::LazySpecializationInfoLookupTable>
641+
SpecializationsLookups;
642+
635643
// Updates for visible decls can occur for other contexts than just the
636644
// TU, and when we read those update records, the actual context may not
637645
// be available yet, so have this pending map using the ID as a key. It
638-
// will be realized when the context is actually loaded.
639-
struct PendingVisibleUpdate {
646+
// will be realized when the data is actually loaded.
647+
struct UpdateData {
640648
ModuleFile *Mod;
641649
const unsigned char *Data;
642650
};
643-
using DeclContextVisibleUpdates = SmallVector<PendingVisibleUpdate, 1>;
651+
using DeclContextVisibleUpdates = SmallVector<UpdateData, 1>;
644652

645653
/// Updates to the visible declarations of declaration contexts that
646654
/// haven't been loaded yet.
647655
llvm::DenseMap<GlobalDeclID, DeclContextVisibleUpdates> PendingVisibleUpdates;
648656

657+
using SpecializationsUpdate = SmallVector<UpdateData, 1>;
658+
llvm::DenseMap<GlobalDeclID, SpecializationsUpdate>
659+
PendingSpecializationsUpdates;
660+
649661
/// The set of C++ or Objective-C classes that have forward
650662
/// declarations that have not yet been linked to their definitions.
651663
llvm::SmallPtrSet<Decl *, 4> PendingDefinitions;
@@ -678,6 +690,11 @@ class ASTReader
678690
llvm::BitstreamCursor &Cursor,
679691
uint64_t Offset, GlobalDeclID ID);
680692

693+
bool ReadSpecializations(ModuleFile &M, llvm::BitstreamCursor &Cursor,
694+
uint64_t Offset, Decl *D);
695+
void AddSpecializations(const Decl *D, const unsigned char *Data,
696+
ModuleFile &M);
697+
681698
/// A vector containing identifiers that have already been
682699
/// loaded.
683700
///
@@ -1419,6 +1436,11 @@ class ASTReader
14191436
const serialization::reader::DeclContextLookupTable *
14201437
getLoadedLookupTables(DeclContext *Primary) const;
14211438

1439+
/// Get the loaded specializations lookup tables for \p D,
1440+
/// if any.
1441+
serialization::reader::LazySpecializationInfoLookupTable *
1442+
getLoadedSpecializationsLookupTables(const Decl *D);
1443+
14221444
private:
14231445
struct ImportedModule {
14241446
ModuleFile *Mod;
@@ -2076,6 +2098,12 @@ class ASTReader
20762098
unsigned BlockID,
20772099
uint64_t *StartOfBlockOffset = nullptr);
20782100

2101+
void LoadExternalSpecializations(const Decl *D, bool OnlyPartial) override;
2102+
2103+
void
2104+
LoadExternalSpecializations(const Decl *D,
2105+
ArrayRef<TemplateArgument> TemplateArgs) override;
2106+
20792107
/// Finds all the visible declarations with a given name.
20802108
/// The current implementation of this method just loads the entire
20812109
/// lookup table as unmaterialized references.

clang/include/clang/Serialization/ASTWriter.h

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -423,6 +423,12 @@ class ASTWriter : public ASTDeserializationListener,
423423
/// Only meaningful for reduced BMI.
424424
DeclUpdateMap DeclUpdatesFromGMF;
425425

426+
/// Mapping from decl templates and its new specialization in the
427+
/// current TU.
428+
using SpecializationUpdateMap =
429+
llvm::MapVector<const NamedDecl *, SmallVector<const Decl *>>;
430+
SpecializationUpdateMap SpecializationsUpdates;
431+
426432
using FirstLatestDeclMap = llvm::DenseMap<Decl *, Decl *>;
427433

428434
/// Map of first declarations from a chained PCH that point to the
@@ -572,6 +578,11 @@ class ASTWriter : public ASTDeserializationListener,
572578

573579
bool isLookupResultExternal(StoredDeclsList &Result, DeclContext *DC);
574580

581+
void GenerateSpecializationInfoLookupTable(
582+
const NamedDecl *D, llvm::SmallVectorImpl<const Decl *> &Specializations,
583+
llvm::SmallVectorImpl<char> &LookupTable);
584+
uint64_t WriteSpecializationInfoLookupTable(
585+
const NamedDecl *D, llvm::SmallVectorImpl<const Decl *> &Specializations);
575586
void GenerateNameLookupTable(ASTContext &Context, const DeclContext *DC,
576587
llvm::SmallVectorImpl<char> &LookupTable);
577588
uint64_t WriteDeclContextLexicalBlock(ASTContext &Context,
@@ -587,6 +598,7 @@ class ASTWriter : public ASTDeserializationListener,
587598
void WriteDeclAndTypes(ASTContext &Context);
588599
void PrepareWritingSpecialDecls(Sema &SemaRef);
589600
void WriteSpecialDeclRecords(Sema &SemaRef);
601+
void WriteSpecializationsUpdates();
590602
void WriteDeclUpdatesBlocks(ASTContext &Context,
591603
RecordDataImpl &OffsetsRecord);
592604
void WriteDeclContextVisibleUpdate(ASTContext &Context,
@@ -616,6 +628,8 @@ class ASTWriter : public ASTDeserializationListener,
616628
unsigned DeclEnumAbbrev = 0;
617629
unsigned DeclObjCIvarAbbrev = 0;
618630
unsigned DeclCXXMethodAbbrev = 0;
631+
unsigned DeclSpecializationsAbbrev = 0;
632+
619633
unsigned DeclDependentNonTemplateCXXMethodAbbrev = 0;
620634
unsigned DeclTemplateCXXMethodAbbrev = 0;
621635
unsigned DeclMemberSpecializedCXXMethodAbbrev = 0;

clang/lib/AST/DeclTemplate.cpp

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -355,6 +355,14 @@ RedeclarableTemplateDecl::CommonBase *RedeclarableTemplateDecl::getCommonPtr() c
355355

356356
void RedeclarableTemplateDecl::loadLazySpecializationsImpl(
357357
bool OnlyPartial /*=false*/) const {
358+
auto *ExternalSource = getASTContext().getExternalSource();
359+
if (!ExternalSource)
360+
return;
361+
362+
ExternalSource->LoadExternalSpecializations(this->getCanonicalDecl(),
363+
OnlyPartial);
364+
return;
365+
358366
// Grab the most recent declaration to ensure we've loaded any lazy
359367
// redeclarations of this template.
360368
CommonBase *CommonBasePtr = getMostRecentDecl()->getCommonPtr();
@@ -374,6 +382,8 @@ void RedeclarableTemplateDecl::loadLazySpecializationsImpl(
374382

375383
Decl *RedeclarableTemplateDecl::loadLazySpecializationImpl(
376384
LazySpecializationInfo &LazySpecInfo) const {
385+
llvm_unreachable("We don't use LazySpecializationInfo any more");
386+
377387
GlobalDeclID ID = LazySpecInfo.DeclID;
378388
assert(ID.isValid() && "Loading already loaded specialization!");
379389
// Note that we loaded the specialization.
@@ -384,6 +394,13 @@ Decl *RedeclarableTemplateDecl::loadLazySpecializationImpl(
384394

385395
void RedeclarableTemplateDecl::loadLazySpecializationsImpl(
386396
ArrayRef<TemplateArgument> Args, TemplateParameterList *TPL) const {
397+
auto *ExternalSource = getASTContext().getExternalSource();
398+
if (!ExternalSource)
399+
return;
400+
401+
ExternalSource->LoadExternalSpecializations(this->getCanonicalDecl(), Args);
402+
return;
403+
387404
CommonBase *CommonBasePtr = getMostRecentDecl()->getCommonPtr();
388405
if (auto *Specs = CommonBasePtr->LazySpecializations) {
389406
unsigned Hash = TemplateArgumentList::ComputeODRHash(Args);

clang/lib/AST/ExternalASTSource.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,11 @@ ExternalASTSource::FindExternalVisibleDeclsByName(const DeclContext *DC,
9898
return false;
9999
}
100100

101+
void ExternalASTSource::LoadExternalSpecializations(const Decl *D, bool) {}
102+
103+
void ExternalASTSource::LoadExternalSpecializations(
104+
const Decl *D, ArrayRef<TemplateArgument>) {}
105+
101106
void ExternalASTSource::completeVisibleDeclsMap(const DeclContext *DC) {}
102107

103108
void ExternalASTSource::FindExternalLexicalDecls(

clang/lib/Sema/MultiplexExternalSemaSource.cpp

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

118+
void MultiplexExternalSemaSource::LoadExternalSpecializations(
119+
const Decl *D, bool OnlyPartial) {
120+
for (size_t i = 0; i < Sources.size(); ++i)
121+
Sources[i]->LoadExternalSpecializations(D, OnlyPartial);
122+
}
123+
124+
void MultiplexExternalSemaSource::LoadExternalSpecializations(
125+
const Decl *D, ArrayRef<TemplateArgument> TemplateArgs) {
126+
for (size_t i = 0; i < Sources.size(); ++i)
127+
Sources[i]->LoadExternalSpecializations(D, TemplateArgs);
128+
}
129+
118130
void MultiplexExternalSemaSource::completeVisibleDeclsMap(const DeclContext *DC){
119131
for(size_t i = 0; i < Sources.size(); ++i)
120132
Sources[i]->completeVisibleDeclsMap(DC);

0 commit comments

Comments
 (0)