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) << "\"";
// 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;
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,
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) {
--- /dev/null
+// 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