clang-tools 10.0.0

Background.cpp
Go to the documentation of this file.
1 //===-- Background.cpp - Build an index in a background thread ------------===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8
9 #include "index/Background.h"
10 #include "Compiler.h"
11 #include "Context.h"
12 #include "FSProvider.h"
13 #include "Headers.h"
14 #include "Logger.h"
15 #include "ParsedAST.h"
16 #include "Path.h"
17 #include "SourceCode.h"
18 #include "Symbol.h"
19 #include "Threading.h"
20 #include "Trace.h"
21 #include "URI.h"
22 #include "index/BackgroundIndexLoader.h"
23 #include "index/FileIndex.h"
24 #include "index/IndexAction.h"
25 #include "index/MemIndex.h"
26 #include "index/Ref.h"
27 #include "index/Relation.h"
28 #include "index/Serialization.h"
29 #include "index/SymbolCollector.h"
30 #include "clang/Basic/SourceLocation.h"
31 #include "clang/Basic/SourceManager.h"
32 #include "clang/Driver/Types.h"
33 #include "llvm/ADT/ArrayRef.h"
34 #include "llvm/ADT/DenseSet.h"
35 #include "llvm/ADT/Hashing.h"
36 #include "llvm/ADT/STLExtras.h"
37 #include "llvm/ADT/ScopeExit.h"
38 #include "llvm/ADT/StringMap.h"
39 #include "llvm/ADT/StringRef.h"
40 #include "llvm/ADT/StringSet.h"
41 #include "llvm/Support/Error.h"
42 #include "llvm/Support/Path.h"
43 #include "llvm/Support/Threading.h"
44
45 #include <algorithm>
46 #include <atomic>
47 #include <chrono>
48 #include <condition_variable>
49 #include <cstddef>
50 #include <memory>
51 #include <mutex>
52 #include <numeric>
53 #include <queue>
54 #include <random>
55 #include <string>
56 #include <thread>
57 #include <utility>
58 #include <vector>
59
60 namespace clang {
61 namespace clangd {
62 namespace {
63
64 // Resolves URI to file paths with cache.
65 class URIToFileCache {
66 public:
67 URIToFileCache(llvm::StringRef HintPath) : HintPath(HintPath) {}
68
69 llvm::StringRef resolve(llvm::StringRef FileURI) {
70 auto I = URIToPathCache.try_emplace(FileURI);
71 if (I.second) {
72 auto Path = URI::resolve(FileURI, HintPath);
73 if (!Path) {
74 elog("Failed to resolve URI {0}: {1}", FileURI, Path.takeError());
75 assert(false && "Failed to resolve URI");
76 return "";
77 }
78 I.first->second = *Path;
79 }
80 return I.first->second;
81 }
82
83 private:
84 std::string HintPath;
85 llvm::StringMap<std::string> URIToPathCache;
86 };
87
88 // We keep only the node "U" and its edges. Any node other than "U" will be
89 // empty in the resultant graph.
90 IncludeGraph getSubGraph(const URI &U, const IncludeGraph &FullGraph) {
91 IncludeGraph IG;
92
93 std::string FileURI = U.toString();
94 auto Entry = IG.try_emplace(FileURI).first;
95 auto &Node = Entry->getValue();
96 Node = FullGraph.lookup(Entry->getKey());
97 Node.URI = Entry->getKey();
98
99 // URIs inside nodes must point into the keys of the same IncludeGraph.
100 for (auto &Include : Node.DirectIncludes) {
101 auto I = IG.try_emplace(Include).first;
102 I->getValue().URI = I->getKey();
103 Include = I->getKey();
104 }
105
106 return IG;
107 }
108
109 // We cannot use vfs->makeAbsolute because Cmd.FileName is either absolute or
110 // relative to Cmd.Directory, which might not be the same as current working
111 // directory.
112 llvm::SmallString<128> getAbsolutePath(const tooling::CompileCommand &Cmd) {
113 llvm::SmallString<128> AbsolutePath;
114 if (llvm::sys::path::is_absolute(Cmd.Filename)) {
115 AbsolutePath = Cmd.Filename;
116 } else {
117 AbsolutePath = Cmd.Directory;
118 llvm::sys::path::append(AbsolutePath, Cmd.Filename);
119 llvm::sys::path::remove_dots(AbsolutePath, true);
120 }
121 return AbsolutePath;
122 }
123
124 bool shardIsStale(const LoadedShard &LS, llvm::vfs::FileSystem *FS) {
125 auto Buf = FS->getBufferForFile(LS.AbsolutePath);
126 if (!Buf) {
127 elog("Background-index: Couldn't read {0} to validate stored index: {1}",
128 LS.AbsolutePath, Buf.getError().message());
129 // There is no point in indexing an unreadable file.
130 return false;
131 }
132 return digest(Buf->get()->getBuffer()) != LS.Digest;
133 }
134
135 } // namespace
136
137 BackgroundIndex::BackgroundIndex(
138 Context BackgroundContext, const FileSystemProvider &FSProvider,
139 const GlobalCompilationDatabase &CDB,
140 BackgroundIndexStorage::Factory IndexStorageFactory, size_t ThreadPoolSize)
141 : SwapIndex(std::make_unique<MemIndex>()), FSProvider(FSProvider),
142 CDB(CDB), BackgroundContext(std::move(BackgroundContext)),
143 Rebuilder(this, &IndexedSymbols, ThreadPoolSize),
144 IndexStorageFactory(std::move(IndexStorageFactory)),
145 CommandsChanged(
146 CDB.watch([&](const std::vector<std::string> &ChangedFiles) {
147 enqueue(ChangedFiles);
148 })) {
149 assert(ThreadPoolSize > 0 && "Thread pool size can't be zero.");
150 assert(this->IndexStorageFactory && "Storage factory can not be null!");
151 for (unsigned I = 0; I < ThreadPoolSize; ++I) {
152 ThreadPool.runAsync("background-worker-" + llvm::Twine(I + 1), [this] {
153 WithContext Ctx(this->BackgroundContext.clone());
154 Queue.work([&] { Rebuilder.idle(); });
155 });
156 }
157 }
158
159 BackgroundIndex::~BackgroundIndex() {
160 stop();
161 ThreadPool.wait();
162 }
163
164 BackgroundQueue::Task BackgroundIndex::changedFilesTask(
165 const std::vector<std::string> &ChangedFiles) {
166 BackgroundQueue::Task T([this, ChangedFiles] {
167 trace::Span Tracer("BackgroundIndexEnqueue");
168 // We're doing this asynchronously, because we'll read shards here too.
169 log("Enqueueing {0} commands for indexing", ChangedFiles.size());
170 SPAN_ATTACH(Tracer, "files", int64_t(ChangedFiles.size()));
171
172 auto NeedsReIndexing = loadProject(std::move(ChangedFiles));
173 // Run indexing for files that need to be updated.
174 std::shuffle(NeedsReIndexing.begin(), NeedsReIndexing.end(),
175 std::mt19937(std::random_device{}()));
176 std::vector<BackgroundQueue::Task> Tasks;
177 Tasks.reserve(NeedsReIndexing.size());
178 for (auto &Cmd : NeedsReIndexing)
179 Tasks.push_back(indexFileTask(std::move(Cmd)));
180 Queue.append(std::move(Tasks));
181 });
182
183 T.QueuePri = LoadShards;
184 T.ThreadPri = llvm::ThreadPriority::Default;
185 return T;
186 }
187
188 static llvm::StringRef filenameWithoutExtension(llvm::StringRef Path) {
189 Path = llvm::sys::path::filename(Path);
190 return Path.drop_back(llvm::sys::path::extension(Path).size());
191 }
192
193 BackgroundQueue::Task
194 BackgroundIndex::indexFileTask(tooling::CompileCommand Cmd) {
195 BackgroundQueue::Task T([this, Cmd] {
196 // We can't use llvm::StringRef here since we are going to
197 // move from Cmd during the call below.
198 const std::string FileName = Cmd.Filename;
199 if (auto Error = index(std::move(Cmd)))
200 elog("Indexing {0} failed: {1}", FileName, std::move(Error));
201 });
202 T.QueuePri = IndexFile;
203 T.Tag = filenameWithoutExtension(Cmd.Filename);
204 return T;
205 }
206
207 void BackgroundIndex::boostRelated(llvm::StringRef Path) {
208 if (isHeaderFile(Path))
209 Queue.boost(filenameWithoutExtension(Path), IndexBoostedFile);
210 }
211
212 /// Given index results from a TU, only update symbols coming from files that
213 /// are different or missing from than \p ShardVersionsSnapshot. Also stores new
214 /// index information on IndexStorage.
215 void BackgroundIndex::update(
216 llvm::StringRef MainFile, IndexFileIn Index,
217 const llvm::StringMap<ShardVersion> &ShardVersionsSnapshot,
218 bool HadErrors) {
219 // Partition symbols/references into files.
220 struct File {
221 llvm::DenseSet<const Symbol *> Symbols;
222 llvm::DenseSet<const Ref *> Refs;
223 llvm::DenseSet<const Relation *> Relations;
224 FileDigest Digest;
225 };
226 llvm::StringMap<File> Files;
227 URIToFileCache URICache(MainFile);
228 for (const auto &IndexIt : *Index.Sources) {
229 const auto &IGN = IndexIt.getValue();
230 // Note that sources do not contain any information regarding missing
231 // headers, since we don't even know what absolute path they should fall in.
232 const auto AbsPath = URICache.resolve(IGN.URI);
233 const auto DigestIt = ShardVersionsSnapshot.find(AbsPath);
234 // File has different contents, or indexing was successfull this time.
235 if (DigestIt == ShardVersionsSnapshot.end() ||
236 DigestIt->getValue().Digest != IGN.Digest ||
237 (DigestIt->getValue().HadErrors && !HadErrors))
238 Files.try_emplace(AbsPath).first->getValue().Digest = IGN.Digest;
239 }
240 // This map is used to figure out where to store relations.
241 llvm::DenseMap<SymbolID, File *> SymbolIDToFile;
242 for (const auto &Sym : *Index.Symbols) {
243 if (Sym.CanonicalDeclaration) {
244 auto DeclPath = URICache.resolve(Sym.CanonicalDeclaration.FileURI);
245 const auto FileIt = Files.find(DeclPath);
246 if (FileIt != Files.end()) {
247 FileIt->second.Symbols.insert(&Sym);
248 SymbolIDToFile[Sym.ID] = &FileIt->second;
249 }
250 }
251 // For symbols with different declaration and definition locations, we store
252 // the full symbol in both the header file and the implementation file, so
253 // that merging can tell the preferred symbols (from canonical headers) from
254 // other symbols (e.g. forward declarations).
255 if (Sym.Definition &&
256 Sym.Definition.FileURI != Sym.CanonicalDeclaration.FileURI) {
257 auto DefPath = URICache.resolve(Sym.Definition.FileURI);
258 const auto FileIt = Files.find(DefPath);
259 if (FileIt != Files.end())
260 FileIt->second.Symbols.insert(&Sym);
261 }
262 }
263 llvm::DenseMap<const Ref *, SymbolID> RefToIDs;
264 for (const auto &SymRefs : *Index.Refs) {
265 for (const auto &R : SymRefs.second) {
266 auto Path = URICache.resolve(R.Location.FileURI);
267 const auto FileIt = Files.find(Path);
268 if (FileIt != Files.end()) {
269 auto &F = FileIt->getValue();
270 RefToIDs[&R] = SymRefs.first;
271 F.Refs.insert(&R);
272 }
273 }
274 }
275 for (const auto &Rel : *Index.Relations) {
276 const auto FileIt = SymbolIDToFile.find(Rel.Subject);
277 if (FileIt != SymbolIDToFile.end())
278 FileIt->second->Relations.insert(&Rel);
279 }
280
281 // Build and store new slabs for each updated file.
282 for (const auto &FileIt : Files) {
283 llvm::StringRef Path = FileIt.getKey();
284 SymbolSlab::Builder Syms;
285 RefSlab::Builder Refs;
286 RelationSlab::Builder Relations;
287 for (const auto *S : FileIt.second.Symbols)
288 Syms.insert(*S);
289 for (const auto *R : FileIt.second.Refs)
290 Refs.insert(RefToIDs[R], *R);
291 for (const auto *Rel : FileIt.second.Relations)
292 Relations.insert(*Rel);
293 auto SS = std::make_unique<SymbolSlab>(std::move(Syms).build());
294 auto RS = std::make_unique<RefSlab>(std::move(Refs).build());
295 auto RelS = std::make_unique<RelationSlab>(std::move(Relations).build());
296 auto IG = std::make_unique<IncludeGraph>(
297 getSubGraph(URI::create(Path), Index.Sources.getValue()));
298
299 // We need to store shards before updating the index, since the latter
300 // consumes slabs.
301 // FIXME: Also skip serializing the shard if it is already up-to-date.
302 BackgroundIndexStorage *IndexStorage = IndexStorageFactory(Path);
303 IndexFileOut Shard;
304 Shard.Symbols = SS.get();
305 Shard.Refs = RS.get();
306 Shard.Relations = RelS.get();
307 Shard.Sources = IG.get();
308
309 // Only store command line hash for main files of the TU, since our
310 // current model keeps only one version of a header file.
311 if (Path == MainFile)
312 Shard.Cmd = Index.Cmd.getPointer();
313
314 if (auto Error = IndexStorage->storeShard(Path, Shard))
315 elog("Failed to write background-index shard for file {0}: {1}", Path,
316 std::move(Error));
317
318 {
319 std::lock_guard<std::mutex> Lock(ShardVersionsMu);
320 auto Hash = FileIt.second.Digest;
321 auto DigestIt = ShardVersions.try_emplace(Path);
322 ShardVersion &SV = DigestIt.first->second;
323 // Skip if file is already up to date, unless previous index was broken
324 // and this one is not.
325 if (!DigestIt.second && SV.Digest == Hash && SV.HadErrors && !HadErrors)
326 continue;
327 SV.Digest = Hash;
328 SV.HadErrors = HadErrors;
329
330 // This can override a newer version that is added in another thread, if
331 // this thread sees the older version but finishes later. This should be
332 // rare in practice.
333 IndexedSymbols.update(Path, std::move(SS), std::move(RS), std::move(RelS),
334 Path == MainFile);
335 }
336 }
337 }
338
339 llvm::Error BackgroundIndex::index(tooling::CompileCommand Cmd) {
340 trace::Span Tracer("BackgroundIndex");
341 SPAN_ATTACH(Tracer, "file", Cmd.Filename);
342 auto AbsolutePath = getAbsolutePath(Cmd);
343
344 auto FS = FSProvider.getFileSystem();
345 auto Buf = FS->getBufferForFile(AbsolutePath);
346 if (!Buf)
347 return llvm::errorCodeToError(Buf.getError());
348 auto Hash = digest(Buf->get()->getBuffer());
349
350 // Take a snapshot of the versions to avoid locking for each file in the TU.
351 llvm::StringMap<ShardVersion> ShardVersionsSnapshot;
352 {
353 std::lock_guard<std::mutex> Lock(ShardVersionsMu);
354 ShardVersionsSnapshot = ShardVersions;
355 }
356
357 vlog("Indexing {0} (digest:={1})", Cmd.Filename, llvm::toHex(Hash));
358 ParseInputs Inputs;
359 Inputs.FS = std::move(FS);
360 Inputs.FS->setCurrentWorkingDirectory(Cmd.Directory);
361 Inputs.CompileCommand = std::move(Cmd);
362 IgnoreDiagnostics IgnoreDiags;
363 auto CI = buildCompilerInvocation(Inputs, IgnoreDiags);
364 if (!CI)
365 return llvm::createStringError(llvm::inconvertibleErrorCode(),
366 "Couldn't build compiler invocation");
367 auto Clang = prepareCompilerInstance(std::move(CI), /*Preamble=*/nullptr,
368 std::move(*Buf), Inputs.FS, IgnoreDiags);
369 if (!Clang)
370 return llvm::createStringError(llvm::inconvertibleErrorCode(),
371 "Couldn't build compiler instance");
372
373 SymbolCollector::Options IndexOpts;
374 // Creates a filter to not collect index results from files with unchanged
375 // digests.
376 IndexOpts.FileFilter = [&ShardVersionsSnapshot](const SourceManager &SM,
377 FileID FID) {
378 const auto *F = SM.getFileEntryForID(FID);
379 if (!F)
380 return false; // Skip invalid files.
381 auto AbsPath = getCanonicalPath(F, SM);
382 if (!AbsPath)
383 return false; // Skip files without absolute path.
384 auto Digest = digestFile(SM, FID);
385 if (!Digest)
386 return false;
387 auto D = ShardVersionsSnapshot.find(*AbsPath);
388 if (D != ShardVersionsSnapshot.end() && D->second.Digest == Digest &&
389 !D->second.HadErrors)
390 return false; // Skip files that haven't changed, without errors.
391 return true;
392 };
393
394 IndexFileIn Index;
395 auto Action = createStaticIndexingAction(
396 IndexOpts, [&](SymbolSlab S) { Index.Symbols = std::move(S); },
397 [&](RefSlab R) { Index.Refs = std::move(R); },
398 [&](RelationSlab R) { Index.Relations = std::move(R); },
399 [&](IncludeGraph IG) { Index.Sources = std::move(IG); });
400
401 // We're going to run clang here, and it could potentially crash.
402 // We could use CrashRecoveryContext to try to make indexing crashes nonfatal,
403 // but the leaky "recovery" is pretty scary too in a long-running process.
404 // If crashes are a real problem, maybe we should fork a child process.
405
406 const FrontendInputFile &Input = Clang->getFrontendOpts().Inputs.front();
407 if (!Action->BeginSourceFile(*Clang, Input))
408 return llvm::createStringError(llvm::inconvertibleErrorCode(),
409 "BeginSourceFile() failed");
410 if (llvm::Error Err = Action->Execute())
411 return Err;
412
413 Action->EndSourceFile();
414
415 Index.Cmd = Inputs.CompileCommand;
416 assert(Index.Symbols && Index.Refs && Index.Sources &&
417 "Symbols, Refs and Sources must be set.");
418
419 log("Indexed {0} ({1} symbols, {2} refs, {3} files)",
420 Inputs.CompileCommand.Filename, Index.Symbols->size(),
421 Index.Refs->numRefs(), Index.Sources->size());
422 SPAN_ATTACH(Tracer, "symbols", int(Index.Symbols->size()));
423 SPAN_ATTACH(Tracer, "refs", int(Index.Refs->numRefs()));
424 SPAN_ATTACH(Tracer, "sources", int(Index.Sources->size()));
425
426 bool HadErrors = Clang->hasDiagnostics() &&
427 Clang->getDiagnostics().hasUncompilableErrorOccurred();
428 if (HadErrors) {
429 log("Failed to compile {0}, index may be incomplete", AbsolutePath);
430 for (auto &It : *Index.Sources)
431 It.second.Flags |= IncludeGraphNode::SourceFlag::HadErrors;
432 }
433 update(AbsolutePath, std::move(Index), ShardVersionsSnapshot, HadErrors);
434
435 Rebuilder.indexedTU();
436 return llvm::Error::success();
437 }
438
439 // Restores shards for \p MainFiles from index storage. Then checks staleness of
440 // those shards and returns a list of TUs that needs to be indexed to update
441 // staleness.
442 std::vector<tooling::CompileCommand>
443 BackgroundIndex::loadProject(std::vector<std::string> MainFiles) {
444 std::vector<tooling::CompileCommand> NeedsReIndexing;
445
446 Rebuilder.startLoading();
447 // Load shards for all of the mainfiles.
448 const std::vector<LoadedShard> Result =
449 loadIndexShards(MainFiles, IndexStorageFactory, CDB);
450 size_t LoadedShards = 0;
451 {
452 // Update in-memory state.
453 std::lock_guard<std::mutex> Lock(ShardVersionsMu);
454 for (auto &LS : Result) {
455 if (!LS.Shard)
456 continue;
457 auto SS =
458 LS.Shard->Symbols
459 ? std::make_unique<SymbolSlab>(std::move(*LS.Shard->Symbols))
460 : nullptr;
461 auto RS = LS.Shard->Refs
462 ? std::make_unique<RefSlab>(std::move(*LS.Shard->Refs))
463 : nullptr;
464 auto RelS =
465 LS.Shard->Relations
466 ? std::make_unique<RelationSlab>(std::move(*LS.Shard->Relations))
467 : nullptr;
468 ShardVersion &SV = ShardVersions[LS.AbsolutePath];
469 SV.Digest = LS.Digest;
470 SV.HadErrors = LS.HadErrors;
471 ++LoadedShards;
472
473 IndexedSymbols.update(LS.AbsolutePath, std::move(SS), std::move(RS),
474 std::move(RelS), LS.CountReferences);
475 }
476 }
477 Rebuilder.loadedShard(LoadedShards);
478 Rebuilder.doneLoading();
479
480 auto FS = FSProvider.getFileSystem();
481 llvm::DenseSet<PathRef> TUsToIndex;
482 // We'll accept data from stale shards, but ensure the files get reindexed
483 // soon.
484 for (auto &LS : Result) {
485 if (!shardIsStale(LS, FS.get()))
486 continue;
487 PathRef TUForFile = LS.DependentTU;
488 assert(!TUForFile.empty() && "File without a TU!");
489
490 // FIXME: Currently, we simply schedule indexing on a TU whenever any of
491 // its dependencies needs re-indexing. We might do it smarter by figuring
492 // out a minimal set of TUs that will cover all the stale dependencies.
493 // FIXME: Try looking at other TUs if no compile commands are available
494 // for this TU, i.e TU was deleted after we performed indexing.
495 TUsToIndex.insert(TUForFile);
496 }
497
498 for (PathRef TU : TUsToIndex) {
499 auto Cmd = CDB.getCompileCommand(TU);
500 if (!Cmd)
501 continue;
502 NeedsReIndexing.emplace_back(std::move(*Cmd));
503 }
504
505 return NeedsReIndexing;
506 }
507
508 } // namespace clangd
509 } // namespace clang
clang::clangd::IndexFileOut::Cmd
const tooling::CompileCommand * Cmd
Definition: Serialization.h:63
clang::clangd::IndexFileIn::Symbols
llvm::Optional< SymbolSlab > Symbols
Definition: Serialization.h:43
clang::clangd::SymbolSlab
An immutable symbol container that stores a set of symbols.
Definition: Symbol.h:177
clang::clangd::IndexFileIn::Cmd
llvm::Optional< tooling::CompileCommand > Cmd
Definition: Serialization.h:49
Trace.h
clang::clangd::BackgroundIndexStorage::Factory
llvm::unique_function< BackgroundIndexStorage *(PathRef)> Factory
Definition: Background.h:56
clang::clangd::IndexFileOut::Refs
const RefSlab * Refs
Definition: Serialization.h:57
clang::clangd::RefSlab
An efficient structure of storing large set of symbol references in memory.
Definition: Ref.h:69
clang::clangd::MessageType::Error
An error message.
clang::clangd::RelationSlab
Definition: Relation.h:45
Symbol.h
clang::clangd::BackgroundIndex::boostRelated
void boostRelated(llvm::StringRef Path)
Boosts priority of indexing related to Path.
Definition: Background.cpp:207
clang::clangd::FileDigest
std::array< uint8_t, 8 > FileDigest
Definition: SourceCode.h:38
SourceCode.h
clang::clangd::filenameWithoutExtension
static llvm::StringRef filenameWithoutExtension(llvm::StringRef Path)
Definition: Background.cpp:188
MemIndex.h
clang::clangd::PathRef
llvm::StringRef PathRef
A typedef to represent a ref to file path.
Definition: Path.h:23
clang::clangd::SymbolSlab::Builder::insert
void insert(const Symbol &S)
Adds a symbol, overwriting any existing one with the same ID.
Definition: Symbol.cpp:50
FS
MockFSProvider FS
Definition: HeadersTests.cpp:119
clang::clangd::prepareCompilerInstance
std::unique_ptr< CompilerInstance > prepareCompilerInstance(std::unique_ptr< clang::CompilerInvocation > CI, const PrecompiledPreamble *Preamble, std::unique_ptr< llvm::MemoryBuffer > Buffer, llvm::IntrusiveRefCntPtr< llvm::vfs::FileSystem > VFS, DiagnosticConsumer &DiagsClient)
Definition: Compiler.cpp:72
Context.h
clang::clangd::FileSystemProvider
Definition: FSProvider.h:20
clang::clangd::IndexFileIn::Relations
llvm::Optional< RelationSlab > Relations
Definition: Serialization.h:45
clang::clangd::vlog
void vlog(const char *Fmt, Ts &&... Vals)
Definition: Logger.h:67
clang::clangd::elog
void elog(const char *Fmt, Ts &&... Vals)
Definition: Logger.h:56
Serialization.h
Headers.h
clang::clangd::IndexFileIn::Sources
llvm::Optional< IncludeGraph > Sources
Definition: Serialization.h:47
clang::clangd::IndexFileOut::Symbols
const SymbolSlab * Symbols
Definition: Serialization.h:56
clang::clangd::BackgroundQueue::Task::QueuePri
unsigned QueuePri
Definition: Background.h:75
FSProvider
MockFSProvider FSProvider
Definition: FindSymbolsTests.cpp:67
clang::clangd::SymbolSlab::Builder
SymbolSlab::Builder is a mutable container that can &#39;freeze&#39; to SymbolSlab.
Definition: Symbol.h:199
BackgroundIndexLoader.h
MainFile
std::string MainFile
Definition: HeadersTests.cpp:121
clang::clangd::BackgroundQueue::boost
void boost(llvm::StringRef Tag, unsigned NewPriority)
Definition: BackgroundQueue.cpp:88
clang::clangd::AsyncTaskRunner::wait
void wait() const
Definition: Threading.h:110
clang::clangd::GlobalCompilationDatabase
Provides compilation arguments used for parsing C and C++ files.
Definition: GlobalCompilationDatabase.h:35
Ctx
Context Ctx
Definition: TUScheduler.cpp:237
clang::clangd::IndexFileIn
Definition: Serialization.h:42
clang::clangd::IncludeGraph
llvm::StringMap< IncludeGraphNode > IncludeGraph
Definition: Headers.h:82
clang::clangd::Context::clone
Context clone() const
Clone this context object.
Definition: Context.cpp:20
clang::clangd::AsyncTaskRunner::runAsync
void runAsync(const llvm::Twine &Name, llvm::unique_function< void()> Action)
Definition: Threading.cpp:70
IgnoreDiags
IgnoringDiagConsumer IgnoreDiags
Definition: HeadersTests.cpp:124
clang::clangd::BackgroundIndexRebuilder::idle
void idle()
Definition: BackgroundRebuild.cpp:70
Compiler.h
Action
llvm::unique_function< void()> Action
Definition: TUScheduler.cpp:234
clang::clangd::MemIndex
MemIndex is a naive in-memory index suitable for a small set of symbols.
Definition: MemIndex.h:19
clang::clangd::log
void log(const char *Fmt, Ts &&... Vals)
Definition: Logger.h:62
clang::clangd::Path
std::string Path
A typedef to represent a file path.
Definition: Path.h:20
Relation.h
clang::clangd::loadIndexShards
std::vector< LoadedShard > loadIndexShards(llvm::ArrayRef< Path > MainFiles, BackgroundIndexStorage::Factory &IndexStorageFactory, const GlobalCompilationDatabase &CDB)
Loads all shards for the TU MainFile from Storage.
Definition: BackgroundIndexLoader.cpp:123
clang::clangd::ParseInputs::CompileCommand
tooling::CompileCommand CompileCommand
Definition: Compiler.h:45
clang::clangd::SymbolCollector::Options
Definition: SymbolCollector.h:48
clang::clangd::IgnoreDiagnostics
Definition: Compiler.h:28
clang::clangd::BackgroundIndex::enqueue
void enqueue(const std::vector< std::string > &ChangedFiles)
Definition: Background.h:130
clang::clangd::RelationSlab::Builder::insert
void insert(const Relation &R)
Adds a relation to the slab.
Definition: Relation.h:73
FileName
PathRef FileName
Definition: CodeComplete.cpp:1018
clang::clangd::IndexFileOut::Sources
const IncludeGraph * Sources
Definition: Serialization.h:60
Symbols
SymbolSlab Symbols
Definition: SymbolCollectorTests.cpp:295
clang::clangd::digestFile
llvm::Optional< FileDigest > digestFile(const SourceManager &SM, FileID FID)
Definition: SourceCode.cpp:685
clang::clangd::Context
A context is an immutable container for per-request data that must be propagated through layers that ...
Definition: Context.h:69
clang::clangd::BackgroundIndex::stop
void stop()
Definition: Background.h:140
clang::clangd::RelationSlab::Builder
RelationSlab::Builder is a mutable container that can &#39;freeze&#39; to RelationSlab.
Definition: Relation.h:70
clang::clangd::SymbolCollector::Options::FileFilter
std::function< bool(const SourceManager &, FileID)> FileFilter
If this is set, only collect symbols/references from a file if FileFilter(SM, FID) is true...
Definition: SymbolCollector.h:87
clang::clangd::IncludeGraphNode::SourceFlag::HadErrors
clang::clangd::RefSlab::Builder
RefSlab::Builder is a mutable container that can &#39;freeze&#39; to RefSlab.
Definition: Ref.h:93
clang::clangd::WithContext
WithContext replaces Context::current() with a provided scope.
Definition: Context.h:189
clang::clangd::digest
FileDigest digest(llvm::StringRef Content)
Definition: SourceCode.cpp:675
clang::clangd::SwapIndex
Definition: Index.h:128
clang::clangd::BackgroundIndexStorage::storeShard
virtual llvm::Error storeShard(llvm::StringRef ShardIdentifier, IndexFileOut Shard) const =0
clang::clangd::BackgroundIndex::~BackgroundIndex
~BackgroundIndex()
Definition: Background.cpp:159
clang::clangd::IndexFileOut::Relations
const RelationSlab * Relations
Definition: Serialization.h:58
Ref.h
clang::clangd::IndexFileIn::Refs
llvm::Optional< RefSlab > Refs
Definition: Serialization.h:44
Logger.h
clang::clangd::BackgroundIndex::BackgroundIndex
BackgroundIndex(Context BackgroundContext, const FileSystemProvider &, const GlobalCompilationDatabase &CDB, BackgroundIndexStorage::Factory IndexStorageFactory, size_t ThreadPoolSize=llvm::heavyweight_hardware_concurrency())
If BuildIndexPeriodMs is greater than 0, the symbol index will only be rebuilt periodically (one per ...
Definition: Background.cpp:137
clang::clangd::ParseInputs
Information required to run clang, e.g. to parse AST or do code completion.
Definition: Compiler.h:44
Background.h
clang::clangd::URI::create
static llvm::Expected< URI > create(llvm::StringRef AbsolutePath, llvm::StringRef Scheme)
Creates a URI for a file in the given scheme.
Definition: URI.cpp:197
clang
===– Representation.cpp - ClangDoc Representation --------—*- C++ -*-===//
Definition: ApplyReplacements.h:27
SymbolCollector.h
ParsedAST.h
clang::clangd::createStaticIndexingAction
std::unique_ptr< FrontendAction > createStaticIndexingAction(SymbolCollector::Options Opts, std::function< void(SymbolSlab)> SymbolsCallback, std::function< void(RefSlab)> RefsCallback, std::function< void(RelationSlab)> RelationsCallback, std::function< void(IncludeGraph)> IncludeGraphCallback)
Definition: IndexAction.cpp:205
Path.h
FSProvider.h
clang::clangd::getCanonicalPath
llvm::Optional< std::string > getCanonicalPath(const FileEntry *F, const SourceManager &SourceMgr)
Get the canonical path of F.
Definition: SourceCode.cpp:622
clang::clangd::buildCompilerInvocation
std::unique_ptr< CompilerInvocation > buildCompilerInvocation(const ParseInputs &Inputs, clang::DiagnosticConsumer &D, std::vector< std::string > *CC1Args)
Builds compiler invocation that could be used to build AST or preamble.
Definition: Compiler.cpp:44
URI.h
clang::clangd::RefSlab::Builder::insert
void insert(const SymbolID &ID, const Ref &S)
Adds a ref to the slab. Deep copy: Strings will be owned by the slab.
Definition: Ref.cpp:35
clang::clangd::isHeaderFile
bool isHeaderFile(llvm::StringRef FileName, llvm::Optional< LangOptions > LangOpts)
Infers whether this is a header from the FileName and LangOpts (if presents).
Definition: SourceCode.cpp:1118
clang::clangd::URI::resolve
static llvm::Expected< std::string > resolve(const URI &U, llvm::StringRef HintPath="")
Resolves the absolute path of U.
Definition: URI.cpp:233
clang::clangd::IndexFileOut
Definition: Serialization.h:55
clang::clangd::ParseInputs::FS
IntrusiveRefCntPtr< llvm::vfs::FileSystem > FS
Definition: Compiler.h:46
clang::clangd::BackgroundQueue::append
void append(std::vector< Task >)
Definition: BackgroundQueue.cpp:77
FileIndex.h
Refs
RefSlab Refs
Definition: SymbolCollectorTests.cpp:296
clang::clangd::BackgroundQueue::Task
A work item on the thread pool&#39;s queue.
Definition: Background.h:70
IndexAction.h
clang::clangd::trace::Span
Records an event whose duration is the lifetime of the Span object.
Definition: Trace.h:81
clang::clangd::CompletionItemKind::File
clang::clangd::BackgroundIndexStorage
Definition: Background.h:39
SPAN_ATTACH
#define SPAN_ATTACH(S, Name, Expr)
Attach a key-value pair to a Span event.
Definition: Trace.h:97
Files
llvm::StringMap< std::string > Files
Definition: TUSchedulerTests.cpp:119
Entry
Definition: Modularize.cpp:429
clang::clangd::BackgroundQueue::work
void work(std::function< void()> OnIdle=nullptr)
Definition: BackgroundQueue.cpp:20
Threading.h