@@ -85,9 +85,10 @@ std::vector<std::string> parseDriverOutput(llvm::StringRef Output) {
8585 return SystemIncludes;
8686}
8787
88- std::vector<std::string> extractSystemIncludes (PathRef Driver,
89- llvm::StringRef Lang,
90- llvm::Regex &QueryDriverRegex) {
88+ std::vector<std::string>
89+ extractSystemIncludes (PathRef Driver, llvm::StringRef Lang,
90+ llvm::ArrayRef<std::string> CommandLine,
91+ llvm::Regex &QueryDriverRegex) {
9192 trace::Span Tracer (" Extract system includes" );
9293 SPAN_ATTACH (Tracer, " driver" , Driver);
9394 SPAN_ATTACH (Tracer, " lang" , Lang);
@@ -120,14 +121,43 @@ std::vector<std::string> extractSystemIncludes(PathRef Driver,
120121 llvm::Optional<llvm::StringRef> Redirects[] = {
121122 {" " }, {" " }, llvm::StringRef (StdErrPath)};
122123
123- // Should we also preserve flags like "-sysroot", "-nostdinc" ?
124- const llvm::StringRef Args[] = {Driver, " -E" , " -x" , Lang, " -" , " -v" };
124+ llvm::SmallVector<llvm::StringRef, 12 > Args = {Driver, " -E" , " -x" ,
125+ Lang, " -" , " -v" };
126+
127+ // These flags will be preserved
128+ const llvm::StringRef FlagsToPreserve[] = {
129+ " -nostdinc" , " --no-standard-includes" , " -nostdinc++" , " -nobuiltininc" };
130+ // Preserves these flags and their values, either as separate args or with an
131+ // equalsbetween them
132+ const llvm::StringRef ArgsToPreserve[] = {" --sysroot" , " -isysroot" };
133+
134+ for (size_t I = 0 , E = CommandLine.size (); I < E; ++I) {
135+ llvm::StringRef Arg = CommandLine[I];
136+ if (llvm::any_of (FlagsToPreserve,
137+ [&Arg](llvm::StringRef S) { return S == Arg; })) {
138+ Args.push_back (Arg);
139+ } else {
140+ const auto *Found =
141+ llvm::find_if (ArgsToPreserve, [&Arg](llvm::StringRef S) {
142+ return Arg.startswith (S);
143+ });
144+ if (Found == std::end (ArgsToPreserve))
145+ continue ;
146+ Arg.consume_front (*Found);
147+ if (Arg.empty () && I + 1 < E) {
148+ Args.push_back (CommandLine[I]);
149+ Args.push_back (CommandLine[++I]);
150+ } else if (Arg.startswith (" =" )) {
151+ Args.push_back (CommandLine[I]);
152+ }
153+ }
154+ }
125155
126156 if (int RC = llvm::sys::ExecuteAndWait (Driver, Args, /* Env=*/ llvm::None,
127157 Redirects)) {
128158 elog (" System include extraction: driver execution failed with return code: "
129- " {0}" ,
130- llvm::to_string (RC));
159+ " {0}. Args: ['{1}'] " ,
160+ llvm::to_string (RC), llvm::join (Args, " ', ' " ) );
131161 return {};
132162 }
133163
@@ -237,7 +267,7 @@ class QueryDriverDatabase : public GlobalCompilationDatabase {
237267
238268 llvm::SmallString<128 > Driver (Cmd->CommandLine .front ());
239269 llvm::sys::fs::make_absolute (Cmd->Directory , Driver);
240- auto Key = std::make_pair (Driver.str (), Lang);
270+ auto Key = std::make_pair (Driver.str (). str () , Lang. str () );
241271
242272 std::vector<std::string> SystemIncludes;
243273 {
@@ -247,8 +277,8 @@ class QueryDriverDatabase : public GlobalCompilationDatabase {
247277 if (It != DriverToIncludesCache.end ())
248278 SystemIncludes = It->second ;
249279 else
250- DriverToIncludesCache[Key] = SystemIncludes =
251- extractSystemIncludes ( Key.first , Key.second , QueryDriverRegex);
280+ DriverToIncludesCache[Key] = SystemIncludes = extractSystemIncludes (
281+ Key.first , Key.second , Cmd-> CommandLine , QueryDriverRegex);
252282 }
253283
254284 return addSystemIncludes (*Cmd, SystemIncludes);
@@ -278,7 +308,7 @@ getQueryDriverDatabase(llvm::ArrayRef<std::string> QueryDriverGlobs,
278308 if (QueryDriverGlobs.empty ())
279309 return Base;
280310 return std::make_unique<QueryDriverDatabase>(QueryDriverGlobs,
281- std::move (Base));
311+ std::move (Base));
282312}
283313
284314} // namespace clangd
0 commit comments