14
14
#include " clang/Driver/Options.h"
15
15
#include " clang/Frontend/CompilerInvocation.h"
16
16
#include " clang/Tooling/CompilationDatabase.h"
17
+ #include " clang/Tooling/Tooling.h"
17
18
#include " llvm/ADT/ArrayRef.h"
18
19
#include " llvm/ADT/STLExtras.h"
19
20
#include " llvm/ADT/SmallVector.h"
27
28
#include " llvm/Support/MemoryBuffer.h"
28
29
#include " llvm/Support/Path.h"
29
30
#include " llvm/Support/Program.h"
31
+ #include " llvm/TargetParser/Host.h"
30
32
#include < iterator>
31
33
#include < optional>
32
34
#include < string>
@@ -185,6 +187,12 @@ static std::string resolveDriver(llvm::StringRef Driver, bool FollowSymlink,
185
187
186
188
} // namespace
187
189
190
+ CommandMangler::CommandMangler () {
191
+ Tokenizer = llvm::Triple (llvm::sys::getProcessTriple ()).isOSWindows ()
192
+ ? llvm::cl::TokenizeWindowsCommandLine
193
+ : llvm::cl::TokenizeGNUCommandLine;
194
+ }
195
+
188
196
CommandMangler CommandMangler::detect () {
189
197
CommandMangler Result;
190
198
Result.ClangPath = detectClangPath ();
@@ -201,9 +209,18 @@ void CommandMangler::operator()(tooling::CompileCommand &Command,
201
209
trace::Span S (" AdjustCompileFlags" );
202
210
// Most of the modifications below assumes the Cmd starts with a driver name.
203
211
// We might consider injecting a generic driver name like "cc" or "c++", but
204
- // a Cmd missing the driver is probably rare enough in practice and errnous .
212
+ // a Cmd missing the driver is probably rare enough in practice and erroneous .
205
213
if (Cmd.empty ())
206
214
return ;
215
+
216
+ // FS used for expanding response files.
217
+ // FIXME: ExpandResponseFiles appears not to provide the usual
218
+ // thread-safety guarantees, as the access to FS is not locked!
219
+ // For now, use the real FS, which is known to be threadsafe (if we don't
220
+ // use/change working directory, which ExpandResponseFiles doesn't).
221
+ auto FS = llvm::vfs::getRealFileSystem ();
222
+ tooling::addExpandedResponseFiles (Cmd, Command.Directory , Tokenizer, *FS);
223
+
207
224
auto &OptTable = clang::driver::getDriverOptTable ();
208
225
// OriginalArgs needs to outlive ArgList.
209
226
llvm::SmallVector<const char *, 16 > OriginalArgs;
@@ -212,7 +229,7 @@ void CommandMangler::operator()(tooling::CompileCommand &Command,
212
229
OriginalArgs.push_back (S.c_str ());
213
230
bool IsCLMode = driver::IsClangCL (driver::getDriverMode (
214
231
OriginalArgs[0 ], llvm::ArrayRef (OriginalArgs).slice (1 )));
215
- // ParseArgs propagates missig arg/opt counts on error, but preserves
232
+ // ParseArgs propagates missing arg/opt counts on error, but preserves
216
233
// everything it could parse in ArgList. So we just ignore those counts.
217
234
unsigned IgnoredCount;
218
235
// Drop the executable name, as ParseArgs doesn't expect it. This means
@@ -307,12 +324,16 @@ void CommandMangler::operator()(tooling::CompileCommand &Command,
307
324
// necessary for the system include extractor to identify the file type
308
325
// - AFTER applying CompileFlags.Edits, because the name of the compiler
309
326
// that needs to be invoked may come from the CompileFlags->Compiler key
327
+ // - BEFORE addTargetAndModeForProgramName(), because gcc doesn't support
328
+ // the target flag that might be added.
310
329
// - BEFORE resolveDriver() because that can mess up the driver path,
311
330
// e.g. changing gcc to /path/to/clang/bin/gcc
312
331
if (SystemIncludeExtractor) {
313
332
SystemIncludeExtractor (Command, File);
314
333
}
315
334
335
+ tooling::addTargetAndModeForProgramName (Cmd, Cmd.front ());
336
+
316
337
// Check whether the flag exists, either as -flag or -flag=*
317
338
auto Has = [&](llvm::StringRef Flag) {
318
339
for (llvm::StringRef Arg : Cmd) {
0 commit comments