clang-tools 8.0.0

Serialization.cpp
Go to the documentation of this file.
1 //===-- Serialization.cpp - Binary serialization of index data ------------===//
2 //
3 // The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9
10 #include "Serialization.h"
11 #include "Index.h"
12 #include "Logger.h"
13 #include "RIFF.h"
14 #include "Trace.h"
15 #include "dex/Dex.h"
16 #include "llvm/Support/Compression.h"
17 #include "llvm/Support/Endian.h"
18 #include "llvm/Support/Error.h"
19
20 namespace clang {
21 namespace clangd {
22 namespace {
23 llvm::Error makeError(const llvm::Twine &Msg) {
24 return llvm::make_error<llvm::StringError>(Msg,
25 llvm::inconvertibleErrorCode());
26 }
27
28 // IO PRIMITIVES
29 // We use little-endian 32 bit ints, sometimes with variable-length encoding.
30 //
31 // Variable-length int encoding (varint) uses the bottom 7 bits of each byte
32 // to encode the number, and the top bit to indicate whether more bytes follow.
33 // e.g. 9a 2f means [0x1a and keep reading, 0x2f and stop].
34 // This represents 0x1a | 0x2f<<7 = 6042.
35 // A 32-bit integer takes 1-5 bytes to encode; small numbers are more compact.
36
37 // Reads binary data from a StringRef, and keeps track of position.
38 class Reader {
39 const char *Begin, *End;
40 bool Err = false;
41
42 public:
43 Reader(llvm::StringRef Data) : Begin(Data.begin()), End(Data.end()) {}
44 // The "error" bit is set by reading past EOF or reading invalid data.
45 // When in an error state, reads may return zero values: callers should check.
46 bool err() const { return Err; }
47 // Did we read all the data, or encounter an error?
48 bool eof() const { return Begin == End || Err; }
49 // All the data we didn't read yet.
50 llvm::StringRef rest() const { return llvm::StringRef(Begin, End - Begin); }
51
52 uint8_t consume8() {
53 if (LLVM_UNLIKELY(Begin == End)) {
54 Err = true;
55 return 0;
56 }
57 return *Begin++;
58 }
59
60 uint32_t consume32() {
61 if (LLVM_UNLIKELY(Begin + 4 > End)) {
62 Err = true;
63 return 0;
64 }
65 auto Ret = llvm::support::endian::read32le(Begin);
66 Begin += 4;
67 return Ret;
68 }
69
70 llvm::StringRef consume(int N) {
71 if (LLVM_UNLIKELY(Begin + N > End)) {
72 Err = true;
73 return llvm::StringRef();
74 }
75 llvm::StringRef Ret(Begin, N);
76 Begin += N;
77 return Ret;
78 }
79
80 uint32_t consumeVar() {
81 constexpr static uint8_t More = 1 << 7;
82 uint8_t B = consume8();
83 if (LLVM_LIKELY(!(B & More)))
84 return B;
85 uint32_t Val = B & ~More;
86 for (int Shift = 7; B & More && Shift < 32; Shift += 7) {
87 B = consume8();
88 Val |= (B & ~More) << Shift;
89 }
90 return Val;
91 }
92
93 llvm::StringRef consumeString(llvm::ArrayRef<llvm::StringRef> Strings) {
94 auto StringIndex = consumeVar();
95 if (LLVM_UNLIKELY(StringIndex >= Strings.size())) {
96 Err = true;
97 return llvm::StringRef();
98 }
99 return Strings[StringIndex];
100 }
101
102 SymbolID consumeID() {
103 llvm::StringRef Raw = consume(SymbolID::RawSize); // short if truncated.
104 return LLVM_UNLIKELY(err()) ? SymbolID() : SymbolID::fromRaw(Raw);
105 }
106 };
107
108 void write32(uint32_t I, llvm::raw_ostream &OS) {
109 char buf[4];
110 llvm::support::endian::write32le(buf, I);
111 OS.write(buf, sizeof(buf));
112 }
113
114 void writeVar(uint32_t I, llvm::raw_ostream &OS) {
115 constexpr static uint8_t More = 1 << 7;
116 if (LLVM_LIKELY(I < 1 << 7)) {
117 OS.write(I);
118 return;
119 }
120 for (;;) {
121 OS.write(I | More);
122 I >>= 7;
123 if (I < 1 << 7) {
124 OS.write(I);
125 return;
126 }
127 }
128 }
129
130 // STRING TABLE ENCODING
131 // Index data has many string fields, and many strings are identical.
132 // We store each string once, and refer to them by index.
133 //
134 // The string table's format is:
135 // - UncompressedSize : uint32 (or 0 for no compression)
136 // - CompressedData : byte[CompressedSize]
137 //
138 // CompressedData is a zlib-compressed byte[UncompressedSize].
139 // It contains a sequence of null-terminated strings, e.g. "foo\0bar\0".
140 // These are sorted to improve compression.
141
142 // Maps each string to a canonical representation.
143 // Strings remain owned externally (e.g. by SymbolSlab).
144 class StringTableOut {
145 llvm::DenseSet<llvm::StringRef> Unique;
146 std::vector<llvm::StringRef> Sorted;
147 // Since strings are interned, look up can be by pointer.
148 llvm::DenseMap<std::pair<const char *, size_t>, unsigned> Index;
149
150 public:
151 StringTableOut() {
152 // Ensure there's at least one string in the table.
153 // Table size zero is reserved to indicate no compression.
154 Unique.insert("");
155 }
156 // Add a string to the table. Overwrites S if an identical string exists.
157 void intern(llvm::StringRef &S) { S = *Unique.insert(S).first; };
158 // Finalize the table and write it to OS. No more strings may be added.
159 void finalize(llvm::raw_ostream &OS) {
160 Sorted = {Unique.begin(), Unique.end()};
161 llvm::sort(Sorted);
162 for (unsigned I = 0; I < Sorted.size(); ++I)
163 Index.try_emplace({Sorted[I].data(), Sorted[I].size()}, I);
164
165 std::string RawTable;
166 for (llvm::StringRef S : Sorted) {
167 RawTable.append(S);
168 RawTable.push_back(0);
169 }
170 if (llvm::zlib::isAvailable()) {
171 llvm::SmallString<1> Compressed;
172 llvm::cantFail(llvm::zlib::compress(RawTable, Compressed));
173 write32(RawTable.size(), OS);
174 OS << Compressed;
175 } else {
176 write32(0, OS); // No compression.
177 OS << RawTable;
178 }
179 }
180 // Get the ID of an string, which must be interned. Table must be finalized.
181 unsigned index(llvm::StringRef S) const {
182 assert(!Sorted.empty() && "table not finalized");
183 assert(Index.count({S.data(), S.size()}) && "string not interned");
184 return Index.find({S.data(), S.size()})->second;
185 }
186 };
187
188 struct StringTableIn {
189 llvm::BumpPtrAllocator Arena;
190 std::vector<llvm::StringRef> Strings;
191 };
192
193 llvm::Expected<StringTableIn> readStringTable(llvm::StringRef Data) {
194 Reader R(Data);
195 size_t UncompressedSize = R.consume32();
196 if (R.err())
197 return makeError("Truncated string table");
198
199 llvm::StringRef Uncompressed;
200 llvm::SmallString<1> UncompressedStorage;
201 if (UncompressedSize == 0) // No compression
202 Uncompressed = R.rest();
203 else {
204 if (llvm::Error E = llvm::zlib::uncompress(R.rest(), UncompressedStorage,
205 UncompressedSize))
206 return std::move(E);
207 Uncompressed = UncompressedStorage;
208 }
209
210 StringTableIn Table;
211 llvm::StringSaver Saver(Table.Arena);
212 R = Reader(Uncompressed);
213 for (Reader R(Uncompressed); !R.eof();) {
214 auto Len = R.rest().find(0);
215 if (Len == llvm::StringRef::npos)
216 return makeError("Bad string table: not null terminated");
217 Table.Strings.push_back(Saver.save(R.consume(Len)));
218 R.consume8();
219 }
220 if (R.err())
221 return makeError("Truncated string table");
222 return std::move(Table);
223 }
224
225 // SYMBOL ENCODING
226 // Each field of clangd::Symbol is encoded in turn (see implementation).
227 // - StringRef fields encode as varint (index into the string table)
228 // - enums encode as the underlying type
229 // - most numbers encode as varint
230
231 void writeLocation(const SymbolLocation &Loc, const StringTableOut &Strings,
232 llvm::raw_ostream &OS) {
233 writeVar(Strings.index(Loc.FileURI), OS);
234 for (const auto &Endpoint : {Loc.Start, Loc.End}) {
235 writeVar(Endpoint.line(), OS);
236 writeVar(Endpoint.column(), OS);
237 }
238 }
239
240 SymbolLocation readLocation(Reader &Data,
241 llvm::ArrayRef<llvm::StringRef> Strings) {
242 SymbolLocation Loc;
243 Loc.FileURI = Data.consumeString(Strings).data();
244 for (auto *Endpoint : {&Loc.Start, &Loc.End}) {
245 Endpoint->setLine(Data.consumeVar());
246 Endpoint->setColumn(Data.consumeVar());
247 }
248 return Loc;
249 }
250
251 IncludeGraphNode readIncludeGraphNode(Reader &Data,
252 llvm::ArrayRef<llvm::StringRef> Strings) {
253 IncludeGraphNode IGN;
254 IGN.IsTU = Data.consume8();
255 IGN.URI = Data.consumeString(Strings);
256 llvm::StringRef Digest = Data.consume(IGN.Digest.size());
257 std::copy(Digest.bytes_begin(), Digest.bytes_end(), IGN.Digest.begin());
258 IGN.DirectIncludes.resize(Data.consumeVar());
259 for (llvm::StringRef &Include : IGN.DirectIncludes)
260 Include = Data.consumeString(Strings);
261 return IGN;
262 }
263
264 void writeIncludeGraphNode(const IncludeGraphNode &IGN,
265 const StringTableOut &Strings,
266 llvm::raw_ostream &OS) {
267 OS.write(IGN.IsTU);
268 writeVar(Strings.index(IGN.URI), OS);
269 llvm::StringRef Hash(reinterpret_cast<const char *>(IGN.Digest.data()),
270 IGN.Digest.size());
271 OS << Hash;
272 writeVar(IGN.DirectIncludes.size(), OS);
273 for (llvm::StringRef Include : IGN.DirectIncludes)
274 writeVar(Strings.index(Include), OS);
275 }
276
277 void writeSymbol(const Symbol &Sym, const StringTableOut &Strings,
278 llvm::raw_ostream &OS) {
279 OS << Sym.ID.raw(); // TODO: once we start writing xrefs and posting lists,
280 // symbol IDs should probably be in a string table.
281 OS.write(static_cast<uint8_t>(Sym.SymInfo.Kind));
282 OS.write(static_cast<uint8_t>(Sym.SymInfo.Lang));
283 writeVar(Strings.index(Sym.Name), OS);
284 writeVar(Strings.index(Sym.Scope), OS);
285 writeLocation(Sym.Definition, Strings, OS);
286 writeLocation(Sym.CanonicalDeclaration, Strings, OS);
287 writeVar(Sym.References, OS);
288 OS.write(static_cast<uint8_t>(Sym.Flags));
289 OS.write(static_cast<uint8_t>(Sym.Origin));
290 writeVar(Strings.index(Sym.Signature), OS);
291 writeVar(Strings.index(Sym.CompletionSnippetSuffix), OS);
292 writeVar(Strings.index(Sym.Documentation), OS);
293 writeVar(Strings.index(Sym.ReturnType), OS);
294 writeVar(Strings.index(Sym.Type), OS);
295
296 auto WriteInclude = [&](const Symbol::IncludeHeaderWithReferences &Include) {
297 writeVar(Strings.index(Include.IncludeHeader), OS);
298 writeVar(Include.References, OS);
299 };
300 writeVar(Sym.IncludeHeaders.size(), OS);
301 for (const auto &Include : Sym.IncludeHeaders)
302 WriteInclude(Include);
303 }
304
305 Symbol readSymbol(Reader &Data, llvm::ArrayRef<llvm::StringRef> Strings) {
306 Symbol Sym;
307 Sym.ID = Data.consumeID();
308 Sym.SymInfo.Kind = static_cast<index::SymbolKind>(Data.consume8());
309 Sym.SymInfo.Lang = static_cast<index::SymbolLanguage>(Data.consume8());
310 Sym.Name = Data.consumeString(Strings);
311 Sym.Scope = Data.consumeString(Strings);
312 Sym.Definition = readLocation(Data, Strings);
313 Sym.CanonicalDeclaration = readLocation(Data, Strings);
314 Sym.References = Data.consumeVar();
315 Sym.Flags = static_cast<Symbol::SymbolFlag>(Data.consumeVar());
316 Sym.Origin = static_cast<SymbolOrigin>(Data.consumeVar());
317 Sym.Signature = Data.consumeString(Strings);
318 Sym.CompletionSnippetSuffix = Data.consumeString(Strings);
319 Sym.Documentation = Data.consumeString(Strings);
320 Sym.ReturnType = Data.consumeString(Strings);
321 Sym.Type = Data.consumeString(Strings);
322 Sym.IncludeHeaders.resize(Data.consumeVar());
323 for (auto &I : Sym.IncludeHeaders) {
324 I.IncludeHeader = Data.consumeString(Strings);
325 I.References = Data.consumeVar();
326 }
327 return Sym;
328 }
329
330 // REFS ENCODING
331 // A refs section has data grouped by Symbol. Each symbol has:
332 // - SymbolID: 8 bytes
333 // - NumRefs: varint
334 // - Ref[NumRefs]
335 // Fields of Ref are encoded in turn, see implementation.
336
337 void writeRefs(const SymbolID &ID, llvm::ArrayRef<Ref> Refs,
338 const StringTableOut &Strings, llvm::raw_ostream &OS) {
339 OS << ID.raw();
340 writeVar(Refs.size(), OS);
341 for (const auto &Ref : Refs) {
342 OS.write(static_cast<unsigned char>(Ref.Kind));
343 writeLocation(Ref.Location, Strings, OS);
344 }
345 }
346
347 std::pair<SymbolID, std::vector<Ref>>
348 readRefs(Reader &Data, llvm::ArrayRef<llvm::StringRef> Strings) {
349 std::pair<SymbolID, std::vector<Ref>> Result;
350 Result.first = Data.consumeID();
351 Result.second.resize(Data.consumeVar());
352 for (auto &Ref : Result.second) {
353 Ref.Kind = static_cast<RefKind>(Data.consume8());
354 Ref.Location = readLocation(Data, Strings);
355 }
356 return Result;
357 }
358
359 // FILE ENCODING
360 // A file is a RIFF chunk with type 'CdIx'.
361 // It contains the sections:
362 // - meta: version number
363 // - srcs: information related to include graph
364 // - stri: string table
365 // - symb: symbols
366 // - refs: references to symbols
367
368 // The current versioning scheme is simple - non-current versions are rejected.
369 // If you make a breaking change, bump this version number to invalidate stored
370 // data. Later we may want to support some backward compatibility.
371 constexpr static uint32_t Version = 8;
372
373 llvm::Expected<IndexFileIn> readRIFF(llvm::StringRef Data) {
374 auto RIFF = riff::readFile(Data);
375 if (!RIFF)
376 return RIFF.takeError();
377 if (RIFF->Type != riff::fourCC("CdIx"))
378 return makeError("wrong RIFF type");
379 llvm::StringMap<llvm::StringRef> Chunks;
380 for (const auto &Chunk : RIFF->Chunks)
381 Chunks.try_emplace(llvm::StringRef(Chunk.ID.data(), Chunk.ID.size()),
382 Chunk.Data);
383
384 for (llvm::StringRef RequiredChunk : {"meta", "stri"})
385 if (!Chunks.count(RequiredChunk))
386 return makeError("missing required chunk " + RequiredChunk);
387
388 Reader Meta(Chunks.lookup("meta"));
389 if (Meta.consume32() != Version)
390 return makeError("wrong version");
391
392 auto Strings = readStringTable(Chunks.lookup("stri"));
393 if (!Strings)
394 return Strings.takeError();
395
396 IndexFileIn Result;
397 if (Chunks.count("srcs")) {
398 Reader SrcsReader(Chunks.lookup("srcs"));
399 Result.Sources.emplace();
400 while (!SrcsReader.eof()) {
401 auto IGN = readIncludeGraphNode(SrcsReader, Strings->Strings);
402 auto Entry = Result.Sources->try_emplace(IGN.URI).first;
403 Entry->getValue() = std::move(IGN);
404 // We change all the strings inside the structure to point at the keys in
405 // the map, since it is the only copy of the string that's going to live.
406 Entry->getValue().URI = Entry->getKey();
407 for (auto &Include : Entry->getValue().DirectIncludes)
408 Include = Result.Sources->try_emplace(Include).first->getKey();
409 }
410 if (SrcsReader.err())
411 return makeError("malformed or truncated include uri");
412 }
413
414 if (Chunks.count("symb")) {
415 Reader SymbolReader(Chunks.lookup("symb"));
416 SymbolSlab::Builder Symbols;
417 while (!SymbolReader.eof())
418 Symbols.insert(readSymbol(SymbolReader, Strings->Strings));
419 if (SymbolReader.err())
420 return makeError("malformed or truncated symbol");
421 Result.Symbols = std::move(Symbols).build();
422 }
423 if (Chunks.count("refs")) {
424 Reader RefsReader(Chunks.lookup("refs"));
425 RefSlab::Builder Refs;
426 while (!RefsReader.eof()) {
427 auto RefsBundle = readRefs(RefsReader, Strings->Strings);
428 for (const auto &Ref : RefsBundle.second) // FIXME: bulk insert?
429 Refs.insert(RefsBundle.first, Ref);
430 }
431 if (RefsReader.err())
432 return makeError("malformed or truncated refs");
433 Result.Refs = std::move(Refs).build();
434 }
435 return std::move(Result);
436 }
437
438 template <class Callback>
439 void visitStrings(IncludeGraphNode &IGN, const Callback &CB) {
440 CB(IGN.URI);
441 for (llvm::StringRef &Include : IGN.DirectIncludes)
442 CB(Include);
443 }
444
445 void writeRIFF(const IndexFileOut &Data, llvm::raw_ostream &OS) {
446 assert(Data.Symbols && "An index file without symbols makes no sense!");
447 riff::File RIFF;
448 RIFF.Type = riff::fourCC("CdIx");
449
450 llvm::SmallString<4> Meta;
451 {
452 llvm::raw_svector_ostream MetaOS(Meta);
453 write32(Version, MetaOS);
454 }
455 RIFF.Chunks.push_back({riff::fourCC("meta"), Meta});
456
457 StringTableOut Strings;
458 std::vector<Symbol> Symbols;
459 for (const auto &Sym : *Data.Symbols) {
460 Symbols.emplace_back(Sym);
461 visitStrings(Symbols.back(),
462 [&](llvm::StringRef &S) { Strings.intern(S); });
463 }
464 std::vector<IncludeGraphNode> Sources;
465 if (Data.Sources)
466 for (const auto &Source : *Data.Sources) {
467 Sources.push_back(Source.getValue());
468 visitStrings(Sources.back(),
469 [&](llvm::StringRef &S) { Strings.intern(S); });
470 }
471
472 std::vector<std::pair<SymbolID, std::vector<Ref>>> Refs;
473 if (Data.Refs) {
474 for (const auto &Sym : *Data.Refs) {
475 Refs.emplace_back(Sym);
476 for (auto &Ref : Refs.back().second) {
477 llvm::StringRef File = Ref.Location.FileURI;
478 Strings.intern(File);
479 Ref.Location.FileURI = File.data();
480 }
481 }
482 }
483
484 std::string StringSection;
485 {
486 llvm::raw_string_ostream StringOS(StringSection);
487 Strings.finalize(StringOS);
488 }
489 RIFF.Chunks.push_back({riff::fourCC("stri"), StringSection});
490
491 std::string SymbolSection;
492 {
493 llvm::raw_string_ostream SymbolOS(SymbolSection);
494 for (const auto &Sym : Symbols)
495 writeSymbol(Sym, Strings, SymbolOS);
496 }
497 RIFF.Chunks.push_back({riff::fourCC("symb"), SymbolSection});
498
499 std::string RefsSection;
500 if (Data.Refs) {
501 {
502 llvm::raw_string_ostream RefsOS(RefsSection);
503 for (const auto &Sym : Refs)
504 writeRefs(Sym.first, Sym.second, Strings, RefsOS);
505 }
506 RIFF.Chunks.push_back({riff::fourCC("refs"), RefsSection});
507 }
508
509 std::string SrcsSection;
510 {
511 {
512 llvm::raw_string_ostream SrcsOS(SrcsSection);
513 for (const auto &SF : Sources)
514 writeIncludeGraphNode(SF, Strings, SrcsOS);
515 }
516 RIFF.Chunks.push_back({riff::fourCC("srcs"), SrcsSection});
517 }
518
519 OS << RIFF;
520 }
521
522 } // namespace
523
524 // Defined in YAMLSerialization.cpp.
525 void writeYAML(const IndexFileOut &, llvm::raw_ostream &);
526 llvm::Expected<IndexFileIn> readYAML(llvm::StringRef);
527
528 llvm::raw_ostream &operator<<(llvm::raw_ostream &OS, const IndexFileOut &O) {
529 switch (O.Format) {
530 case IndexFileFormat::RIFF:
531 writeRIFF(O, OS);
532 break;
533 case IndexFileFormat::YAML:
534 writeYAML(O, OS);
535 break;
536 }
537 return OS;
538 }
539
540 llvm::Expected<IndexFileIn> readIndexFile(llvm::StringRef Data) {
541 if (Data.startswith("RIFF")) {
542 return readRIFF(Data);
543 } else if (auto YAMLContents = readYAML(Data)) {
544 return std::move(*YAMLContents);
545 } else {
546 return makeError("Not a RIFF file and failed to parse as YAML: " +
547 llvm::toString(YAMLContents.takeError()));
548 }
549 }
550
551 std::unique_ptr<SymbolIndex> loadIndex(llvm::StringRef SymbolFilename,
552 bool UseDex) {
553 trace::Span OverallTracer("LoadIndex");
554 auto Buffer = llvm::MemoryBuffer::getFile(SymbolFilename);
555 if (!Buffer) {
556 llvm::errs() << "Can't open " << SymbolFilename << "\n";
557 return nullptr;
558 }
559
560 SymbolSlab Symbols;
561 RefSlab Refs;
562 {
563 trace::Span Tracer("ParseIndex");
564 if (auto I = readIndexFile(Buffer->get()->getBuffer())) {
565 if (I->Symbols)
566 Symbols = std::move(*I->Symbols);
567 if (I->Refs)
568 Refs = std::move(*I->Refs);
569 } else {
570 llvm::errs() << "Bad Index: " << llvm::toString(I.takeError()) << "\n";
571 return nullptr;
572 }
573 }
574
575 size_t NumSym = Symbols.size();
576 size_t NumRefs = Refs.numRefs();
577
578 trace::Span Tracer("BuildIndex");
579 auto Index = UseDex ? dex::Dex::build(std::move(Symbols), std::move(Refs))
580 : MemIndex::build(std::move(Symbols), std::move(Refs));
581 vlog("Loaded {0} from {1} with estimated memory usage {2} bytes\n"
582 " - number of symbols: {3}\n"
583 " - number of refs: {4}\n",
584 UseDex ? "Dex" : "MemIndex", SymbolFilename,
585 Index->estimateMemoryUsage(), NumSym, NumRefs);
586 return Index;
587 }
588
589 } // namespace clangd
590 } // namespace clang
Loc
SourceLocation Loc
&#39;#&#39; location in the include directive
Definition: IncludeOrderCheck.cpp:37
clang::clangd::readYAML
llvm::Expected< IndexFileIn > readYAML(llvm::StringRef)
Definition: YAMLSerialization.cpp:310
clang::clangd::SymbolSlab
Definition: Index.h:292
Trace.h
RIFF.h
clang::clangd::loadIndex
std::unique_ptr< SymbolIndex > loadIndex(llvm::StringRef SymbolFilename, bool UseDex)
Definition: Serialization.cpp:551
clang::clangd::RefSlab
Definition: Index.h:388
clang::clangd::riff::makeError
static llvm::Error makeError(const char *Msg)
Definition: RIFF.cpp:17
Dex.h
This defines Dex - a symbol index implementation based on query iterators over symbol tokens...
Index.h
clang::clangd::writeYAML
void writeYAML(const IndexFileOut &, llvm::raw_ostream &)
Definition: YAMLSerialization.cpp:295
SymbolKind
clang::find_all_symbols::SymbolInfo::SymbolKind SymbolKind
Definition: SymbolInfo.cpp:22
clang::clangd::IndexFileOut::Format
IndexFileFormat Format
Definition: Serialization.h:56
clang::clangd::riff::fourCC
constexpr FourCC fourCC(const char(&Literal)[5])
Definition: RIFF.h:45
clang::clangd::IndexFileFormat::YAML
clang::clangd::MemIndex::build
static std::unique_ptr< SymbolIndex > build(SymbolSlab Symbols, RefSlab Refs)
Builds an index from slabs. The index takes ownership of the data.
Definition: MemIndex.cpp:19
clang::tidy::cppcoreguidelines::toString
static llvm::StringRef toString(SpecialMemberFunctionsCheck::SpecialMemberFunctionKind K)
Definition: SpecialMemberFunctionsCheck.cpp:59
clang::clangd::Callback
llvm::unique_function< void(llvm::Expected< T >)> Callback
A Callback<T> is a void function that accepts Expected<T>.
Definition: Function.h:29
clang::clangd::riff::readFile
llvm::Expected< File > readFile(llvm::StringRef Stream)
Definition: RIFF.cpp:52
clang::clangd::RefSlab::numRefs
size_t numRefs() const
Definition: Index.h:402
clang::clangd::IndexFileFormat::RIFF
clang::clangd::Symbol::SymbolFlag
SymbolFlag
Definition: Index.h:233
clang::clangd::readIndexFile
llvm::Expected< IndexFileIn > readIndexFile(llvm::StringRef Data)
Definition: Serialization.cpp:540
clang::clangd::vlog
void vlog(const char *Fmt, Ts &&... Vals)
Definition: Logger.h:68
Serialization.h
clang::clangd::SymbolID::RawSize
static constexpr size_t RawSize
Definition: SymbolID.h:45
clang::clangd::UseDex
static llvm::cl::opt< bool > UseDex("use-dex-index", llvm::cl::desc("Use experimental Dex dynamic index."), llvm::cl::init(false), llvm::cl::Hidden)
Arena
llvm::BumpPtrAllocator Arena
Definition: Serialization.cpp:189
clang::clangd::dex::consume
std::vector< std::pair< DocID, float > > consume(Iterator &It)
Advances the iterator until it is exhausted.
Definition: Iterator.cpp:351
clang::clangd::dex::Dex::build
static std::unique_ptr< SymbolIndex > build(SymbolSlab, RefSlab)
Builds an index from slabs. The index takes ownership of the slab.
Definition: Dex.cpp:27
Result
llvm::Optional< llvm::Expected< tooling::AtomicChanges > > Result
Definition: ClangdServer.cpp:60
clang::clangd::RefKind
RefKind
Definition: Index.h:351
Strings
std::vector< llvm::StringRef > Strings
Definition: Serialization.cpp:190
Logger.h
clang
===– Representation.cpp - ClangDoc Representation --------—*- C++ -*-===//
Definition: ChangeNamespace.cpp:18
clang::clangd::IndexFileOut
Definition: Serialization.h:50
clang::clangd::operator<<
llvm::raw_ostream & operator<<(llvm::raw_ostream &OS, const CodeCompletion &C)
Definition: CodeComplete.cpp:1719
clang::clangd::trace::Span
Records an event whose duration is the lifetime of the Span object.
Definition: Trace.h:83
clang::clangd::CompletionItemKind::File
clang::clangd::SymbolOrigin
SymbolOrigin
Definition: Index.h:126
clang::clangd::SymbolSlab::size
size_t size() const
Definition: Index.h:304
clang::doc::SymbolID
std::array< uint8_t, 20 > SymbolID
Definition: Representation.h:31
Entry
Definition: Modularize.cpp:430
clang::clangd::visitStrings
void visitStrings(Symbol &S, const Callback &CB)
Definition: Index.h:263
Index
const SymbolIndex * Index
Definition: Dexp.cpp:85