summaryrefslogtreecommitdiff
path: root/clang/lib/Serialization/ASTWriter.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'clang/lib/Serialization/ASTWriter.cpp')
-rw-r--r--clang/lib/Serialization/ASTWriter.cpp191
1 files changed, 107 insertions, 84 deletions
diff --git a/clang/lib/Serialization/ASTWriter.cpp b/clang/lib/Serialization/ASTWriter.cpp
index be22ee522191..af7229d74887 100644
--- a/clang/lib/Serialization/ASTWriter.cpp
+++ b/clang/lib/Serialization/ASTWriter.cpp
@@ -4089,11 +4089,9 @@ public:
using hash_value_type = unsigned;
using offset_type = unsigned;
-protected:
explicit ASTDeclContextNameLookupTraitBase(ASTWriter &Writer)
: Writer(Writer) {}
-public:
data_type getData(const DeclIDsTy &LocalIDs) {
unsigned Start = DeclIDs.size();
for (auto ID : LocalIDs)
@@ -4231,6 +4229,38 @@ public:
}
};
+class ASTDeclContextNameTrivialLookupTrait
+ : public ASTDeclContextNameLookupTraitBase {
+public:
+ using key_type = DeclarationNameKey;
+ using key_type_ref = key_type;
+
+public:
+ using ASTDeclContextNameLookupTraitBase::ASTDeclContextNameLookupTraitBase;
+
+ using ASTDeclContextNameLookupTraitBase::getData;
+
+ static bool EqualKey(key_type_ref a, key_type_ref b) { return a == b; }
+
+ hash_value_type ComputeHash(key_type Name) { return Name.getHash(); }
+
+ std::pair<unsigned, unsigned> EmitKeyDataLength(raw_ostream &Out,
+ DeclarationNameKey Name,
+ data_type_ref Lookup) {
+ auto [KeyLen, DataLen] = EmitKeyDataLengthBase(Out, Name, Lookup);
+ return emitULEBKeyDataLength(KeyLen, DataLen, Out);
+ }
+
+ void EmitKey(raw_ostream &Out, DeclarationNameKey Name, unsigned) {
+ return EmitKeyBase(Out, Name);
+ }
+
+ void EmitData(raw_ostream &Out, key_type_ref, data_type Lookup,
+ unsigned DataLen) {
+ EmitDataBase(Out, Lookup, DataLen);
+ }
+};
+
static bool isModuleLocalDecl(NamedDecl *D) {
// For decls not in a file context, they should have the same visibility
// with their parent.
@@ -4273,25 +4303,43 @@ static bool isTULocalInNamedModules(NamedDecl *D) {
return D->getLinkageInternal() == Linkage::Internal;
}
-// Trait used for the on-disk hash table used in the method pool.
-template <bool CollectingTULocalDecls>
-class ASTDeclContextNameLookupTrait : public ASTDeclContextNameLookupTraitBase {
+class ASTDeclContextNameLookupTrait
+ : public ASTDeclContextNameTrivialLookupTrait {
public:
+ using TULocalDeclsMapTy = llvm::DenseMap<key_type, DeclIDsTy>;
+
using ModuleLevelDeclsMapTy =
llvm::DenseMap<ModuleLevelNameLookupTrait::key_type, DeclIDsTy>;
- using key_type = DeclarationNameKey;
- using key_type_ref = key_type;
+private:
+ enum class LookupVisibility {
+ GenerallyVisibile,
+ // The decls can only be found by other TU in the same module.
+ // Note a clang::Module models a module unit instead of logical module
+ // in C++20.
+ ModuleLocalVisible,
+ // The decls can only be found by the TU itself that defines it.
+ TULocal,
+ };
- using TULocalDeclsMapTy = llvm::DenseMap<key_type, DeclIDsTy>;
+ LookupVisibility getLookupVisibility(NamedDecl *D) const {
+ // Only named modules have other lookup visibility.
+ if (!Writer.isWritingStdCXXNamedModules())
+ return LookupVisibility::GenerallyVisibile;
+
+ if (isModuleLocalDecl(D))
+ return LookupVisibility::ModuleLocalVisible;
+ if (isTULocalInNamedModules(D))
+ return LookupVisibility::TULocal;
+ return LookupVisibility::GenerallyVisibile;
+ }
-private:
ModuleLevelDeclsMapTy ModuleLocalDeclsMap;
TULocalDeclsMapTy TULocalDeclsMap;
public:
- explicit ASTDeclContextNameLookupTrait(ASTWriter &Writer)
- : ASTDeclContextNameLookupTraitBase(Writer) {}
+ using ASTDeclContextNameTrivialLookupTrait::
+ ASTDeclContextNameTrivialLookupTrait;
template <typename Coll> data_type getData(const Coll &Decls) {
unsigned Start = DeclIDs.size();
@@ -4312,7 +4360,8 @@ public:
auto ID = Writer.GetDeclRef(DeclForLocalLookup);
- if (isModuleLocalDecl(D)) {
+ switch (getLookupVisibility(DeclForLocalLookup)) {
+ case LookupVisibility::ModuleLocalVisible:
if (UnsignedOrNone PrimaryModuleHash =
getPrimaryModuleHash(D->getOwningModule())) {
auto Key = std::make_pair(D->getDeclName(), *PrimaryModuleHash);
@@ -4323,17 +4372,18 @@ public:
Iter->second.push_back(ID);
continue;
}
+ break;
+ case LookupVisibility::TULocal: {
+ auto Iter = TULocalDeclsMap.find(D->getDeclName());
+ if (Iter == TULocalDeclsMap.end())
+ TULocalDeclsMap.insert({D->getDeclName(), DeclIDsTy{ID}});
+ else
+ Iter->second.push_back(ID);
+ continue;
}
-
- if constexpr (CollectingTULocalDecls) {
- if (isTULocalInNamedModules(D)) {
- auto Iter = TULocalDeclsMap.find(D->getDeclName());
- if (Iter == TULocalDeclsMap.end())
- TULocalDeclsMap.insert({D->getDeclName(), DeclIDsTy{ID}});
- else
- Iter->second.push_back(ID);
- continue;
- }
+ case LookupVisibility::GenerallyVisibile:
+ // Generally visible decls go into the general lookup table.
+ break;
}
DeclIDs.push_back(ID);
@@ -4341,33 +4391,11 @@ public:
return std::make_pair(Start, DeclIDs.size());
}
- using ASTDeclContextNameLookupTraitBase::getData;
-
const ModuleLevelDeclsMapTy &getModuleLocalDecls() {
return ModuleLocalDeclsMap;
}
const TULocalDeclsMapTy &getTULocalDecls() { return TULocalDeclsMap; }
-
- static bool EqualKey(key_type_ref a, key_type_ref b) { return a == b; }
-
- hash_value_type ComputeHash(key_type Name) { return Name.getHash(); }
-
- std::pair<unsigned, unsigned> EmitKeyDataLength(raw_ostream &Out,
- DeclarationNameKey Name,
- data_type_ref Lookup) {
- auto [KeyLen, DataLen] = EmitKeyDataLengthBase(Out, Name, Lookup);
- return emitULEBKeyDataLength(KeyLen, DataLen, Out);
- }
-
- void EmitKey(raw_ostream &Out, DeclarationNameKey Name, unsigned) {
- return EmitKeyBase(Out, Name);
- }
-
- void EmitData(raw_ostream &Out, key_type_ref, data_type Lookup,
- unsigned DataLen) {
- EmitDataBase(Out, Lookup, DataLen);
- }
};
} // namespace
@@ -4581,11 +4609,10 @@ void ASTWriter::GenerateNameLookupTable(
assert(DC == DC->getPrimaryContext() && "only primary DC has lookup table");
// Create the on-disk hash table representation.
- MultiOnDiskHashTableGenerator<
- reader::ASTDeclContextNameLookupTrait,
- ASTDeclContextNameLookupTrait</*CollectingTULocal=*/true>>
+ MultiOnDiskHashTableGenerator<reader::ASTDeclContextNameLookupTrait,
+ ASTDeclContextNameLookupTrait>
Generator;
- ASTDeclContextNameLookupTrait</*CollectingTULocal=*/true> Trait(*this);
+ ASTDeclContextNameLookupTrait Trait(*this);
// The first step is to collect the declaration names which we need to
// serialize into the name lookup table, and to collect them in a stable
@@ -4743,12 +4770,10 @@ void ASTWriter::GenerateNameLookupTable(
const auto &TULocalDecls = Trait.getTULocalDecls();
if (!TULocalDecls.empty() && !isGeneratingReducedBMI()) {
- MultiOnDiskHashTableGenerator<
- reader::ASTDeclContextNameLookupTrait,
- ASTDeclContextNameLookupTrait</*CollectingTULocal=*/false>>
+ MultiOnDiskHashTableGenerator<reader::ASTDeclContextNameLookupTrait,
+ ASTDeclContextNameTrivialLookupTrait>
TULookupGenerator;
- ASTDeclContextNameLookupTrait</*CollectingTULocal=*/false> TULocalTrait(
- *this);
+ ASTDeclContextNameTrivialLookupTrait TULocalTrait(*this);
for (const auto &TULocalIter : TULocalDecls) {
const auto &Key = TULocalIter.first;
@@ -4767,14 +4792,9 @@ void ASTWriter::GenerateNameLookupTable(
///
/// \returns the offset of the DECL_CONTEXT_VISIBLE block within the
/// bitstream, or 0 if no block was written.
-void ASTWriter::WriteDeclContextVisibleBlock(ASTContext &Context,
- DeclContext *DC,
- uint64_t &VisibleBlockOffset,
- uint64_t &ModuleLocalBlockOffset,
- uint64_t &TULocalBlockOffset) {
- assert(VisibleBlockOffset == 0);
- assert(ModuleLocalBlockOffset == 0);
- assert(TULocalBlockOffset == 0);
+void ASTWriter::WriteDeclContextVisibleBlock(
+ ASTContext &Context, DeclContext *DC, VisibleLookupBlockOffsets &Offsets) {
+ assert(!Offsets);
// If we imported a key declaration of this namespace, write the visible
// lookup results as an update record for it rather than including them
@@ -4858,7 +4878,7 @@ void ASTWriter::WriteDeclContextVisibleBlock(ASTContext &Context,
if (!Map || Map->empty())
return;
- VisibleBlockOffset = Stream.GetCurrentBitNo();
+ Offsets.VisibleOffset = Stream.GetCurrentBitNo();
// Create the on-disk hash table in a buffer.
SmallString<4096> LookupTable;
SmallString<4096> ModuleLocalLookupTable;
@@ -4873,8 +4893,8 @@ void ASTWriter::WriteDeclContextVisibleBlock(ASTContext &Context,
++NumVisibleDeclContexts;
if (!ModuleLocalLookupTable.empty()) {
- ModuleLocalBlockOffset = Stream.GetCurrentBitNo();
- assert(ModuleLocalBlockOffset > VisibleBlockOffset);
+ Offsets.ModuleLocalOffset = Stream.GetCurrentBitNo();
+ assert(Offsets.ModuleLocalOffset > Offsets.VisibleOffset);
// Write the lookup table
RecordData::value_type ModuleLocalRecord[] = {
DECL_CONTEXT_MODULE_LOCAL_VISIBLE};
@@ -4884,7 +4904,7 @@ void ASTWriter::WriteDeclContextVisibleBlock(ASTContext &Context,
}
if (!TULookupTable.empty()) {
- TULocalBlockOffset = Stream.GetCurrentBitNo();
+ Offsets.TULocalOffset = Stream.GetCurrentBitNo();
// Write the lookup table
RecordData::value_type TULocalDeclsRecord[] = {
DECL_CONTEXT_TU_LOCAL_VISIBLE};
@@ -6203,31 +6223,26 @@ void ASTWriter::WriteDeclAndTypes(ASTContext &Context) {
assert(DelayedNamespace.empty() || GeneratingReducedBMI);
RecordData DelayedNamespaceRecord;
for (NamespaceDecl *NS : DelayedNamespace) {
- uint64_t LexicalOffset = WriteDeclContextLexicalBlock(Context, NS);
- uint64_t VisibleOffset = 0;
- uint64_t ModuleLocalOffset = 0;
- uint64_t TULocalOffset = 0;
- WriteDeclContextVisibleBlock(Context, NS, VisibleOffset, ModuleLocalOffset,
- TULocalOffset);
+ LookupBlockOffsets Offsets;
- // Write the offset relative to current block.
- if (LexicalOffset)
- LexicalOffset -= DeclTypesBlockStartOffset;
+ Offsets.LexicalOffset = WriteDeclContextLexicalBlock(Context, NS);
+ WriteDeclContextVisibleBlock(Context, NS, Offsets);
- if (VisibleOffset)
- VisibleOffset -= DeclTypesBlockStartOffset;
+ if (Offsets.LexicalOffset)
+ Offsets.LexicalOffset -= DeclTypesBlockStartOffset;
- if (ModuleLocalOffset)
- ModuleLocalOffset -= DeclTypesBlockStartOffset;
+ // Write the offset relative to current block.
+ if (Offsets.VisibleOffset)
+ Offsets.VisibleOffset -= DeclTypesBlockStartOffset;
- if (TULocalOffset)
- TULocalOffset -= DeclTypesBlockStartOffset;
+ if (Offsets.ModuleLocalOffset)
+ Offsets.ModuleLocalOffset -= DeclTypesBlockStartOffset;
+
+ if (Offsets.TULocalOffset)
+ Offsets.TULocalOffset -= DeclTypesBlockStartOffset;
AddDeclRef(NS, DelayedNamespaceRecord);
- DelayedNamespaceRecord.push_back(LexicalOffset);
- DelayedNamespaceRecord.push_back(VisibleOffset);
- DelayedNamespaceRecord.push_back(ModuleLocalOffset);
- DelayedNamespaceRecord.push_back(TULocalOffset);
+ AddLookupOffsets(Offsets, DelayedNamespaceRecord);
}
// The process of writing lexical and visible block for delayed namespace
@@ -6818,6 +6833,14 @@ TypeID ASTWriter::GetOrCreateTypeID(ASTContext &Context, QualType T) {
});
}
+void ASTWriter::AddLookupOffsets(const LookupBlockOffsets &Offsets,
+ RecordDataImpl &Record) {
+ Record.push_back(Offsets.LexicalOffset);
+ Record.push_back(Offsets.VisibleOffset);
+ Record.push_back(Offsets.ModuleLocalOffset);
+ Record.push_back(Offsets.TULocalOffset);
+}
+
void ASTWriter::AddEmittedDeclRef(const Decl *D, RecordDataImpl &Record) {
if (!wasDeclEmitted(D))
return;