diff --git a/clang/lib/Tooling/CompilationDatabase.cpp b/clang/lib/Tooling/CompilationDatabase.cpp --- a/clang/lib/Tooling/CompilationDatabase.cpp +++ b/clang/lib/Tooling/CompilationDatabase.cpp @@ -275,6 +275,20 @@ Diagnostics)); NewDriver->setCheckInputsExist(false); + // Try to infer driver mode and target from the original argv[0]. + driver::ParsedClangName NameParts; + if (!Args.empty()) { + NameParts = driver::ToolChain::getTargetAndModeFromProgramName(Args[0]); + if (NameParts.DriverMode) { + Args.insert(Args.begin(), NameParts.DriverMode); + } + + if (NameParts.TargetIsValid) { + const char *arr[] = {"-target", NameParts.TargetPrefix.c_str()}; + Args.insert(Args.begin(), std::begin(arr), std::end(arr)); + } + } + // This becomes the new argv[0]. The value is used to detect libc++ include // dirs on Mac, it isn't used for other platforms. std::string Argv0 = GetClangToolCommand(); diff --git a/clang/unittests/Tooling/CompilationDatabaseTest.cpp b/clang/unittests/Tooling/CompilationDatabaseTest.cpp --- a/clang/unittests/Tooling/CompilationDatabaseTest.cpp +++ b/clang/unittests/Tooling/CompilationDatabaseTest.cpp @@ -641,6 +641,43 @@ EXPECT_EQ(2, Argc); } +TEST(ParseFixedCompilationDatabase, InferDriverMode) { + const char *Argv[] = {"1", "2", "--", "cl.exe", "-nologo", "somefile.cpp"}; + int Argc = sizeof(Argv) / sizeof(char *); + std::string ErrorMsg; + std::unique_ptr Database = + FixedCompilationDatabase::loadFromCommandLine(Argc, Argv, ErrorMsg); + ASSERT_TRUE((bool)Database); + ASSERT_TRUE(ErrorMsg.empty()); + std::vector Result = Database->getCompileCommands("source"); + ASSERT_EQ(1ul, Result.size()); + ASSERT_EQ(".", Result[0].Directory); + std::vector Expected; + ASSERT_THAT(Result[0].CommandLine, + ElementsAre(EndsWith("clang-tool"), "--driver-mode=cl", "-nologo", + "source")); + EXPECT_EQ(2, Argc); +} + +TEST(ParseFixedCompilationDatabase, InferTarget) { + const char *Argv[] = {"1", "2", "--", "x86_64-linux-gnu-gcc", "somefile.cpp"}; + int Argc = sizeof(Argv) / sizeof(char *); + std::string ErrorMsg; + LLVMInitializeX86TargetInfo(); + std::unique_ptr Database = + FixedCompilationDatabase::loadFromCommandLine(Argc, Argv, ErrorMsg); + ASSERT_TRUE((bool)Database); + ASSERT_TRUE(ErrorMsg.empty()); + std::vector Result = Database->getCompileCommands("source"); + ASSERT_EQ(1ul, Result.size()); + ASSERT_EQ(".", Result[0].Directory); + std::vector Expected; + ASSERT_THAT(Result[0].CommandLine, + ElementsAre(EndsWith("clang-tool"), "-target", "x86_64-linux-gnu", + "source")); + EXPECT_EQ(2, Argc); +} + struct MemCDB : public CompilationDatabase { using EntryMap = llvm::StringMap>; EntryMap Entries;