r369938 - [driver] add a new option `-gen-cdb-fragment-path` to emit

Alex Lorenz via cfe-commits cfe-commits at lists.llvm.org
Mon Aug 26 10:59:41 PDT 2019


Author: arphaman
Date: Mon Aug 26 10:59:41 2019
New Revision: 369938

URL: http://llvm.org/viewvc/llvm-project?rev=369938&view=rev
Log:
[driver] add a new option `-gen-cdb-fragment-path` to emit
a fragment of a compilation database for each compilation

This patch adds a new option called -gen-cdb-fragment-path to the driver,
which can be used to specify a directory path to which clang can emit a fragment
of a CDB for each compilation it needs to invoke.

This option emits the same CDB contents as -MJ, and will be ignored if -MJ is specified.

Differential Revision: https://reviews.llvm.org/D66555

Added:
    cfe/trunk/test/Driver/gen-cdb-fragment.c
Modified:
    cfe/trunk/include/clang/Driver/Options.td
    cfe/trunk/lib/Driver/ToolChains/Clang.cpp
    cfe/trunk/lib/Driver/ToolChains/Clang.h

Modified: cfe/trunk/include/clang/Driver/Options.td
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Driver/Options.td?rev=369938&r1=369937&r2=369938&view=diff
==============================================================================
--- cfe/trunk/include/clang/Driver/Options.td (original)
+++ cfe/trunk/include/clang/Driver/Options.td Mon Aug 26 10:59:41 2019
@@ -280,6 +280,8 @@ def arcmt_migrate_emit_arc_errors : Flag
   Flags<[CC1Option]>;
 def gen_reproducer: Flag<["-"], "gen-reproducer">, InternalDebugOpt,
   HelpText<"Auto-generates preprocessed source files and a reproduction script">;
+def gen_cdb_fragment_path: Separate<["-"], "gen-cdb-fragment-path">, InternalDebugOpt,
+  HelpText<"Emit a compilation database fragment to the specified directory">;
 
 def _migrate : Flag<["--"], "migrate">, Flags<[DriverOption]>,
   HelpText<"Run the migrator">;

Modified: cfe/trunk/lib/Driver/ToolChains/Clang.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Driver/ToolChains/Clang.cpp?rev=369938&r1=369937&r2=369938&view=diff
==============================================================================
--- cfe/trunk/lib/Driver/ToolChains/Clang.cpp (original)
+++ cfe/trunk/lib/Driver/ToolChains/Clang.cpp Mon Aug 26 10:59:41 2019
@@ -2013,13 +2013,14 @@ void Clang::DumpCompilationDatabase(Comp
     CompilationDatabase = std::move(File);
   }
   auto &CDB = *CompilationDatabase;
-  SmallString<128> Buf;
-  if (llvm::sys::fs::current_path(Buf))
-    Buf = ".";
-  CDB << "{ \"directory\": \"" << escape(Buf) << "\"";
+  auto CWD = D.getVFS().getCurrentWorkingDirectory();
+  if (!CWD)
+    CWD = ".";
+  CDB << "{ \"directory\": \"" << escape(*CWD) << "\"";
   CDB << ", \"file\": \"" << escape(Input.getFilename()) << "\"";
   CDB << ", \"output\": \"" << escape(Output.getFilename()) << "\"";
   CDB << ", \"arguments\": [\"" << escape(D.ClangExecutable) << "\"";
+  SmallString<128> Buf;
   Buf = "-x";
   Buf += types::getTypeName(Input.getType());
   CDB << ", \"" << escape(Buf) << "\"";
@@ -2037,6 +2038,8 @@ void Clang::DumpCompilationDatabase(Comp
     // Skip writing dependency output and the compilation database itself.
     if (O.getGroup().isValid() && O.getGroup().getID() == options::OPT_M_Group)
       continue;
+    if (O.getID() == options::OPT_gen_cdb_fragment_path)
+      continue;
     // Skip inputs.
     if (O.getKind() == Option::InputClass)
       continue;
@@ -2051,6 +2054,40 @@ void Clang::DumpCompilationDatabase(Comp
   CDB << ", \"" << escape(Buf) << "\"]},\n";
 }
 
+void Clang::DumpCompilationDatabaseFragmentToDir(
+    StringRef Dir, Compilation &C, StringRef Target, const InputInfo &Output,
+    const InputInfo &Input, const llvm::opt::ArgList &Args) const {
+  // If this is a dry run, do not create the compilation database file.
+  if (C.getArgs().hasArg(options::OPT__HASH_HASH_HASH))
+    return;
+
+  if (CompilationDatabase)
+    DumpCompilationDatabase(C, "", Target, Output, Input, Args);
+
+  SmallString<256> Path = Dir;
+  const auto &Driver = C.getDriver();
+  Driver.getVFS().makeAbsolute(Path);
+  auto Err = llvm::sys::fs::create_directory(Path, /*IgnoreExisting=*/true);
+  if (Err) {
+    Driver.Diag(diag::err_drv_compilationdatabase) << Dir << Err.message();
+    return;
+  }
+
+  llvm::sys::path::append(
+      Path,
+      Twine(llvm::sys::path::filename(Input.getFilename())) + ".%%%%.json");
+  int FD;
+  SmallString<256> TempPath;
+  Err = llvm::sys::fs::createUniqueFile(Path, FD, TempPath);
+  if (Err) {
+    Driver.Diag(diag::err_drv_compilationdatabase) << Path << Err.message();
+    return;
+  }
+  CompilationDatabase =
+      std::make_unique<llvm::raw_fd_ostream>(FD, /*shouldClose=*/true);
+  DumpCompilationDatabase(C, "", Target, Output, Input, Args);
+}
+
 static void CollectArgsForIntegratedAssembler(Compilation &C,
                                               const ArgList &Args,
                                               ArgStringList &CmdArgs,
@@ -3495,6 +3532,11 @@ void Clang::ConstructJob(Compilation &C,
   if (const Arg *MJ = Args.getLastArg(options::OPT_MJ)) {
     DumpCompilationDatabase(C, MJ->getValue(), TripleStr, Output, Input, Args);
     Args.ClaimAllArgs(options::OPT_MJ);
+  } else if (const Arg *GenCDBFragment =
+                 Args.getLastArg(options::OPT_gen_cdb_fragment_path)) {
+    DumpCompilationDatabaseFragmentToDir(GenCDBFragment->getValue(), C,
+                                         TripleStr, Output, Input, Args);
+    Args.ClaimAllArgs(options::OPT_gen_cdb_fragment_path);
   }
 
   if (IsCuda || IsHIP) {

Modified: cfe/trunk/lib/Driver/ToolChains/Clang.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Driver/ToolChains/Clang.h?rev=369938&r1=369937&r2=369938&view=diff
==============================================================================
--- cfe/trunk/lib/Driver/ToolChains/Clang.h (original)
+++ cfe/trunk/lib/Driver/ToolChains/Clang.h Mon Aug 26 10:59:41 2019
@@ -95,6 +95,10 @@ private:
                                const InputInfo &Output, const InputInfo &Input,
                                const llvm::opt::ArgList &Args) const;
 
+  void DumpCompilationDatabaseFragmentToDir(
+      StringRef Dir, Compilation &C, StringRef Target, const InputInfo &Output,
+      const InputInfo &Input, const llvm::opt::ArgList &Args) const;
+
 public:
   Clang(const ToolChain &TC);
   ~Clang() override;

Added: cfe/trunk/test/Driver/gen-cdb-fragment.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Driver/gen-cdb-fragment.c?rev=369938&view=auto
==============================================================================
--- cfe/trunk/test/Driver/gen-cdb-fragment.c (added)
+++ cfe/trunk/test/Driver/gen-cdb-fragment.c Mon Aug 26 10:59:41 2019
@@ -0,0 +1,37 @@
+// REQUIRES: x86-registered-target
+// RUN: rm -rf %t.cdb
+// RUN: %clang -target x86_64-apple-macos10.15 -c %s -o -  -gen-cdb-fragment-path %t.cdb
+// RUN: ls %t.cdb | FileCheck --check-prefix=CHECK-LS %s
+// CHECK-LS: gen-cdb-fragment.c.{{.*}}.json
+
+// RUN: cat %t.cdb/*.json | FileCheck --check-prefix=CHECK %s
+// CHECK: { "directory": "{{.*}}", "file": "{{.*}}gen-cdb-fragment.c", "output": "-", "arguments": [{{.*}}, "--target=x86_64-apple-macos10.15"{{.*}}]},
+// RUN: cat %t.cdb/*.json | FileCheck --check-prefix=CHECK-FLAG %s
+// CHECK-FLAG-NOT: -gen-cdb-fragment-path
+
+// RUN: rm -rf %t.cdb
+// RUN: mkdir %t.cdb
+// RUN: ls %t.cdb | not FileCheck --check-prefix=CHECK-LS %s
+// RUN: %clang -target x86_64-apple-macos10.15 -S %s -o -  -gen-cdb-fragment-path %t.cdb
+// RUN: ls %t.cdb | FileCheck --check-prefix=CHECK-LS %s
+
+// Empty path is equivalent to '.'
+// RUN: rm -rf %t.cdb
+// RUN: mkdir %t.cdb
+// RUN: %clang -target x86_64-apple-macos10.15 -working-directory %t.cdb -c %s -o -  -gen-cdb-fragment-path ""
+// RUN: ls %t.cdb | FileCheck --check-prefix=CHECK-LS %s
+// RUN: cat %t.cdb/*.json | FileCheck --check-prefix=CHECK-CWD %s
+// CHECK-CWD: "directory": "{{.*}}.cdb"
+
+// -### does not emit the CDB fragment
+// RUN: rm -rf %t.cdb
+// RUN: mkdir %t.cdb
+// RUN: %clang -target x86_64-apple-macos10.15 -S %s -o -  -gen-cdb-fragment-path %t.cdb -###
+// RUN: ls %t.cdb | not FileCheck --check-prefix=CHECK-LS %s
+
+// -MJ is preferred over -gen-cdb-fragment-path
+// RUN: rm -rf %t.cdb
+// RUN: mkdir %t.cdb
+// RUN: %clang -target x86_64-apple-macos10.15 -S %s -o -  -gen-cdb-fragment-path %t.cdb -MJ %t.out
+// RUN: ls %t.cdb | not FileCheck --check-prefix=CHECK-LS %s
+// RUN: FileCheck %s < %t.out




More information about the cfe-commits mailing list