https://github.com/aganea updated https://github.com/llvm/llvm-project/pull/89950
>From 13c411018e491fc2be4f4118a56f9b8cf2e5b76f Mon Sep 17 00:00:00 2001 From: Alexandre Ganea <aga...@havenstudios.com> Date: Wed, 17 Apr 2024 16:28:21 -0400 Subject: [PATCH 1/5] [clang-scan-deps] Expand response files before the argument ajuster Previously, since response (.rsp) files weren't expanded, we only parsed the command-line as provided in the Clang CDB file. Unfortunately, when using Unreal Engine, arguments are always generated in a .rsp file. After this patch, /Fo can be parsed and added to the final command-line. Without this option, the make targets that are emitted are made up from the input file name alone. We have some cases where the same input in the project generates several output files, so we end up with duplicate make targets in the scan-deps emitted dependency file. --- clang/tools/clang-scan-deps/ClangScanDeps.cpp | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/clang/tools/clang-scan-deps/ClangScanDeps.cpp b/clang/tools/clang-scan-deps/ClangScanDeps.cpp index f42af7e330e17..7b7f10c4be742 100644 --- a/clang/tools/clang-scan-deps/ClangScanDeps.cpp +++ b/clang/tools/clang-scan-deps/ClangScanDeps.cpp @@ -792,10 +792,15 @@ int clang_scan_deps_main(int argc, char **argv, const llvm::ToolContext &) { llvm::cl::PrintOptionValues(); + // Expand response files in advance, so that we can "see" all the arguments + // when adjusting below. + auto ResponseExpander = expandResponseFiles(std::move(Compilations), + llvm::vfs::getRealFileSystem()); + // The command options are rewritten to run Clang in preprocessor only mode. auto AdjustingCompilations = std::make_unique<tooling::ArgumentsAdjustingCompilations>( - std::move(Compilations)); + std::move(ResponseExpander)); ResourceDirectoryCache ResourceDirCache; AdjustingCompilations->appendArgumentsAdjuster( >From d6122c7fe41fb16425655550985abafb9444f3e6 Mon Sep 17 00:00:00 2001 From: Alexandre Ganea <aga...@havenstudios.com> Date: Wed, 24 Apr 2024 13:52:55 -0400 Subject: [PATCH 2/5] Add test --- .../ClangScanDeps/response-file-clang-cl.c | 32 +++++++++++++++++++ 1 file changed, 32 insertions(+) create mode 100644 clang/test/ClangScanDeps/response-file-clang-cl.c diff --git a/clang/test/ClangScanDeps/response-file-clang-cl.c b/clang/test/ClangScanDeps/response-file-clang-cl.c new file mode 100644 index 0000000000000..78e3d15deb167 --- /dev/null +++ b/clang/test/ClangScanDeps/response-file-clang-cl.c @@ -0,0 +1,32 @@ +// Check that the scanner can adjust arguments by reading .rsp files in advance. + +// RUN: rm -rf %t +// RUN: split-file %s %t +// RUN: sed -e "s|DIR|%/t|g" %t/cdb.json.template > %t/cdb.json +// RUN: echo /Fo%t/tu.obj >> %t/args_nested.rsp + +// RUN: clang-scan-deps -compilation-database %t/cdb.json > %t/deps.json + +// RUN: cat %t/deps.json | sed 's:\\\\\?:/:g' | FileCheck -DPREFIX=%/t %s + +// Here we ensure that we got a qualified .obj with its full path, since that's what we're passing with /Fo +// CHECK: [[PREFIX]]/tu.obj: + +//--- cdb.json.template +[{ + "file": "DIR/t.cpp", + "directory": "DIR", + "command": "clang-cl @DIR/args.rsp" +}] + +//--- args.rsp +@args_nested.rsp +/c tu.cpp + +//--- args_nested.rsp +/I include + +//--- include/header.h + +//--- tu.cpp +#include "header.h" >From d74e133dc023d24e66b853940a1b4bb799c0a491 Mon Sep 17 00:00:00 2001 From: Alexandre Ganea <aga...@havenstudios.com> Date: Wed, 24 Apr 2024 17:02:17 -0400 Subject: [PATCH 3/5] Handle /Fo in the Clang driver as well. --- clang/lib/Driver/ToolChains/Clang.cpp | 2 +- clang/test/ClangScanDeps/response-file-clang-cl.c | 6 +++++- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/clang/lib/Driver/ToolChains/Clang.cpp b/clang/lib/Driver/ToolChains/Clang.cpp index 18de8781e894a..15cf58f9d3339 100644 --- a/clang/lib/Driver/ToolChains/Clang.cpp +++ b/clang/lib/Driver/ToolChains/Clang.cpp @@ -1030,7 +1030,7 @@ void Clang::AddPreprocessingOptions(Compilation &C, const JobAction &JA, // If user provided -o, that is the dependency target, except // when we are only generating a dependency file. - Arg *OutputOpt = Args.getLastArg(options::OPT_o); + Arg *OutputOpt = Args.getLastArg(options::OPT_o, options::OPT__SLASH_Fo); if (OutputOpt && Output.getType() != types::TY_Dependencies) { DepTarget = OutputOpt->getValue(); } else { diff --git a/clang/test/ClangScanDeps/response-file-clang-cl.c b/clang/test/ClangScanDeps/response-file-clang-cl.c index 78e3d15deb167..77cecfff0b9ca 100644 --- a/clang/test/ClangScanDeps/response-file-clang-cl.c +++ b/clang/test/ClangScanDeps/response-file-clang-cl.c @@ -5,8 +5,12 @@ // RUN: sed -e "s|DIR|%/t|g" %t/cdb.json.template > %t/cdb.json // RUN: echo /Fo%t/tu.obj >> %t/args_nested.rsp +// RUN: echo /c >> %t/args_nested.rsp // RUN: clang-scan-deps -compilation-database %t/cdb.json > %t/deps.json +// RUN: cat %t/deps.json | sed 's:\\\\\?:/:g' | FileCheck -DPREFIX=%/t %s +// RUN: echo /E >> %t/args_nested.rsp +// RUN: clang-scan-deps -compilation-database %t/cdb.json > %t/deps.json // RUN: cat %t/deps.json | sed 's:\\\\\?:/:g' | FileCheck -DPREFIX=%/t %s // Here we ensure that we got a qualified .obj with its full path, since that's what we're passing with /Fo @@ -21,7 +25,7 @@ //--- args.rsp @args_nested.rsp -/c tu.cpp +tu.cpp //--- args_nested.rsp /I include >From 3eaba5207b3e6a99c061ccb22349ab8a90cc9d40 Mon Sep 17 00:00:00 2001 From: Alexandre Ganea <aga...@havenstudios.com> Date: Mon, 29 Apr 2024 15:57:04 -0400 Subject: [PATCH 4/5] Cover extracting -MT dependency from /Fo flag in clang-cl mode --- clang/test/Driver/cl-options.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/clang/test/Driver/cl-options.c b/clang/test/Driver/cl-options.c index 75f49deca0653..733f243d3c69b 100644 --- a/clang/test/Driver/cl-options.c +++ b/clang/test/Driver/cl-options.c @@ -740,9 +740,10 @@ // NOCLANG-SAME: "-vectorize-slp" // NOCLANG-NOT: "--dependent-lib=msvcrt" -// RUN: %clang_cl -O2 -MD /clang:-fno-slp-vectorize /clang:-MD /clang:-MF /clang:my_dependency_file.dep -### -- %s 2>&1 | FileCheck -check-prefix=CLANG %s +// RUN: %clang_cl -O2 -MD /clang:-fno-slp-vectorize /clang:-MD /clang:-MF /clang:my_dependency_file.dep /c /Fo%/t/cl-options.obj -### -- %s 2>&1 | FileCheck -DPREFIX=%/t -check-prefix=CLANG %s // CLANG: "--dependent-lib=msvcrt" // CLANG-SAME: "-dependency-file" "my_dependency_file.dep" +// CLANG-SAME: "-MT" "[[PREFIX]]/cl-options.obj" // CLANG-NOT: "--dependent-lib=libcmt" // CLANG-NOT: "-vectorize-slp" >From 7b6f5732a72320fa65e44ad4ca5d0ef9b582988f Mon Sep 17 00:00:00 2001 From: Alexandre Ganea <aga...@havenstudios.com> Date: Mon, 29 Apr 2024 15:57:56 -0400 Subject: [PATCH 5/5] Address review comments Also fix stack-allocated `CommandLine` entries when using a InplaceCompilationDatabase --- .../ClangScanDeps/response-file-clang-cl.c | 38 ++++++++++++++----- clang/tools/clang-scan-deps/ClangScanDeps.cpp | 10 ++--- 2 files changed, 34 insertions(+), 14 deletions(-) diff --git a/clang/test/ClangScanDeps/response-file-clang-cl.c b/clang/test/ClangScanDeps/response-file-clang-cl.c index 77cecfff0b9ca..b543231f4bb1b 100644 --- a/clang/test/ClangScanDeps/response-file-clang-cl.c +++ b/clang/test/ClangScanDeps/response-file-clang-cl.c @@ -2,33 +2,53 @@ // RUN: rm -rf %t // RUN: split-file %s %t + +// First run the tests with a .cdb // RUN: sed -e "s|DIR|%/t|g" %t/cdb.json.template > %t/cdb.json -// RUN: echo /Fo%t/tu.obj >> %t/args_nested.rsp +// RUN: sed -e "s|DIR|%/t|g" %t/args_nested.template > %t/args_nested.rsp -// RUN: echo /c >> %t/args_nested.rsp -// RUN: clang-scan-deps -compilation-database %t/cdb.json > %t/deps.json +// RUN: cp %t/args_compilation.rsp %t/args.rsp +// RUN: clang-scan-deps --compilation-database %t/cdb.json > %t/deps.json // RUN: cat %t/deps.json | sed 's:\\\\\?:/:g' | FileCheck -DPREFIX=%/t %s -// RUN: echo /E >> %t/args_nested.rsp -// RUN: clang-scan-deps -compilation-database %t/cdb.json > %t/deps.json +// RUN: cp %t/args_preprocess.rsp %t/args.rsp +// RUN: clang-scan-deps --compilation-database %t/cdb.json > %t/deps.json // RUN: cat %t/deps.json | sed 's:\\\\\?:/:g' | FileCheck -DPREFIX=%/t %s + +// Now run the tests again with a in-place compilation database +// RUN: cd %t + +// RUN: cp args_compilation.rsp args.rsp +// RUN: clang-scan-deps -o deps.json -- %clang_cl @args.rsp +// RUN: cat deps.json | sed 's:\\\\\?:/:g' | FileCheck -DPREFIX=%/t %s + +// RUN: cp args_preprocess.rsp args.rsp +// RUN: clang-scan-deps -o deps.json -- %clang_cl @args.rsp +// RUN: cat deps.json | sed 's:\\\\\?:/:g' | FileCheck -DPREFIX=%/t %s + // Here we ensure that we got a qualified .obj with its full path, since that's what we're passing with /Fo // CHECK: [[PREFIX]]/tu.obj: //--- cdb.json.template [{ - "file": "DIR/t.cpp", + "file": "DIR/tu.cpp", "directory": "DIR", "command": "clang-cl @DIR/args.rsp" }] -//--- args.rsp +//--- args_compilation.rsp @args_nested.rsp -tu.cpp +/c + +//--- args_preprocess.rsp +@args_nested.rsp +/E -//--- args_nested.rsp +//--- args_nested.template /I include +tu.cpp +/FoDIR/tu.obj //--- include/header.h diff --git a/clang/tools/clang-scan-deps/ClangScanDeps.cpp b/clang/tools/clang-scan-deps/ClangScanDeps.cpp index 7b7f10c4be742..036e57c8d213b 100644 --- a/clang/tools/clang-scan-deps/ClangScanDeps.cpp +++ b/clang/tools/clang-scan-deps/ClangScanDeps.cpp @@ -86,6 +86,8 @@ static bool DeprecatedDriverCommand; static ResourceDirRecipeKind ResourceDirRecipe; static bool Verbose; static bool PrintTiming; +static llvm::BumpPtrAllocator Alloc; +static llvm::StringSaver Saver{Alloc}; static std::vector<const char *> CommandLine; #ifndef NDEBUG @@ -99,8 +101,6 @@ static bool RoundTripArgs = DoRoundTripDefault; static void ParseArgs(int argc, char **argv) { ScanDepsOptTable Tbl; llvm::StringRef ToolName = argv[0]; - llvm::BumpPtrAllocator Alloc; - llvm::StringSaver Saver{Alloc}; llvm::opt::InputArgList Args = Tbl.parseArgs(argc, argv, OPT_UNKNOWN, Saver, [&](StringRef Msg) { llvm::errs() << Msg << '\n'; @@ -794,13 +794,13 @@ int clang_scan_deps_main(int argc, char **argv, const llvm::ToolContext &) { // Expand response files in advance, so that we can "see" all the arguments // when adjusting below. - auto ResponseExpander = expandResponseFiles(std::move(Compilations), - llvm::vfs::getRealFileSystem()); + Compilations = expandResponseFiles(std::move(Compilations), + llvm::vfs::getRealFileSystem()); // The command options are rewritten to run Clang in preprocessor only mode. auto AdjustingCompilations = std::make_unique<tooling::ArgumentsAdjustingCompilations>( - std::move(ResponseExpander)); + std::move(Compilations)); ResourceDirectoryCache ResourceDirCache; AdjustingCompilations->appendArgumentsAdjuster( _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits