benlangmuir updated this revision to Diff 455666. benlangmuir added a comment.
- Rebased, picking up the changes that were previously split out. - Broke up applying changes to CI from passing to consumer. The MDC is no longer responsible for passing invocations to the consumer, and it is done at the Worker level. CHANGES SINCE LAST ACTION https://reviews.llvm.org/D132405/new/ https://reviews.llvm.org/D132405 Files: clang/include/clang/Tooling/DependencyScanning/DependencyScanningTool.h clang/include/clang/Tooling/DependencyScanning/DependencyScanningWorker.h clang/include/clang/Tooling/DependencyScanning/ModuleDepCollector.h clang/lib/Tooling/DependencyScanning/DependencyScanningTool.cpp clang/lib/Tooling/DependencyScanning/DependencyScanningWorker.cpp clang/lib/Tooling/DependencyScanning/ModuleDepCollector.cpp clang/test/ClangScanDeps/deprecated-driver-api.c clang/test/ClangScanDeps/diagnostics.c clang/test/ClangScanDeps/header-search-pruning-transitive.c clang/test/ClangScanDeps/modules-context-hash-ignore-macros.c clang/test/ClangScanDeps/modules-context-hash-outputs.c clang/test/ClangScanDeps/modules-context-hash-warnings.c clang/test/ClangScanDeps/modules-context-hash.c clang/test/ClangScanDeps/modules-dep-args.c clang/test/ClangScanDeps/modules-fmodule-name-no-module-built.m clang/test/ClangScanDeps/modules-full.cpp clang/test/ClangScanDeps/modules-implicit-dot-private.m clang/test/ClangScanDeps/modules-incomplete-umbrella.c clang/test/ClangScanDeps/modules-inferred.m clang/test/ClangScanDeps/modules-no-undeclared-includes.c clang/test/ClangScanDeps/modules-pch-common-submodule.c clang/test/ClangScanDeps/modules-pch-common-via-submodule.c clang/test/ClangScanDeps/modules-pch.c clang/test/ClangScanDeps/multiple-commands.c clang/test/ClangScanDeps/removed-args.c clang/tools/clang-scan-deps/ClangScanDeps.cpp clang/utils/module-deps-to-rsp.py
Index: clang/utils/module-deps-to-rsp.py =================================================================== --- clang/utils/module-deps-to-rsp.py +++ clang/utils/module-deps-to-rsp.py @@ -48,6 +48,9 @@ type=str) action.add_argument("--tu-index", help="The index of the translation unit to get arguments for", type=int) + parser.add_argument("--tu-cmd-index", + help="The index of the command within the translation unit (default=0)", + type=int, default=0) args = parser.parse_args() full_deps = parseFullDeps(json.load(open(args.full_deps_file, 'r'))) @@ -58,7 +61,8 @@ if args.module_name: cmd = findModule(args.module_name, full_deps)['command-line'] elif args.tu_index != None: - cmd = full_deps.translation_units[args.tu_index]['command-line'] + tu = full_deps.translation_units[args.tu_index] + cmd = tu['commands'][args.tu_cmd_index]['command-line'] print(" ".join(map(quote, cmd))) except: Index: clang/tools/clang-scan-deps/ClangScanDeps.cpp =================================================================== --- clang/tools/clang-scan-deps/ClangScanDeps.cpp +++ clang/tools/clang-scan-deps/ClangScanDeps.cpp @@ -182,6 +182,11 @@ llvm::cl::desc("The names of dependency targets for the dependency file"), llvm::cl::cat(DependencyScannerCategory)); +llvm::cl::opt<bool> DeprecatedDriverCommand( + "deprecated-driver-command", llvm::cl::Optional, + llvm::cl::desc("use a single driver command to build the tu (deprecated)"), + llvm::cl::cat(DependencyScannerCategory)); + enum ResourceDirRecipeKind { RDRK_ModifyCompilerPath, RDRK_InvokeCompiler, @@ -256,7 +261,7 @@ public: void mergeDeps(StringRef Input, FullDependenciesResult FDR, size_t InputIndex) { - const FullDependencies &FD = FDR.FullDeps; + FullDependencies &FD = FDR.FullDeps; InputDeps ID; ID.FileName = std::string(Input); @@ -274,7 +279,8 @@ Modules.insert(I, {{MD.ID, InputIndex}, std::move(MD)}); } - ID.CommandLine = FD.CommandLine; + ID.DriverCommandLine = std::move(FD.DriverCommandLine); + ID.Commands = std::move(FD.Commands); Inputs.push_back(std::move(ID)); } @@ -311,14 +317,33 @@ Array TUs; for (auto &&I : Inputs) { - Object O{ - {"input-file", I.FileName}, - {"clang-context-hash", I.ContextHash}, - {"file-deps", I.FileDeps}, - {"clang-module-deps", toJSONSorted(I.ModuleDeps)}, - {"command-line", I.CommandLine}, - }; - TUs.push_back(std::move(O)); + Array Commands; + if (I.DriverCommandLine.empty()) { + for (const auto &Cmd : I.Commands) { + Object O{ + {"input-file", I.FileName}, + {"clang-context-hash", I.ContextHash}, + {"file-deps", I.FileDeps}, + {"clang-module-deps", toJSONSorted(I.ModuleDeps)}, + {"executable", Cmd.Executable}, + {"command-line", Cmd.Arguments}, + }; + Commands.push_back(std::move(O)); + } + } else { + Object O{ + {"input-file", I.FileName}, + {"clang-context-hash", I.ContextHash}, + {"file-deps", I.FileDeps}, + {"clang-module-deps", toJSONSorted(I.ModuleDeps)}, + {"executable", "clang"}, + {"command-line", I.DriverCommandLine}, + }; + Commands.push_back(std::move(O)); + } + TUs.push_back(Object{ + {"commands", std::move(Commands)}, + }); } Object Output{ @@ -353,7 +378,8 @@ std::string ContextHash; std::vector<std::string> FileDeps; std::vector<ModuleID> ModuleDeps; - std::vector<std::string> CommandLine; + std::vector<std::string> DriverCommandLine; + std::vector<Command> Commands; }; std::mutex Lock; @@ -559,6 +585,14 @@ if (handleMakeDependencyToolResult(Filename, MaybeFile, DependencyOS, Errs)) HadErrors = true; + } else if (DeprecatedDriverCommand) { + auto MaybeFullDeps = + WorkerTools[I]->getFullDependenciesLegacyDriverCommand( + Input->CommandLine, CWD, AlreadySeenModules, LookupOutput, + MaybeModuleName); + if (handleFullDependencyToolResult(Filename, MaybeFullDeps, FD, + LocalIndex, DependencyOS, Errs)) + HadErrors = true; } else { auto MaybeFullDeps = WorkerTools[I]->getFullDependencies( Input->CommandLine, CWD, AlreadySeenModules, LookupOutput, Index: clang/test/ClangScanDeps/removed-args.c =================================================================== --- clang/test/ClangScanDeps/removed-args.c +++ clang/test/ClangScanDeps/removed-args.c @@ -61,7 +61,7 @@ // CHECK-NEXT: ], // CHECK-NEXT: "translation-units": [ // CHECK-NEXT: { -// CHECK-NEXT: "clang-context-hash": "[[HASH_TU:.*]]", +// CHECK: "clang-context-hash": "[[HASH_TU:.*]]", // CHECK-NEXT: "clang-module-deps": [ // CHECK-NEXT: { // CHECK-NEXT: "context-hash": "[[HASH_MOD_HEADER]]", @@ -73,13 +73,11 @@ // CHECK-NEXT: } // CHECK-NEXT: ] // CHECK-NEXT: "command-line": [ -// CHECK-NEXT: "-fsyntax-only", +// CHECK-NEXT: "-cc1", // CHECK-NOT: "-fmodules-cache-path= // CHECK-NOT: "-fmodules-validate-once-per-build-session" +// CHECK-NOT: "-fbuild-session-timestamp= // CHECK-NOT: "-fbuild-session-file= // CHECK-NOT: "-fmodules-prune-interval= // CHECK-NOT: "-fmodules-prune-after= // CHECK: ], -// CHECK: } -// CHECK-NEXT: ] -// CHECK-NEXT: } Index: clang/test/ClangScanDeps/multiple-commands.c =================================================================== --- /dev/null +++ clang/test/ClangScanDeps/multiple-commands.c @@ -0,0 +1,165 @@ +// RUN: rm -rf %t +// RUN: split-file %s %t +// RUN: sed -e "s|DIR|%/t|g" %t/cdb.json.in > %t/cdb.json + +// RUN: clang-scan-deps -compilation-database %t/cdb.json -module-files-dir %t/modules \ +// RUN: -j 1 -format experimental-full -mode preprocess-dependency-directives \ +// RUN: > %t/deps.json + +// RUN: cat %t/deps.json | sed 's:\\\\\?:/:g' | FileCheck %s -DPREFIX=%/t + +// Build the -save-temps + -fmodules case +// RUN: %deps-to-rsp %t/deps.json --module-name=Mod > %t/Mod.rsp +// RUN: %deps-to-rsp %t/deps.json --tu-index 1 --tu-cmd-index 0 > %t/tu-cpp.rsp +// RUN: %deps-to-rsp %t/deps.json --tu-index 1 --tu-cmd-index 1 > %t/tu-emit-ir.rsp +// RUN: %deps-to-rsp %t/deps.json --tu-index 1 --tu-cmd-index 2 > %t/tu-emit-asm.rsp +// RUN: %deps-to-rsp %t/deps.json --tu-index 1 --tu-cmd-index 3 > %t/tu-cc1as.rsp +// RUN: %clang @%t/Mod.rsp +// RUN: %clang @%t/tu-cpp.rsp +// RUN: ls %t/tu_save_temps_module.i +// RUN: %clang @%t/tu-emit-ir.rsp +// RUN: ls %t/tu_save_temps_module.bc +// RUN: %clang @%t/tu-emit-asm.rsp +// RUN: ls %t/tu_save_temps_module.s +// RUN: %clang @%t/tu-cc1as.rsp +// RUN: ls %t/tu_save_temps_module.o + + +// CHECK: "modules": [ +// CHECK-NEXT: { +// CHECK: "clang-modulemap-file": "[[PREFIX]]{{.}}module.modulemap" +// CHECK: "name": "Mod" +// CHECK: } +// CHECK-NEXT: ] +// CHECK-NEXT: "translation-units": [ +// CHECK-NEXT: { +// CHECK: "commands": [ +// CHECK-NEXT: { +// CHECK-NEXT: "clang-context-hash": +// CHECK-NEXT: "clang-module-deps": [] +// CHECK-NEXT: "command-line": [ +// CHECK-NEXT: "-cc1" +// CHECK: "-o" +// CHECK-NEXT: "{{.*}}tu_no_integrated_cpp{{.*}}.i" +// CHECK: "-E" +// CHECK: ] +// CHECK-NEXT: "executable": "clang_tool" +// CHECK: "input-file": "[[PREFIX]]{{.}}tu_no_integrated_cpp.c" +// CHECK-NEXT: } +// CHECK-NEXT: { +// CHECK-NEXT: "clang-context-hash": +// CHECK-NEXT: "clang-module-deps": [] +// CHECK-NEXT: "command-line": [ +// CHECK-NEXT: "-cc1" +// CHECK: "-o" +// CHECK-NEXT: "{{.*}}tu_no_integrated_cpp.o" +// CHECK: "-emit-obj" +// CHECK: "{{.*}}tu_no_integrated_cpp{{.*}}.i" +// CHECK: ] +// CHECK-NEXT: "executable": "clang_tool" +// CHECK: "input-file": "[[PREFIX]]{{.}}tu_no_integrated_cpp.c" +// CHECK-NEXT: } +// CHECK-NEXT: ] +// CHECK-NEXT: } +// CHECK-NEXT: { +// CHECK-NEXT: "commands": [ +// CHECK-NEXT: { +// CHECK: "clang-module-deps": [ +// CHECK-NEXT: { +// CHECK: "module-name": "Mod" +// CHECK-NEXT: } +// CHECK-NEXT: ] +// CHECK-NEXT: "command-line": [ +// CHECK-NEXT: "-cc1" +// CHECK: "-o" +// CHECK-NEXT: "{{.*}}tu_save_temps_module.i" +// CHECK: "-E" +// CHECK: "-fmodule-file={{.*}}[[PREFIX]]{{.}}modules{{.*}}Mod-{{.*}}.pcm" +// CHECK: "{{.*}}tu_save_temps_module.c" +// CHECK: ] +// CHECK-NEXT: "executable": "clang_tool" +// CHECK: "input-file": "[[PREFIX]]{{.}}tu_save_temps_module.c" +// CHECK-NEXT: } +// CHECK-NEXT: { +// CHECK: "clang-module-deps": [ +// CHECK-NEXT: { +// CHECK: "module-name": "Mod" +// CHECK-NEXT: } +// CHECK-NEXT: ] +// CHECK-NEXT: "command-line": [ +// CHECK-NEXT: "-cc1" +// CHECK: "-o" +// CHECK-NEXT: "{{.*}}tu_save_temps_module.bc" +// CHECK: "-emit-llvm-bc" +// CHECK: "{{.*}}tu_save_temps_module.i" +// CHECK: "-fmodule-file={{.*}}[[PREFIX]]{{.}}modules{{.*}}Mod-{{.*}}.pcm" +// CHECK: ] +// CHECK-NEXT: "executable": "clang_tool" +// CHECK: "input-file": "[[PREFIX]]{{.}}tu_save_temps_module.c" +// CHECK-NEXT: } +// CHECK-NEXT: { +// CHECK: "clang-module-deps": [ +// CHECK-NEXT: { +// CHECK: "module-name": "Mod" +// CHECK-NEXT: } +// CHECK-NEXT: ] +// CHECK-NEXT: "command-line": [ +// CHECK-NEXT: "-cc1" +// CHECK: "-o" +// CHECK-NEXT: "{{.*}}tu_save_temps_module.s" +// CHECK: "-S" +// CHECK: "{{.*}}tu_save_temps_module.bc" +// CHECK: ] +// CHECK-NEXT: "executable": "clang_tool" +// CHECK: "input-file": "[[PREFIX]]{{.}}tu_save_temps_module.c" +// CHECK-NEXT: } +// CHECK-NEXT: { +// CHECK: "clang-module-deps": [ +// CHECK-NEXT: { +// CHECK: "module-name": "Mod" +// CHECK-NEXT: } +// CHECK-NEXT: ] +// CHECK-NEXT: "command-line": [ +// CHECK-NEXT: "-cc1as" +// CHECK: "-o" +// CHECK-NEXT: "{{.*}}tu_save_temps_module.o" +// CHECK: "{{.*}}tu_save_temps_module.s" +// CHECK: ] +// CHECK-NEXT: "executable": "clang_tool" +// CHECK: "input-file": "[[PREFIX]]{{.}}tu_save_temps_module.c" +// CHECK-NEXT: } +// CHECK-NEXT: ] +// CHECK-NEXT: } +// CHECK-NEXT: ] + + +//--- cdb.json.in +[ + { + "directory": "DIR" + "command": "clang_tool -c DIR/tu_no_integrated_cpp.c -no-integrated-cpp -o DIR/tu_no_integrated_cpp.o" + "file": "DIR/tu_no_integrated_cpp.c" + }, + { + "directory": "DIR" + "command": "clang_tool -c DIR/tu_save_temps_module.c -save-temps=obj -o DIR/tu_save_temps_module.o -fmodules -fimplicit-modules -fimplicit-module-maps" + "file": "DIR/tu_save_temps_module.c" + } +] + +//--- plain_header.h +void foo(void); + +//--- module_header.h +void bar(void); + +//--- module.modulemap +module Mod { header "module_header.h" } + +//--- tu_no_integrated_cpp.c +#include "plain_header.h" +void tu_no_integrated_cpp(void) { foo(); } + +//--- tu_save_temps_module.c +#include "module_header.h" +void tu_save_temps(void) { bar(); } Index: clang/test/ClangScanDeps/modules-pch.c =================================================================== --- clang/test/ClangScanDeps/modules-pch.c +++ clang/test/ClangScanDeps/modules-pch.c @@ -61,7 +61,7 @@ // CHECK-PCH-NEXT: ], // CHECK-PCH-NEXT: "translation-units": [ // CHECK-PCH-NEXT: { -// CHECK-PCH-NEXT: "clang-context-hash": "[[HASH_PCH:.*]]", +// CHECK-PCH: "clang-context-hash": "[[HASH_PCH:.*]]", // CHECK-PCH-NEXT: "clang-module-deps": [ // CHECK-PCH-NEXT: { // CHECK-PCH-NEXT: "context-hash": "[[HASH_MOD_COMMON_1]]", @@ -74,13 +74,11 @@ // CHECK-PCH-NEXT: ], // CHECK-PCH-NEXT: "command-line": [ // CHECK-PCH: ], -// CHECK-PCH-NEXT: "file-deps": [ +// CHECK-PCH: "file-deps": [ // CHECK-PCH-NEXT: "[[PREFIX]]/pch.h" // CHECK-PCH-NEXT: ], // CHECK-PCH-NEXT: "input-file": "[[PREFIX]]/pch.h" // CHECK-PCH-NEXT: } -// CHECK-PCH-NEXT: ] -// CHECK-PCH-NEXT: } // Explicitly build the PCH: // @@ -118,7 +116,7 @@ // CHECK-TU-NEXT: ], // CHECK-TU-NEXT: "translation-units": [ // CHECK-TU-NEXT: { -// CHECK-TU-NEXT: "clang-context-hash": "[[HASH_TU:.*]]", +// CHECK-TU: "clang-context-hash": "[[HASH_TU:.*]]", // CHECK-TU-NEXT: "clang-module-deps": [ // CHECK-TU-NEXT: { // CHECK-TU-NEXT: "context-hash": "[[HASH_MOD_TU]]", @@ -127,14 +125,12 @@ // CHECK-TU-NEXT: ], // CHECK-TU-NEXT: "command-line": [ // CHECK-TU: ], -// CHECK-TU-NEXT: "file-deps": [ +// CHECK-TU: "file-deps": [ // CHECK-TU-NEXT: "[[PREFIX]]/tu.c", // CHECK-TU-NEXT: "[[PREFIX]]/pch.h.gch" // CHECK-TU-NEXT: ], // CHECK-TU-NEXT: "input-file": "[[PREFIX]]/tu.c" // CHECK-TU-NEXT: } -// CHECK-TU-NEXT: ] -// CHECK-TU-NEXT: } // Explicitly build the TU: // @@ -168,7 +164,7 @@ // CHECK-TU-WITH-COMMON-NEXT: ], // CHECK-TU-WITH-COMMON-NEXT: "translation-units": [ // CHECK-TU-WITH-COMMON-NEXT: { -// CHECK-TU-WITH-COMMON-NEXT: "clang-context-hash": "[[HASH_TU_WITH_COMMON:.*]]", +// CHECK-TU-WITH-COMMON: "clang-context-hash": "[[HASH_TU_WITH_COMMON:.*]]", // CHECK-TU-WITH-COMMON-NEXT: "clang-module-deps": [ // CHECK-TU-WITH-COMMON-NEXT: { // CHECK-TU-WITH-COMMON-NEXT: "context-hash": "[[HASH_MOD_TU_WITH_COMMON]]", @@ -178,14 +174,12 @@ // CHECK-TU-WITH-COMMON-NEXT: "command-line": [ // CHECK-TU-WITH-COMMON: "-fmodule-file=[[PREFIX]]/build/{{.*}}/ModCommon2-{{.*}}.pcm" // CHECK-TU-WITH-COMMON: ], -// CHECK-TU-WITH-COMMON-NEXT: "file-deps": [ +// CHECK-TU-WITH-COMMON: "file-deps": [ // CHECK-TU-WITH-COMMON-NEXT: "[[PREFIX]]/tu_with_common.c", // CHECK-TU-WITH-COMMON-NEXT: "[[PREFIX]]/pch.h.gch" // CHECK-TU-WITH-COMMON-NEXT: ], // CHECK-TU-WITH-COMMON-NEXT: "input-file": "[[PREFIX]]/tu_with_common.c" // CHECK-TU-WITH-COMMON-NEXT: } -// CHECK-TU-WITH-COMMON-NEXT: ] -// CHECK-TU-WITH-COMMON-NEXT: } // Explicitly build the TU that has common modules with the PCH: // Index: clang/test/ClangScanDeps/modules-pch-common-via-submodule.c =================================================================== --- clang/test/ClangScanDeps/modules-pch-common-via-submodule.c +++ clang/test/ClangScanDeps/modules-pch-common-via-submodule.c @@ -32,7 +32,7 @@ // CHECK-PCH-NEXT: ], // CHECK-PCH-NEXT: "translation-units": [ // CHECK-PCH-NEXT: { -// CHECK-PCH-NEXT: "clang-context-hash": "[[HASH_PCH:.*]]", +// CHECK-PCH: "clang-context-hash": "[[HASH_PCH:.*]]", // CHECK-PCH-NEXT: "clang-module-deps": [ // CHECK-PCH-NEXT: { // CHECK-PCH-NEXT: "context-hash": "[[HASH_MOD_COMMON]]", @@ -41,13 +41,11 @@ // CHECK-PCH-NEXT: ], // CHECK-PCH-NEXT: "command-line": [ // CHECK-PCH: ], -// CHECK-PCH-NEXT: "file-deps": [ +// CHECK-PCH: "file-deps": [ // CHECK-PCH-NEXT: "[[PREFIX]]/pch.h" // CHECK-PCH-NEXT: ], // CHECK-PCH-NEXT: "input-file": "[[PREFIX]]/pch.h" // CHECK-PCH-NEXT: } -// CHECK-PCH-NEXT: ] -// CHECK-PCH-NEXT: } // Explicitly build the PCH: // @@ -82,7 +80,7 @@ // CHECK-TU-NEXT: ], // CHECK-TU-NEXT: "translation-units": [ // CHECK-TU-NEXT: { -// CHECK-TU-NEXT: "clang-context-hash": "[[HASH_TU:.*]]", +// CHECK-TU: "clang-context-hash": "[[HASH_TU:.*]]", // CHECK-TU-NEXT: "clang-module-deps": [ // CHECK-TU-NEXT: { // CHECK-TU-NEXT: "context-hash": "[[HASH_MOD_TU]]" @@ -91,14 +89,12 @@ // CHECK-TU-NEXT: ], // CHECK-TU-NEXT: "command-line": [ // CHECK-TU: ], -// CHECK-TU-NEXT: "file-deps": [ +// CHECK-TU: "file-deps": [ // CHECK-TU-NEXT: "[[PREFIX]]/tu.c", // CHECK-TU-NEXT: "[[PREFIX]]/pch.h.gch" // CHECK-TU-NEXT: ], // CHECK-TU-NEXT: "input-file": "[[PREFIX]]/tu.c" // CHECK-TU-NEXT: } -// CHECK-TU-NEXT: ] -// CHECK-TU-NEXT: } // Explicitly build the TU: // Index: clang/test/ClangScanDeps/modules-pch-common-submodule.c =================================================================== --- clang/test/ClangScanDeps/modules-pch-common-submodule.c +++ clang/test/ClangScanDeps/modules-pch-common-submodule.c @@ -36,7 +36,7 @@ // CHECK-PCH-NEXT: ], // CHECK-PCH-NEXT: "translation-units": [ // CHECK-PCH-NEXT: { -// CHECK-PCH-NEXT: "clang-context-hash": "[[HASH_PCH:.*]]", +// CHECK-PCH: "clang-context-hash": "[[HASH_PCH:.*]]", // CHECK-PCH-NEXT: "clang-module-deps": [ // CHECK-PCH-NEXT: { // CHECK-PCH-NEXT: "context-hash": "[[HASH_MOD_COMMON]]", @@ -45,13 +45,11 @@ // CHECK-PCH-NEXT: ], // CHECK-PCH-NEXT: "command-line": [ // CHECK-PCH: ], -// CHECK-PCH-NEXT: "file-deps": [ +// CHECK-PCH: "file-deps": [ // CHECK-PCH-NEXT: "[[PREFIX]]/pch.h" // CHECK-PCH-NEXT: ], // CHECK-PCH-NEXT: "input-file": "[[PREFIX]]/pch.h" // CHECK-PCH-NEXT: } -// CHECK-PCH-NEXT: ] -// CHECK-PCH-NEXT: } // Explicitly build the PCH: // @@ -85,7 +83,7 @@ // CHECK-TU-NEXT: ], // CHECK-TU-NEXT: "translation-units": [ // CHECK-TU-NEXT: { -// CHECK-TU-NEXT: "clang-context-hash": "[[HASH_TU:.*]]", +// CHECK-TU: "clang-context-hash": "[[HASH_TU:.*]]", // CHECK-TU-NEXT: "clang-module-deps": [ // CHECK-TU-NEXT: { // CHECK-TU-NEXT: "context-hash": "[[HASH_MOD_TU]]" @@ -94,14 +92,12 @@ // CHECK-TU-NEXT: ], // CHECK-TU-NEXT: "command-line": [ // CHECK-TU: ], -// CHECK-TU-NEXT: "file-deps": [ +// CHECK-TU: "file-deps": [ // CHECK-TU-NEXT: "[[PREFIX]]/tu.c", // CHECK-TU-NEXT: "[[PREFIX]]/pch.h.gch" // CHECK-TU-NEXT: ], // CHECK-TU-NEXT: "input-file": "[[PREFIX]]/tu.c" // CHECK-TU-NEXT: } -// CHECK-TU-NEXT: ] -// CHECK-TU-NEXT: } // Explicitly build the TU: // Index: clang/test/ClangScanDeps/modules-no-undeclared-includes.c =================================================================== --- clang/test/ClangScanDeps/modules-no-undeclared-includes.c +++ clang/test/ClangScanDeps/modules-no-undeclared-includes.c @@ -52,7 +52,7 @@ // CHECK-NEXT: ], // CHECK-NEXT: "translation-units": [ // CHECK-NEXT: { -// CHECK-NEXT: "clang-context-hash": "{{.*}}" +// CHECK: "clang-context-hash": "{{.*}}" // CHECK-NEXT: "clang-module-deps": [ // CHECK-NEXT: { // CHECK-NEXT: "context-hash": "{{.*}}" @@ -61,13 +61,11 @@ // CHECK-NEXT: ], // CHECK-NEXT: "command-line": [ // CHECK: ], -// CHECK-NEXT: "file-deps": [ +// CHECK: "file-deps": [ // CHECK-NEXT: "[[PREFIX]]/test.c" // CHECK-NEXT: ], // CHECK-NEXT: "input-file": "[[PREFIX]]/test.c" // CHECK-NEXT: } -// CHECK: ] -// CHECK-NEXT: } // RUN: %deps-to-rsp %t/result.json --module-name=User > %t/User.cc1.rsp // RUN: %deps-to-rsp %t/result.json --tu-index=0 > %t/tu.rsp Index: clang/test/ClangScanDeps/modules-inferred.m =================================================================== --- clang/test/ClangScanDeps/modules-inferred.m +++ clang/test/ClangScanDeps/modules-inferred.m @@ -31,7 +31,7 @@ // CHECK-NEXT: ], // CHECK-NEXT: "translation-units": [ // CHECK-NEXT: { -// CHECK-NEXT: "clang-context-hash": "[[HASH_TU:[A-Z0-9]+]]", +// CHECK: "clang-context-hash": "[[HASH_TU:[A-Z0-9]+]]", // CHECK-NEXT: "clang-module-deps": [ // CHECK-NEXT: { // CHECK-NEXT: "context-hash": "[[HASH_INFERRED]]", @@ -40,10 +40,8 @@ // CHECK-NEXT: ], // CHECK-NEXT: "command-line": [ // CHECK: ], -// CHECK-NEXT: "file-deps": [ +// CHECK: "file-deps": [ // CHECK-NEXT: "[[PREFIX]]/modules_cdb_input.cpp" // CHECK-NEXT: ], // CHECK-NEXT: "input-file": "[[PREFIX]]/modules_cdb_input.cpp" // CHECK-NEXT: } -// CHECK-NEXT: ] -// CHECK-NEXT: } Index: clang/test/ClangScanDeps/modules-incomplete-umbrella.c =================================================================== --- clang/test/ClangScanDeps/modules-incomplete-umbrella.c +++ clang/test/ClangScanDeps/modules-incomplete-umbrella.c @@ -67,7 +67,7 @@ // CHECK_TU-NEXT: ], // CHECK_TU-NEXT: "translation-units": [ // CHECK_TU-NEXT: { -// CHECK_TU-NEXT: "clang-context-hash": "{{.*}}", +// CHECK_TU: "clang-context-hash": "{{.*}}", // CHECK_TU-NEXT: "clang-module-deps": [ // CHECK_TU-NEXT: { // CHECK_TU-NEXT: "context-hash": "{{.*}}", @@ -82,14 +82,12 @@ // CHECK_TU: "-fmodule-file={{.*}}/FW-{{.*}}.pcm" // CHECK_TU: "-fmodule-file={{.*}}/FW_Private-{{.*}}.pcm" // CHECK_TU: ], -// CHECK_TU-NEXT: "file-deps": [ +// CHECK_TU: "file-deps": [ // CHECK_TU-NEXT: "[[PREFIX]]/from_tu.m", // CHECK_TU-NEXT: "[[PREFIX]]/frameworks/FW.framework/PrivateHeaders/Two.h" // CHECK_TU-NEXT: ], // CHECK_TU-NEXT: "input-file": "[[PREFIX]]/from_tu.m" // CHECK_TU-NEXT: } -// CHECK_TU-NEXT: ] -// CHECK_TU-NEXT: } // RUN: %deps-to-rsp %t/from_tu_result.json --module-name=FW > %t/FW.cc1.rsp // RUN: %deps-to-rsp %t/from_tu_result.json --module-name=FW_Private > %t/FW_Private.cc1.rsp @@ -175,7 +173,7 @@ // CHECK_MODULE-NEXT: ], // CHECK_MODULE-NEXT: "translation-units": [ // CHECK_MODULE-NEXT: { -// CHECK_MODULE-NEXT: "clang-context-hash": "{{.*}}", +// CHECK_MODULE: "clang-context-hash": "{{.*}}", // CHECK_MODULE-NEXT: "clang-module-deps": [ // CHECK_MODULE-NEXT: { // CHECK_MODULE-NEXT: "context-hash": "{{.*}}", @@ -184,13 +182,11 @@ // CHECK_MODULE-NEXT: ], // CHECK_MODULE-NEXT: "command-line": [ // CHECK_MODULE: ], -// CHECK_MODULE-NEXT: "file-deps": [ +// CHECK_MODULE: "file-deps": [ // CHECK_MODULE-NEXT: "[[PREFIX]]/from_module.m" // CHECK_MODULE-NEXT: ], // CHECK_MODULE-NEXT: "input-file": "[[PREFIX]]/from_module.m" // CHECK_MODULE-NEXT: } -// CHECK_MODULE-NEXT: ] -// CHECK_MODULE-NEXT: } // RUN: %deps-to-rsp %t/from_module_result.json --module-name=FW > %t/FW.cc1.rsp // RUN: %deps-to-rsp %t/from_module_result.json --module-name=FW_Private > %t/FW_Private.cc1.rsp Index: clang/test/ClangScanDeps/modules-implicit-dot-private.m =================================================================== --- clang/test/ClangScanDeps/modules-implicit-dot-private.m +++ clang/test/ClangScanDeps/modules-implicit-dot-private.m @@ -26,35 +26,35 @@ // CHECK: { // CHECK-NEXT: "modules": [ // CHECK-NEXT: { -// CHECK-NEXT: "clang-module-deps": [], +// CHECK: "clang-module-deps": [], // CHECK-NEXT: "clang-modulemap-file": "[[PREFIX]]/frameworks/FW.framework/Modules/module.modulemap", // CHECK-NEXT: "command-line": [ // CHECK: ], // CHECK-NEXT: "context-hash": "{{.*}}", -// CHECK-NEXT: "file-deps": [ +// CHECK: "file-deps": [ // CHECK-NEXT: "[[PREFIX]]/frameworks/FW.framework/Headers/FW.h", // CHECK-NEXT: "[[PREFIX]]/frameworks/FW.framework/Modules/module.modulemap", // CHECK-NEXT: "[[PREFIX]]/frameworks/FW.framework/Modules/module.private.modulemap" // CHECK-NEXT: ], // CHECK-NEXT: "name": "FW" -// CHECK-NEXT: }, -// CHECK-NEXT: { -// CHECK-NEXT: "clang-module-deps": [], +// CHECK: }, +// CHECK: { +// CHECK: "clang-module-deps": [], // CHECK-NEXT: "clang-modulemap-file": "[[PREFIX]]/frameworks/FW.framework/Modules/module.private.modulemap", // CHECK-NEXT: "command-line": [ // CHECK: ], // CHECK-NEXT: "context-hash": "{{.*}}", -// CHECK-NEXT: "file-deps": [ +// CHECK: "file-deps": [ // CHECK-NEXT: "[[PREFIX]]/frameworks/FW.framework/Modules/module.modulemap", // CHECK-NEXT: "[[PREFIX]]/frameworks/FW.framework/Modules/module.private.modulemap", // CHECK-NEXT: "[[PREFIX]]/frameworks/FW.framework/PrivateHeaders/FW_Private.h" // CHECK-NEXT: ], // CHECK-NEXT: "name": "FW_Private" -// CHECK-NEXT: } -// CHECK-NEXT: ], +// CHECK: } +// CHECK: ], // CHECK-NEXT: "translation-units": [ // CHECK-NEXT: { -// CHECK-NEXT: "clang-context-hash": "{{.*}}", +// CHECK: "clang-context-hash": "{{.*}}", // CHECK-NEXT: "clang-module-deps": [ // CHECK-NEXT: { // CHECK-NEXT: "context-hash": "{{.*}}", @@ -66,16 +66,14 @@ // CHECK-NEXT: } // CHECK-NEXT: ], // CHECK-NEXT: "command-line": [ -// CHECK: "-fmodule-file={{.*}}/FW_Private-{{.*}}.pcm" // CHECK: "-fmodule-file={{.*}}/FW-{{.*}}.pcm" +// CHECK: "-fmodule-file={{.*}}/FW_Private-{{.*}}.pcm" // CHECK: ], -// CHECK-NEXT: "file-deps": [ +// CHECK: "file-deps": [ // CHECK-NEXT: "[[PREFIX]]/tu.m" // CHECK-NEXT: ], // CHECK-NEXT: "input-file": "[[PREFIX]]/tu.m" // CHECK-NEXT: } -// CHECK-NEXT: ] -// CHECK-NEXT: } // RUN: %deps-to-rsp %t/result.json --module-name=FW > %t/FW.cc1.rsp // RUN: %deps-to-rsp %t/result.json --module-name=FW_Private > %t/FW_Private.cc1.rsp Index: clang/test/ClangScanDeps/modules-full.cpp =================================================================== --- clang/test/ClangScanDeps/modules-full.cpp +++ clang/test/ClangScanDeps/modules-full.cpp @@ -82,76 +82,96 @@ // CHECK-NEXT: ], // CHECK-NEXT: "translation-units": [ // CHECK-NEXT: { -// CHECK-NEXT: "clang-context-hash": "[[HASH_TU:[A-Z0-9]+]]", -// CHECK-NEXT: "clang-module-deps": [ +// CHECK-NEXT: "commands": [ // CHECK-NEXT: { -// CHECK-NEXT: "context-hash": "[[HASH_H1]]", -// CHECK-NEXT: "module-name": "header1" +// CHECK-NEXT: "clang-context-hash": "[[HASH_TU:[A-Z0-9]+]]", +// CHECK-NEXT: "clang-module-deps": [ +// CHECK-NEXT: { +// CHECK-NEXT: "context-hash": "[[HASH_H1]]", +// CHECK-NEXT: "module-name": "header1" +// CHECK-NEXT: } +// CHECK-NEXT: ], +// CHECK-NEXT: "command-line": [ +// CHECK-NOT: "-fimplicit-modules" +// CHECK-NOT: "-fimplicit-module-maps" +// CHECK: "-fmodule-file={{.*}}[[PREFIX]]/module-cache{{(_clangcl)?}}/[[HASH_H1]]/header1-{{[A-Z0-9]+}}.pcm" +// CHECK: ], +// CHECK-NEXT: "executable": "{{.*}}clang{{.*}}" +// CHECK-NEXT: "file-deps": [ +// CHECK-NEXT: "[[PREFIX]]/modules_cdb_input.cpp" +// CHECK-NEXT: ], +// CHECK-NEXT: "input-file": "[[PREFIX]]/modules_cdb_input.cpp" // CHECK-NEXT: } -// CHECK-NEXT: ], -// CHECK-NEXT: "command-line": [ -// CHECK: "-fno-implicit-modules" -// CHECK: "-fno-implicit-module-maps" -// CHECK: "-fmodule-file={{.*}}[[PREFIX]]/module-cache{{(_clangcl)?}}/[[HASH_H1]]/header1-{{[A-Z0-9]+}}.pcm" -// CHECK: ], -// CHECK-NEXT: "file-deps": [ -// CHECK-NEXT: "[[PREFIX]]/modules_cdb_input.cpp" -// CHECK-NEXT: ], -// CHECK-NEXT: "input-file": "[[PREFIX]]/modules_cdb_input.cpp" +// CHECK-NEXT: ] // CHECK-NEXT: }, // CHECK-NEXT: { -// CHECK-NEXT: "clang-context-hash": "[[HASH_TU:[A-Z0-9]+]]", -// CHECK-NEXT: "clang-module-deps": [ +// CHECK-NEXT: "commands": [ // CHECK-NEXT: { -// CHECK-NEXT: "context-hash": "[[HASH_H1]]", -// CHECK-NEXT: "module-name": "header1" +// CHECK-NEXT: "clang-context-hash": "[[HASH_TU:[A-Z0-9]+]]", +// CHECK-NEXT: "clang-module-deps": [ +// CHECK-NEXT: { +// CHECK-NEXT: "context-hash": "[[HASH_H1]]", +// CHECK-NEXT: "module-name": "header1" +// CHECK-NEXT: } +// CHECK-NEXT: ], +// CHECK-NEXT: "command-line": [ +// CHECK-NOT: "-fimplicit-modules" +// CHECK-NOT: "-fimplicit-module-maps" +// CHECK: "-fmodule-file={{.*}}[[PREFIX]]/module-cache{{(_clangcl)?}}/[[HASH_H1]]/header1-{{[A-Z0-9]+}}.pcm" +// CHECK: ], +// CHECK-NEXT: "executable": "{{.*}}clang{{.*}}" +// CHECK-NEXT: "file-deps": [ +// CHECK-NEXT: "[[PREFIX]]/modules_cdb_input.cpp" +// CHECK-NEXT: ], +// CHECK-NEXT: "input-file": "[[PREFIX]]/modules_cdb_input.cpp" // CHECK-NEXT: } -// CHECK-NEXT: ], -// CHECK-NEXT: "command-line": [ -// CHECK: "-fno-implicit-modules" -// CHECK: "-fno-implicit-module-maps" -// CHECK: "-fmodule-file={{.*}}[[PREFIX]]/module-cache{{(_clangcl)?}}/[[HASH_H1]]/header1-{{[A-Z0-9]+}}.pcm" -// CHECK: ], -// CHECK-NEXT: "file-deps": [ -// CHECK-NEXT: "[[PREFIX]]/modules_cdb_input.cpp" -// CHECK-NEXT: ], -// CHECK-NEXT: "input-file": "[[PREFIX]]/modules_cdb_input.cpp" +// CHECK-NEXT: ] // CHECK-NEXT: }, // CHECK-NEXT: { -// CHECK-NEXT: "clang-context-hash": "[[HASH_TU:[A-Z0-9]+]]", -// CHECK-NEXT: "clang-module-deps": [ +// CHECK-NEXT: "commands": [ // CHECK-NEXT: { -// CHECK-NEXT: "context-hash": "[[HASH_H1]]", -// CHECK-NEXT: "module-name": "header1" +// CHECK-NEXT: "clang-context-hash": "[[HASH_TU:[A-Z0-9]+]]", +// CHECK-NEXT: "clang-module-deps": [ +// CHECK-NEXT: { +// CHECK-NEXT: "context-hash": "[[HASH_H1]]", +// CHECK-NEXT: "module-name": "header1" +// CHECK-NEXT: } +// CHECK-NEXT: ], +// CHECK-NEXT: "command-line": [ +// CHECK-NOT: "-fimplicit-modules" +// CHECK-NOT: "-fimplicit-module-maps" +// CHECK: "-fmodule-file={{.*}}[[PREFIX]]/module-cache{{(_clangcl)?}}/[[HASH_H1]]/header1-{{[A-Z0-9]+}}.pcm" +// CHECK: ], +// CHECK-NEXT: "executable": "{{.*}}clang{{.*}}" +// CHECK-NEXT: "file-deps": [ +// CHECK-NEXT: "[[PREFIX]]/modules_cdb_input.cpp" +// CHECK-NEXT: ], +// CHECK-NEXT: "input-file": "[[PREFIX]]/modules_cdb_input.cpp" // CHECK-NEXT: } -// CHECK-NEXT: ], -// CHECK-NEXT: "command-line": [ -// CHECK: "-fno-implicit-modules" -// CHECK: "-fno-implicit-module-maps" -// CHECK: "-fmodule-file={{.*}}[[PREFIX]]/module-cache{{(_clangcl)?}}/[[HASH_H1]]/header1-{{[A-Z0-9]+}}.pcm" -// CHECK: ], -// CHECK-NEXT: "file-deps": [ -// CHECK-NEXT: "[[PREFIX]]/modules_cdb_input.cpp" -// CHECK-NEXT: ], -// CHECK-NEXT: "input-file": "[[PREFIX]]/modules_cdb_input.cpp" +// CHECK-NEXT: ] // CHECK-NEXT: }, // CHECK-NEXT: { -// CHECK-NEXT: "clang-context-hash": "[[HASH_TU_DINCLUDE:[A-Z0-9]+]]", -// CHECK-NEXT: "clang-module-deps": [ +// CHECK-NEXT: "commands": [ // CHECK-NEXT: { -// CHECK-NEXT: "context-hash": "[[HASH_H1_DINCLUDE]]", -// CHECK-NEXT: "module-name": "header1" +// CHECK-NEXT: "clang-context-hash": "[[HASH_TU_DINCLUDE:[A-Z0-9]+]]", +// CHECK-NEXT: "clang-module-deps": [ +// CHECK-NEXT: { +// CHECK-NEXT: "context-hash": "[[HASH_H1_DINCLUDE]]", +// CHECK-NEXT: "module-name": "header1" +// CHECK-NEXT: } +// CHECK-NEXT: ], +// CHECK-NEXT: "command-line": [ +// CHECK-NOT: "-fimplicit-modules" +// CHECK-NOT: "-fimplicit-module-maps" +// CHECK: "-fmodule-file={{.*}}[[PREFIX]]/module-cache{{(_clangcl)?}}/[[HASH_H1_DINCLUDE]]/header1-{{[A-Z0-9]+}}.pcm" +// CHECK: ], +// CHECK-NEXT: "executable": "{{.*}}clang{{.*}}" +// CHECK-NEXT: "file-deps": [ +// CHECK-NEXT: "[[PREFIX]]/modules_cdb_input2.cpp" +// CHECK-NEXT: ], +// CHECK-NEXT: "input-file": "[[PREFIX]]/modules_cdb_input2.cpp" // CHECK-NEXT: } -// CHECK-NEXT: ], -// CHECK-NEXT: "command-line": [ -// CHECK: "-fno-implicit-modules" -// CHECK: "-fno-implicit-module-maps" -// CHECK: "-fmodule-file={{.*}}[[PREFIX]]/module-cache{{(_clangcl)?}}/[[HASH_H1_DINCLUDE]]/header1-{{[A-Z0-9]+}}.pcm" -// CHECK: ], -// CHECK-NEXT: "file-deps": [ -// CHECK-NEXT: "[[PREFIX]]/modules_cdb_input2.cpp" -// CHECK-NEXT: ], -// CHECK-NEXT: "input-file": "[[PREFIX]]/modules_cdb_input2.cpp" +// CHECK-NEXT: ] // CHECK-NEXT: } // CHECK-NEXT: ] // CHECK-NEXT: } Index: clang/test/ClangScanDeps/modules-fmodule-name-no-module-built.m =================================================================== --- clang/test/ClangScanDeps/modules-fmodule-name-no-module-built.m +++ clang/test/ClangScanDeps/modules-fmodule-name-no-module-built.m @@ -33,7 +33,7 @@ // CHECK-NEXT: ], // CHECK-NEXT: "translation-units": [ // CHECK-NEXT: { -// CHECK-NEXT: "clang-context-hash": "[[HASH_TU:[A-Z0-9]+]]", +// CHECK: "clang-context-hash": "[[HASH_TU:[A-Z0-9]+]]", // CHECK-NEXT: "clang-module-deps": [ // CHECK-NEXT: { // CHECK-NEXT: "context-hash": "[[HASH_H2]]", @@ -42,12 +42,10 @@ // CHECK-NEXT: ], // CHECK-NEXT: "command-line": [ // CHECK: ], -// CHECK-NEXT: "file-deps": [ +// CHECK: "file-deps": [ // CHECK-NEXT: "[[PREFIX]]/modules-fmodule-name-no-module-built.m" // CHECK-NEXT: "[[PREFIX]]/Inputs/header3.h" // CHECK-NEXT: "[[PREFIX]]/Inputs/header.h" // CHECK-NEXT: ], // CHECK-NEXT: "input-file": "[[PREFIX]]/modules-fmodule-name-no-module-built.m" // CHECK-NEXT: } -// CHECK-NEXT: ] -// CHECK-NEXT: } Index: clang/test/ClangScanDeps/modules-dep-args.c =================================================================== --- clang/test/ClangScanDeps/modules-dep-args.c +++ clang/test/ClangScanDeps/modules-dep-args.c @@ -78,7 +78,7 @@ // CHECK-NEXT: ], // CHECK-NEXT: "translation-units": [ // CHECK-NEXT: { -// CHECK-NEXT: "clang-context-hash": "{{.*}}", +// CHECK: "clang-context-hash": "{{.*}}", // CHECK-NEXT: "clang-module-deps": [ // CHECK-NEXT: { // CHECK-NEXT: "context-hash": "{{.*}}", @@ -93,10 +93,8 @@ // CHECK_EAGER-NOT: "-fmodule-map-file={{.*}}" // CHECK_EAGER: "-fmodule-file=[[PREFIX]]/{{.*}}/Direct-{{.*}}.pcm" // CHECK: ], -// CHECK-NEXT: "file-deps": [ +// CHECK: "file-deps": [ // CHECK-NEXT: "[[PREFIX]]/tu.c" // CHECK-NEXT: ], // CHECK-NEXT: "input-file": "[[PREFIX]]/tu.c" // CHECK-NEXT: } -// CHECK-NEXT: ] -// CHECK-NEXT: } \ No newline at end of file Index: clang/test/ClangScanDeps/modules-context-hash.c =================================================================== --- clang/test/ClangScanDeps/modules-context-hash.c +++ clang/test/ClangScanDeps/modules-context-hash.c @@ -40,7 +40,7 @@ // CHECK-NEXT: ], // CHECK-NEXT: "translation-units": [ // CHECK-NEXT: { -// CHECK-NEXT: "clang-context-hash": "{{.*}}", +// CHECK: "clang-context-hash": "{{.*}}", // CHECK-NEXT: "clang-module-deps": [ // CHECK-NEXT: { // CHECK-NEXT: "context-hash": "[[HASH_MOD_A]]", @@ -49,15 +49,13 @@ // CHECK-NEXT: ], // CHECK-NEXT: "command-line": [ // CHECK: ], -// CHECK-NEXT: "file-deps": [ +// CHECK: "file-deps": [ // CHECK-NEXT: "[[PREFIX]]/tu.c" // CHECK-NEXT: ], // CHECK-NEXT: "input-file": "[[PREFIX]]/tu.c" // CHECK-NEXT: } -// CHECK-NEXT: ] -// CHECK-NEXT: } -// CHECK-NEXT: { -// CHECK-NEXT: "modules": [ + +// CHECK: "modules": [ // CHECK-NEXT: { // CHECK-NEXT: "clang-module-deps": [], // CHECK-NEXT: "clang-modulemap-file": "[[PREFIX]]/module.modulemap", @@ -79,7 +77,7 @@ // CHECK-NEXT: ], // CHECK-NEXT: "translation-units": [ // CHECK-NEXT: { -// CHECK-NEXT: "clang-context-hash": "{{.*}}", +// CHECK: "clang-context-hash": "{{.*}}", // CHECK-NEXT: "clang-module-deps": [ // CHECK-NEXT: { // CHECK-NOT: "context-hash": "[[HASH_MOD_A]]", @@ -88,10 +86,8 @@ // CHECK-NEXT: ], // CHECK-NEXT: "command-line": [ // CHECK: ], -// CHECK-NEXT: "file-deps": [ +// CHECK: "file-deps": [ // CHECK-NEXT: "[[PREFIX]]/tu.c" // CHECK-NEXT: ], // CHECK-NEXT: "input-file": "[[PREFIX]]/tu.c" // CHECK-NEXT: } -// CHECK-NEXT: ] -// CHECK-NEXT: } Index: clang/test/ClangScanDeps/modules-context-hash-warnings.c =================================================================== --- clang/test/ClangScanDeps/modules-context-hash-warnings.c +++ clang/test/ClangScanDeps/modules-context-hash-warnings.c @@ -39,7 +39,7 @@ // CHECK: ] // CHECK: "input-file": "{{.*}}tu1.c" // CHECK-NEXT: } -// CHECK-NEXT: { +// CHECK: { // CHECK: "clang-module-deps": [ // CHECK-NEXT: { // CHECK-NEXT: "context-hash": "[[HASH2]]" Index: clang/test/ClangScanDeps/modules-context-hash-outputs.c =================================================================== --- clang/test/ClangScanDeps/modules-context-hash-outputs.c +++ clang/test/ClangScanDeps/modules-context-hash-outputs.c @@ -35,11 +35,11 @@ // CHECK-NEXT: } // CHECK-NEXT: ] // CHECK-NEXT: "command-line": [ -// CHECK: "-MF" +// CHECK: "-dependency-file" // CHECK: ] // CHECK: "input-file": "{{.*}}tu1.c" // CHECK-NEXT: } -// CHECK-NEXT: { +// CHECK: { // CHECK: "clang-module-deps": [ // CHECK-NEXT: { // CHECK-NEXT: "context-hash": "[[HASH2]]" @@ -48,6 +48,7 @@ // CHECK-NEXT: ] // CHECK-NEXT: "command-line": [ // CHECK-NOT: "-MF" +// CHECK-NOT: "-dependency-file" // CHECK: ] // CHECK: "input-file": "{{.*}}tu2.c" Index: clang/test/ClangScanDeps/modules-context-hash-ignore-macros.c =================================================================== --- clang/test/ClangScanDeps/modules-context-hash-ignore-macros.c +++ clang/test/ClangScanDeps/modules-context-hash-ignore-macros.c @@ -38,10 +38,11 @@ // CHECK-NEXT: ] // CHECK-NEXT: "command-line": [ // CHECK-NOT: "-DFOO" +// CHECK-NOT: "FOO" // CHECK: ] // CHECK: "input-file": "{{.*}}tu1.c" // CHECK-NEXT: } -// CHECK-NEXT: { +// CHECK: { // CHECK: "clang-module-deps": [ // CHECK-NEXT: { // CHECK-NEXT: "context-hash": "[[HASH_FOO]]" @@ -49,11 +50,12 @@ // CHECK-NEXT: } // CHECK-NEXT: ] // CHECK-NEXT: "command-line": [ -// CHECK: "-DFOO" +// CHECK: "-D" +// CHECK-NEXT: "FOO" // CHECK: ] // CHECK: "input-file": "{{.*}}tu2.c" // CHECK-NEXT: } -// CHECK-NEXT: { +// CHECK: { // CHECK: "clang-module-deps": [ // CHECK-NEXT: { // CHECK-NEXT: "context-hash": "[[HASH_NO_FOO]]" @@ -61,8 +63,9 @@ // CHECK-NEXT: } // CHECK-NEXT: ] // CHECK-NEXT: "command-line": [ -// CHECK: "-DFOO" // CHECK: "-fmodules-ignore-macro=FOO" +// CHECK: "-D" +// CHECK-NEXT: "FOO" // CHECK: ] // CHECK: "input-file": "{{.*}}tu3.c" Index: clang/test/ClangScanDeps/header-search-pruning-transitive.c =================================================================== --- clang/test/ClangScanDeps/header-search-pruning-transitive.c +++ clang/test/ClangScanDeps/header-search-pruning-transitive.c @@ -95,7 +95,7 @@ // CHECK-NEXT: ], // CHECK-NEXT: "translation-units": [ // CHECK-NEXT: { -// CHECK-NEXT: "clang-context-hash": "{{.*}}", +// CHECK: "clang-context-hash": "{{.*}}", // CHECK-NEXT: "clang-module-deps": [ // CHECK-NEXT: { // CHECK-NEXT: "context-hash": "[[HASH_X]]", @@ -104,14 +104,13 @@ // CHECK-NEXT: ], // CHECK-NEXT: "command-line": [ // CHECK: ], -// CHECK-NEXT: "file-deps": [ +// CHECK: "file-deps": [ // CHECK-NEXT: "[[PREFIX]]/test.c" // CHECK-NEXT: ], // CHECK-NEXT: "input-file": "[[PREFIX]]/test.c" // CHECK-NEXT: } -// CHECK-NEXT: ] -// CHECK-NEXT: } -// CHECK-NEXT: { + +// CHECK: { // CHECK-NEXT: "modules": [ // CHECK-NEXT: { // CHECK-NEXT: "clang-module-deps": [ @@ -149,7 +148,7 @@ // CHECK-NEXT: ], // CHECK-NEXT: "translation-units": [ // CHECK-NEXT: { -// CHECK-NEXT: "clang-context-hash": "{{.*}}", +// CHECK: "clang-context-hash": "{{.*}}", // CHECK-NEXT: "clang-module-deps": [ // CHECK-NEXT: { // CHECK-NEXT: "context-hash": "{{.*}}", @@ -158,10 +157,8 @@ // CHECK-NEXT: ], // CHECK-NEXT: "command-line": [ // CHECK: ], -// CHECK-NEXT: "file-deps": [ +// CHECK: "file-deps": [ // CHECK-NEXT: "[[PREFIX]]/test.c" // CHECK-NEXT: ], // CHECK-NEXT: "input-file": "[[PREFIX]]/test.c" // CHECK-NEXT: } -// CHECK-NEXT: ] -// CHECK-NEXT: } Index: clang/test/ClangScanDeps/diagnostics.c =================================================================== --- clang/test/ClangScanDeps/diagnostics.c +++ clang/test/ClangScanDeps/diagnostics.c @@ -28,7 +28,7 @@ // CHECK-NEXT: ], // CHECK-NEXT: "translation-units": [ // CHECK-NEXT: { -// CHECK-NEXT: "clang-context-hash": "[[HASH_TU:.*]], +// CHECK: "clang-context-hash": "[[HASH_TU:.*]], // CHECK-NEXT: "clang-module-deps": [ // CHECK-NEXT: { // CHECK-NEXT: "context-hash": "[[HASH_MOD]]", @@ -36,13 +36,11 @@ // CHECK-NEXT: } // CHECK-NEXT: ], // CHECK-NEXT: "command-line": [ -// CHECK: "-fno-implicit-modules" -// CHECK: "-fno-implicit-module-maps" +// CHECK-NOT: "-fimplicit-modules" +// CHECK-NOT: "-fimplicit-module-maps" // CHECK: ], -// CHECK-NEXT: "file-deps": [ +// CHECK: "file-deps": [ // CHECK-NEXT: "[[PREFIX]]/tu.c" // CHECK-NEXT: ], // CHECK-NEXT: "input-file": "[[PREFIX]]/tu.c" // CHECK-NEXT: } -// CHECK-NEXT: ] -// CHECK-NEXT: } Index: clang/test/ClangScanDeps/deprecated-driver-api.c =================================================================== --- /dev/null +++ clang/test/ClangScanDeps/deprecated-driver-api.c @@ -0,0 +1,35 @@ +// RUN: rm -rf %t +// RUN: split-file %s %t +// RUN: sed -e "s|DIR|%/t|g" %t/cdb.json.in > %t/cdb.json + +// RUN: clang-scan-deps -compilation-database=%t/cdb.json -format experimental-full \ +// RUN: -deprecated-driver-command | sed 's:\\\\\?:/:g' | FileCheck %s + +// CHECK: "command-line": [ +// CHECK: "-c" +// CHECK: "{{.*}}tu.c" +// CHECK: "-save-temps" +// CHECK: "-fno-implicit-modules" +// CHECK: "-fno-implicit-module-maps" +// CHECK: ] +// CHECK: "file-deps": [ +// CHECK: "{{.*}}tu.c", +// CHECK: "{{.*}}header.h" +// CHECK: ] + +//--- cdb.json.in +[{ + "directory": "DIR", + "command": "clang -c DIR/tu.c -save-temps", + "file": "DIR/tu.c" +}] + +//--- header.h +void bar(void); + +//--- tu.c +#include "header.h" + +void foo(void) { + bar(); +} Index: clang/lib/Tooling/DependencyScanning/ModuleDepCollector.cpp =================================================================== --- clang/lib/Tooling/DependencyScanning/ModuleDepCollector.cpp +++ clang/lib/Tooling/DependencyScanning/ModuleDepCollector.cpp @@ -174,6 +174,34 @@ } } +static bool needsModules(FrontendInputFile FIF) { + switch (FIF.getKind().getLanguage()) { + case Language::Unknown: + case Language::Asm: + case Language::LLVM_IR: + return false; + default: + return true; + } +} + +void ModuleDepCollector::applyDiscoveredDependencies(CompilerInvocation &CI) { + CI.clearImplicitModuleBuildOptions(); + + if (llvm::any_of(CI.getFrontendOpts().Inputs, needsModules)) { + SmallVector<ModuleID> DirectDeps; + for (const auto &KV : ModularDeps) + if (KV.second->ImportedByMainFile) + DirectDeps.push_back(KV.second->ID); + + addModuleMapFiles(CI, DirectDeps); + addModuleFiles(CI, DirectDeps); + + for (const auto &KV : DirectPrebuiltModularDeps) + CI.getFrontendOpts().ModuleFiles.push_back(KV.second.PCMFile); + } +} + static std::string getModuleContextHash(const ModuleDeps &MD, const CompilerInvocation &CI, bool EagerLoadModules) { @@ -508,7 +536,7 @@ ModuleDepCollector::ModuleDepCollector( std::unique_ptr<DependencyOutputOptions> Opts, CompilerInstance &ScanInstance, DependencyConsumer &C, - CompilerInvocation &&OriginalCI, bool OptimizeArgs, bool EagerLoadModules) + CompilerInvocation OriginalCI, bool OptimizeArgs, bool EagerLoadModules) : ScanInstance(ScanInstance), Consumer(C), Opts(std::move(Opts)), OriginalInvocation(std::move(OriginalCI)), OptimizeArgs(OptimizeArgs), EagerLoadModules(EagerLoadModules) {} Index: clang/lib/Tooling/DependencyScanning/DependencyScanningWorker.cpp =================================================================== --- clang/lib/Tooling/DependencyScanning/DependencyScanningWorker.cpp +++ clang/lib/Tooling/DependencyScanning/DependencyScanningWorker.cpp @@ -7,7 +7,12 @@ //===----------------------------------------------------------------------===// #include "clang/Tooling/DependencyScanning/DependencyScanningWorker.h" +#include "clang/Basic/DiagnosticFrontend.h" #include "clang/CodeGen/ObjectFilePCHContainerOperations.h" +#include "clang/Driver/Compilation.h" +#include "clang/Driver/Driver.h" +#include "clang/Driver/Job.h" +#include "clang/Driver/Tool.h" #include "clang/Frontend/CompilerInstance.h" #include "clang/Frontend/CompilerInvocation.h" #include "clang/Frontend/FrontendActions.h" @@ -17,6 +22,7 @@ #include "clang/Tooling/DependencyScanning/DependencyScanningService.h" #include "clang/Tooling/DependencyScanning/ModuleDepCollector.h" #include "clang/Tooling/Tooling.h" +#include "llvm/Support/Host.h" using namespace clang; using namespace tooling; @@ -156,6 +162,15 @@ // Restore the value of DisableFree, which may be modified by Tooling. OriginalInvocation.getFrontendOpts().DisableFree = DisableFree; + if (Scanned) { + // If we have already scanned an upstream command, just forward to the + // dependency consumer. + forwardInvocationToConsumer(std::move(OriginalInvocation)); + return true; + } + + Scanned = true; + // Create a compiler instance to handle the actual work. CompilerInstance ScanInstance(std::move(PCHContainerOps)); ScanInstance.setInvocation(std::move(Invocation)); @@ -230,9 +245,10 @@ std::move(Opts), WorkingDirectory, Consumer)); break; case ScanningOutputFormat::Full: - ScanInstance.addDependencyCollector(std::make_shared<ModuleDepCollector>( - std::move(Opts), ScanInstance, Consumer, - std::move(OriginalInvocation), OptimizeArgs, EagerLoadModules)); + MDC = std::make_shared<ModuleDepCollector>( + std::move(Opts), ScanInstance, Consumer, OriginalInvocation, + OptimizeArgs, EagerLoadModules); + ScanInstance.addDependencyCollector(MDC); break; } @@ -253,9 +269,23 @@ const bool Result = ScanInstance.ExecuteAction(*Action); if (!DepFS) FileMgr->clearStatCache(); + + if (Result) + forwardInvocationToConsumer(std::move(OriginalInvocation)); + return Result; } + bool hasScanned() const { return Scanned; } + +private: + void forwardInvocationToConsumer(CompilerInvocation &&CI) { + if (MDC) + MDC->applyDiscoveredDependencies(CI); + Consumer.handleBuildCommand(CI.getCodeGenOpts().Argv0, + CI.getCC1CommandLine()); + } + private: StringRef WorkingDirectory; DependencyConsumer &Consumer; @@ -265,6 +295,8 @@ bool EagerLoadModules; bool DisableFree; llvm::Optional<StringRef> ModuleName; + std::shared_ptr<ModuleDepCollector> MDC; + bool Scanned = false; }; } // end anonymous namespace @@ -313,6 +345,36 @@ llvm::inconvertibleErrorCode()); } +static bool forEachDriverJob( + ArrayRef<std::string> Args, DiagnosticsEngine &Diags, FileManager &FM, + llvm::function_ref<bool(const driver::Command &Cmd)> Callback) { + std::unique_ptr<driver::Driver> Driver = std::make_unique<driver::Driver>( + Args[0], llvm::sys::getDefaultTargetTriple(), Diags, + "clang LLVM compiler", &FM.getVirtualFileSystem()); + Driver->setTitle("clang_based_tool"); + + std::vector<const char *> Argv; + for (const std::string &Arg : Args) + Argv.push_back(Arg.c_str()); + + // The "input file not found" diagnostics from the driver are useful. + // The driver is only aware of the VFS working directory, but some clients + // change this at the FileManager level instead. + // In this case the checks have false positives, so skip them. + if (!FM.getFileSystemOpts().WorkingDir.empty()) + Driver->setCheckInputsExist(false); + const std::unique_ptr<driver::Compilation> Compilation( + Driver->BuildCompilation(llvm::makeArrayRef(Argv))); + if (!Compilation) + return false; + + for (const driver::Command &Job : Compilation->getJobs()) { + if (!Callback(Job)) + return false; + } + return true; +} + llvm::Error DependencyScanningWorker::computeDependencies( StringRef WorkingDirectory, const std::vector<std::string> &CommandLine, DependencyConsumer &Consumer, llvm::Optional<StringRef> ModuleName) { @@ -338,25 +400,54 @@ llvm::transform(CommandLine, FinalCCommandLine.begin(), [](const std::string &Str) { return Str.c_str(); }); - return runWithDiags(CreateAndPopulateDiagOpts(FinalCCommandLine).release(), - [&](DiagnosticConsumer &DC, DiagnosticOptions &DiagOpts) { - // DisableFree is modified by Tooling for running - // in-process; preserve the original value, which is - // always true for a driver invocation. - bool DisableFree = true; - DependencyScanningAction Action( - WorkingDirectory, Consumer, DepFS, Format, - OptimizeArgs, EagerLoadModules, DisableFree, - ModuleName); - // Create an invocation that uses the underlying file - // system to ensure that any file system requests that - // are made by the driver do not go through the - // dependency scanning filesystem. - ToolInvocation Invocation(FinalCommandLine, &Action, - CurrentFiles.get(), - PCHContainerOps); - Invocation.setDiagnosticConsumer(&DC); - Invocation.setDiagnosticOptions(&DiagOpts); - return Invocation.run(); - }); + return runWithDiags( + CreateAndPopulateDiagOpts(FinalCCommandLine).release(), + [&](DiagnosticConsumer &DC, DiagnosticOptions &DiagOpts) { + IntrusiveRefCntPtr<DiagnosticsEngine> Diags = + CompilerInstance::createDiagnostics(&DiagOpts, &DC, false); + // Although `Diagnostics` are used only for command-line parsing, the + // custom `DiagConsumer` might expect a `SourceManager` to be present. + SourceManager SrcMgr(*Diags, *CurrentFiles); + Diags->setSourceManager(&SrcMgr); + // DisableFree is modified by Tooling for running + // in-process; preserve the original value, which is + // always true for a driver invocation. + bool DisableFree = true; + DependencyScanningAction Action(WorkingDirectory, Consumer, DepFS, + Format, OptimizeArgs, EagerLoadModules, + DisableFree, ModuleName); + bool Success = forEachDriverJob( + FinalCommandLine, *Diags, *CurrentFiles, + [&](const driver::Command &Cmd) { + if (StringRef(Cmd.getCreator().getName()) != "clang") { + // Non-clang command. Just pass through to the dependency + // consumer. + Consumer.handleBuildCommand( + Cmd.getExecutable(), + {Cmd.getArguments().begin(), Cmd.getArguments().end()}); + return true; + } + + std::vector<std::string> Argv; + Argv.push_back(Cmd.getExecutable()); + Argv.insert(Argv.end(), Cmd.getArguments().begin(), + Cmd.getArguments().end()); + + // Create an invocation that uses the underlying file + // system to ensure that any file system requests that + // are made by the driver do not go through the + // dependency scanning filesystem. + ToolInvocation Invocation(std::move(Argv), &Action, + &*CurrentFiles, PCHContainerOps); + Invocation.setDiagnosticConsumer(Diags->getClient()); + Invocation.setDiagnosticOptions(&Diags->getDiagnosticOptions()); + return Invocation.run(); + }); + + if (Success && !Action.hasScanned()) { + Diags->Report(diag::err_fe_expected_compiler_job) + << llvm::join(FinalCommandLine, " "); + } + return Success && Action.hasScanned(); + }); } Index: clang/lib/Tooling/DependencyScanning/DependencyScanningTool.cpp =================================================================== --- clang/lib/Tooling/DependencyScanning/DependencyScanningTool.cpp +++ clang/lib/Tooling/DependencyScanning/DependencyScanningTool.cpp @@ -45,6 +45,9 @@ /// Prints out all of the gathered dependencies into a string. class MakeDependencyPrinterConsumer : public DependencyConsumer { public: + void handleBuildCommand(std::string Executable, + std::vector<std::string> Args) override {} + void handleDependencyOutputOpts(const DependencyOutputOptions &Opts) override { this->Opts = std::make_unique<DependencyOutputOptions>(Opts); @@ -120,14 +123,53 @@ Worker.computeDependencies(CWD, CommandLine, Consumer, ModuleName); if (Result) return std::move(Result); - return Consumer.getFullDependencies(CommandLine); + return Consumer.takeFullDependencies(); +} + +llvm::Expected<FullDependenciesResult> +DependencyScanningTool::getFullDependenciesLegacyDriverCommand( + const std::vector<std::string> &CommandLine, StringRef CWD, + const llvm::StringSet<> &AlreadySeen, + LookupModuleOutputCallback LookupModuleOutput, + llvm::Optional<StringRef> ModuleName) { + FullDependencyConsumer Consumer(AlreadySeen, LookupModuleOutput, + Worker.shouldEagerLoadModules()); + llvm::Error Result = + Worker.computeDependencies(CWD, CommandLine, Consumer, ModuleName); + if (Result) + return std::move(Result); + return Consumer.getFullDependenciesLegacyDriverCommand(CommandLine); +} + +FullDependenciesResult FullDependencyConsumer::takeFullDependencies() { + FullDependenciesResult FDR; + FullDependencies &FD = FDR.FullDeps; + + FD.ID.ContextHash = std::move(ContextHash); + FD.FileDeps = std::move(Dependencies); + FD.PrebuiltModuleDeps = std::move(PrebuiltModuleDeps); + FD.Commands = std::move(Commands); + + for (auto &&M : ClangModuleDeps) { + auto &MD = M.second; + if (MD.ImportedByMainFile) + FD.ClangModuleDeps.push_back(MD.ID); + // TODO: Avoid handleModuleDependency even being called for modules + // we've already seen. + if (AlreadySeen.count(M.first)) + continue; + FDR.DiscoveredModules.push_back(std::move(MD)); + } + + return FDR; } -FullDependenciesResult FullDependencyConsumer::getFullDependencies( +FullDependenciesResult +FullDependencyConsumer::getFullDependenciesLegacyDriverCommand( const std::vector<std::string> &OriginalCommandLine) const { FullDependencies FD; - FD.CommandLine = makeTUCommandLineWithoutPaths( + FD.DriverCommandLine = makeTUCommandLineWithoutPaths( ArrayRef<std::string>(OriginalCommandLine).slice(1)); FD.ID.ContextHash = std::move(ContextHash); @@ -135,7 +177,7 @@ FD.FileDeps.assign(Dependencies.begin(), Dependencies.end()); for (const PrebuiltModuleDep &PMD : PrebuiltModuleDeps) - FD.CommandLine.push_back("-fmodule-file=" + PMD.PCMFile); + FD.DriverCommandLine.push_back("-fmodule-file=" + PMD.PCMFile); for (auto &&M : ClangModuleDeps) { auto &MD = M.second; @@ -143,11 +185,12 @@ FD.ClangModuleDeps.push_back(MD.ID); auto PCMPath = LookupModuleOutput(MD.ID, ModuleOutputKind::ModuleFile); if (EagerLoadModules) { - FD.CommandLine.push_back("-fmodule-file=" + PCMPath); + FD.DriverCommandLine.push_back("-fmodule-file=" + PCMPath); } else { - FD.CommandLine.push_back("-fmodule-map-file=" + MD.ClangModuleMapFile); - FD.CommandLine.push_back("-fmodule-file=" + MD.ID.ModuleName + "=" + - PCMPath); + FD.DriverCommandLine.push_back("-fmodule-map-file=" + + MD.ClangModuleMapFile); + FD.DriverCommandLine.push_back("-fmodule-file=" + MD.ID.ModuleName + + "=" + PCMPath); } } } Index: clang/include/clang/Tooling/DependencyScanning/ModuleDepCollector.h =================================================================== --- clang/include/clang/Tooling/DependencyScanning/ModuleDepCollector.h +++ clang/include/clang/Tooling/DependencyScanning/ModuleDepCollector.h @@ -181,12 +181,16 @@ public: ModuleDepCollector(std::unique_ptr<DependencyOutputOptions> Opts, CompilerInstance &ScanInstance, DependencyConsumer &C, - CompilerInvocation &&OriginalCI, bool OptimizeArgs, + CompilerInvocation OriginalCI, bool OptimizeArgs, bool EagerLoadModules); void attachToPreprocessor(Preprocessor &PP) override; void attachToASTReader(ASTReader &R) override; + /// Apply any changes implied by the discovered dependencies to the given + /// invocation, (e.g. disable implicit modules, add explicit module paths). + void applyDiscoveredDependencies(CompilerInvocation &CI); + private: friend ModuleDepCollectorPP; Index: clang/include/clang/Tooling/DependencyScanning/DependencyScanningWorker.h =================================================================== --- clang/include/clang/Tooling/DependencyScanning/DependencyScanningWorker.h +++ clang/include/clang/Tooling/DependencyScanning/DependencyScanningWorker.h @@ -23,6 +23,10 @@ class DependencyOutputOptions; +namespace driver { +class Command; +} + namespace tooling { namespace dependencies { @@ -32,6 +36,9 @@ public: virtual ~DependencyConsumer() {} + virtual void handleBuildCommand(std::string Executable, + std::vector<std::string> Args) = 0; + virtual void handleDependencyOutputOpts(const DependencyOutputOptions &Opts) = 0; Index: clang/include/clang/Tooling/DependencyScanning/DependencyScanningTool.h =================================================================== --- clang/include/clang/Tooling/DependencyScanning/DependencyScanningTool.h +++ clang/include/clang/Tooling/DependencyScanning/DependencyScanningTool.h @@ -27,6 +27,14 @@ using LookupModuleOutputCallback = llvm::function_ref<std::string(const ModuleID &, ModuleOutputKind)>; +/// A command-line tool invocation that is part of building a TU. +/// +/// \see FullDependencies::Commands. +struct Command { + std::string Executable; + std::vector<std::string> Arguments; +}; + /// The full dependencies and module graph for a specific input. struct FullDependencies { /// The identifier of the C++20 module this translation unit exports. @@ -49,8 +57,16 @@ /// determined that the differences are benign for this compilation. std::vector<ModuleID> ClangModuleDeps; - /// The command line of the TU (excluding the compiler executable). - std::vector<std::string> CommandLine; + /// The sequence of commands required to build the translation unit. Commands + /// should be executed in order. + /// + /// FIXME: If we add support for multi-arch builds in clang-scan-deps, we + /// should make the dependencies between commands explicit to enable parallel + /// builds of each architecture. + std::vector<Command> Commands; + + /// Deprecated driver command-line. This will be removed in a future version. + std::vector<std::string> DriverCommandLine; }; struct FullDependenciesResult { @@ -99,6 +115,12 @@ LookupModuleOutputCallback LookupModuleOutput, llvm::Optional<StringRef> ModuleName = None); + llvm::Expected<FullDependenciesResult> getFullDependenciesLegacyDriverCommand( + const std::vector<std::string> &CommandLine, StringRef CWD, + const llvm::StringSet<> &AlreadySeen, + LookupModuleOutputCallback LookupModuleOutput, + llvm::Optional<StringRef> ModuleName = None); + private: DependencyScanningWorker Worker; }; @@ -111,6 +133,11 @@ : AlreadySeen(AlreadySeen), LookupModuleOutput(LookupModuleOutput), EagerLoadModules(EagerLoadModules) {} + void handleBuildCommand(std::string Executable, + std::vector<std::string> Args) override { + Commands.push_back({std::move(Executable), std::move(Args)}); + } + void handleDependencyOutputOpts(const DependencyOutputOptions &) override {} void handleFileDependency(StringRef File) override { @@ -134,14 +161,17 @@ return LookupModuleOutput(ID, Kind); } - FullDependenciesResult getFullDependencies( + FullDependenciesResult getFullDependenciesLegacyDriverCommand( const std::vector<std::string> &OriginalCommandLine) const; + FullDependenciesResult takeFullDependencies(); + private: std::vector<std::string> Dependencies; std::vector<PrebuiltModuleDep> PrebuiltModuleDeps; llvm::MapVector<std::string, ModuleDeps, llvm::StringMap<unsigned>> ClangModuleDeps; + std::vector<Command> Commands; std::string ContextHash; std::vector<std::string> OutputPaths; const llvm::StringSet<> &AlreadySeen;
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits