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