de1acr0ix updated this revision to Diff 235496.
de1acr0ix added a comment.
Check if argv[0] is an option before inferring - anything starting with dash or
slash (but without a second slash) will be treated as compiler option.
Repository:
rG LLVM Github Monorepo
CHANGES SINCE LAST ACTION
https://reviews.llvm.org/D71953/new/
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
@@ -605,6 +605,25 @@
EXPECT_EQ(2, Argc);
}
+TEST(ParseFixedCompilationDatabase, HandlesPositionalArgsSlash) {
+ // Arguments starting with slash will be stripped without explicitly setting
+ // driver mode to CL.
+ const char *Argv[] = {"1", "2", "--", "/O2", "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"), "source"));
+ EXPECT_EQ(2, Argc);
+}
+
TEST(ParseFixedCompilationDatabase, HandlesPositionalArgsSyntaxOnly) {
// Adjust the given command line arguments to ensure that any positional
// arguments in them are stripped.
@@ -641,6 +660,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,24 @@
Diagnostics));
NewDriver->setCheckInputsExist(false);
+ // Try to infer driver mode and target from the original argv[0].
+ driver::ParsedClangName NameParts;
+ if (!Args.empty()) {
+ StringRef Argv0 = Args[0];
+ if (!Argv0.startswith("-") &&
+ (!Argv0.startswith("/") || Argv0.count("/") > 1)) {
+ NameParts = driver::ToolChain::getTargetAndModeFromProgramName(Argv0);
+ 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
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits