[PATCH] D71953: [Tooling] Infer driver mode and target for FixedCompilationDatabase

Hanjiang Yu via Phabricator via cfe-commits cfe-commits at lists.llvm.org
Fri Dec 27 19:01:05 PST 2019


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();


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D71953.235456.patch
Type: text/x-patch
Size: 2991 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20191228/d946684f/attachment.bin>


More information about the cfe-commits mailing list