Index: include/clang/Tooling/CompilationDatabase.h =================================================================== --- include/clang/Tooling/CompilationDatabase.h +++ include/clang/Tooling/CompilationDatabase.h @@ -189,7 +189,8 @@ /// \brief Constructs a compilation data base from a specified directory /// and command line. - FixedCompilationDatabase(Twine Directory, ArrayRef CommandLine); + FixedCompilationDatabase(Twine Directory, StringRef ProgName, + ArrayRef CommandLine); /// \brief Returns the given compile command. /// Index: lib/Tooling/CommonOptionsParser.cpp =================================================================== --- lib/Tooling/CommonOptionsParser.cpp +++ lib/Tooling/CommonOptionsParser.cpp @@ -136,8 +136,8 @@ if (!Compilations) { llvm::errs() << "Error while trying to load a compilation database:\n" << ErrorMessage << "Running without flags.\n"; - Compilations.reset( - new FixedCompilationDatabase(".", std::vector())); + Compilations.reset(new FixedCompilationDatabase( + ".", "clang-tool", std::vector())); } } auto AdjustingCompilations = Index: lib/Tooling/CompilationDatabase.cpp =================================================================== --- lib/Tooling/CompilationDatabase.cpp +++ lib/Tooling/CompilationDatabase.cpp @@ -205,25 +205,27 @@ /// \li true if successful. /// \li false if \c Args cannot be used for compilation jobs (e.g. /// contains an option like -E or -version). -static bool stripPositionalArgs(std::vector Args, +static bool stripPositionalArgs(std::vector Args, std::string &ProgName, std::vector &Result) { + ProgName = "clang-tool"; + Result.clear(); + if (Args.empty()) + return true; + IntrusiveRefCntPtr DiagOpts = new DiagnosticOptions(); UnusedInputDiagConsumer DiagClient; DiagnosticsEngine Diagnostics( IntrusiveRefCntPtr(new DiagnosticIDs()), &*DiagOpts, &DiagClient, false); - // The clang executable path isn't required since the jobs the driver builds - // will not be executed. + // Although the jobs the driver builds will not be executed, the clang + // executable path is still required in order to determine the correct + // driver mode (CL, GCC, G++, etc). + ProgName = Args[0]; std::unique_ptr NewDriver(new driver::Driver( - /* ClangExecutable= */ "", llvm::sys::getDefaultTargetTriple(), - Diagnostics)); + ProgName, llvm::sys::getDefaultTargetTriple(), Diagnostics)); NewDriver->setCheckInputsExist(false); - // This becomes the new argv[0]. The value is actually not important as it - // isn't used for invoking Tools. - Args.insert(Args.begin(), "clang-tool"); - // By adding -c, we force the driver to treat compilation as the last phase. // It will then issue warnings via Diagnostics about un-used options that // would have been used for linking. If the user provided a compiler name as @@ -290,14 +292,15 @@ Argc = DoubleDash - Argv; std::vector StrippedArgs; - if (!stripPositionalArgs(CommandLine, StrippedArgs)) + std::string ToolName; + if (!stripPositionalArgs(CommandLine, ToolName, StrippedArgs)) return nullptr; - return new FixedCompilationDatabase(Directory, StrippedArgs); + return new FixedCompilationDatabase(Directory, ToolName, StrippedArgs); } -FixedCompilationDatabase:: -FixedCompilationDatabase(Twine Directory, ArrayRef CommandLine) { - std::vector ToolCommandLine(1, "clang-tool"); +FixedCompilationDatabase::FixedCompilationDatabase( + Twine Directory, StringRef ProgName, ArrayRef CommandLine) { + std::vector ToolCommandLine(1, ProgName); ToolCommandLine.insert(ToolCommandLine.end(), CommandLine.begin(), CommandLine.end()); CompileCommands.emplace_back(Directory, StringRef(), Index: lib/Tooling/JSONCompilationDatabase.cpp =================================================================== --- lib/Tooling/JSONCompilationDatabase.cpp +++ lib/Tooling/JSONCompilationDatabase.cpp @@ -16,7 +16,10 @@ #include "clang/Tooling/CompilationDatabasePluginRegistry.h" #include "clang/Tooling/Tooling.h" #include "llvm/ADT/SmallString.h" +#include "llvm/Support/Allocator.h" +#include "llvm/Support/CommandLine.h" #include "llvm/Support/Path.h" +#include "llvm/Support/StringSaver.h" #include namespace clang { @@ -113,8 +116,17 @@ std::vector unescapeCommandLine( StringRef EscapedCommandLine) { +#if defined(LLVM_ON_WIN32) + llvm::BumpPtrAllocator Alloc; + llvm::StringSaver Saver(Alloc); + llvm::SmallVector T; + llvm::cl::TokenizeWindowsCommandLine(EscapedCommandLine, Saver, T); + std::vector Result(T.begin(), T.end()); + return Result; +#else CommandLineArgumentParser parser(EscapedCommandLine); return parser.parse(); +#endif } class JSONCompilationDatabasePlugin : public CompilationDatabasePlugin {