arphaman updated this revision to Diff 216717.
arphaman added a comment.
Herald added a subscriber: ributzka.

Reimplement the new option on top of `-MJ`. `-MJ` is still the preferred option 
if both are specified.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D66555/new/

https://reviews.llvm.org/D66555

Files:
  clang/include/clang/Basic/DiagnosticDriverKinds.td
  clang/include/clang/Driver/Options.td
  clang/lib/Driver/ToolChains/Clang.cpp
  clang/lib/Driver/ToolChains/Clang.h
  clang/test/Driver/gen-cdb-fragment.c

Index: clang/test/Driver/gen-cdb-fragment.c
===================================================================
--- /dev/null
+++ clang/test/Driver/gen-cdb-fragment.c
@@ -0,0 +1,35 @@
+// 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
+
+// -### 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
Index: clang/lib/Driver/ToolChains/Clang.h
===================================================================
--- clang/lib/Driver/ToolChains/Clang.h
+++ clang/lib/Driver/ToolChains/Clang.h
@@ -95,6 +95,10 @@
                                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;
Index: clang/lib/Driver/ToolChains/Clang.cpp
===================================================================
--- clang/lib/Driver/ToolChains/Clang.cpp
+++ clang/lib/Driver/ToolChains/Clang.cpp
@@ -2037,6 +2037,8 @@
     // 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 +2053,47 @@
   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);
+
+  const auto &Driver = C.getDriver();
+  auto CWD = Driver.getVFS().getCurrentWorkingDirectory();
+  if (!CWD) {
+    Driver.Diag(diag::err_drv_emit_cdb_fragment_dir_failure)
+        << CWD.getError().message();
+    return;
+  }
+
+  SmallString<256> Path = Dir;
+  Driver.getVFS().makeAbsolute(Path);
+  auto Err = llvm::sys::fs::create_directory(Path, /*IgnoreExisting=*/true);
+  if (Err) {
+    Driver.Diag(diag::err_drv_emit_cdb_fragment_dir_failure) << 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) << 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 +3538,11 @@
   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) {
Index: clang/include/clang/Driver/Options.td
===================================================================
--- clang/include/clang/Driver/Options.td
+++ clang/include/clang/Driver/Options.td
@@ -280,6 +280,8 @@
   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">;
Index: clang/include/clang/Basic/DiagnosticDriverKinds.td
===================================================================
--- clang/include/clang/Basic/DiagnosticDriverKinds.td
+++ clang/include/clang/Basic/DiagnosticDriverKinds.td
@@ -202,6 +202,8 @@
     "invalid output type '%0' for use with gcc tool">;
 def err_drv_cc_print_options_failure : Error<
     "unable to open CC_PRINT_OPTIONS file: %0">;
+def err_drv_emit_cdb_fragment_dir_failure : Error<
+  "unable to create output directory for cdb fragments: %0">;
 def err_drv_lto_without_lld : Error<"LTO requires -fuse-ld=lld">;
 def err_drv_preamble_format : Error<
     "incorrect format for -preamble-bytes=N,END">;
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to