summaryrefslogtreecommitdiffstats
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.cpp76
1 files changed, 52 insertions, 24 deletions
diff --git a/clang/lib/Serialization/ASTWriter.cpp b/clang/lib/Serialization/ASTWriter.cpp
index b5340dc41d2..51839afce1a 100644
--- a/clang/lib/Serialization/ASTWriter.cpp
+++ b/clang/lib/Serialization/ASTWriter.cpp
@@ -13,6 +13,8 @@
#include "clang/Serialization/ASTWriter.h"
#include "ASTCommon.h"
+#include "ASTReaderInternals.h"
+#include "MultiOnDiskHashTable.h"
#include "clang/AST/ASTContext.h"
#include "clang/AST/Decl.h"
#include "clang/AST/DeclContextInternals.h"
@@ -3338,12 +3340,14 @@ namespace {
// Trait used for the on-disk hash table used in the method pool.
class ASTDeclContextNameLookupTrait {
ASTWriter &Writer;
+ llvm::SmallVector<DeclID, 64> DeclIDs;
public:
typedef DeclarationNameKey key_type;
typedef key_type key_type_ref;
- typedef DeclContext::lookup_result data_type;
+ /// A start and end index into DeclIDs, representing a sequence of decls.
+ typedef std::pair<unsigned, unsigned> data_type;
typedef const data_type& data_type_ref;
typedef unsigned hash_value_type;
@@ -3351,10 +3355,40 @@ public:
explicit ASTDeclContextNameLookupTrait(ASTWriter &Writer) : Writer(Writer) { }
+ template<typename Coll>
+ data_type getData(const Coll &Decls) {
+ unsigned Start = DeclIDs.size();
+ for (NamedDecl *D : Decls) {
+ DeclIDs.push_back(
+ Writer.GetDeclRef(getDeclForLocalLookup(Writer.getLangOpts(), D)));
+ }
+ return std::make_pair(Start, DeclIDs.size());
+ }
+
+ data_type ImportData(const reader::ASTDeclContextNameLookupTrait::data_type &FromReader) {
+ unsigned Start = DeclIDs.size();
+ for (auto ID : FromReader)
+ DeclIDs.push_back(ID);
+ return std::make_pair(Start, DeclIDs.size());
+ }
+
+ static bool EqualKey(key_type_ref a, key_type_ref b) {
+ return a == b;
+ }
+
hash_value_type ComputeHash(DeclarationNameKey Name) {
return Name.getHash();
}
+ void EmitFileRef(raw_ostream &Out, ModuleFile *F) const {
+ assert(Writer.hasChain() &&
+ "have reference to loaded module file but no chain?");
+
+ using namespace llvm::support;
+ endian::Writer<little>(Out)
+ .write<uint32_t>(Writer.getChain()->getModuleFileID(F));
+ }
+
std::pair<unsigned, unsigned> EmitKeyDataLength(raw_ostream &Out,
DeclarationNameKey Name,
data_type_ref Lookup) {
@@ -3381,7 +3415,9 @@ public:
LE.write<uint16_t>(KeyLen);
// 4 bytes for each DeclID.
- unsigned DataLen = 4 * Lookup.size();
+ unsigned DataLen = 4 * (Lookup.second - Lookup.first);
+ assert(uint16_t(DataLen) == DataLen &&
+ "too many decls for serialized lookup result");
LE.write<uint16_t>(DataLen);
return std::make_pair(KeyLen, DataLen);
@@ -3421,11 +3457,8 @@ public:
using namespace llvm::support;
endian::Writer<little> LE(Out);
uint64_t Start = Out.tell(); (void)Start;
- for (DeclContext::lookup_iterator I = Lookup.begin(), E = Lookup.end();
- I != E; ++I)
- LE.write<uint32_t>(
- Writer.GetDeclRef(getDeclForLocalLookup(Writer.getLangOpts(), *I)));
-
+ for (unsigned I = Lookup.first, N = Lookup.second; I != N; ++I)
+ LE.write<uint32_t>(DeclIDs[I]);
assert(Out.tell() - Start == DataLen && "Data length is wrong");
}
};
@@ -3445,7 +3478,7 @@ bool ASTWriter::isLookupResultEntirelyExternal(StoredDeclsList &Result,
return true;
}
-uint32_t
+void
ASTWriter::GenerateNameLookupTable(const DeclContext *ConstDC,
llvm::SmallVectorImpl<char> &LookupTable) {
assert(!ConstDC->HasLazyLocalLexicalLookups &&
@@ -3457,8 +3490,8 @@ ASTWriter::GenerateNameLookupTable(const DeclContext *ConstDC,
assert(DC == DC->getPrimaryContext() && "only primary DC has lookup table");
// Create the on-disk hash table representation.
- llvm::OnDiskChainedHashTableGenerator<ASTDeclContextNameLookupTrait>
- Generator;
+ MultiOnDiskHashTableGenerator<reader::ASTDeclContextNameLookupTrait,
+ ASTDeclContextNameLookupTrait> Generator;
ASTDeclContextNameLookupTrait Trait(*this);
// The first step is to collect the declaration names which we need to
@@ -3593,7 +3626,7 @@ ASTWriter::GenerateNameLookupTable(const DeclContext *ConstDC,
switch (Name.getNameKind()) {
default:
- Generator.insert(Name, Result, Trait);
+ Generator.insert(Name, Trait.getData(Result), Trait);
break;
case DeclarationName::CXXConstructorName:
@@ -3611,17 +3644,15 @@ ASTWriter::GenerateNameLookupTable(const DeclContext *ConstDC,
// the key, only the kind of name is used.
if (!ConstructorDecls.empty())
Generator.insert(ConstructorDecls.front()->getDeclName(),
- DeclContext::lookup_result(ConstructorDecls), Trait);
+ Trait.getData(ConstructorDecls), Trait);
if (!ConversionDecls.empty())
Generator.insert(ConversionDecls.front()->getDeclName(),
- DeclContext::lookup_result(ConversionDecls), Trait);
+ Trait.getData(ConversionDecls), Trait);
- // Create the on-disk hash table in a buffer.
- llvm::raw_svector_ostream Out(LookupTable);
- // Make sure that no bucket is at offset 0
- using namespace llvm::support;
- endian::Writer<little>(Out).write<uint32_t>(0);
- return Generator.Emit(Out, Trait);
+ // Create the on-disk hash table. Also emit the existing imported and
+ // merged table if there is one.
+ auto *Lookups = Chain ? Chain->getLoadedLookupTables(DC) : nullptr;
+ Generator.emit(LookupTable, Trait, Lookups ? &Lookups->Table : nullptr);
}
/// \brief Write the block containing all of the declaration IDs
@@ -3704,12 +3735,11 @@ uint64_t ASTWriter::WriteDeclContextVisibleBlock(ASTContext &Context,
// Create the on-disk hash table in a buffer.
SmallString<4096> LookupTable;
- uint32_t BucketOffset = GenerateNameLookupTable(DC, LookupTable);
+ GenerateNameLookupTable(DC, LookupTable);
// Write the lookup table
RecordData Record;
Record.push_back(DECL_CONTEXT_VISIBLE);
- Record.push_back(BucketOffset);
Stream.EmitRecordWithBlob(DeclContextVisibleLookupAbbrev, Record,
LookupTable);
++NumVisibleDeclContexts;
@@ -3732,7 +3762,7 @@ void ASTWriter::WriteDeclContextVisibleUpdate(const DeclContext *DC) {
// Create the on-disk hash table in a buffer.
SmallString<4096> LookupTable;
- uint32_t BucketOffset = GenerateNameLookupTable(DC, LookupTable);
+ GenerateNameLookupTable(DC, LookupTable);
// If we're updating a namespace, select a key declaration as the key for the
// update record; those are the only ones that will be checked on reload.
@@ -3743,7 +3773,6 @@ void ASTWriter::WriteDeclContextVisibleUpdate(const DeclContext *DC) {
RecordData Record;
Record.push_back(UPDATE_VISIBLE);
Record.push_back(getDeclID(cast<Decl>(DC)));
- Record.push_back(BucketOffset);
Stream.EmitRecordWithBlob(UpdateVisibleAbbrev, Record, LookupTable);
}
@@ -4207,7 +4236,6 @@ void ASTWriter::WriteASTCore(Sema &SemaRef,
Abv = new llvm::BitCodeAbbrev();
Abv->Add(llvm::BitCodeAbbrevOp(UPDATE_VISIBLE));
Abv->Add(llvm::BitCodeAbbrevOp(llvm::BitCodeAbbrevOp::VBR, 6));
- Abv->Add(llvm::BitCodeAbbrevOp(llvm::BitCodeAbbrevOp::Fixed, 32));
Abv->Add(llvm::BitCodeAbbrevOp(llvm::BitCodeAbbrevOp::Blob));
UpdateVisibleAbbrev = Stream.EmitAbbrev(Abv);
WriteDeclContextVisibleUpdate(TU);
OpenPOWER on IntegriCloud