clang-tools  15.0.0git
GlobalCompilationDatabase.h
Go to the documentation of this file.
1 //===--- GlobalCompilationDatabase.h -----------------------------*- 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 #ifndef LLVM_CLANG_TOOLS_EXTRA_CLANGD_GLOBALCOMPILATIONDATABASE_H
10 #define LLVM_CLANG_TOOLS_EXTRA_CLANGD_GLOBALCOMPILATIONDATABASE_H
11 
12 #include "support/Function.h"
13 #include "support/Path.h"
14 #include "support/Threading.h"
15 #include "support/ThreadsafeFS.h"
16 #include "clang/Tooling/ArgumentsAdjusters.h"
17 #include "clang/Tooling/CompilationDatabase.h"
18 #include "llvm/ADT/Optional.h"
19 #include "llvm/ADT/StringMap.h"
20 #include <memory>
21 #include <mutex>
22 #include <vector>
23 
24 namespace clang {
25 namespace clangd {
26 
27 struct ProjectInfo {
28  // The directory in which the compilation database was discovered.
29  // Empty if directory-based compilation database discovery was not used.
30  std::string SourceRoot;
31 };
32 
33 /// Provides compilation arguments used for parsing C and C++ files.
35 public:
36  virtual ~GlobalCompilationDatabase() = default;
37 
38  /// If there are any known-good commands for building this file, returns one.
39  virtual llvm::Optional<tooling::CompileCommand>
40  getCompileCommand(PathRef File) const = 0;
41 
42  /// Finds the closest project to \p File.
43  virtual llvm::Optional<ProjectInfo> getProjectInfo(PathRef File) const {
44  return llvm::None;
45  }
46 
47  /// Makes a guess at how to build a file.
48  /// The default implementation just runs clang on the file.
49  /// Clangd should treat the results as unreliable.
50  virtual tooling::CompileCommand getFallbackCommand(PathRef File) const;
51 
52  /// If the CDB does any asynchronous work, wait for it to complete.
53  /// For use in tests.
54  virtual bool blockUntilIdle(Deadline D) const { return true; }
55 
57  /// The callback is notified when files may have new compile commands.
58  /// The argument is a list of full file paths.
59  CommandChanged::Subscription watch(CommandChanged::Listener L) const {
60  return OnCommandChanged.observe(std::move(L));
61  }
62 
63 protected:
65 };
66 
67 // Helper class for implementing GlobalCompilationDatabases that wrap others.
69 public:
71  DelegatingCDB(std::unique_ptr<GlobalCompilationDatabase> Base);
72 
73  llvm::Optional<tooling::CompileCommand>
74  getCompileCommand(PathRef File) const override;
75 
76  llvm::Optional<ProjectInfo> getProjectInfo(PathRef File) const override;
77 
78  tooling::CompileCommand getFallbackCommand(PathRef File) const override;
79 
80  bool blockUntilIdle(Deadline D) const override;
81 
82 private:
83  const GlobalCompilationDatabase *Base;
84  std::unique_ptr<GlobalCompilationDatabase> BaseOwner;
85  CommandChanged::Subscription BaseChanged;
86 };
87 
88 /// Gets compile args from tooling::CompilationDatabases built for parent
89 /// directories.
91  : public GlobalCompilationDatabase {
92 public:
93  struct Options {
94  Options(const ThreadsafeFS &TFS) : TFS(TFS) {}
95 
96  const ThreadsafeFS &TFS;
97  // Frequency to check whether e.g. compile_commands.json has changed.
98  std::chrono::steady_clock::duration RevalidateAfter =
99  std::chrono::seconds(5);
100  // Frequency to check whether e.g. compile_commands.json has been created.
101  // (This is more expensive to check frequently, as we check many locations).
102  std::chrono::steady_clock::duration RevalidateMissingAfter =
103  std::chrono::seconds(30);
104  // Used to provide per-file configuration.
105  std::function<Context(llvm::StringRef)> ContextProvider;
106  // Only look for a compilation database in this one fixed directory.
107  // FIXME: fold this into config/context mechanism.
108  llvm::Optional<Path> CompileCommandsDir;
109  };
110 
113 
114  /// Scans File's parents looking for compilation databases.
115  /// Any extra flags will be added.
116  /// Might trigger OnCommandChanged, if CDB wasn't broadcasted yet.
117  llvm::Optional<tooling::CompileCommand>
118  getCompileCommand(PathRef File) const override;
119 
120  /// Returns the path to first directory containing a compilation database in
121  /// \p File's parents.
122  llvm::Optional<ProjectInfo> getProjectInfo(PathRef File) const override;
123 
124  bool blockUntilIdle(Deadline Timeout) const override;
125 
126 private:
127  Options Opts;
128 
129  class DirectoryCache;
130  // Keyed by possibly-case-folded directory path.
131  // We can hand out pointers as they're stable and entries are never removed.
132  mutable llvm::StringMap<DirectoryCache> DirCaches;
133  mutable std::mutex DirCachesMutex;
134 
135  std::vector<DirectoryCache *>
136  getDirectoryCaches(llvm::ArrayRef<llvm::StringRef> Dirs) const;
137 
138  struct CDBLookupRequest {
140  // Whether this lookup should trigger discovery of the CDB found.
141  bool ShouldBroadcast = false;
142  // Cached results newer than this are considered fresh and not checked
143  // against disk.
144  std::chrono::steady_clock::time_point FreshTime;
145  std::chrono::steady_clock::time_point FreshTimeMissing;
146  };
147  struct CDBLookupResult {
148  std::shared_ptr<const tooling::CompilationDatabase> CDB;
149  ProjectInfo PI;
150  };
151  llvm::Optional<CDBLookupResult> lookupCDB(CDBLookupRequest Request) const;
152 
153  class BroadcastThread;
154  std::unique_ptr<BroadcastThread> Broadcaster;
155 
156  // Performs broadcast on governed files.
157  void broadcastCDB(CDBLookupResult Res) const;
158 
159  // cache test calls lookupCDB directly to ensure valid/invalid times.
161 };
162 
163 /// Extracts system include search path from drivers matching QueryDriverGlobs
164 /// and adds them to the compile flags. Base may not be nullptr.
165 /// Returns Base when \p QueryDriverGlobs is empty.
166 std::unique_ptr<GlobalCompilationDatabase>
167 getQueryDriverDatabase(llvm::ArrayRef<std::string> QueryDriverGlobs,
168  std::unique_ptr<GlobalCompilationDatabase> Base);
169 
170 /// Wraps another compilation database, and supports overriding the commands
171 /// using an in-memory mapping.
172 class OverlayCDB : public DelegatingCDB {
173 public:
174  // Base may be null, in which case no entries are inherited.
175  // FallbackFlags are added to the fallback compile command.
176  // Adjuster is applied to all commands, fallback or not.
178  std::vector<std::string> FallbackFlags = {},
179  tooling::ArgumentsAdjuster Adjuster = nullptr);
180 
181  llvm::Optional<tooling::CompileCommand>
182  getCompileCommand(PathRef File) const override;
183  tooling::CompileCommand getFallbackCommand(PathRef File) const override;
184 
185  /// Sets or clears the compilation command for a particular file.
186  void
188  llvm::Optional<tooling::CompileCommand> CompilationCommand);
189 
190 private:
191  mutable std::mutex Mutex;
192  llvm::StringMap<tooling::CompileCommand> Commands; /* GUARDED_BY(Mut) */
193  tooling::ArgumentsAdjuster ArgsAdjuster;
194  std::vector<std::string> FallbackFlags;
195 };
196 
197 } // namespace clangd
198 } // namespace clang
199 
200 #endif // LLVM_CLANG_TOOLS_EXTRA_CLANGD_GLOBALCOMPILATIONDATABASE_H
clang::clangd::ProjectInfo::SourceRoot
std::string SourceRoot
Definition: GlobalCompilationDatabase.h:30
clang::clangd::DirectoryBasedGlobalCompilationDatabase::~DirectoryBasedGlobalCompilationDatabase
~DirectoryBasedGlobalCompilationDatabase() override
Base
std::unique_ptr< GlobalCompilationDatabase > Base
Definition: GlobalCompilationDatabaseTests.cpp:85
clang::clangd::OverlayCDB::OverlayCDB
OverlayCDB(const GlobalCompilationDatabase *Base, std::vector< std::string > FallbackFlags={}, tooling::ArgumentsAdjuster Adjuster=nullptr)
Definition: GlobalCompilationDatabase.cpp:742
Path.h
clang::clangd::DirectoryBasedGlobalCompilationDatabase::getCompileCommand
llvm::Optional< tooling::CompileCommand > getCompileCommand(PathRef File) const override
Scans File's parents looking for compilation databases.
Definition: GlobalCompilationDatabase.cpp:358
clang::clangd::DirectoryBasedGlobalCompilationDatabaseCacheTest
Definition: GlobalCompilationDatabaseTests.cpp:429
clang::clangd::OverlayCDB::getCompileCommand
llvm::Optional< tooling::CompileCommand > getCompileCommand(PathRef File) const override
If there are any known-good commands for building this file, returns one.
Definition: GlobalCompilationDatabase.cpp:749
clang::clangd::DirectoryBasedGlobalCompilationDatabase::getProjectInfo
llvm::Optional< ProjectInfo > getProjectInfo(PathRef File) const override
Returns the path to first directory containing a compilation database in File's parents.
Definition: GlobalCompilationDatabase.cpp:730
clang::clangd::GlobalCompilationDatabase::getCompileCommand
virtual llvm::Optional< tooling::CompileCommand > getCompileCommand(PathRef File) const =0
If there are any known-good commands for building this file, returns one.
clang::clangd::GlobalCompilationDatabase
Provides compilation arguments used for parsing C and C++ files.
Definition: GlobalCompilationDatabase.h:34
clang::clangd::ProjectInfo
Definition: GlobalCompilationDatabase.h:27
clang::clangd::Event::observe
Subscription observe(Listener L)
Definition: Function.h:75
clang::clangd::DelegatingCDB::blockUntilIdle
bool blockUntilIdle(Deadline D) const override
If the CDB does any asynchronous work, wait for it to complete.
Definition: GlobalCompilationDatabase.cpp:824
clang::clangd::DelegatingCDB::getFallbackCommand
tooling::CompileCommand getFallbackCommand(PathRef File) const override
Makes a guess at how to build a file.
Definition: GlobalCompilationDatabase.cpp:818
clang::clangd::Deadline
A point in time we can wait for.
Definition: Threading.h:45
ThreadsafeFS.h
clang::clangd::DelegatingCDB::getCompileCommand
llvm::Optional< tooling::CompileCommand > getCompileCommand(PathRef File) const override
If there are any known-good commands for building this file, returns one.
Definition: GlobalCompilationDatabase.cpp:806
clang::clangd::DirectoryBasedGlobalCompilationDatabase::blockUntilIdle
bool blockUntilIdle(Deadline Timeout) const override
If the CDB does any asynchronous work, wait for it to complete.
Definition: GlobalCompilationDatabase.cpp:724
ns1::ns2::D
@ D
Definition: CategoricalFeature.h:3
Threading.h
FileName
StringRef FileName
Definition: KernelNameRestrictionCheck.cpp:46
clang::clangd::GlobalCompilationDatabase::blockUntilIdle
virtual bool blockUntilIdle(Deadline D) const
If the CDB does any asynchronous work, wait for it to complete.
Definition: GlobalCompilationDatabase.h:54
clang::clangd::OverlayCDB::getFallbackCommand
tooling::CompileCommand getFallbackCommand(PathRef File) const override
Makes a guess at how to build a file.
Definition: GlobalCompilationDatabase.cpp:766
clang::clangd::GlobalCompilationDatabase::getFallbackCommand
virtual tooling::CompileCommand getFallbackCommand(PathRef File) const
Makes a guess at how to build a file.
Definition: GlobalCompilationDatabase.cpp:54
clang::clangd::DirectoryBasedGlobalCompilationDatabase::Options::Options
Options(const ThreadsafeFS &TFS)
Definition: GlobalCompilationDatabase.h:94
clang::clangd::GlobalCompilationDatabase::~GlobalCompilationDatabase
virtual ~GlobalCompilationDatabase()=default
clang::clangd::Event< std::vector< std::string > >::Listener
std::function< void(const std::vector< std::string > &)> Listener
Definition: Function.h:34
clang::clangd::getQueryDriverDatabase
std::unique_ptr< GlobalCompilationDatabase > getQueryDriverDatabase(llvm::ArrayRef< std::string > QueryDriverGlobs, std::unique_ptr< GlobalCompilationDatabase > Base)
Extracts system include search path from drivers matching QueryDriverGlobs and adds them to the compi...
Definition: QueryDriverDatabase.cpp:365
clang::clangd::DirectoryBasedGlobalCompilationDatabase::Options::RevalidateAfter
std::chrono::steady_clock::duration RevalidateAfter
Definition: GlobalCompilationDatabase.h:98
clang::clangd::DirectoryBasedGlobalCompilationDatabase::Options
Definition: GlobalCompilationDatabase.h:93
clang::clangd::OverlayCDB::setCompileCommand
void setCompileCommand(PathRef File, llvm::Optional< tooling::CompileCommand > CompilationCommand)
Sets or clears the compilation command for a particular file.
Definition: GlobalCompilationDatabase.cpp:776
clang::clangd::DelegatingCDB::getProjectInfo
llvm::Optional< ProjectInfo > getProjectInfo(PathRef File) const override
Finds the closest project to File.
Definition: GlobalCompilationDatabase.cpp:812
clang::clangd::PathRef
llvm::StringRef PathRef
A typedef to represent a ref to file path.
Definition: Path.h:29
clang::clangd::ThreadsafeFS
Wrapper for vfs::FileSystem for use in multithreaded programs like clangd.
Definition: ThreadsafeFS.h:27
clang::clangd::DirectoryBasedGlobalCompilationDatabase::DirectoryCache
Definition: GlobalCompilationDatabase.cpp:81
clang::clangd::DirectoryBasedGlobalCompilationDatabase::Options::RevalidateMissingAfter
std::chrono::steady_clock::duration RevalidateMissingAfter
Definition: GlobalCompilationDatabase.h:102
clang::clangd::DelegatingCDB::DelegatingCDB
DelegatingCDB(const GlobalCompilationDatabase *Base)
Definition: GlobalCompilationDatabase.cpp:792
clang
===– Representation.cpp - ClangDoc Representation --------—*- C++ -*-===//
Definition: ApplyReplacements.h:27
Function.h
clang::clangd::GlobalCompilationDatabase::getProjectInfo
virtual llvm::Optional< ProjectInfo > getProjectInfo(PathRef File) const
Finds the closest project to File.
Definition: GlobalCompilationDatabase.h:43
clang::clangd::DirectoryBasedGlobalCompilationDatabase
Gets compile args from tooling::CompilationDatabases built for parent directories.
Definition: GlobalCompilationDatabase.h:90
clang::clangd::DirectoryBasedGlobalCompilationDatabase::Options::CompileCommandsDir
llvm::Optional< Path > CompileCommandsDir
Definition: GlobalCompilationDatabase.h:108
clang::clangd::DirectoryBasedGlobalCompilationDatabase::Options::TFS
const ThreadsafeFS & TFS
Definition: GlobalCompilationDatabase.h:96
clang::clangd::DirectoryBasedGlobalCompilationDatabase::Options::ContextProvider
std::function< Context(llvm::StringRef)> ContextProvider
Definition: GlobalCompilationDatabase.h:105
clang::clangd::DirectoryBasedGlobalCompilationDatabase::DirectoryBasedGlobalCompilationDatabase
DirectoryBasedGlobalCompilationDatabase(const Options &Opts)
Definition: GlobalCompilationDatabase.cpp:346
clang::clangd::GlobalCompilationDatabase::watch
CommandChanged::Subscription watch(CommandChanged::Listener L) const
The callback is notified when files may have new compile commands.
Definition: GlobalCompilationDatabase.h:59
clang::clangd::DelegatingCDB
Definition: GlobalCompilationDatabase.h:68
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::GlobalCompilationDatabase::OnCommandChanged
CommandChanged OnCommandChanged
Definition: GlobalCompilationDatabase.h:64
clang::clangd::Event< std::vector< std::string > >
clang::clangd::OverlayCDB
Wraps another compilation database, and supports overriding the commands using an in-memory mapping.
Definition: GlobalCompilationDatabase.h:172