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