annotate clang-tools-extra/clangd/QueryDriverDatabase.cpp @ 180:680fa57a2f20

fix compile errors.
author Shinji KONO <kono@ie.u-ryukyu.ac.jp>
date Sat, 30 May 2020 17:44:06 +0900
parents 0572611fdcc8
children 2e18cbf3894f
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
150
anatofuz
parents:
diff changeset
1 //===--- QueryDriverDatabase.cpp ---------------------------------*- C++-*-===//
anatofuz
parents:
diff changeset
2 //
anatofuz
parents:
diff changeset
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
anatofuz
parents:
diff changeset
4 // See https://llvm.org/LICENSE.txt for license information.
anatofuz
parents:
diff changeset
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
anatofuz
parents:
diff changeset
6 //
anatofuz
parents:
diff changeset
7 //===----------------------------------------------------------------------===//
anatofuz
parents:
diff changeset
8 // Some compiler drivers have implicit search mechanism for system headers.
anatofuz
parents:
diff changeset
9 // This compilation database implementation tries to extract that information by
anatofuz
parents:
diff changeset
10 // executing the driver in verbose mode. gcc-compatible drivers print something
anatofuz
parents:
diff changeset
11 // like:
anatofuz
parents:
diff changeset
12 // ....
anatofuz
parents:
diff changeset
13 // ....
anatofuz
parents:
diff changeset
14 // #include <...> search starts here:
anatofuz
parents:
diff changeset
15 // /usr/lib/gcc/x86_64-linux-gnu/7/include
anatofuz
parents:
diff changeset
16 // /usr/local/include
anatofuz
parents:
diff changeset
17 // /usr/lib/gcc/x86_64-linux-gnu/7/include-fixed
anatofuz
parents:
diff changeset
18 // /usr/include/x86_64-linux-gnu
anatofuz
parents:
diff changeset
19 // /usr/include
anatofuz
parents:
diff changeset
20 // End of search list.
anatofuz
parents:
diff changeset
21 // ....
anatofuz
parents:
diff changeset
22 // ....
anatofuz
parents:
diff changeset
23 // This component parses that output and adds each path to command line args
anatofuz
parents:
diff changeset
24 // provided by Base, after prepending them with -isystem. Therefore current
anatofuz
parents:
diff changeset
25 // implementation would not work with a driver that is not gcc-compatible.
anatofuz
parents:
diff changeset
26 //
anatofuz
parents:
diff changeset
27 // First argument of the command line received from underlying compilation
anatofuz
parents:
diff changeset
28 // database is used as compiler driver path. Due to this arbitrary binary
anatofuz
parents:
diff changeset
29 // execution, this mechanism is not used by default and only executes binaries
anatofuz
parents:
diff changeset
30 // in the paths that are explicitly whitelisted by the user.
anatofuz
parents:
diff changeset
31
anatofuz
parents:
diff changeset
32 #include "GlobalCompilationDatabase.h"
173
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
33 #include "support/Logger.h"
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
34 #include "support/Path.h"
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
35 #include "support/Trace.h"
150
anatofuz
parents:
diff changeset
36 #include "clang/Driver/Types.h"
anatofuz
parents:
diff changeset
37 #include "clang/Tooling/CompilationDatabase.h"
anatofuz
parents:
diff changeset
38 #include "llvm/ADT/DenseMap.h"
anatofuz
parents:
diff changeset
39 #include "llvm/ADT/ScopeExit.h"
anatofuz
parents:
diff changeset
40 #include "llvm/ADT/SmallString.h"
anatofuz
parents:
diff changeset
41 #include "llvm/ADT/StringExtras.h"
anatofuz
parents:
diff changeset
42 #include "llvm/ADT/StringRef.h"
anatofuz
parents:
diff changeset
43 #include "llvm/ADT/iterator_range.h"
anatofuz
parents:
diff changeset
44 #include "llvm/Support/FileSystem.h"
anatofuz
parents:
diff changeset
45 #include "llvm/Support/MemoryBuffer.h"
anatofuz
parents:
diff changeset
46 #include "llvm/Support/Path.h"
anatofuz
parents:
diff changeset
47 #include "llvm/Support/Program.h"
anatofuz
parents:
diff changeset
48 #include "llvm/Support/Regex.h"
anatofuz
parents:
diff changeset
49 #include "llvm/Support/ScopedPrinter.h"
anatofuz
parents:
diff changeset
50 #include <algorithm>
anatofuz
parents:
diff changeset
51 #include <map>
anatofuz
parents:
diff changeset
52 #include <string>
anatofuz
parents:
diff changeset
53 #include <vector>
anatofuz
parents:
diff changeset
54
anatofuz
parents:
diff changeset
55 namespace clang {
anatofuz
parents:
diff changeset
56 namespace clangd {
anatofuz
parents:
diff changeset
57 namespace {
anatofuz
parents:
diff changeset
58
anatofuz
parents:
diff changeset
59 std::vector<std::string> parseDriverOutput(llvm::StringRef Output) {
anatofuz
parents:
diff changeset
60 std::vector<std::string> SystemIncludes;
anatofuz
parents:
diff changeset
61 const char SIS[] = "#include <...> search starts here:";
anatofuz
parents:
diff changeset
62 const char SIE[] = "End of search list.";
anatofuz
parents:
diff changeset
63 llvm::SmallVector<llvm::StringRef, 8> Lines;
anatofuz
parents:
diff changeset
64 Output.split(Lines, '\n', /*MaxSplit=*/-1, /*KeepEmpty=*/false);
anatofuz
parents:
diff changeset
65
anatofuz
parents:
diff changeset
66 auto StartIt = llvm::find_if(
anatofuz
parents:
diff changeset
67 Lines, [SIS](llvm::StringRef Line) { return Line.trim() == SIS; });
anatofuz
parents:
diff changeset
68 if (StartIt == Lines.end()) {
anatofuz
parents:
diff changeset
69 elog("System include extraction: start marker not found: {0}", Output);
anatofuz
parents:
diff changeset
70 return {};
anatofuz
parents:
diff changeset
71 }
anatofuz
parents:
diff changeset
72 ++StartIt;
anatofuz
parents:
diff changeset
73 const auto EndIt =
anatofuz
parents:
diff changeset
74 llvm::find_if(llvm::make_range(StartIt, Lines.end()),
anatofuz
parents:
diff changeset
75 [SIE](llvm::StringRef Line) { return Line.trim() == SIE; });
anatofuz
parents:
diff changeset
76 if (EndIt == Lines.end()) {
anatofuz
parents:
diff changeset
77 elog("System include extraction: end marker missing: {0}", Output);
anatofuz
parents:
diff changeset
78 return {};
anatofuz
parents:
diff changeset
79 }
anatofuz
parents:
diff changeset
80
anatofuz
parents:
diff changeset
81 for (llvm::StringRef Line : llvm::make_range(StartIt, EndIt)) {
anatofuz
parents:
diff changeset
82 SystemIncludes.push_back(Line.trim().str());
anatofuz
parents:
diff changeset
83 vlog("System include extraction: adding {0}", Line);
anatofuz
parents:
diff changeset
84 }
anatofuz
parents:
diff changeset
85 return SystemIncludes;
anatofuz
parents:
diff changeset
86 }
anatofuz
parents:
diff changeset
87
anatofuz
parents:
diff changeset
88 std::vector<std::string>
anatofuz
parents:
diff changeset
89 extractSystemIncludes(PathRef Driver, llvm::StringRef Lang,
anatofuz
parents:
diff changeset
90 llvm::ArrayRef<std::string> CommandLine,
anatofuz
parents:
diff changeset
91 llvm::Regex &QueryDriverRegex) {
anatofuz
parents:
diff changeset
92 trace::Span Tracer("Extract system includes");
anatofuz
parents:
diff changeset
93 SPAN_ATTACH(Tracer, "driver", Driver);
anatofuz
parents:
diff changeset
94 SPAN_ATTACH(Tracer, "lang", Lang);
anatofuz
parents:
diff changeset
95
anatofuz
parents:
diff changeset
96 if (!QueryDriverRegex.match(Driver)) {
anatofuz
parents:
diff changeset
97 vlog("System include extraction: not whitelisted driver {0}", Driver);
anatofuz
parents:
diff changeset
98 return {};
anatofuz
parents:
diff changeset
99 }
anatofuz
parents:
diff changeset
100
anatofuz
parents:
diff changeset
101 if (!llvm::sys::fs::exists(Driver)) {
anatofuz
parents:
diff changeset
102 elog("System include extraction: {0} does not exist.", Driver);
anatofuz
parents:
diff changeset
103 return {};
anatofuz
parents:
diff changeset
104 }
anatofuz
parents:
diff changeset
105 if (!llvm::sys::fs::can_execute(Driver)) {
anatofuz
parents:
diff changeset
106 elog("System include extraction: {0} is not executable.", Driver);
anatofuz
parents:
diff changeset
107 return {};
anatofuz
parents:
diff changeset
108 }
anatofuz
parents:
diff changeset
109
anatofuz
parents:
diff changeset
110 llvm::SmallString<128> StdErrPath;
anatofuz
parents:
diff changeset
111 if (auto EC = llvm::sys::fs::createTemporaryFile("system-includes", "clangd",
anatofuz
parents:
diff changeset
112 StdErrPath)) {
anatofuz
parents:
diff changeset
113 elog("System include extraction: failed to create temporary file with "
anatofuz
parents:
diff changeset
114 "error {0}",
anatofuz
parents:
diff changeset
115 EC.message());
anatofuz
parents:
diff changeset
116 return {};
anatofuz
parents:
diff changeset
117 }
anatofuz
parents:
diff changeset
118 auto CleanUp = llvm::make_scope_exit(
anatofuz
parents:
diff changeset
119 [&StdErrPath]() { llvm::sys::fs::remove(StdErrPath); });
anatofuz
parents:
diff changeset
120
anatofuz
parents:
diff changeset
121 llvm::Optional<llvm::StringRef> Redirects[] = {
anatofuz
parents:
diff changeset
122 {""}, {""}, llvm::StringRef(StdErrPath)};
anatofuz
parents:
diff changeset
123
anatofuz
parents:
diff changeset
124 llvm::SmallVector<llvm::StringRef, 12> Args = {Driver, "-E", "-x",
anatofuz
parents:
diff changeset
125 Lang, "-", "-v"};
anatofuz
parents:
diff changeset
126
anatofuz
parents:
diff changeset
127 // These flags will be preserved
anatofuz
parents:
diff changeset
128 const llvm::StringRef FlagsToPreserve[] = {
anatofuz
parents:
diff changeset
129 "-nostdinc", "--no-standard-includes", "-nostdinc++", "-nobuiltininc"};
anatofuz
parents:
diff changeset
130 // Preserves these flags and their values, either as separate args or with an
anatofuz
parents:
diff changeset
131 // equalsbetween them
anatofuz
parents:
diff changeset
132 const llvm::StringRef ArgsToPreserve[] = {"--sysroot", "-isysroot"};
anatofuz
parents:
diff changeset
133
anatofuz
parents:
diff changeset
134 for (size_t I = 0, E = CommandLine.size(); I < E; ++I) {
anatofuz
parents:
diff changeset
135 llvm::StringRef Arg = CommandLine[I];
anatofuz
parents:
diff changeset
136 if (llvm::any_of(FlagsToPreserve,
anatofuz
parents:
diff changeset
137 [&Arg](llvm::StringRef S) { return S == Arg; })) {
anatofuz
parents:
diff changeset
138 Args.push_back(Arg);
anatofuz
parents:
diff changeset
139 } else {
anatofuz
parents:
diff changeset
140 const auto *Found =
anatofuz
parents:
diff changeset
141 llvm::find_if(ArgsToPreserve, [&Arg](llvm::StringRef S) {
anatofuz
parents:
diff changeset
142 return Arg.startswith(S);
anatofuz
parents:
diff changeset
143 });
anatofuz
parents:
diff changeset
144 if (Found == std::end(ArgsToPreserve))
anatofuz
parents:
diff changeset
145 continue;
anatofuz
parents:
diff changeset
146 Arg.consume_front(*Found);
anatofuz
parents:
diff changeset
147 if (Arg.empty() && I + 1 < E) {
anatofuz
parents:
diff changeset
148 Args.push_back(CommandLine[I]);
anatofuz
parents:
diff changeset
149 Args.push_back(CommandLine[++I]);
anatofuz
parents:
diff changeset
150 } else if (Arg.startswith("=")) {
anatofuz
parents:
diff changeset
151 Args.push_back(CommandLine[I]);
anatofuz
parents:
diff changeset
152 }
anatofuz
parents:
diff changeset
153 }
anatofuz
parents:
diff changeset
154 }
anatofuz
parents:
diff changeset
155
anatofuz
parents:
diff changeset
156 if (int RC = llvm::sys::ExecuteAndWait(Driver, Args, /*Env=*/llvm::None,
anatofuz
parents:
diff changeset
157 Redirects)) {
anatofuz
parents:
diff changeset
158 elog("System include extraction: driver execution failed with return code: "
anatofuz
parents:
diff changeset
159 "{0}. Args: ['{1}']",
anatofuz
parents:
diff changeset
160 llvm::to_string(RC), llvm::join(Args, "', '"));
anatofuz
parents:
diff changeset
161 return {};
anatofuz
parents:
diff changeset
162 }
anatofuz
parents:
diff changeset
163
anatofuz
parents:
diff changeset
164 auto BufOrError = llvm::MemoryBuffer::getFile(StdErrPath);
anatofuz
parents:
diff changeset
165 if (!BufOrError) {
anatofuz
parents:
diff changeset
166 elog("System include extraction: failed to read {0} with error {1}",
anatofuz
parents:
diff changeset
167 StdErrPath, BufOrError.getError().message());
anatofuz
parents:
diff changeset
168 return {};
anatofuz
parents:
diff changeset
169 }
anatofuz
parents:
diff changeset
170
anatofuz
parents:
diff changeset
171 auto Includes = parseDriverOutput(BufOrError->get()->getBuffer());
173
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
172 log("System include extractor: successfully executed {0}, got includes: "
150
anatofuz
parents:
diff changeset
173 "\"{1}\"",
anatofuz
parents:
diff changeset
174 Driver, llvm::join(Includes, ", "));
anatofuz
parents:
diff changeset
175 return Includes;
anatofuz
parents:
diff changeset
176 }
anatofuz
parents:
diff changeset
177
anatofuz
parents:
diff changeset
178 tooling::CompileCommand &
anatofuz
parents:
diff changeset
179 addSystemIncludes(tooling::CompileCommand &Cmd,
anatofuz
parents:
diff changeset
180 llvm::ArrayRef<std::string> SystemIncludes) {
anatofuz
parents:
diff changeset
181 for (llvm::StringRef Include : SystemIncludes) {
anatofuz
parents:
diff changeset
182 // FIXME(kadircet): This doesn't work when we have "--driver-mode=cl"
anatofuz
parents:
diff changeset
183 Cmd.CommandLine.push_back("-isystem");
anatofuz
parents:
diff changeset
184 Cmd.CommandLine.push_back(Include.str());
anatofuz
parents:
diff changeset
185 }
anatofuz
parents:
diff changeset
186 return Cmd;
anatofuz
parents:
diff changeset
187 }
anatofuz
parents:
diff changeset
188
anatofuz
parents:
diff changeset
189 /// Converts a glob containing only ** or * into a regex.
anatofuz
parents:
diff changeset
190 std::string convertGlobToRegex(llvm::StringRef Glob) {
anatofuz
parents:
diff changeset
191 std::string RegText;
anatofuz
parents:
diff changeset
192 llvm::raw_string_ostream RegStream(RegText);
anatofuz
parents:
diff changeset
193 RegStream << '^';
anatofuz
parents:
diff changeset
194 for (size_t I = 0, E = Glob.size(); I < E; ++I) {
anatofuz
parents:
diff changeset
195 if (Glob[I] == '*') {
anatofuz
parents:
diff changeset
196 if (I + 1 < E && Glob[I + 1] == '*') {
anatofuz
parents:
diff changeset
197 // Double star, accept any sequence.
anatofuz
parents:
diff changeset
198 RegStream << ".*";
anatofuz
parents:
diff changeset
199 // Also skip the second star.
anatofuz
parents:
diff changeset
200 ++I;
anatofuz
parents:
diff changeset
201 } else {
anatofuz
parents:
diff changeset
202 // Single star, accept any sequence without a slash.
anatofuz
parents:
diff changeset
203 RegStream << "[^/]*";
anatofuz
parents:
diff changeset
204 }
anatofuz
parents:
diff changeset
205 } else {
anatofuz
parents:
diff changeset
206 RegStream << llvm::Regex::escape(Glob.substr(I, 1));
anatofuz
parents:
diff changeset
207 }
anatofuz
parents:
diff changeset
208 }
anatofuz
parents:
diff changeset
209 RegStream << '$';
anatofuz
parents:
diff changeset
210 RegStream.flush();
anatofuz
parents:
diff changeset
211 return RegText;
anatofuz
parents:
diff changeset
212 }
anatofuz
parents:
diff changeset
213
anatofuz
parents:
diff changeset
214 /// Converts a glob containing only ** or * into a regex.
anatofuz
parents:
diff changeset
215 llvm::Regex convertGlobsToRegex(llvm::ArrayRef<std::string> Globs) {
anatofuz
parents:
diff changeset
216 assert(!Globs.empty() && "Globs cannot be empty!");
anatofuz
parents:
diff changeset
217 std::vector<std::string> RegTexts;
anatofuz
parents:
diff changeset
218 RegTexts.reserve(Globs.size());
anatofuz
parents:
diff changeset
219 for (llvm::StringRef Glob : Globs)
anatofuz
parents:
diff changeset
220 RegTexts.push_back(convertGlobToRegex(Glob));
anatofuz
parents:
diff changeset
221
anatofuz
parents:
diff changeset
222 llvm::Regex Reg(llvm::join(RegTexts, "|"));
anatofuz
parents:
diff changeset
223 assert(Reg.isValid(RegTexts.front()) &&
anatofuz
parents:
diff changeset
224 "Created an invalid regex from globs");
anatofuz
parents:
diff changeset
225 return Reg;
anatofuz
parents:
diff changeset
226 }
anatofuz
parents:
diff changeset
227
anatofuz
parents:
diff changeset
228 /// Extracts system includes from a trusted driver by parsing the output of
anatofuz
parents:
diff changeset
229 /// include search path and appends them to the commands coming from underlying
anatofuz
parents:
diff changeset
230 /// compilation database.
anatofuz
parents:
diff changeset
231 class QueryDriverDatabase : public GlobalCompilationDatabase {
anatofuz
parents:
diff changeset
232 public:
anatofuz
parents:
diff changeset
233 QueryDriverDatabase(llvm::ArrayRef<std::string> QueryDriverGlobs,
anatofuz
parents:
diff changeset
234 std::unique_ptr<GlobalCompilationDatabase> Base)
anatofuz
parents:
diff changeset
235 : QueryDriverRegex(convertGlobsToRegex(QueryDriverGlobs)),
anatofuz
parents:
diff changeset
236 Base(std::move(Base)) {
anatofuz
parents:
diff changeset
237 assert(this->Base);
anatofuz
parents:
diff changeset
238 BaseChanged =
anatofuz
parents:
diff changeset
239 this->Base->watch([this](const std::vector<std::string> &Changes) {
anatofuz
parents:
diff changeset
240 OnCommandChanged.broadcast(Changes);
anatofuz
parents:
diff changeset
241 });
anatofuz
parents:
diff changeset
242 }
anatofuz
parents:
diff changeset
243
anatofuz
parents:
diff changeset
244 llvm::Optional<tooling::CompileCommand>
anatofuz
parents:
diff changeset
245 getCompileCommand(PathRef File) const override {
anatofuz
parents:
diff changeset
246 auto Cmd = Base->getCompileCommand(File);
anatofuz
parents:
diff changeset
247 if (!Cmd || Cmd->CommandLine.empty())
anatofuz
parents:
diff changeset
248 return Cmd;
anatofuz
parents:
diff changeset
249
anatofuz
parents:
diff changeset
250 llvm::StringRef Lang;
anatofuz
parents:
diff changeset
251 for (size_t I = 0, E = Cmd->CommandLine.size(); I < E; ++I) {
anatofuz
parents:
diff changeset
252 llvm::StringRef Arg = Cmd->CommandLine[I];
anatofuz
parents:
diff changeset
253 if (Arg == "-x" && I + 1 < E)
anatofuz
parents:
diff changeset
254 Lang = Cmd->CommandLine[I + 1];
anatofuz
parents:
diff changeset
255 else if (Arg.startswith("-x"))
anatofuz
parents:
diff changeset
256 Lang = Arg.drop_front(2).trim();
anatofuz
parents:
diff changeset
257 }
anatofuz
parents:
diff changeset
258 if (Lang.empty()) {
anatofuz
parents:
diff changeset
259 llvm::StringRef Ext = llvm::sys::path::extension(File).trim('.');
anatofuz
parents:
diff changeset
260 auto Type = driver::types::lookupTypeForExtension(Ext);
anatofuz
parents:
diff changeset
261 if (Type == driver::types::TY_INVALID) {
anatofuz
parents:
diff changeset
262 elog("System include extraction: invalid file type for {0}", Ext);
anatofuz
parents:
diff changeset
263 return {};
anatofuz
parents:
diff changeset
264 }
anatofuz
parents:
diff changeset
265 Lang = driver::types::getTypeName(Type);
anatofuz
parents:
diff changeset
266 }
anatofuz
parents:
diff changeset
267
anatofuz
parents:
diff changeset
268 llvm::SmallString<128> Driver(Cmd->CommandLine.front());
anatofuz
parents:
diff changeset
269 llvm::sys::fs::make_absolute(Cmd->Directory, Driver);
anatofuz
parents:
diff changeset
270 auto Key = std::make_pair(Driver.str().str(), Lang.str());
anatofuz
parents:
diff changeset
271
anatofuz
parents:
diff changeset
272 std::vector<std::string> SystemIncludes;
anatofuz
parents:
diff changeset
273 {
anatofuz
parents:
diff changeset
274 std::lock_guard<std::mutex> Lock(Mu);
anatofuz
parents:
diff changeset
275
anatofuz
parents:
diff changeset
276 auto It = DriverToIncludesCache.find(Key);
anatofuz
parents:
diff changeset
277 if (It != DriverToIncludesCache.end())
anatofuz
parents:
diff changeset
278 SystemIncludes = It->second;
anatofuz
parents:
diff changeset
279 else
anatofuz
parents:
diff changeset
280 DriverToIncludesCache[Key] = SystemIncludes = extractSystemIncludes(
anatofuz
parents:
diff changeset
281 Key.first, Key.second, Cmd->CommandLine, QueryDriverRegex);
anatofuz
parents:
diff changeset
282 }
anatofuz
parents:
diff changeset
283
anatofuz
parents:
diff changeset
284 return addSystemIncludes(*Cmd, SystemIncludes);
anatofuz
parents:
diff changeset
285 }
anatofuz
parents:
diff changeset
286
anatofuz
parents:
diff changeset
287 llvm::Optional<ProjectInfo> getProjectInfo(PathRef File) const override {
anatofuz
parents:
diff changeset
288 return Base->getProjectInfo(File);
anatofuz
parents:
diff changeset
289 }
anatofuz
parents:
diff changeset
290
anatofuz
parents:
diff changeset
291 private:
anatofuz
parents:
diff changeset
292 mutable std::mutex Mu;
anatofuz
parents:
diff changeset
293 // Caches includes extracted from a driver.
anatofuz
parents:
diff changeset
294 mutable std::map<std::pair<std::string, std::string>,
anatofuz
parents:
diff changeset
295 std::vector<std::string>>
anatofuz
parents:
diff changeset
296 DriverToIncludesCache;
anatofuz
parents:
diff changeset
297 mutable llvm::Regex QueryDriverRegex;
anatofuz
parents:
diff changeset
298
anatofuz
parents:
diff changeset
299 std::unique_ptr<GlobalCompilationDatabase> Base;
anatofuz
parents:
diff changeset
300 CommandChanged::Subscription BaseChanged;
anatofuz
parents:
diff changeset
301 };
anatofuz
parents:
diff changeset
302 } // namespace
anatofuz
parents:
diff changeset
303
anatofuz
parents:
diff changeset
304 std::unique_ptr<GlobalCompilationDatabase>
anatofuz
parents:
diff changeset
305 getQueryDriverDatabase(llvm::ArrayRef<std::string> QueryDriverGlobs,
anatofuz
parents:
diff changeset
306 std::unique_ptr<GlobalCompilationDatabase> Base) {
anatofuz
parents:
diff changeset
307 assert(Base && "Null base to SystemIncludeExtractor");
anatofuz
parents:
diff changeset
308 if (QueryDriverGlobs.empty())
anatofuz
parents:
diff changeset
309 return Base;
anatofuz
parents:
diff changeset
310 return std::make_unique<QueryDriverDatabase>(QueryDriverGlobs,
anatofuz
parents:
diff changeset
311 std::move(Base));
anatofuz
parents:
diff changeset
312 }
anatofuz
parents:
diff changeset
313
anatofuz
parents:
diff changeset
314 } // namespace clangd
anatofuz
parents:
diff changeset
315 } // namespace clang