Skip to content
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

[Serialization] Code cleanups and polish 83233 #83237

Closed
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
@@ -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,
@@ -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 {
@@ -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);
@@ -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
8 changes: 6 additions & 2 deletions clang/include/clang/AST/ExternalASTSource.h
Original file line number Diff line number Diff line change
@@ -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);

4 changes: 2 additions & 2 deletions clang/include/clang/Sema/MultiplexExternalSemaSource.h
Original file line number Diff line number Diff line change
@@ -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;

11 changes: 9 additions & 2 deletions clang/include/clang/Serialization/ASTBitCodes.h
Original file line number Diff line number Diff line change
@@ -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.
@@ -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
};
34 changes: 24 additions & 10 deletions clang/include/clang/Serialization/ASTReader.h
Original file line number Diff line number Diff line change
@@ -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
@@ -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.
@@ -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.
@@ -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 {
@@ -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;

9 changes: 6 additions & 3 deletions clang/include/clang/Serialization/ASTWriter.h
Original file line number Diff line number Diff line change
@@ -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 *>;

@@ -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,
@@ -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,
@@ -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;
85 changes: 31 additions & 54 deletions clang/lib/AST/DeclTemplate.cpp
Original file line number Diff line number Diff line change
@@ -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)...,
@@ -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,
@@ -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,
10 changes: 7 additions & 3 deletions clang/lib/AST/ExternalASTSource.cpp
Original file line number Diff line number Diff line change
@@ -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) {}

10 changes: 0 additions & 10 deletions clang/lib/AST/ODRHash.cpp
Original file line number Diff line number Diff line change
@@ -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).
Loading
Loading