jansvoboda11 created this revision. jansvoboda11 added reviewers: benlangmuir, Bigcheese. Herald added a project: All. jansvoboda11 requested review of this revision. Herald added a project: clang. Herald added a subscriber: cfe-commits.
This patch introduces new option for `clang-scan-deps`: `-eager-load-pcm`. It controlls whether the resulting command-lines will load PCM files eagerly (at the start of compilation) or lazily (when handling import directive). To reduce the potential for churn in LIT tests in the future, this patch removes redundant checks of command-line arguments and introduces new test `modules-dep-args.c`. Repository: rG LLVM Github Monorepo https://reviews.llvm.org/D132066 Files: clang/include/clang/Tooling/DependencyScanning/DependencyScanningService.h 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/DependencyScanningService.cpp clang/lib/Tooling/DependencyScanning/DependencyScanningTool.cpp clang/lib/Tooling/DependencyScanning/DependencyScanningWorker.cpp clang/lib/Tooling/DependencyScanning/ModuleDepCollector.cpp 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-inferred.m clang/test/ClangScanDeps/modules-pch-common-submodule.c clang/test/ClangScanDeps/modules-pch-common-via-submodule.c clang/test/ClangScanDeps/modules-pch.c clang/tools/clang-scan-deps/ClangScanDeps.cpp
Index: clang/tools/clang-scan-deps/ClangScanDeps.cpp =================================================================== --- clang/tools/clang-scan-deps/ClangScanDeps.cpp +++ clang/tools/clang-scan-deps/ClangScanDeps.cpp @@ -151,6 +151,11 @@ llvm::cl::desc("Whether to optimize command-line arguments of modules."), llvm::cl::init(false), llvm::cl::cat(DependencyScannerCategory)); +static llvm::cl::opt<bool> EagerLoadModules( + "eager-load-pcm", + llvm::cl::desc("Load PCM files eagerly (instead of lazily on import)."), + llvm::cl::init(false), llvm::cl::cat(DependencyScannerCategory)); + llvm::cl::opt<unsigned> NumThreads("j", llvm::cl::Optional, llvm::cl::desc("Number of worker threads to use (default: use " @@ -499,7 +504,7 @@ SharedStream DependencyOS(llvm::outs()); DependencyScanningService Service(ScanMode, Format, ReuseFileManager, - OptimizeArgs); + OptimizeArgs, EagerLoadModules); llvm::ThreadPool Pool(llvm::hardware_concurrency(NumThreads)); std::vector<std::unique_ptr<DependencyScanningTool>> WorkerTools; for (unsigned I = 0; I < Pool.getThreadCount(); ++I) Index: clang/test/ClangScanDeps/modules-pch.c =================================================================== --- clang/test/ClangScanDeps/modules-pch.c +++ clang/test/ClangScanDeps/modules-pch.c @@ -21,12 +21,6 @@ // CHECK-PCH-NEXT: "clang-module-deps": [], // CHECK-PCH-NEXT: "clang-modulemap-file": "[[PREFIX]]/module.modulemap", // CHECK-PCH-NEXT: "command-line": [ -// CHECK-PCH-NEXT: "-cc1" -// CHECK-PCH: "-emit-module" -// CHECK-PCH: "-fmodules" -// CHECK-PCH-NOT: "-fimplicit-module-maps" -// CHECK-PCH: "-fmodule-name=ModCommon1" -// CHECK-PCH: "-fno-implicit-modules" // CHECK-PCH: ], // CHECK-PCH-NEXT: "context-hash": "[[HASH_MOD_COMMON_1:.*]]", // CHECK-PCH-NEXT: "file-deps": [ @@ -39,12 +33,6 @@ // CHECK-PCH-NEXT: "clang-module-deps": [], // CHECK-PCH-NEXT: "clang-modulemap-file": "[[PREFIX]]/module.modulemap", // CHECK-PCH-NEXT: "command-line": [ -// CHECK-PCH-NEXT: "-cc1" -// CHECK-PCH: "-emit-module" -// CHECK-PCH: "-fmodules" -// CHECK-PCH-NOT: "-fimplicit-module-maps" -// CHECK-PCH: "-fmodule-name=ModCommon2" -// CHECK-PCH: "-fno-implicit-modules" // CHECK-PCH: ], // CHECK-PCH-NEXT: "context-hash": "[[HASH_MOD_COMMON_2:.*]]", // CHECK-PCH-NEXT: "file-deps": [ @@ -62,13 +50,6 @@ // CHECK-PCH-NEXT: ], // CHECK-PCH-NEXT: "clang-modulemap-file": "[[PREFIX]]/module.modulemap", // CHECK-PCH-NEXT: "command-line": [ -// CHECK-PCH-NEXT: "-cc1" -// CHECK-PCH: "-emit-module" -// CHECK-PCH: "-fmodule-file=[[PREFIX]]/build/[[HASH_MOD_COMMON_2]]/ModCommon2-{{.*}}.pcm" -// CHECK-PCH: "-fmodules" -// CHECK-PCH-NOT: "-fimplicit-module-maps" -// CHECK-PCH: "-fmodule-name=ModPCH" -// CHECK-PCH: "-fno-implicit-modules" // CHECK-PCH: ], // CHECK-PCH-NEXT: "context-hash": "[[HASH_MOD_PCH:.*]]", // CHECK-PCH-NEXT: "file-deps": [ @@ -92,11 +73,7 @@ // CHECK-PCH-NEXT: } // CHECK-PCH-NEXT: ], // CHECK-PCH-NEXT: "command-line": [ -// CHECK-PCH: "-fno-implicit-modules", -// CHECK-PCH-NEXT: "-fno-implicit-module-maps", -// CHECK-PCH-NEXT: "-fmodule-file=[[PREFIX]]/build/[[HASH_MOD_COMMON_1]]/ModCommon1-{{.*}}.pcm", -// CHECK-PCH-NEXT: "-fmodule-file=[[PREFIX]]/build/[[HASH_MOD_PCH]]/ModPCH-{{.*}}.pcm" -// CHECK-PCH-NEXT: ], +// CHECK-PCH: ], // CHECK-PCH-NEXT: "file-deps": [ // CHECK-PCH-NEXT: "[[PREFIX]]/pch.h" // CHECK-PCH-NEXT: ], @@ -130,11 +107,6 @@ // CHECK-TU-NEXT: "clang-module-deps": [], // CHECK-TU-NEXT: "clang-modulemap-file": "[[PREFIX]]/module.modulemap", // CHECK-TU-NEXT: "command-line": [ -// CHECK-TU-NEXT: "-cc1", -// CHECK-TU: "-emit-module", -// CHECK-TU-NOT: "-fimplicit-module-maps", -// CHECK-TU: "-fmodule-name=ModTU", -// CHECK-TU: "-fno-implicit-modules", // CHECK-TU: ], // CHECK-TU-NEXT: "context-hash": "[[HASH_MOD_TU:.*]]", // CHECK-TU-NEXT: "file-deps": [ @@ -154,10 +126,7 @@ // CHECK-TU-NEXT: } // CHECK-TU-NEXT: ], // CHECK-TU-NEXT: "command-line": [ -// CHECK-TU: "-fno-implicit-modules", -// CHECK-TU-NEXT: "-fno-implicit-module-maps", -// CHECK-TU-NEXT: "-fmodule-file=[[PREFIX]]/build/[[HASH_MOD_TU]]/ModTU-{{.*}}.pcm" -// CHECK-TU-NEXT: ], +// CHECK-TU: ], // CHECK-TU-NEXT: "file-deps": [ // CHECK-TU-NEXT: "[[PREFIX]]/tu.c", // CHECK-TU-NEXT: "[[PREFIX]]/pch.h.gch" @@ -188,12 +157,6 @@ // CHECK-TU-WITH-COMMON-NEXT: "clang-module-deps": [], // CHECK-TU-WITH-COMMON-NEXT: "clang-modulemap-file": "[[PREFIX]]/module.modulemap", // CHECK-TU-WITH-COMMON-NEXT: "command-line": [ -// CHECK-TU-WITH-COMMON-NEXT: "-cc1", -// CHECK-TU-WITH-COMMON: "-emit-module", -// CHECK-TU-WITH-COMMON: "-fmodule-file=[[PREFIX]]/build/{{.*}}/ModCommon1-{{.*}}.pcm", -// CHECK-TU-WITH-COMMON-NOT: "-fimplicit-module-maps", -// CHECK-TU-WITH-COMMON: "-fmodule-name=ModTUWithCommon", -// CHECK-TU-WITH-COMMON: "-fno-implicit-modules", // CHECK-TU-WITH-COMMON: ], // CHECK-TU-WITH-COMMON-NEXT: "context-hash": "[[HASH_MOD_TU_WITH_COMMON:.*]]", // CHECK-TU-WITH-COMMON-NEXT: "file-deps": [ @@ -213,11 +176,8 @@ // CHECK-TU-WITH-COMMON-NEXT: } // CHECK-TU-WITH-COMMON-NEXT: ], // CHECK-TU-WITH-COMMON-NEXT: "command-line": [ -// CHECK-TU-WITH-COMMON: "-fno-implicit-modules", -// CHECK-TU-WITH-COMMON-NEXT: "-fno-implicit-module-maps", -// CHECK-TU-WITH-COMMON-NEXT: "-fmodule-file=[[PREFIX]]/build/{{.*}}/ModCommon2-{{.*}}.pcm", -// CHECK-TU-WITH-COMMON-NEXT: "-fmodule-file=[[PREFIX]]/build/[[HASH_MOD_TU_WITH_COMMON]]/ModTUWithCommon-{{.*}}.pcm" -// CHECK-TU-WITH-COMMON-NEXT: ], +// 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-NEXT: "[[PREFIX]]/tu_with_common.c", // CHECK-TU-WITH-COMMON-NEXT: "[[PREFIX]]/pch.h.gch" 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 @@ -2,9 +2,8 @@ // section in XCOFF yet. // UNSUPPORTED: aix -// Check that we discover dependency on a precompiled module (and generate the -// appropriate `-fmodule-file=` argument) when it's imported by a **submodule** -// instead of a top-level module. +// Check that we discover dependency on a precompiled module when it's imported +// by a **submodule** instead of a top-level module. // RUN: rm -rf %t && mkdir %t // RUN: cp %S/Inputs/modules-pch-common-via-submodule/* %t @@ -22,11 +21,6 @@ // CHECK-PCH-NEXT: "clang-module-deps": [], // CHECK-PCH-NEXT: "clang-modulemap-file": "[[PREFIX]]/module.modulemap", // CHECK-PCH-NEXT: "command-line": [ -// CHECK-PCH-NEXT: "-cc1" -// CHECK-PCH: "-emit-module" -// CHECK-PCH: "-fmodules" -// CHECK-PCH: "-fmodule-name=ModCommon" -// CHECK-PCH: "-fno-implicit-modules" // CHECK-PCH: ], // CHECK-PCH-NEXT: "context-hash": "[[HASH_MOD_COMMON:.*]]", // CHECK-PCH-NEXT: "file-deps": [ @@ -46,10 +40,7 @@ // CHECK-PCH-NEXT: } // CHECK-PCH-NEXT: ], // CHECK-PCH-NEXT: "command-line": [ -// CHECK-PCH: "-fno-implicit-modules" -// CHECK-PCH-NEXT: "-fno-implicit-module-maps" -// CHECK-PCH-NEXT: "-fmodule-file=[[PREFIX]]/build/[[HASH_MOD_COMMON]]/ModCommon-{{.*}}.pcm" -// CHECK-PCH-NEXT: ], +// CHECK-PCH: ], // CHECK-PCH-NEXT: "file-deps": [ // CHECK-PCH-NEXT: "[[PREFIX]]/pch.h" // CHECK-PCH-NEXT: ], @@ -79,12 +70,6 @@ // CHECK-TU-NEXT: "clang-module-deps": [], // CHECK-TU-NEXT: "clang-modulemap-file": "[[PREFIX]]/module.modulemap", // CHECK-TU-NEXT: "command-line": [ -// CHECK-TU-NEXT: "-cc1" -// CHECK-TU: "-emit-module" -// CHECK-TU: "-fmodule-file=[[PREFIX]]/build/[[HASH_MOD_COMMON:.*]]/ModCommon-{{.*}}.pcm" -// CHECK-TU: "-fmodules" -// CHECK-TU: "-fmodule-name=ModTU" -// CHECK-TU: "-fno-implicit-modules" // CHECK-TU: ], // CHECK-TU-NEXT: "context-hash": "[[HASH_MOD_TU:.*]]", // CHECK-TU-NEXT: "file-deps": [ @@ -105,10 +90,7 @@ // CHECK-TU-NEXT: } // CHECK-TU-NEXT: ], // CHECK-TU-NEXT: "command-line": [ -// CHECK-TU: "-fno-implicit-modules", -// CHECK-TU-NEXT: "-fno-implicit-module-maps", -// CHECK-TU-NEXT: "-fmodule-file=[[PREFIX]]/build/[[HASH_MOD_TU:.*]]/ModTU-{{.*}}.pcm" -// CHECK-TU-NEXT: ], +// CHECK-TU: ], // CHECK-TU-NEXT: "file-deps": [ // CHECK-TU-NEXT: "[[PREFIX]]/tu.c", // CHECK-TU-NEXT: "[[PREFIX]]/pch.h.gch" 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 @@ -24,11 +24,6 @@ // CHECK-PCH-NEXT: "clang-module-deps": [], // CHECK-PCH-NEXT: "clang-modulemap-file": "[[PREFIX]]/module.modulemap", // CHECK-PCH-NEXT: "command-line": [ -// CHECK-PCH-NEXT: "-cc1" -// CHECK-PCH: "-emit-module" -// CHECK-PCH: "-fmodules" -// CHECK-PCH: "-fmodule-name=ModCommon" -// CHECK-PCH: "-fno-implicit-modules" // CHECK-PCH: ], // CHECK-PCH-NEXT: "context-hash": "[[HASH_MOD_COMMON:.*]]", // CHECK-PCH-NEXT: "file-deps": [ @@ -49,10 +44,7 @@ // CHECK-PCH-NEXT: } // CHECK-PCH-NEXT: ], // CHECK-PCH-NEXT: "command-line": [ -// CHECK-PCH: "-fno-implicit-modules" -// CHECK-PCH-NEXT: "-fno-implicit-module-maps" -// CHECK-PCH-NEXT: "-fmodule-file=[[PREFIX]]/build/[[HASH_MOD_COMMON]]/ModCommon-{{.*}}.pcm" -// CHECK-PCH-NEXT: ], +// CHECK-PCH: ], // CHECK-PCH-NEXT: "file-deps": [ // CHECK-PCH-NEXT: "[[PREFIX]]/pch.h" // CHECK-PCH-NEXT: ], @@ -82,12 +74,6 @@ // CHECK-TU-NEXT: "clang-module-deps": [], // CHECK-TU-NEXT: "clang-modulemap-file": "[[PREFIX]]/module.modulemap", // CHECK-TU-NEXT: "command-line": [ -// CHECK-TU-NEXT: "-cc1" -// CHECK-TU: "-emit-module" -// CHECK-TU: "-fmodule-file=[[PREFIX]]/build/[[HASH_MOD_COMMON:.*]]/ModCommon-{{.*}}.pcm" -// CHECK-TU: "-fmodules" -// CHECK-TU: "-fmodule-name=ModTU" -// CHECK-TU: "-fno-implicit-modules" // CHECK-TU: ], // CHECK-TU-NEXT: "context-hash": "[[HASH_MOD_TU:.*]]", // CHECK-TU-NEXT: "file-deps": [ @@ -107,10 +93,7 @@ // CHECK-TU-NEXT: } // CHECK-TU-NEXT: ], // CHECK-TU-NEXT: "command-line": [ -// CHECK-TU: "-fno-implicit-modules", -// CHECK-TU-NEXT: "-fno-implicit-module-maps", -// CHECK-TU-NEXT: "-fmodule-file=[[PREFIX]]/build/[[HASH_MOD_TU:.*]]/ModTU-{{.*}}.pcm" -// CHECK-TU-NEXT: ], +// CHECK-TU: ], // CHECK-TU-NEXT: "file-deps": [ // CHECK-TU-NEXT: "[[PREFIX]]/tu.c", // CHECK-TU-NEXT: "[[PREFIX]]/pch.h.gch" Index: clang/test/ClangScanDeps/modules-inferred.m =================================================================== --- clang/test/ClangScanDeps/modules-inferred.m +++ clang/test/ClangScanDeps/modules-inferred.m @@ -19,11 +19,6 @@ // CHECK-NEXT: "clang-module-deps": [], // CHECK-NEXT: "clang-modulemap-file": "[[SOURCEDIR]]/Inputs/frameworks/module.modulemap", // CHECK-NEXT: "command-line": [ -// CHECK-NEXT: "-cc1", -// CHECK: "-emit-module", -// CHECK-NOT: "-fimplicit-module-maps", -// CHECK: "-fmodule-name=Inferred", -// CHECK: "-fno-implicit-modules", // CHECK: ], // CHECK-NEXT: "context-hash": "[[HASH_INFERRED:[A-Z0-9]+]]", // CHECK-NEXT: "file-deps": [ @@ -44,10 +39,7 @@ // CHECK-NEXT: } // CHECK-NEXT: ], // CHECK-NEXT: "command-line": [ -// CHECK: "-fno-implicit-modules", -// CHECK-NEXT: "-fno-implicit-module-maps", -// CHECK-NEXT: "-fmodule-file=[[PREFIX]]/module-cache/[[HASH_INFERRED]]/Inferred-{{[A-Z0-9]+}}.pcm" -// CHECK-NEXT: ], +// CHECK: ], // CHECK-NEXT: "file-deps": [ // CHECK-NEXT: "[[PREFIX]]/modules_cdb_input.cpp" // CHECK-NEXT: ], Index: clang/test/ClangScanDeps/modules-full.cpp =================================================================== --- clang/test/ClangScanDeps/modules-full.cpp +++ clang/test/ClangScanDeps/modules-full.cpp @@ -12,16 +12,11 @@ // // RUN: clang-scan-deps -compilation-database %t.cdb -j 4 -format experimental-full \ // RUN: -mode preprocess-dependency-directives > %t.result -// RUN: cat %t.result | sed 's:\\\\\?:/:g' | FileCheck -DPREFIX=%/t.dir --check-prefixes=CHECK,CHECK-ABS %s -// -// RUN: clang-scan-deps -compilation-database %t.cdb -j 4 -format experimental-full \ -// RUN: -module-files-dir %t.dir/custom \ -// RUN: -mode preprocess-dependency-directives > %t.result -// RUN: cat %t.result | sed 's:\\\\\?:/:g' | FileCheck -DPREFIX=%/t.dir --check-prefixes=CHECK,CHECK-CUSTOM %s +// RUN: cat %t.result | sed 's:\\\\\?:/:g' | FileCheck -DPREFIX=%/t.dir %s // // RUN: clang-scan-deps -compilation-database %t_clangcl.cdb -j 4 -format experimental-full \ // RUN: -mode preprocess-dependency-directives > %t_clangcl.result -// RUN: cat %t_clangcl.result | sed 's:\\\\\?:/:g' | FileCheck -DPREFIX=%/t.dir --check-prefixes=CHECK,CHECK-ABS %s +// RUN: cat %t_clangcl.result | sed 's:\\\\\?:/:g' | FileCheck -DPREFIX=%/t.dir %s #include "header.h" @@ -38,8 +33,7 @@ // CHECK-NEXT: "command-line": [ // CHECK-NEXT: "-cc1" // CHECK: "-emit-module" -// CHECK-ABS: "-fmodule-file=[[PREFIX]]/module-cache{{(_clangcl)?}}/[[HASH_H2_DINCLUDE]]/header2-{{[A-Z0-9]+}}.pcm" -// CHECK-CUSTOM: "-fmodule-file=[[PREFIX]]/custom/[[HASH_H2_DINCLUDE]]/header2-{{[A-Z0-9]+}}.pcm" +// CHECK: "-fmodule-file={{.*}}[[PREFIX]]/module-cache{{(_clangcl)?}}/[[HASH_H2_DINCLUDE]]/header2-{{[A-Z0-9]+}}.pcm" // CHECK-NOT: "-fimplicit-module-maps" // CHECK: "-fmodule-name=header1" // CHECK: "-fno-implicit-modules" @@ -97,10 +91,9 @@ // CHECK-NEXT: ], // CHECK-NEXT: "command-line": [ // CHECK: "-fno-implicit-modules" -// CHECK-NEXT: "-fno-implicit-module-maps" -// CHECK-ABS-NEXT: "-fmodule-file=[[PREFIX]]/module-cache{{(_clangcl)?}}/[[HASH_H1]]/header1-{{[A-Z0-9]+}}.pcm" -// CHECK-CUSTOM-NEXT: "-fmodule-file=[[PREFIX]]/custom/[[HASH_H1]]/header1-{{[A-Z0-9]+}}.pcm" -// CHECK-NEXT: ], +// 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: ], @@ -116,10 +109,9 @@ // CHECK-NEXT: ], // CHECK-NEXT: "command-line": [ // CHECK: "-fno-implicit-modules" -// CHECK-NEXT: "-fno-implicit-module-maps" -// CHECK-ABS-NEXT: "-fmodule-file=[[PREFIX]]/module-cache{{(_clangcl)?}}/[[HASH_H1]]/header1-{{[A-Z0-9]+}}.pcm" -// CHECK-CUSTOM-NEXT: "-fmodule-file=[[PREFIX]]/custom/[[HASH_H1]]/header1-{{[A-Z0-9]+}}.pcm" -// CHECK-NEXT: ], +// 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: ], @@ -135,10 +127,9 @@ // CHECK-NEXT: ], // CHECK-NEXT: "command-line": [ // CHECK: "-fno-implicit-modules" -// CHECK-NEXT: "-fno-implicit-module-maps" -// CHECK-ABS-NEXT: "-fmodule-file=[[PREFIX]]/module-cache{{(_clangcl)?}}/[[HASH_H1]]/header1-{{[A-Z0-9]+}}.pcm" -// CHECK-CUSTOM-NEXT: "-fmodule-file=[[PREFIX]]/custom/[[HASH_H1]]/header1-{{[A-Z0-9]+}}.pcm" -// CHECK-NEXT: ], +// 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: ], @@ -154,10 +145,9 @@ // CHECK-NEXT: ], // CHECK-NEXT: "command-line": [ // CHECK: "-fno-implicit-modules" -// CHECK-NEXT: "-fno-implicit-module-maps" -// CHECK-ABS-NEXT: "-fmodule-file=[[PREFIX]]/module-cache{{(_clangcl)?}}/[[HASH_H1_DINCLUDE]]/header1-{{[A-Z0-9]+}}.pcm" -// CHECK-CUSTOM-NEXT: "-fmodule-file=[[PREFIX]]/custom/[[HASH_H1_DINCLUDE]]/header1-{{[A-Z0-9]+}}.pcm" -// CHECK-NEXT: ], +// 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: ], 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 @@ -41,10 +41,7 @@ // CHECK-NEXT: } // CHECK-NEXT: ], // CHECK-NEXT: "command-line": [ -// CHECK: "-fno-implicit-modules" -// CHECK-NEXT: "-fno-implicit-module-maps" -// CHECK-NEXT: "-fmodule-file=[[PREFIX]]/module-cache{{(_clangcl)?}}/[[HASH_H2]]/header2-{{[A-Z0-9]+}}.pcm" -// CHECK-NEXT: ], +// CHECK: ], // CHECK-NEXT: "file-deps": [ // CHECK-NEXT: "[[PREFIX]]/modules-fmodule-name-no-module-built.m" // CHECK-NEXT: "[[PREFIX]]/Inputs/header3.h" Index: clang/test/ClangScanDeps/modules-dep-args.c =================================================================== --- /dev/null +++ clang/test/ClangScanDeps/modules-dep-args.c @@ -0,0 +1,102 @@ +// This test exercises the different ways explicit modular dependencies are +// provided on the command-line. + +// RUN: rm -rf %t +// RUN: split-file %s %t + +//--- cdb.json.template +[{ + "file": "DIR/tu.c", + "directory": "DIR", + "command": "clang DIR/tu.c -fmodules -fmodules-cache-path=DIR/cache -o DIR/tu.o" +}] + +//--- module.modulemap +module Transitive { header "transitive.h" } +module Direct { header "direct.h" } +//--- transitive.h +//--- direct.h +#include "transitive.h" +//--- tu.c +#include "direct.h" + +// RUN: sed -e "s|DIR|%/t|g" %t/cdb.json.template > %t/cdb.json + +// Check that the PCM path defaults to the modules cache from implicit build. +// RUN: clang-scan-deps -compilation-database %t/cdb.json -format experimental-full > %t/result_cache.json +// RUN: cat %t/result_cache.json | sed 's:\\\\\?:/:g' | FileCheck %s -DPREFIX=%/t --check-prefixes=CHECK,CHECK_CACHE + +// Check that the PCM path can be customized. +// RUN: clang-scan-deps -compilation-database %t/cdb.json -format experimental-full -module-files-dir %t/build > %t/result_build.json +// RUN: cat %t/result_build.json | sed 's:\\\\\?:/:g' | FileCheck %s -DPREFIX=%/t --check-prefixes=CHECK,CHECK_BUILD + +// Check that the PCM file is loaded lazily by default. +// RUN: clang-scan-deps -compilation-database %t/cdb.json -format experimental-full > %t/result_lazy.json +// RUN: cat %t/result_lazy.json | sed 's:\\\\\?:/:g' | FileCheck %s -DPREFIX=%/t --check-prefixes=CHECK,CHECK_LAZY + +// Check that the PCM file can be loaded eagerly. +// RUN: clang-scan-deps -compilation-database %t/cdb.json -format experimental-full -eager-load-pcm > %t/result_eager.json +// RUN: cat %t/result_eager.json | sed 's:\\\\\?:/:g' | FileCheck %s -DPREFIX=%/t --check-prefixes=CHECK,CHECK_EAGER + +// CHECK: { +// CHECK-NEXT: "modules": [ +// CHECK-NEXT: { +// CHECK-NEXT: "clang-module-deps": [ +// CHECK-NEXT: { +// CHECK-NEXT: "context-hash": "{{.*}}", +// CHECK-NEXT: "module-name": "Transitive" +// CHECK-NEXT: } +// CHECK-NEXT: ], +// CHECK-NEXT: "clang-modulemap-file": "[[PREFIX]]/module.modulemap", +// CHECK-NEXT: "command-line": [ +// CHECK_CACHE: "-fmodule-file={{.*}}/cache/{{.*}}/Transitive-{{.*}}.pcm" +// CHECK_BUILD: "-fmodule-file={{.*}}/build/{{.*}}/Transitive-{{.*}}.pcm" +// CHECK_LAZY: "-fmodule-map-file=[[PREFIX]]/module.modulemap" +// CHECK_LAZY: "-fmodule-file=Transitive=[[PREFIX]]/{{.*}}/Transitive-{{.*}}.pcm" +// CHECK_EAGER-NOT: "-fmodule-map-file={{.*}}" +// CHECK_EAGER: "-fmodule-file=[[PREFIX]]/{{.*}}/Transitive-{{.*}}.pcm" +// CHECK: ], +// CHECK-NEXT: "context-hash": "{{.*}}", +// CHECK-NEXT: "file-deps": [ +// CHECK-NEXT: "[[PREFIX]]/direct.h", +// CHECK-NEXT: "[[PREFIX]]/module.modulemap" +// CHECK-NEXT: ], +// CHECK-NEXT: "name": "Direct" +// CHECK-NEXT: }, +// CHECK-NEXT: { +// CHECK-NEXT: "clang-module-deps": [], +// CHECK-NEXT: "clang-modulemap-file": "[[PREFIX]]/module.modulemap", +// CHECK-NEXT: "command-line": [ +// CHECK: ], +// CHECK-NEXT: "context-hash": "{{.*}}", +// CHECK-NEXT: "file-deps": [ +// CHECK-NEXT: "[[PREFIX]]/module.modulemap", +// CHECK-NEXT: "[[PREFIX]]/transitive.h" +// CHECK-NEXT: ], +// CHECK-NEXT: "name": "Transitive" +// CHECK-NEXT: } +// CHECK-NEXT: ], +// CHECK-NEXT: "translation-units": [ +// CHECK-NEXT: { +// CHECK-NEXT: "clang-context-hash": "{{.*}}", +// CHECK-NEXT: "clang-module-deps": [ +// CHECK-NEXT: { +// CHECK-NEXT: "context-hash": "{{.*}}", +// CHECK-NEXT: "module-name": "Direct" +// CHECK-NEXT: } +// CHECK-NEXT: ], +// CHECK-NEXT: "command-line": [ +// CHECK_CACHE: "-fmodule-file={{.*}}/cache/{{.*}}/Direct-{{.*}}.pcm" +// CHECK_BUILD: "-fmodule-file={{.*}}/build/{{.*}}/Direct-{{.*}}.pcm" +// CHECK_LAZY: "-fmodule-map-file=[[PREFIX]]/module.modulemap" +// CHECK_LAZY: "-fmodule-file=Direct=[[PREFIX]]/{{.*}}/Direct-{{.*}}.pcm" +// CHECK_EAGER-NOT: "-fmodule-map-file={{.*}}" +// CHECK_EAGER: "-fmodule-file=[[PREFIX]]/{{.*}}/Direct-{{.*}}.pcm" +// CHECK: ], +// CHECK-NEXT: "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/lib/Tooling/DependencyScanning/ModuleDepCollector.cpp =================================================================== --- clang/lib/Tooling/DependencyScanning/ModuleDepCollector.cpp +++ clang/lib/Tooling/DependencyScanning/ModuleDepCollector.cpp @@ -54,9 +54,23 @@ void ModuleDepCollector::addOutputPaths(ModuleDeps &Deps) { CompilerInvocation &CI = Deps.BuildInvocation; - for (ModuleID MID : Deps.ClangModuleDeps) - CI.getFrontendOpts().ModuleFiles.push_back( - Consumer.lookupModuleOutput(MID, ModuleOutputKind::ModuleFile)); + for (ModuleID MID : Deps.ClangModuleDeps) { + auto PCMPath = + Consumer.lookupModuleOutput(MID, ModuleOutputKind::ModuleFile); + + if (EagerLoadModules) { + CI.getFrontendOpts().ModuleFiles.push_back(PCMPath); + } else { + Module *M = ScanInstance.getPreprocessor() + .getHeaderSearchInfo() + .getModuleMap() + .findModule(MID.ModuleName); + CI.getHeaderSearchOpts().PrebuiltModuleFiles.insert( + {MID.ModuleName, PCMPath}); + CI.getFrontendOpts().ModuleMapFiles.push_back( + ModularDeps[M]->ClangModuleMapFile); + } + } CI.getFrontendOpts().OutputFile = Consumer.lookupModuleOutput(Deps.ID, ModuleOutputKind::ModuleFile); @@ -465,9 +479,10 @@ ModuleDepCollector::ModuleDepCollector( std::unique_ptr<DependencyOutputOptions> Opts, CompilerInstance &ScanInstance, DependencyConsumer &C, - CompilerInvocation &&OriginalCI, bool OptimizeArgs) + CompilerInvocation &&OriginalCI, bool OptimizeArgs, bool EagerLoadModules) : ScanInstance(ScanInstance), Consumer(C), Opts(std::move(Opts)), - OriginalInvocation(std::move(OriginalCI)), OptimizeArgs(OptimizeArgs) {} + OriginalInvocation(std::move(OriginalCI)), OptimizeArgs(OptimizeArgs), + EagerLoadModules(EagerLoadModules) {} void ModuleDepCollector::attachToPreprocessor(Preprocessor &PP) { PP.addPPCallbacks(std::make_unique<ModuleDepCollectorPP>(*this)); Index: clang/lib/Tooling/DependencyScanning/DependencyScanningWorker.cpp =================================================================== --- clang/lib/Tooling/DependencyScanning/DependencyScanningWorker.cpp +++ clang/lib/Tooling/DependencyScanning/DependencyScanningWorker.cpp @@ -140,11 +140,12 @@ DependencyScanningAction( StringRef WorkingDirectory, DependencyConsumer &Consumer, llvm::IntrusiveRefCntPtr<DependencyScanningWorkerFilesystem> DepFS, - ScanningOutputFormat Format, bool OptimizeArgs, bool DisableFree, - llvm::Optional<StringRef> ModuleName = None) + ScanningOutputFormat Format, bool OptimizeArgs, bool EagerLoadModules, + bool DisableFree, llvm::Optional<StringRef> ModuleName = None) : WorkingDirectory(WorkingDirectory), Consumer(Consumer), DepFS(std::move(DepFS)), Format(Format), OptimizeArgs(OptimizeArgs), - DisableFree(DisableFree), ModuleName(ModuleName) {} + EagerLoadModules(EagerLoadModules), DisableFree(DisableFree), + ModuleName(ModuleName) {} bool runInvocation(std::shared_ptr<CompilerInvocation> Invocation, FileManager *FileMgr, @@ -231,7 +232,7 @@ case ScanningOutputFormat::Full: ScanInstance.addDependencyCollector(std::make_shared<ModuleDepCollector>( std::move(Opts), ScanInstance, Consumer, - std::move(OriginalInvocation), OptimizeArgs)); + std::move(OriginalInvocation), OptimizeArgs, EagerLoadModules)); break; } @@ -261,6 +262,7 @@ llvm::IntrusiveRefCntPtr<DependencyScanningWorkerFilesystem> DepFS; ScanningOutputFormat Format; bool OptimizeArgs; + bool EagerLoadModules; bool DisableFree; llvm::Optional<StringRef> ModuleName; }; @@ -270,7 +272,8 @@ DependencyScanningWorker::DependencyScanningWorker( DependencyScanningService &Service, llvm::IntrusiveRefCntPtr<llvm::vfs::FileSystem> FS) - : Format(Service.getFormat()), OptimizeArgs(Service.canOptimizeArgs()) { + : Format(Service.getFormat()), OptimizeArgs(Service.canOptimizeArgs()), + EagerLoadModules(Service.shouldEagerLoadModules()) { PCHContainerOps = std::make_shared<PCHContainerOperations>(); PCHContainerOps->registerReader( std::make_unique<ObjectFilePCHContainerReader>()); @@ -343,7 +346,8 @@ bool DisableFree = true; DependencyScanningAction Action( WorkingDirectory, Consumer, DepFS, Format, - OptimizeArgs, DisableFree, ModuleName); + 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 Index: clang/lib/Tooling/DependencyScanning/DependencyScanningTool.cpp =================================================================== --- clang/lib/Tooling/DependencyScanning/DependencyScanningTool.cpp +++ clang/lib/Tooling/DependencyScanning/DependencyScanningTool.cpp @@ -37,7 +37,8 @@ DependencyScanningTool::DependencyScanningTool( DependencyScanningService &Service, llvm::IntrusiveRefCntPtr<llvm::vfs::FileSystem> FS) - : Worker(Service, std::move(FS)) {} + : Worker(Service, std::move(FS)), + EagerLoadModules(Service.shouldEagerLoadModules()) {} llvm::Expected<std::string> DependencyScanningTool::getDependencyFile( const std::vector<std::string> &CommandLine, StringRef CWD, @@ -119,11 +120,12 @@ Worker.computeDependencies(CWD, CommandLine, Consumer, ModuleName); if (Result) return std::move(Result); - return Consumer.getFullDependencies(CommandLine); + return Consumer.getFullDependencies(CommandLine, EagerLoadModules); } FullDependenciesResult FullDependencyConsumer::getFullDependencies( - const std::vector<std::string> &OriginalCommandLine) const { + const std::vector<std::string> &OriginalCommandLine, + bool EagerLoadModules) const { FullDependencies FD; FD.CommandLine = makeTUCommandLineWithoutPaths( @@ -140,9 +142,14 @@ auto &MD = M.second; if (MD.ImportedByMainFile) { FD.ClangModuleDeps.push_back(MD.ID); - FD.CommandLine.push_back( - "-fmodule-file=" + - LookupModuleOutput(MD.ID, ModuleOutputKind::ModuleFile)); + auto PCMPath = LookupModuleOutput(MD.ID, ModuleOutputKind::ModuleFile); + if (EagerLoadModules) { + FD.CommandLine.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); + } } } Index: clang/lib/Tooling/DependencyScanning/DependencyScanningService.cpp =================================================================== --- clang/lib/Tooling/DependencyScanning/DependencyScanningService.cpp +++ clang/lib/Tooling/DependencyScanning/DependencyScanningService.cpp @@ -15,9 +15,9 @@ DependencyScanningService::DependencyScanningService( ScanningMode Mode, ScanningOutputFormat Format, bool ReuseFileManager, - bool OptimizeArgs) + bool OptimizeArgs, bool EagerLoadModules) : Mode(Mode), Format(Format), ReuseFileManager(ReuseFileManager), - OptimizeArgs(OptimizeArgs) { + OptimizeArgs(OptimizeArgs), EagerLoadModules(EagerLoadModules) { // Initialize targets for object file support. llvm::InitializeAllTargets(); llvm::InitializeAllTargetMCs(); Index: clang/include/clang/Tooling/DependencyScanning/ModuleDepCollector.h =================================================================== --- clang/include/clang/Tooling/DependencyScanning/ModuleDepCollector.h +++ clang/include/clang/Tooling/DependencyScanning/ModuleDepCollector.h @@ -184,7 +184,8 @@ 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; @@ -211,6 +212,8 @@ CompilerInvocation OriginalInvocation; /// Whether to optimize the modules' command-line arguments. bool OptimizeArgs; + /// Whether to set up command-lines to load PCM files eagerly. + bool EagerLoadModules; /// Checks whether the module is known as being prebuilt. bool isPrebuiltModule(const Module *M); Index: clang/include/clang/Tooling/DependencyScanning/DependencyScanningWorker.h =================================================================== --- clang/include/clang/Tooling/DependencyScanning/DependencyScanningWorker.h +++ clang/include/clang/Tooling/DependencyScanning/DependencyScanningWorker.h @@ -87,6 +87,8 @@ ScanningOutputFormat Format; /// Whether to optimize the modules' command-line arguments. bool OptimizeArgs; + /// Whether to set up command-lines to load PCM files eagerly. + bool EagerLoadModules; }; } // end namespace dependencies Index: clang/include/clang/Tooling/DependencyScanning/DependencyScanningTool.h =================================================================== --- clang/include/clang/Tooling/DependencyScanning/DependencyScanningTool.h +++ clang/include/clang/Tooling/DependencyScanning/DependencyScanningTool.h @@ -101,6 +101,7 @@ private: DependencyScanningWorker Worker; + bool EagerLoadModules; }; class FullDependencyConsumer : public DependencyConsumer { @@ -132,8 +133,9 @@ return LookupModuleOutput(ID, Kind); } - FullDependenciesResult getFullDependencies( - const std::vector<std::string> &OriginalCommandLine) const; + FullDependenciesResult + getFullDependencies(const std::vector<std::string> &OriginalCommandLine, + bool EagerLoadModules) const; private: std::vector<std::string> Dependencies; Index: clang/include/clang/Tooling/DependencyScanning/DependencyScanningService.h =================================================================== --- clang/include/clang/Tooling/DependencyScanning/DependencyScanningService.h +++ clang/include/clang/Tooling/DependencyScanning/DependencyScanningService.h @@ -46,7 +46,8 @@ public: DependencyScanningService(ScanningMode Mode, ScanningOutputFormat Format, bool ReuseFileManager = true, - bool OptimizeArgs = false); + bool OptimizeArgs = false, + bool EagerLoadModules = false); ScanningMode getMode() const { return Mode; } @@ -56,6 +57,8 @@ bool canOptimizeArgs() const { return OptimizeArgs; } + bool shouldEagerLoadModules() const { return EagerLoadModules; } + DependencyScanningFilesystemSharedCache &getSharedCache() { return SharedCache; } @@ -66,6 +69,8 @@ const bool ReuseFileManager; /// Whether to optimize the modules' command-line arguments. const bool OptimizeArgs; + /// Whether to set up command-lines to load PCM files eagerly. + const bool EagerLoadModules; /// The global file system cache. DependencyScanningFilesystemSharedCache SharedCache; };
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits