1 //===--- GlobalCompilationDatabase.cpp ---------------------------*- C++-*-===//
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 "GlobalCompilationDatabase.h"
10 #include "FS.h"
11 #include "SourceCode.h"
12 #include "support/Logger.h"
13 #include "support/Path.h"
14 #include "support/Threading.h"
15 #include "support/ThreadsafeFS.h"
16 #include "clang/Frontend/CompilerInvocation.h"
17 #include "clang/Tooling/ArgumentsAdjusters.h"
18 #include "clang/Tooling/CompilationDatabase.h"
19 #include "clang/Tooling/CompilationDatabasePluginRegistry.h"
20 #include "clang/Tooling/JSONCompilationDatabase.h"
21 #include "llvm/ADT/None.h"
22 #include "llvm/ADT/Optional.h"
23 #include "llvm/ADT/STLExtras.h"
24 #include "llvm/ADT/ScopeExit.h"
25 #include "llvm/ADT/SmallString.h"
26 #include "llvm/ADT/StringMap.h"
27 #include "llvm/Support/FileSystem.h"
28 #include "llvm/Support/FileUtilities.h"
29 #include "llvm/Support/Path.h"
30 #include "llvm/Support/Program.h"
31 #include "llvm/Support/VirtualFileSystem.h"
32 #include <atomic>
33 #include <chrono>
34 #include <condition_variable>
35 #include <string>
36 #include <tuple>
37 #include <vector>
38 
39 namespace clang {
40 namespace clangd {
41 namespace {
42 
43 // Variant of parent_path that operates only on absolute paths.
44 PathRef absoluteParent(PathRef Path) {
45   assert(llvm::sys::path::is_absolute(Path));
46 #if defined(_WIN32)
47   // llvm::sys says "C:\" is absolute, and its parent is "C:" which is relative.
48   // This unhelpful behavior seems to have been inherited from boost.
49   if (llvm::sys::path::relative_path(Path).empty()) {
50     return PathRef();
51   }
52 #endif
53   PathRef Result = llvm::sys::path::parent_path(Path);
54   assert(Result.empty() || llvm::sys::path::is_absolute(Result));
55   return Result;
56 }
57 
58 // Runs the given action on all parent directories of filename, starting from
59 // deepest directory and going up to root. Stops whenever action succeeds.
60 void actOnAllParentDirectories(PathRef FileName,
61                                llvm::function_ref<bool(PathRef)> Action) {
62   for (auto Path = absoluteParent(FileName); !Path.empty() && !Action(Path);
63        Path = absoluteParent(Path))
64     ;
65 }
66 
67 } // namespace
68 
69 tooling::CompileCommand
70 GlobalCompilationDatabase::getFallbackCommand(PathRef File) const {
71   std::vector<std::string> Argv = {"clang"};
72   // Clang treats .h files as C by default and files without extension as linker
73   // input, resulting in unhelpful diagnostics.
74   // Parsing as Objective C++ is friendly to more cases.
75   auto FileExtension = llvm::sys::path::extension(File);
76   if (FileExtension.empty() || FileExtension == ".h")
77     Argv.push_back("-xobjective-c++-header");
78   Argv.push_back(std::string(File));
79   tooling::CompileCommand Cmd(llvm::sys::path::parent_path(File),
80                               llvm::sys::path::filename(File), std::move(Argv),
81                               /*Output=*/"");
82   Cmd.Heuristic = "clangd fallback";
83   return Cmd;
84 }
85 
86 // Loads and caches the CDB from a single directory.
87 //
88 // This class is threadsafe, which is to say we have independent locks for each
89 // directory we're searching for a CDB.
90 // Loading is deferred until first access.
91 //
92 // The DirectoryBasedCDB keeps a map from path => DirectoryCache.
93 // Typical usage is to:
94 //  - 1) determine all the paths that might be searched
95 //  - 2) acquire the map lock and get-or-create all the DirectoryCache entries
96 //  - 3) release the map lock and query the caches as desired
97 class DirectoryBasedGlobalCompilationDatabase::DirectoryCache {
98   using stopwatch = std::chrono::steady_clock;
99 
100   // CachedFile is used to read a CDB file on disk (e.g. compile_commands.json).
101   // It specializes in being able to quickly bail out if the file is unchanged,
102   // which is the common case.
103   // Internally, it stores file metadata so a stat() can verify it's unchanged.
104   // We don't actually cache the content as it's not needed - if the file is
105   // unchanged then the previous CDB is valid.
106   struct CachedFile {
107     CachedFile(llvm::StringRef Parent, llvm::StringRef Rel) {
108       llvm::SmallString<256> Path = Parent;
109       llvm::sys::path::append(Path, Rel);
110       this->Path = Path.str().str();
111     }
112     std::string Path;
113     size_t Size = NoFileCached;
114     llvm::sys::TimePoint<> ModifiedTime;
115     FileDigest ContentHash;
116 
117     static constexpr size_t NoFileCached = -1;
118 
119     struct LoadResult {
120       enum {
121         FileNotFound,
122         TransientError,
123         FoundSameData,
124         FoundNewData,
125       } Result;
126       std::unique_ptr<llvm::MemoryBuffer> Buffer; // Set only if FoundNewData
127     };
128 
129     LoadResult load(llvm::vfs::FileSystem &FS, bool HasOldData);
130   };
131 
132   // If we've looked for a CDB here and found none, the time when that happened.
133   // (Atomics make it possible for get() to return without taking a lock)
134   std::atomic<stopwatch::rep> NoCDBAt = {
135       stopwatch::time_point::min().time_since_epoch().count()};
136 
137   // Guards the following cache state.
138   std::mutex Mu;
139   // When was the cache last known to be in sync with disk state?
140   stopwatch::time_point CachePopulatedAt = stopwatch::time_point::min();
141   // Whether a new CDB has been loaded but not broadcast yet.
142   bool NeedsBroadcast = false;
143   // Last loaded CDB, meaningful if CachePopulatedAt was ever set.
144   // shared_ptr so we can overwrite this when callers are still using the CDB.
145   std::shared_ptr<tooling::CompilationDatabase> CDB;
146   // File metadata for the CDB files we support tracking directly.
147   CachedFile CompileCommandsJson;
148   CachedFile BuildCompileCommandsJson;
149   CachedFile CompileFlagsTxt;
150   // CachedFile member corresponding to CDB.
151   //   CDB  | ACF  | Scenario
152   //   null | null | no CDB found, or initial empty cache
153   //   set  | null | CDB was loaded via generic plugin interface
154   //   null | set  | found known CDB file, but parsing it failed
155   //   set  | set  | CDB was parsed from a known file
156   CachedFile *ActiveCachedFile = nullptr;
157 
158 public:
159   DirectoryCache(llvm::StringRef Path)
160       : CompileCommandsJson(Path, "compile_commands.json"),
161         BuildCompileCommandsJson(Path, "build/compile_commands.json"),
162         CompileFlagsTxt(Path, "compile_flags.txt"), Path(Path) {
163     assert(llvm::sys::path::is_absolute(Path));
164   }
165 
166   // Absolute canonical path that we're the cache for. (Not case-folded).
167   const std::string Path;
168 
169   // Get the CDB associated with this directory.
170   // ShouldBroadcast:
171   //  - as input, signals whether the caller is willing to broadcast a
172   //    newly-discovered CDB. (e.g. to trigger background indexing)
173   //  - as output, signals whether the caller should do so.
174   // (If a new CDB is discovered and ShouldBroadcast is false, we mark the
175   // CDB as needing broadcast, and broadcast it next time we can).
176   std::shared_ptr<const tooling::CompilationDatabase>
177   get(const ThreadsafeFS &TFS, bool &ShouldBroadcast,
178       stopwatch::time_point FreshTime, stopwatch::time_point FreshTimeMissing) {
179     // Fast path for common case without taking lock.
180     if (stopwatch::time_point(stopwatch::duration(NoCDBAt.load())) >
181         FreshTimeMissing) {
182       ShouldBroadcast = false;
183       return nullptr;
184     }
185 
186     std::lock_guard<std::mutex> Lock(Mu);
187     auto RequestBroadcast = llvm::make_scope_exit([&, OldCDB(CDB.get())] {
188       // If we loaded a new CDB, it should be broadcast at some point.
189       if (CDB != nullptr && CDB.get() != OldCDB)
190         NeedsBroadcast = true;
191       else if (CDB == nullptr) // nothing to broadcast anymore!
192         NeedsBroadcast = false;
193       // If we have something to broadcast, then do so iff allowed.
194       if (!ShouldBroadcast)
195         return;
196       ShouldBroadcast = NeedsBroadcast;
197       NeedsBroadcast = false;
198     });
199 
200     // If our cache is valid, serve from it.
201     if (CachePopulatedAt > FreshTime)
202       return CDB;
203 
204     if (/*MayCache=*/load(*TFS.view(/*CWD=*/llvm::None))) {
205       // Use new timestamp, as loading may be slow.
206       CachePopulatedAt = stopwatch::now();
207       NoCDBAt.store((CDB ? stopwatch::time_point::min() : CachePopulatedAt)
208                         .time_since_epoch()
209                         .count());
210     }
211 
212     return CDB;
213   }
214 
215 private:
216   // Updates `CDB` from disk state. Returns false on failure.
217   bool load(llvm::vfs::FileSystem &FS);
218 };
219 
220 DirectoryBasedGlobalCompilationDatabase::DirectoryCache::CachedFile::LoadResult
221 DirectoryBasedGlobalCompilationDatabase::DirectoryCache::CachedFile::load(
222     llvm::vfs::FileSystem &FS, bool HasOldData) {
223   auto Stat = FS.status(Path);
224   if (!Stat || !Stat->isRegularFile()) {
225     Size = NoFileCached;
226     ContentHash = {};
227     return {LoadResult::FileNotFound, nullptr};
228   }
229   // If both the size and mtime match, presume unchanged without reading.
230   if (HasOldData && Stat->getLastModificationTime() == ModifiedTime &&
231       Stat->getSize() == Size)
232     return {LoadResult::FoundSameData, nullptr};
233   auto Buf = FS.getBufferForFile(Path);
234   if (!Buf || (*Buf)->getBufferSize() != Stat->getSize()) {
235     // Don't clear the cache - possible we're seeing inconsistent size as the
236     // file is being recreated. If it ends up identical later, great!
237     //
238     // This isn't a complete solution: if we see a partial file but stat/read
239     // agree on its size, we're ultimately going to have spurious CDB reloads.
240     // May be worth fixing if generators don't write atomically (CMake does).
241     elog("Failed to read {0}: {1}", Path,
242          Buf ? "size changed" : Buf.getError().message());
243     return {LoadResult::TransientError, nullptr};
244   }
245 
246   FileDigest NewContentHash = digest((*Buf)->getBuffer());
247   if (HasOldData && NewContentHash == ContentHash) {
248     // mtime changed but data is the same: avoid rebuilding the CDB.
249     ModifiedTime = Stat->getLastModificationTime();
250     return {LoadResult::FoundSameData, nullptr};
251   }
252 
253   Size = (*Buf)->getBufferSize();
254   ModifiedTime = Stat->getLastModificationTime();
255   ContentHash = NewContentHash;
256   return {LoadResult::FoundNewData, std::move(*Buf)};
257 }
258 
259 // Adapt CDB-loading functions to a common interface for DirectoryCache::load().
260 static std::unique_ptr<tooling::CompilationDatabase>
261 parseJSON(PathRef Path, llvm::StringRef Data, std::string &Error) {
262   if (auto CDB = tooling::JSONCompilationDatabase::loadFromBuffer(
263           Data, Error, tooling::JSONCommandLineSyntax::AutoDetect)) {
264     // FS used for expanding response files.
265     // FIXME: ExpandResponseFilesDatabase appears not to provide the usual
266     // thread-safety guarantees, as the access to FS is not locked!
267     // For now, use the real FS, which is known to be threadsafe (if we don't
268     // use/change working directory, which ExpandResponseFilesDatabase doesn't).
269     auto FS = llvm::vfs::getRealFileSystem();
270     return tooling::inferTargetAndDriverMode(
271         tooling::inferMissingCompileCommands(
272             expandResponseFiles(std::move(CDB), std::move(FS))));
273   }
274   return nullptr;
275 }
276 static std::unique_ptr<tooling::CompilationDatabase>
277 parseFixed(PathRef Path, llvm::StringRef Data, std::string &Error) {
278   return tooling::FixedCompilationDatabase::loadFromBuffer(
279       llvm::sys::path::parent_path(Path), Data, Error);
280 }
281 
282 bool DirectoryBasedGlobalCompilationDatabase::DirectoryCache::load(
283     llvm::vfs::FileSystem &FS) {
284   dlog("Probing directory {0}", Path);
285   std::string Error;
286 
287   // Load from the specially-supported compilation databases (JSON + Fixed).
288   // For these, we know the files they read and cache their metadata so we can
289   // cheaply validate whether they've changed, and hot-reload if they have.
290   // (As a bonus, these are also VFS-clean)!
291   struct CDBFile {
292     CachedFile *File;
293     // Wrapper for {Fixed,JSON}CompilationDatabase::loadFromBuffer.
294     llvm::function_ref<std::unique_ptr<tooling::CompilationDatabase>(
295         PathRef,
296         /*Data*/ llvm::StringRef,
297         /*ErrorMsg*/ std::string &)>
298         Parser;
299   };
300   for (const auto &Entry : {CDBFile{&CompileCommandsJson, parseJSON},
301                             CDBFile{&BuildCompileCommandsJson, parseJSON},
302                             CDBFile{&CompileFlagsTxt, parseFixed}}) {
303     bool Active = ActiveCachedFile == Entry.File;
304     auto Loaded = Entry.File->load(FS, Active);
305     switch (Loaded.Result) {
306     case CachedFile::LoadResult::FileNotFound:
307       if (Active) {
308         log("Unloaded compilation database from {0}", Entry.File->Path);
309         ActiveCachedFile = nullptr;
310         CDB = nullptr;
311       }
312       // Continue looking at other candidates.
313       break;
314     case CachedFile::LoadResult::TransientError:
315       // File existed but we couldn't read it. Reuse the cache, retry later.
316       return false; // Load again next time.
317     case CachedFile::LoadResult::FoundSameData:
318       assert(Active && "CachedFile may not return 'same data' if !HasOldData");
319       // This is the critical file, and it hasn't changed.
320       return true;
321     case CachedFile::LoadResult::FoundNewData:
322       // We have a new CDB!
323       CDB = Entry.Parser(Entry.File->Path, Loaded.Buffer->getBuffer(), Error);
324       if (CDB)
325         log("{0} compilation database from {1}", Active ? "Reloaded" : "Loaded",
326             Entry.File->Path);
327       else
328         elog("Failed to load compilation database from {0}: {1}",
329              Entry.File->Path, Error);
330       ActiveCachedFile = Entry.File;
331       return true;
332     }
333   }
334 
335   // Fall back to generic handling of compilation databases.
336   // We don't know what files they read, so can't efficiently check whether
337   // they need to be reloaded. So we never do that.
338   // FIXME: the interface doesn't provide a way to virtualize FS access.
339 
340   // Don't try these more than once. If we've scanned before, we're done.
341   if (CachePopulatedAt > stopwatch::time_point::min())
342     return true;
343   for (const auto &Entry :
344        tooling::CompilationDatabasePluginRegistry::entries()) {
345     // Avoid duplicating the special cases handled above.
346     if (Entry.getName() == "fixed-compilation-database" ||
347         Entry.getName() == "json-compilation-database")
348       continue;
349     auto Plugin = Entry.instantiate();
350     if (auto CDB = Plugin->loadFromDirectory(Path, Error)) {
351       log("Loaded compilation database from {0} with plugin {1}", Path,
352           Entry.getName());
353       this->CDB = std::move(CDB);
354       return true;
355     }
356     // Don't log Error here, it's usually just "couldn't find <file>".
357   }
358   dlog("No compilation database at {0}", Path);
359   return true;
360 }
361 
362 DirectoryBasedGlobalCompilationDatabase::
363     DirectoryBasedGlobalCompilationDatabase(const Options &Opts)
364     : Opts(Opts), Broadcaster(std::make_unique<BroadcastThread>(*this)) {
365   if (Opts.CompileCommandsDir)
366     OnlyDirCache = std::make_unique<DirectoryCache>(*Opts.CompileCommandsDir);
367 }
368 
369 DirectoryBasedGlobalCompilationDatabase::
370     ~DirectoryBasedGlobalCompilationDatabase() = default;
371 
372 llvm::Optional<tooling::CompileCommand>
373 DirectoryBasedGlobalCompilationDatabase::getCompileCommand(PathRef File) const {
374   CDBLookupRequest Req;
375   Req.FileName = File;
376   Req.ShouldBroadcast = true;
377   auto Now = std::chrono::steady_clock::now();
378   Req.FreshTime = Now - Opts.RevalidateAfter;
379   Req.FreshTimeMissing = Now - Opts.RevalidateMissingAfter;
380 
381   auto Res = lookupCDB(Req);
382   if (!Res) {
383     log("Failed to find compilation database for {0}", File);
384     return llvm::None;
385   }
386 
387   auto Candidates = Res->CDB->getCompileCommands(File);
388   if (!Candidates.empty())
389     return std::move(Candidates.front());
390 
391   return None;
392 }
393 
394 // For platforms where paths are case-insensitive (but case-preserving),
395 // we need to do case-insensitive comparisons and use lowercase keys.
396 // FIXME: Make Path a real class with desired semantics instead.
397 //        This class is not the only place this problem exists.
398 // FIXME: Mac filesystems default to case-insensitive, but may be sensitive.
399 
400 static std::string maybeCaseFoldPath(PathRef Path) {
401 #if defined(_WIN32) || defined(__APPLE__)
402   return Path.lower();
403 #else
404   return std::string(Path);
405 #endif
406 }
407 
408 static bool pathEqual(PathRef A, PathRef B) {
409 #if defined(_WIN32) || defined(__APPLE__)
410   return A.equals_lower(B);
411 #else
412   return A == B;
413 #endif
414 }
415 
416 std::vector<DirectoryBasedGlobalCompilationDatabase::DirectoryCache *>
417 DirectoryBasedGlobalCompilationDatabase::getDirectoryCaches(
418     llvm::ArrayRef<llvm::StringRef> Dirs) const {
419   std::vector<std::string> FoldedDirs;
420   FoldedDirs.reserve(Dirs.size());
421   for (const auto &Dir : Dirs) {
422 #ifndef NDEBUG
423     if (!llvm::sys::path::is_absolute(Dir))
424       elog("Trying to cache CDB for relative {0}");
425 #endif
426     FoldedDirs.push_back(maybeCaseFoldPath(Dir));
427   }
428 
429   std::vector<DirectoryCache *> Ret;
430   Ret.reserve(Dirs.size());
431 
432   std::lock_guard<std::mutex> Lock(DirCachesMutex);
433   for (unsigned I = 0; I < Dirs.size(); ++I)
434     Ret.push_back(&DirCaches.try_emplace(FoldedDirs[I], Dirs[I]).first->second);
435   return Ret;
436 }
437 
438 llvm::Optional<DirectoryBasedGlobalCompilationDatabase::CDBLookupResult>
439 DirectoryBasedGlobalCompilationDatabase::lookupCDB(
440     CDBLookupRequest Request) const {
441   assert(llvm::sys::path::is_absolute(Request.FileName) &&
442          "path must be absolute");
443 
444   bool ShouldBroadcast = false;
445   DirectoryCache *DirCache = nullptr;
446   std::shared_ptr<const tooling::CompilationDatabase> CDB = nullptr;
447   if (OnlyDirCache) {
448     DirCache = OnlyDirCache.get();
449     ShouldBroadcast = Request.ShouldBroadcast;
450     CDB = DirCache->get(Opts.TFS, ShouldBroadcast, Request.FreshTime,
451                         Request.FreshTimeMissing);
452   } else {
453     // Traverse the canonical version to prevent false positives. i.e.:
454     // src/build/../a.cc can detect a CDB in /src/build if not canonicalized.
455     std::string CanonicalPath = removeDots(Request.FileName);
456     std::vector<llvm::StringRef> SearchDirs;
457     actOnAllParentDirectories(CanonicalPath, [&](PathRef Path) {
458       SearchDirs.push_back(Path);
459       return false;
460     });
461     for (DirectoryCache *Candidate : getDirectoryCaches(SearchDirs)) {
462       bool CandidateShouldBroadcast = Request.ShouldBroadcast;
463       if ((CDB = Candidate->get(Opts.TFS, CandidateShouldBroadcast,
464                                 Request.FreshTime, Request.FreshTimeMissing))) {
465         DirCache = Candidate;
466         ShouldBroadcast = CandidateShouldBroadcast;
467         break;
468       }
469     }
470   }
471 
472   if (!CDB)
473     return llvm::None;
474 
475   CDBLookupResult Result;
476   Result.CDB = std::move(CDB);
477   Result.PI.SourceRoot = DirCache->Path;
478 
479   if (ShouldBroadcast)
480     broadcastCDB(Result);
481   return Result;
482 }
483 
484 // The broadcast thread announces files with new compile commands to the world.
485 // Primarily this is used to enqueue them for background indexing.
486 //
487 // It's on a separate thread because:
488 //  - otherwise it would block the first parse of the initial file
489 //  - we need to enumerate all files in the CDB, of which there are many
490 //  - we (will) have to evaluate config for every file in the CDB, which is slow
491 class DirectoryBasedGlobalCompilationDatabase::BroadcastThread {
492   class Filter;
493   DirectoryBasedGlobalCompilationDatabase &Parent;
494 
495   std::mutex Mu;
496   std::condition_variable CV;
497   // Shutdown flag (CV is notified after writing).
498   // This is atomic so that broadcasts can also observe it and abort early.
499   std::atomic<bool> ShouldStop = {false};
500   struct Task {
501     CDBLookupResult Lookup;
502     Context Ctx;
503   };
504   std::deque<Task> Queue;
505   llvm::Optional<Task> ActiveTask;
506   std::thread Thread; // Must be last member.
507 
508   // Thread body: this is just the basic queue procesing boilerplate.
509   void run() {
510     std::unique_lock<std::mutex> Lock(Mu);
511     while (true) {
512       bool Stopping = false;
513       CV.wait(Lock, [&] {
514         return (Stopping = ShouldStop.load(std::memory_order_acquire)) ||
515                !Queue.empty();
516       });
517       if (Stopping) {
518         Queue.clear();
519         CV.notify_all();
520         return;
521       }
522       ActiveTask = std::move(Queue.front());
523       Queue.pop_front();
524 
525       Lock.unlock();
526       {
527         WithContext WithCtx(std::move(ActiveTask->Ctx));
528         process(ActiveTask->Lookup);
529       }
530       Lock.lock();
531       ActiveTask.reset();
532       CV.notify_all();
533     }
534   }
535 
536   // Inspects a new CDB and broadcasts the files it owns.
537   void process(const CDBLookupResult &T);
538 
539 public:
540   BroadcastThread(DirectoryBasedGlobalCompilationDatabase &Parent)
541       : Parent(Parent), Thread([this] { run(); }) {}
542 
543   void enqueue(CDBLookupResult Lookup) {
544     {
545       assert(!Lookup.PI.SourceRoot.empty());
546       std::lock_guard<std::mutex> Lock(Mu);
547       // New CDB takes precedence over any queued one for the same directory.
548       llvm::erase_if(Queue, [&](const Task &T) {
549         return T.Lookup.PI.SourceRoot == Lookup.PI.SourceRoot;
550       });
551       Queue.push_back({std::move(Lookup), Context::current().clone()});
552     }
553     CV.notify_all();
554   }
555 
556   bool blockUntilIdle(Deadline Timeout) {
557     std::unique_lock<std::mutex> Lock(Mu);
558     return wait(Lock, CV, Timeout,
559                 [&] { return Queue.empty() && !ActiveTask.hasValue(); });
560   }
561 
562   ~BroadcastThread() {
563     ShouldStop.store(true, std::memory_order_release);
564     CV.notify_all();
565     Thread.join();
566   }
567 };
568 
569 void DirectoryBasedGlobalCompilationDatabase::BroadcastThread::process(
570     const CDBLookupResult &T) {
571   vlog("Broadcasting compilation database from {0}", T.PI.SourceRoot);
572 
573   std::vector<std::string> AllFiles = T.CDB->getAllFiles();
574   // We assume CDB in CompileCommandsDir owns all of its entries, since we don't
575   // perform any search in parent paths whenever it is set.
576   if (Parent.OnlyDirCache) {
577     assert(Parent.OnlyDirCache->Path == T.PI.SourceRoot &&
578            "Trying to broadcast a CDB outside of CompileCommandsDir!");
579     Parent.OnCommandChanged.broadcast(std::move(AllFiles));
580     return;
581   }
582 
583   // Uniquify all parent directories of all files.
584   llvm::StringMap<bool> DirectoryHasCDB;
585   std::vector<llvm::StringRef> FileAncestors;
586   for (llvm::StringRef File : AllFiles) {
587     actOnAllParentDirectories(File, [&](PathRef Path) {
588       auto It = DirectoryHasCDB.try_emplace(Path);
589       // Already seen this path, and all of its parents.
590       if (!It.second)
591         return true;
592 
593       FileAncestors.push_back(It.first->getKey());
594       return pathEqual(Path, T.PI.SourceRoot);
595     });
596   }
597   // Work out which ones have CDBs in them.
598   // Given that we know that CDBs have been moved/generated, don't trust caches.
599   // (This should be rare, so it's OK to add a little latency).
600   constexpr auto IgnoreCache = std::chrono::steady_clock::time_point::max();
601   auto DirectoryCaches = Parent.getDirectoryCaches(FileAncestors);
602   assert(DirectoryCaches.size() == FileAncestors.size());
603   for (unsigned I = 0; I < DirectoryCaches.size(); ++I) {
604     bool ShouldBroadcast = false;
605     if (ShouldStop.load(std::memory_order_acquire)) {
606       log("Giving up on broadcasting CDB, as we're shutting down");
607       return;
608     }
609     if (DirectoryCaches[I]->get(Parent.Opts.TFS, ShouldBroadcast,
610                                 /*FreshTime=*/IgnoreCache,
611                                 /*FreshTimeMissing=*/IgnoreCache))
612       DirectoryHasCDB.find(FileAncestors[I])->setValue(true);
613   }
614 
615   std::vector<std::string> GovernedFiles;
616   for (llvm::StringRef File : AllFiles) {
617     // A file is governed by this CDB if lookup for the file would find it.
618     // Independent of whether it has an entry for that file or not.
619     actOnAllParentDirectories(File, [&](PathRef Path) {
620       if (DirectoryHasCDB.lookup(Path)) {
621         if (pathEqual(Path, T.PI.SourceRoot))
622           // Make sure listeners always get a canonical path for the file.
623           GovernedFiles.push_back(removeDots(File));
624         // Stop as soon as we hit a CDB.
625         return true;
626       }
627       return false;
628     });
629   }
630 
631   Parent.OnCommandChanged.broadcast(std::move(GovernedFiles));
632 }
633 
634 void DirectoryBasedGlobalCompilationDatabase::broadcastCDB(
635     CDBLookupResult Result) const {
636   assert(Result.CDB && "Trying to broadcast an invalid CDB!");
637   Broadcaster->enqueue(Result);
638 }
639 
640 bool DirectoryBasedGlobalCompilationDatabase::blockUntilIdle(
641     Deadline Timeout) const {
642   return Broadcaster->blockUntilIdle(Timeout);
643 }
644 
645 llvm::Optional<ProjectInfo>
646 DirectoryBasedGlobalCompilationDatabase::getProjectInfo(PathRef File) const {
647   CDBLookupRequest Req;
648   Req.FileName = File;
649   Req.ShouldBroadcast = false;
650   Req.FreshTime = Req.FreshTimeMissing =
651       std::chrono::steady_clock::time_point::min();
652   auto Res = lookupCDB(Req);
653   if (!Res)
654     return llvm::None;
655   return Res->PI;
656 }
657 
658 OverlayCDB::OverlayCDB(const GlobalCompilationDatabase *Base,
659                        std::vector<std::string> FallbackFlags,
660                        tooling::ArgumentsAdjuster Adjuster)
661     : DelegatingCDB(Base), ArgsAdjuster(std::move(Adjuster)),
662       FallbackFlags(std::move(FallbackFlags)) {}
663 
664 llvm::Optional<tooling::CompileCommand>
665 OverlayCDB::getCompileCommand(PathRef File) const {
666   llvm::Optional<tooling::CompileCommand> Cmd;
667   {
668     std::lock_guard<std::mutex> Lock(Mutex);
669     auto It = Commands.find(removeDots(File));
670     if (It != Commands.end())
671       Cmd = It->second;
672   }
673   if (!Cmd)
674     Cmd = DelegatingCDB::getCompileCommand(File);
675   if (!Cmd)
676     return llvm::None;
677   if (ArgsAdjuster)
678     Cmd->CommandLine = ArgsAdjuster(Cmd->CommandLine, Cmd->Filename);
679   return Cmd;
680 }
681 
682 tooling::CompileCommand OverlayCDB::getFallbackCommand(PathRef File) const {
683   auto Cmd = DelegatingCDB::getFallbackCommand(File);
684   std::lock_guard<std::mutex> Lock(Mutex);
685   Cmd.CommandLine.insert(Cmd.CommandLine.end(), FallbackFlags.begin(),
686                          FallbackFlags.end());
687   if (ArgsAdjuster)
688     Cmd.CommandLine = ArgsAdjuster(Cmd.CommandLine, Cmd.Filename);
689   return Cmd;
690 }
691 
692 void OverlayCDB::setCompileCommand(
693     PathRef File, llvm::Optional<tooling::CompileCommand> Cmd) {
694   // We store a canonical version internally to prevent mismatches between set
695   // and get compile commands. Also it assures clients listening to broadcasts
696   // doesn't receive different names for the same file.
697   std::string CanonPath = removeDots(File);
698   {
699     std::unique_lock<std::mutex> Lock(Mutex);
700     if (Cmd)
701       Commands[CanonPath] = std::move(*Cmd);
702     else
703       Commands.erase(CanonPath);
704   }
705   OnCommandChanged.broadcast({CanonPath});
706 }
707 
708 DelegatingCDB::DelegatingCDB(const GlobalCompilationDatabase *Base)
709     : Base(Base) {
710   if (Base)
711     BaseChanged = Base->watch([this](const std::vector<std::string> Changes) {
712       OnCommandChanged.broadcast(Changes);
713     });
714 }
715 
716 DelegatingCDB::DelegatingCDB(std::unique_ptr<GlobalCompilationDatabase> Base)
717     : DelegatingCDB(Base.get()) {
718   BaseOwner = std::move(Base);
719 }
720 
721 llvm::Optional<tooling::CompileCommand>
722 DelegatingCDB::getCompileCommand(PathRef File) const {
723   if (!Base)
724     return llvm::None;
725   return Base->getCompileCommand(File);
726 }
727 
728 llvm::Optional<ProjectInfo> DelegatingCDB::getProjectInfo(PathRef File) const {
729   if (!Base)
730     return llvm::None;
731   return Base->getProjectInfo(File);
732 }
733 
734 tooling::CompileCommand DelegatingCDB::getFallbackCommand(PathRef File) const {
735   if (!Base)
736     return GlobalCompilationDatabase::getFallbackCommand(File);
737   return Base->getFallbackCommand(File);
738 }
739 
740 bool DelegatingCDB::blockUntilIdle(Deadline D) const {
741   if (!Base)
742     return true;
743   return Base->blockUntilIdle(D);
744 }
745 
746 } // namespace clangd
747 } // namespace clang
748