Index: include/clang/Driver/Options.td =================================================================== --- include/clang/Driver/Options.td +++ include/clang/Driver/Options.td @@ -380,6 +380,8 @@ HelpText<"Add missing headers to depfile">; def MJ : JoinedOrSeparate<["-"], "MJ">, Group, HelpText<"Write a compilation database entry per input">; +def MJJ : JoinedOrSeparate<["-"], "MJJ">, Group, + HelpText<"Write or append to a compilation database entry per input">; def MP : Flag<["-"], "MP">, Group, Flags<[CC1Option]>, HelpText<"Create phony target for each dependency (other than main file)">; def MQ : JoinedOrSeparate<["-"], "MQ">, Group, Flags<[CC1Option]>, Index: lib/Driver/ToolChains/Clang.h =================================================================== --- lib/Driver/ToolChains/Clang.h +++ lib/Driver/ToolChains/Clang.h @@ -94,7 +94,8 @@ void DumpCompilationDatabase(Compilation &C, StringRef Filename, StringRef Target, const InputInfo &Output, const InputInfo &Input, - const llvm::opt::ArgList &Args) const; + const llvm::opt::ArgList &Args, + bool Append) const; public: Clang(const ToolChain &TC); Index: lib/Driver/ToolChains/Clang.cpp =================================================================== --- lib/Driver/ToolChains/Clang.cpp +++ lib/Driver/ToolChains/Clang.cpp @@ -1909,7 +1909,8 @@ void Clang::DumpCompilationDatabase(Compilation &C, StringRef Filename, StringRef Target, const InputInfo &Output, - const InputInfo &Input, const ArgList &Args) const { + const InputInfo &Input, const ArgList &Args, + bool Append) const { // If this is a dry run, do not create the compilation database file. if (C.getArgs().hasArg(options::OPT__HASH_HASH_HASH)) return; @@ -1919,7 +1920,11 @@ if (!CompilationDatabase) { std::error_code EC; - auto File = llvm::make_unique(Filename, EC, llvm::sys::fs::F_Text); + llvm::sys::fs::OpenFlags Flags = llvm::sys::fs::F_Text; + if (Append) { + Flags |= llvm::sys::fs::OF_Append; + } + auto File = llvm::make_unique(Filename, EC, Flags); if (EC) { D.Diag(clang::diag::err_drv_compilationdatabase) << Filename << EC.message(); @@ -3365,8 +3370,12 @@ CmdArgs.push_back("-triple"); CmdArgs.push_back(Args.MakeArgString(TripleStr)); - if (const Arg *MJ = Args.getLastArg(options::OPT_MJ)) { - DumpCompilationDatabase(C, MJ->getValue(), TripleStr, Output, Input, Args); + Arg *MJ = nullptr; + if ((MJ = Args.getLastArg(options::OPT_MJ)) || + (MJ = Args.getLastArg(options::OPT_MJJ))) { + bool Append = MJ->getOption().matches(options::OPT_MJJ); + DumpCompilationDatabase(C, MJ->getValue(), TripleStr, Output, Input, Args, + Append); Args.ClaimAllArgs(options::OPT_MJ); } Index: test/Driver/compilation_database_append.c =================================================================== --- /dev/null +++ test/Driver/compilation_database_append.c @@ -0,0 +1,16 @@ +// RUN: mkdir -p %t && cd %t +// RUN: %clang -MD -MP --sysroot=somewhere -c -x c %s -xc++ %s -Wall -MJJ - -no-canonical-prefixes 2>&1 | FileCheck %s +// RUN: %clang -c -x c %s -MJJ json +// RUN: %clang -E -x c %s -MJJ json +// RUN: cat json | FileCheck --check-prefix=DOUBLE %s +// RUN: not %clang -c -x c %s -MJJ %s/non-existant -no-canonical-prefixes 2>&1 | FileCheck --check-prefix=ERROR %s + +// CHECK: { "directory": "{{.*}}", "file": "[[SRC:[^"]+[/|\\]compilation_database_append.c]]", "output": "compilation_database_append.o", "arguments": ["{{[^"]*}}clang{{[^"]*}}", "-xc", "[[SRC]]", "--sysroot=somewhere", "-c", "-Wall",{{.*}} "--target={{[^"]+}}"]}, +// CHECK: { "directory": "{{.*}}", "file": "[[SRC:[^"]+[/|\\]compilation_database_append.c]]", "output": "compilation_database_append.o", "arguments": ["{{[^"]*}}clang{{[^"]*}}", "-xc++", "[[SRC]]", "--sysroot=somewhere", "-c", "-Wall",{{.*}} "--target={{[^"]+}}"]}, +// DOUBLE: { "directory": "{{.*}}", "file": "[[SRC:[^"]+[/|\\]compilation_database_append.c]]", "output": "compilation_database_append.o", "arguments": ["{{[^"]*}}clang{{[^"]*}}", "-xc", "[[SRC]]", "-c",{{.*}} "--target={{[^"]+}}"]}, +// DOUBLE-NEXT: { "directory": "{{.*}}", "file": "[[SRC:[^"]+[/|\\]compilation_database_append.c]]", "output": "-", "arguments": ["{{[^"]*}}clang{{[^"]*}}", "-xc", "[[SRC]]", "-E",{{.*}} "--target={{[^"]+}}"]}, +// ERROR: error: compilation database '{{.*}}/non-existant' could not be opened: + +int main(void) { + return 0; +}