diff options
| author | Nathan Ridge <zeratul976@hotmail.com> | 2019-06-03 05:07:52 +0000 |
|---|---|---|
| committer | Nathan Ridge <zeratul976@hotmail.com> | 2019-06-03 05:07:52 +0000 |
| commit | 92524f9bf84de92a0a61fcdd7305261d7f9501ca (patch) | |
| tree | d9193382f70bb849046c36da183b34b9a493a528 /clang-tools-extra/clangd/index/Serialization.cpp | |
| parent | 3fc299df3d337c8a61d15f42f2537508f2feb92a (diff) | |
| download | bcm5719-llvm-92524f9bf84de92a0a61fcdd7305261d7f9501ca.tar.gz bcm5719-llvm-92524f9bf84de92a0a61fcdd7305261d7f9501ca.zip | |
[clangd] Serialization support for RelationSlab
Summary: This builds on D59407 to provide YAML and RIFF serialization support.
Reviewers: kadircet
Subscribers: ilya-biryukov, MaskRay, jkorous, arphaman, cfe-commits
Tags: #clang
Differential Revision: https://reviews.llvm.org/D62459
llvm-svn: 362353
Diffstat (limited to 'clang-tools-extra/clangd/index/Serialization.cpp')
| -rw-r--r-- | clang-tools-extra/clangd/index/Serialization.cpp | 83 |
1 files changed, 81 insertions, 2 deletions
diff --git a/clang-tools-extra/clangd/index/Serialization.cpp b/clang-tools-extra/clangd/index/Serialization.cpp index 12993eb631c..521e5bd04ad 100644 --- a/clang-tools-extra/clangd/index/Serialization.cpp +++ b/clang-tools-extra/clangd/index/Serialization.cpp @@ -24,6 +24,29 @@ llvm::Error makeError(const llvm::Twine &Msg) { return llvm::make_error<llvm::StringError>(Msg, llvm::inconvertibleErrorCode()); } +} // namespace + +RelationKind symbolRoleToRelationKind(index::SymbolRole Role) { + // SymbolRole is used to record relations in the index. + // Only handle the relations we actually store currently. + // If we start storing more relations, this list can be expanded. + switch (Role) { + case index::SymbolRole::RelationBaseOf: + return RelationKind::BaseOf; + default: + llvm_unreachable("Unsupported symbol role"); + } +} + +index::SymbolRole relationKindToSymbolRole(RelationKind Kind) { + switch (Kind) { + case RelationKind::BaseOf: + return index::SymbolRole::RelationBaseOf; + } + llvm_unreachable("Invalid relation kind"); +} + +namespace { // IO PRIMITIVES // We use little-endian 32 bit ints, sometimes with variable-length encoding. @@ -358,6 +381,28 @@ readRefs(Reader &Data, llvm::ArrayRef<llvm::StringRef> Strings) { return Result; } +// RELATIONS ENCODING +// A relations section is a flat list of relations. Each relation has: +// - SymbolID (subject): 8 bytes +// - relation kind (predicate): 1 byte +// - SymbolID (object): 8 bytes +// In the future, we might prefer a packed representation if the need arises. + +void writeRelation(const Relation &R, llvm::raw_ostream &OS) { + OS << R.Subject.raw(); + RelationKind Kind = symbolRoleToRelationKind(R.Predicate); + OS.write(static_cast<uint8_t>(Kind)); + OS << R.Object.raw(); +} + +Relation readRelation(Reader &Data) { + SymbolID Subject = Data.consumeID(); + index::SymbolRole Predicate = + relationKindToSymbolRole(static_cast<RelationKind>(Data.consume8())); + SymbolID Object = Data.consumeID(); + return {Subject, Predicate, Object}; +} + // FILE ENCODING // A file is a RIFF chunk with type 'CdIx'. // It contains the sections: @@ -434,6 +479,17 @@ llvm::Expected<IndexFileIn> readRIFF(llvm::StringRef Data) { return makeError("malformed or truncated refs"); Result.Refs = std::move(Refs).build(); } + if (Chunks.count("rela")) { + Reader RelationsReader(Chunks.lookup("rela")); + RelationSlab::Builder Relations; + while (!RelationsReader.eof()) { + auto Relation = readRelation(RelationsReader); + Relations.insert(Relation); + } + if (RelationsReader.err()) + return makeError("malformed or truncated relations"); + Result.Relations = std::move(Relations).build(); + } return std::move(Result); } @@ -483,6 +539,14 @@ void writeRIFF(const IndexFileOut &Data, llvm::raw_ostream &OS) { } } + std::vector<Relation> Relations; + if (Data.Relations) { + for (const auto &Relation : *Data.Relations) { + Relations.emplace_back(Relation); + // No strings to be interned in relations. + } + } + std::string StringSection; { llvm::raw_string_ostream StringOS(StringSection); @@ -508,6 +572,16 @@ void writeRIFF(const IndexFileOut &Data, llvm::raw_ostream &OS) { RIFF.Chunks.push_back({riff::fourCC("refs"), RefsSection}); } + std::string RelationSection; + if (Data.Relations) { + { + llvm::raw_string_ostream RelationOS{RelationSection}; + for (const auto &Relation : Relations) + writeRelation(Relation, RelationOS); + } + RIFF.Chunks.push_back({riff::fourCC("rela"), RelationSection}); + } + std::string SrcsSection; { { @@ -561,6 +635,7 @@ std::unique_ptr<SymbolIndex> loadIndex(llvm::StringRef SymbolFilename, SymbolSlab Symbols; RefSlab Refs; + RelationSlab Relations; { trace::Span Tracer("ParseIndex"); if (auto I = readIndexFile(Buffer->get()->getBuffer())) { @@ -568,6 +643,8 @@ std::unique_ptr<SymbolIndex> loadIndex(llvm::StringRef SymbolFilename, Symbols = std::move(*I->Symbols); if (I->Refs) Refs = std::move(*I->Refs); + if (I->Relations) + Relations = std::move(*I->Relations); } else { llvm::errs() << "Bad Index: " << llvm::toString(I.takeError()) << "\n"; return nullptr; @@ -576,15 +653,17 @@ std::unique_ptr<SymbolIndex> loadIndex(llvm::StringRef SymbolFilename, size_t NumSym = Symbols.size(); size_t NumRefs = Refs.numRefs(); + size_t NumRelations = Relations.size(); trace::Span Tracer("BuildIndex"); auto Index = UseDex ? dex::Dex::build(std::move(Symbols), std::move(Refs)) : MemIndex::build(std::move(Symbols), std::move(Refs)); vlog("Loaded {0} from {1} with estimated memory usage {2} bytes\n" " - number of symbols: {3}\n" - " - number of refs: {4}\n", + " - number of refs: {4}\n" + " - numnber of relations: {5}", UseDex ? "Dex" : "MemIndex", SymbolFilename, - Index->estimateMemoryUsage(), NumSym, NumRefs); + Index->estimateMemoryUsage(), NumSym, NumRefs, NumRelations); return Index; } |

