de1acr0ix created this revision. Herald added a project: clang. Herald added a subscriber: cfe-commits.
When creating FixedCompilationDatabase from command line, compiler command is often provided. This commit tries to infer driver mode and target from that so that clang tools does not need to specify them explicitly. Repository: rG LLVM Github Monorepo https://reviews.llvm.org/D71953 Files: clang/lib/Tooling/CompilationDatabase.cpp clang/unittests/Tooling/CompilationDatabaseTest.cpp Index: clang/unittests/Tooling/CompilationDatabaseTest.cpp =================================================================== --- clang/unittests/Tooling/CompilationDatabaseTest.cpp +++ 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<FixedCompilationDatabase> Database = + FixedCompilationDatabase::loadFromCommandLine(Argc, Argv, ErrorMsg); + ASSERT_TRUE((bool)Database); + ASSERT_TRUE(ErrorMsg.empty()); + std::vector<CompileCommand> Result = Database->getCompileCommands("source"); + ASSERT_EQ(1ul, Result.size()); + ASSERT_EQ(".", Result[0].Directory); + std::vector<std::string> 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<FixedCompilationDatabase> Database = + FixedCompilationDatabase::loadFromCommandLine(Argc, Argv, ErrorMsg); + ASSERT_TRUE((bool)Database); + ASSERT_TRUE(ErrorMsg.empty()); + std::vector<CompileCommand> Result = Database->getCompileCommands("source"); + ASSERT_EQ(1ul, Result.size()); + ASSERT_EQ(".", Result[0].Directory); + std::vector<std::string> 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<SmallVector<CompileCommand, 1>>; EntryMap Entries; Index: clang/lib/Tooling/CompilationDatabase.cpp =================================================================== --- clang/lib/Tooling/CompilationDatabase.cpp +++ 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();
Index: clang/unittests/Tooling/CompilationDatabaseTest.cpp =================================================================== --- clang/unittests/Tooling/CompilationDatabaseTest.cpp +++ 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<FixedCompilationDatabase> Database = + FixedCompilationDatabase::loadFromCommandLine(Argc, Argv, ErrorMsg); + ASSERT_TRUE((bool)Database); + ASSERT_TRUE(ErrorMsg.empty()); + std::vector<CompileCommand> Result = Database->getCompileCommands("source"); + ASSERT_EQ(1ul, Result.size()); + ASSERT_EQ(".", Result[0].Directory); + std::vector<std::string> 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<FixedCompilationDatabase> Database = + FixedCompilationDatabase::loadFromCommandLine(Argc, Argv, ErrorMsg); + ASSERT_TRUE((bool)Database); + ASSERT_TRUE(ErrorMsg.empty()); + std::vector<CompileCommand> Result = Database->getCompileCommands("source"); + ASSERT_EQ(1ul, Result.size()); + ASSERT_EQ(".", Result[0].Directory); + std::vector<std::string> 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<SmallVector<CompileCommand, 1>>; EntryMap Entries; Index: clang/lib/Tooling/CompilationDatabase.cpp =================================================================== --- clang/lib/Tooling/CompilationDatabase.cpp +++ 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();
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits