Skip to content

[Serialization] Code cleanups and polish 83233 #83237

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
39 changes: 7 additions & 32 deletions clang/include/clang/AST/DeclTemplate.h
Original file line number Diff line number Diff line change
Expand Up @@ -262,9 +262,6 @@ class TemplateArgumentList final
TemplateArgumentList(const TemplateArgumentList &) = delete;
TemplateArgumentList &operator=(const TemplateArgumentList &) = delete;

/// Create hash for the given arguments.
static unsigned ComputeODRHash(ArrayRef<TemplateArgument> Args);

/// Create a new template argument list that copies the given set of
/// template arguments.
static TemplateArgumentList *CreateCopy(ASTContext &Context,
Expand Down Expand Up @@ -738,25 +735,6 @@ class RedeclarableTemplateDecl : public TemplateDecl,
}

void anchor() override;
struct LazySpecializationInfo {
GlobalDeclID DeclID = GlobalDeclID();
unsigned ODRHash = ~0U;
bool IsPartial = false;
LazySpecializationInfo(GlobalDeclID ID, unsigned Hash = ~0U,
bool Partial = false)
: DeclID(ID), ODRHash(Hash), IsPartial(Partial) {}
LazySpecializationInfo() {}
bool operator<(const LazySpecializationInfo &Other) const {
return DeclID < Other.DeclID;
}
bool operator==(const LazySpecializationInfo &Other) const {
assert((DeclID != Other.DeclID || ODRHash == Other.ODRHash) &&
"Hashes differ!");
assert((DeclID != Other.DeclID || IsPartial == Other.IsPartial) &&
"Both must be the same kinds!");
return DeclID == Other.DeclID;
}
};

protected:
template <typename EntryType> struct SpecEntryTraits {
Expand Down Expand Up @@ -800,16 +778,20 @@ class RedeclarableTemplateDecl : public TemplateDecl,

void loadLazySpecializationsImpl(bool OnlyPartial = false) const;

void loadLazySpecializationsImpl(llvm::ArrayRef<TemplateArgument> Args,
bool loadLazySpecializationsImpl(llvm::ArrayRef<TemplateArgument> Args,
TemplateParameterList *TPL = nullptr) const;

Decl *loadLazySpecializationImpl(LazySpecializationInfo &LazySpecInfo) const;

template <class EntryType, typename ...ProfileArguments>
typename SpecEntryTraits<EntryType>::DeclType*
findSpecializationImpl(llvm::FoldingSetVector<EntryType> &Specs,
void *&InsertPos, ProfileArguments &&...ProfileArgs);

template <class EntryType, typename... ProfileArguments>
typename SpecEntryTraits<EntryType>::DeclType *
findSpecializationLocally(llvm::FoldingSetVector<EntryType> &Specs,
void *&InsertPos,
ProfileArguments &&...ProfileArgs);

template <class Derived, class EntryType>
void addSpecializationImpl(llvm::FoldingSetVector<EntryType> &Specs,
EntryType *Entry, void *InsertPos);
Expand All @@ -824,13 +806,6 @@ class RedeclarableTemplateDecl : public TemplateDecl,
/// was explicitly specialized.
llvm::PointerIntPair<RedeclarableTemplateDecl *, 1, bool>
InstantiatedFromMember;

/// 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.
LazySpecializationInfo *LazySpecializations = nullptr;
};

/// Pointer to the common data shared by all declarations of this
Expand Down
8 changes: 6 additions & 2 deletions clang/include/clang/AST/ExternalASTSource.h
Original file line number Diff line number Diff line change
Expand Up @@ -155,11 +155,15 @@ class ExternalASTSource : public RefCountedBase<ExternalASTSource> {
/// Load all the external specializations for the Decl \param D if \param
/// OnlyPartial is false. Otherwise, load all the external **partial**
/// specializations for the \param D.
virtual void LoadExternalSpecializations(const Decl *D, bool OnlyPartial);
///
/// Return true if any new specializations get loaded. Return false otherwise.
virtual bool LoadExternalSpecializations(const Decl *D, bool OnlyPartial);

/// Load all the specializations for the Decl \param D with the same template
/// args specified by \param TemplateArgs.
virtual void
///
/// Return true if any new specializations get loaded. Return false otherwise.
virtual bool
LoadExternalSpecializations(const Decl *D,
ArrayRef<TemplateArgument> TemplateArgs);

Expand Down
4 changes: 2 additions & 2 deletions clang/include/clang/Sema/MultiplexExternalSemaSource.h
Original file line number Diff line number Diff line change
Expand Up @@ -97,9 +97,9 @@ class MultiplexExternalSemaSource : public ExternalSemaSource {
bool FindExternalVisibleDeclsByName(const DeclContext *DC,
DeclarationName Name) override;

void LoadExternalSpecializations(const Decl *D, bool OnlyPartial) override;
bool LoadExternalSpecializations(const Decl *D, bool OnlyPartial) override;

void
bool
LoadExternalSpecializations(const Decl *D,
ArrayRef<TemplateArgument> TemplateArgs) override;

Expand Down
11 changes: 9 additions & 2 deletions clang/include/clang/Serialization/ASTBitCodes.h
Original file line number Diff line number Diff line change
Expand Up @@ -737,6 +737,10 @@ enum ASTRecordTypes {

/// Record code for updated specialization
UPDATE_SPECIALIZATION = 73,

CXX_ADDED_TEMPLATE_SPECIALIZATION = 74,

CXX_ADDED_TEMPLATE_PARTIAL_SPECIALIZATION = 75,
};

/// Record types used within a source manager block.
Expand Down Expand Up @@ -1503,11 +1507,14 @@ enum DeclCode {
/// A HLSLBufferDecl record.
DECL_HLSL_BUFFER,

/// An ImplicitConceptSpecializationDecl record.
DECL_IMPLICIT_CONCEPT_SPECIALIZATION,

// A decls specilization record.
DECL_SPECIALIZATIONS,

/// An ImplicitConceptSpecializationDecl record.
DECL_IMPLICIT_CONCEPT_SPECIALIZATION,
// A decls specilization record.
DECL_PARTIAL_SPECIALIZATIONS,

DECL_LAST = DECL_IMPLICIT_CONCEPT_SPECIALIZATION
};
Expand Down
34 changes: 24 additions & 10 deletions clang/include/clang/Serialization/ASTReader.h
Original file line number Diff line number Diff line change
Expand Up @@ -635,10 +635,19 @@ class ASTReader
llvm::DenseMap<const DeclContext *,
serialization::reader::DeclContextLookupTable> Lookups;

using SpecLookupTableTy =
llvm::DenseMap<const Decl *,
serialization::reader::LazySpecializationInfoLookupTable>;
/// Map from decls to specialized decls.
llvm::DenseMap<const Decl *,
serialization::reader::LazySpecializationInfoLookupTable>
SpecializationsLookups;
SpecLookupTableTy SpecializationsLookups;
/// Split partial specialization from specialization to speed up lookups.
SpecLookupTableTy PartialSpecializationsLookups;

bool LoadExternalSpecializationsImpl(SpecLookupTableTy &SpecLookups,
const Decl *D);
bool LoadExternalSpecializationsImpl(SpecLookupTableTy &SpecLookups,
const Decl *D,
ArrayRef<TemplateArgument> TemplateArgs);

// Updates for visible decls can occur for other contexts than just the
// TU, and when we read those update records, the actual context may not
Expand All @@ -655,8 +664,10 @@ class ASTReader
llvm::DenseMap<GlobalDeclID, DeclContextVisibleUpdates> PendingVisibleUpdates;

using SpecializationsUpdate = SmallVector<UpdateData, 1>;
llvm::DenseMap<GlobalDeclID, SpecializationsUpdate>
PendingSpecializationsUpdates;
using SpecializationsUpdateMap =
llvm::DenseMap<GlobalDeclID, SpecializationsUpdate>;
SpecializationsUpdateMap PendingSpecializationsUpdates;
SpecializationsUpdateMap PendingPartialSpecializationsUpdates;

/// The set of C++ or Objective-C classes that have forward
/// declarations that have not yet been linked to their definitions.
Expand Down Expand Up @@ -691,9 +702,9 @@ class ASTReader
uint64_t Offset, GlobalDeclID ID);

bool ReadSpecializations(ModuleFile &M, llvm::BitstreamCursor &Cursor,
uint64_t Offset, Decl *D);
uint64_t Offset, Decl *D, bool IsPartial);
void AddSpecializations(const Decl *D, const unsigned char *Data,
ModuleFile &M);
ModuleFile &M, bool IsPartial);

/// A vector containing identifiers that have already been
/// loaded.
Expand Down Expand Up @@ -1439,7 +1450,10 @@ class ASTReader
/// Get the loaded specializations lookup tables for \p D,
/// if any.
serialization::reader::LazySpecializationInfoLookupTable *
getLoadedSpecializationsLookupTables(const Decl *D);
getLoadedSpecializationsLookupTables(const Decl *D, bool IsPartial);

/// If we have any unloaded specialization for \p D
bool haveUnloadedSpecializations(const Decl *D) const;

private:
struct ImportedModule {
Expand Down Expand Up @@ -2098,9 +2112,9 @@ class ASTReader
unsigned BlockID,
uint64_t *StartOfBlockOffset = nullptr);

void LoadExternalSpecializations(const Decl *D, bool OnlyPartial) override;
bool LoadExternalSpecializations(const Decl *D, bool OnlyPartial) override;

void
bool
LoadExternalSpecializations(const Decl *D,
ArrayRef<TemplateArgument> TemplateArgs) override;

Expand Down
9 changes: 6 additions & 3 deletions clang/include/clang/Serialization/ASTWriter.h
Original file line number Diff line number Diff line change
Expand Up @@ -428,6 +428,7 @@ class ASTWriter : public ASTDeserializationListener,
using SpecializationUpdateMap =
llvm::MapVector<const NamedDecl *, SmallVector<const Decl *>>;
SpecializationUpdateMap SpecializationsUpdates;
SpecializationUpdateMap PartialSpecializationsUpdates;

using FirstLatestDeclMap = llvm::DenseMap<Decl *, Decl *>;

Expand Down Expand Up @@ -580,9 +581,10 @@ class ASTWriter : public ASTDeserializationListener,

void GenerateSpecializationInfoLookupTable(
const NamedDecl *D, llvm::SmallVectorImpl<const Decl *> &Specializations,
llvm::SmallVectorImpl<char> &LookupTable);
llvm::SmallVectorImpl<char> &LookupTable, bool IsPartial);
uint64_t WriteSpecializationInfoLookupTable(
const NamedDecl *D, llvm::SmallVectorImpl<const Decl *> &Specializations);
const NamedDecl *D, llvm::SmallVectorImpl<const Decl *> &Specializations,
bool IsPartial);
void GenerateNameLookupTable(ASTContext &Context, const DeclContext *DC,
llvm::SmallVectorImpl<char> &LookupTable);
uint64_t WriteDeclContextLexicalBlock(ASTContext &Context,
Expand All @@ -598,7 +600,7 @@ class ASTWriter : public ASTDeserializationListener,
void WriteDeclAndTypes(ASTContext &Context);
void PrepareWritingSpecialDecls(Sema &SemaRef);
void WriteSpecialDeclRecords(Sema &SemaRef);
void WriteSpecializationsUpdates();
void WriteSpecializationsUpdates(bool IsPartial);
void WriteDeclUpdatesBlocks(ASTContext &Context,
RecordDataImpl &OffsetsRecord);
void WriteDeclContextVisibleUpdate(ASTContext &Context,
Expand Down Expand Up @@ -629,6 +631,7 @@ class ASTWriter : public ASTDeserializationListener,
unsigned DeclObjCIvarAbbrev = 0;
unsigned DeclCXXMethodAbbrev = 0;
unsigned DeclSpecializationsAbbrev = 0;
unsigned DeclPartialSpecializationsAbbrev = 0;

unsigned DeclDependentNonTemplateCXXMethodAbbrev = 0;
unsigned DeclTemplateCXXMethodAbbrev = 0;
Expand Down
85 changes: 31 additions & 54 deletions clang/lib/AST/DeclTemplate.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -362,63 +362,30 @@ void RedeclarableTemplateDecl::loadLazySpecializationsImpl(
ExternalSource->LoadExternalSpecializations(this->getCanonicalDecl(),
OnlyPartial);
return;

// Grab the most recent declaration to ensure we've loaded any lazy
// redeclarations of this template.
CommonBase *CommonBasePtr = getMostRecentDecl()->getCommonPtr();
if (auto *Specs = CommonBasePtr->LazySpecializations) {
if (!OnlyPartial)
CommonBasePtr->LazySpecializations = nullptr;
unsigned N = Specs[0].DeclID.getRawValue();
for (unsigned I = 0; I != N; ++I) {
// Skip over already loaded specializations.
if (!Specs[I + 1].ODRHash)
continue;
if (!OnlyPartial || Specs[I + 1].IsPartial)
(void)loadLazySpecializationImpl(Specs[I + 1]);
}
}
}

Decl *RedeclarableTemplateDecl::loadLazySpecializationImpl(
LazySpecializationInfo &LazySpecInfo) const {
llvm_unreachable("We don't use LazySpecializationInfo any more");

GlobalDeclID ID = LazySpecInfo.DeclID;
assert(ID.isValid() && "Loading already loaded specialization!");
// Note that we loaded the specialization.
LazySpecInfo.DeclID = GlobalDeclID();
LazySpecInfo.ODRHash = LazySpecInfo.IsPartial = 0;
return getASTContext().getExternalSource()->GetExternalDecl(ID);
}

void RedeclarableTemplateDecl::loadLazySpecializationsImpl(
bool RedeclarableTemplateDecl::loadLazySpecializationsImpl(
ArrayRef<TemplateArgument> Args, TemplateParameterList *TPL) const {
auto *ExternalSource = getASTContext().getExternalSource();
if (!ExternalSource)
return;
return false;

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

CommonBase *CommonBasePtr = getMostRecentDecl()->getCommonPtr();
if (auto *Specs = CommonBasePtr->LazySpecializations) {
unsigned Hash = TemplateArgumentList::ComputeODRHash(Args);
unsigned N = Specs[0].DeclID.getRawValue();
for (unsigned I = 0; I != N; ++I)
if (Specs[I + 1].ODRHash && Specs[I + 1].ODRHash == Hash)
(void)loadLazySpecializationImpl(Specs[I + 1]);
}
return ExternalSource->LoadExternalSpecializations(this->getCanonicalDecl(),
Args);
}

template<class EntryType, typename... ProfileArguments>
template <class EntryType, typename... ProfileArguments>
typename RedeclarableTemplateDecl::SpecEntryTraits<EntryType>::DeclType *
RedeclarableTemplateDecl::findSpecializationImpl(
RedeclarableTemplateDecl::findSpecializationLocally(
llvm::FoldingSetVector<EntryType> &Specs, void *&InsertPos,
ProfileArguments&&... ProfileArgs) {
using SETraits = SpecEntryTraits<EntryType>;

loadLazySpecializationsImpl(std::forward<ProfileArguments>(ProfileArgs)...);
ProfileArguments &&...ProfileArgs) {
using SETraits = RedeclarableTemplateDecl::SpecEntryTraits<EntryType>;

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

template <class EntryType, typename... ProfileArguments>
typename RedeclarableTemplateDecl::SpecEntryTraits<EntryType>::DeclType *
RedeclarableTemplateDecl::findSpecializationImpl(
llvm::FoldingSetVector<EntryType> &Specs, void *&InsertPos,
ProfileArguments &&...ProfileArgs) {

if (auto *Found = findSpecializationLocally(
Specs, InsertPos, std::forward<ProfileArguments>(ProfileArgs)...))
return Found;

if (!loadLazySpecializationsImpl(
std::forward<ProfileArguments>(ProfileArgs)...))
return nullptr;

return findSpecializationLocally(
Specs, InsertPos, std::forward<ProfileArguments>(ProfileArgs)...);
}

template<class Derived, class EntryType>
void RedeclarableTemplateDecl::addSpecializationImpl(
llvm::FoldingSetVector<EntryType> &Specializations, EntryType *Entry,
Expand Down Expand Up @@ -955,14 +940,6 @@ TemplateArgumentList::CreateCopy(ASTContext &Context,
return new (Mem) TemplateArgumentList(Args);
}

unsigned TemplateArgumentList::ComputeODRHash(ArrayRef<TemplateArgument> Args) {
ODRHash Hasher;
for (TemplateArgument TA : Args)
Hasher.AddTemplateArgument(TA);

return Hasher.CalculateHash();
}

FunctionTemplateSpecializationInfo *FunctionTemplateSpecializationInfo::Create(
ASTContext &C, FunctionDecl *FD, FunctionTemplateDecl *Template,
TemplateSpecializationKind TSK, TemplateArgumentList *TemplateArgs,
Expand Down
10 changes: 7 additions & 3 deletions clang/lib/AST/ExternalASTSource.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -98,10 +98,14 @@ ExternalASTSource::FindExternalVisibleDeclsByName(const DeclContext *DC,
return false;
}

void ExternalASTSource::LoadExternalSpecializations(const Decl *D, bool) {}
bool ExternalASTSource::LoadExternalSpecializations(const Decl *D, bool) {
return false;
}

void ExternalASTSource::LoadExternalSpecializations(
const Decl *D, ArrayRef<TemplateArgument>) {}
bool ExternalASTSource::LoadExternalSpecializations(
const Decl *D, ArrayRef<TemplateArgument>) {
return false;
}

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

Expand Down
10 changes: 0 additions & 10 deletions clang/lib/AST/ODRHash.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -819,16 +819,6 @@ void ODRHash::AddDecl(const Decl *D) {

AddDeclarationName(ND->getDeclName());

const auto *Specialization =
dyn_cast<ClassTemplateSpecializationDecl>(D);
AddBoolean(Specialization);
if (Specialization) {
const TemplateArgumentList &List = Specialization->getTemplateArgs();
ID.AddInteger(List.size());
for (const TemplateArgument &TA : List.asArray())
AddTemplateArgument(TA);
}

// If this was a specialization we should take into account its template
// arguments. This helps to reduce collisions coming when visiting template
// specialization types (eg. when processing type template arguments).
Expand Down
Loading
Loading