diff --git a/clang/include/clang/Tooling/DependencyScanning/DependencyScanningService.h b/clang/include/clang/Tooling/DependencyScanning/DependencyScanningService.h --- a/clang/include/clang/Tooling/DependencyScanning/DependencyScanningService.h +++ b/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; }; diff --git a/clang/include/clang/Tooling/DependencyScanning/DependencyScanningTool.h b/clang/include/clang/Tooling/DependencyScanning/DependencyScanningTool.h --- a/clang/include/clang/Tooling/DependencyScanning/DependencyScanningTool.h +++ b/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 &OriginalCommandLine) const; + FullDependenciesResult + getFullDependencies(const std::vector &OriginalCommandLine, + bool EagerLoadModules) const; private: std::vector Dependencies; diff --git a/clang/include/clang/Tooling/DependencyScanning/DependencyScanningWorker.h b/clang/include/clang/Tooling/DependencyScanning/DependencyScanningWorker.h --- a/clang/include/clang/Tooling/DependencyScanning/DependencyScanningWorker.h +++ b/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 diff --git a/clang/include/clang/Tooling/DependencyScanning/ModuleDepCollector.h b/clang/include/clang/Tooling/DependencyScanning/ModuleDepCollector.h --- a/clang/include/clang/Tooling/DependencyScanning/ModuleDepCollector.h +++ b/clang/include/clang/Tooling/DependencyScanning/ModuleDepCollector.h @@ -184,7 +184,8 @@ public: ModuleDepCollector(std::unique_ptr 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); diff --git a/clang/lib/Tooling/DependencyScanning/DependencyScanningService.cpp b/clang/lib/Tooling/DependencyScanning/DependencyScanningService.cpp --- a/clang/lib/Tooling/DependencyScanning/DependencyScanningService.cpp +++ b/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(); diff --git a/clang/lib/Tooling/DependencyScanning/DependencyScanningTool.cpp b/clang/lib/Tooling/DependencyScanning/DependencyScanningTool.cpp --- a/clang/lib/Tooling/DependencyScanning/DependencyScanningTool.cpp +++ b/clang/lib/Tooling/DependencyScanning/DependencyScanningTool.cpp @@ -37,7 +37,8 @@ DependencyScanningTool::DependencyScanningTool( DependencyScanningService &Service, llvm::IntrusiveRefCntPtr FS) - : Worker(Service, std::move(FS)) {} + : Worker(Service, std::move(FS)), + EagerLoadModules(Service.shouldEagerLoadModules()) {} llvm::Expected DependencyScanningTool::getDependencyFile( const std::vector &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 &OriginalCommandLine) const { + const std::vector &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); + } } } diff --git a/clang/lib/Tooling/DependencyScanning/DependencyScanningWorker.cpp b/clang/lib/Tooling/DependencyScanning/DependencyScanningWorker.cpp --- a/clang/lib/Tooling/DependencyScanning/DependencyScanningWorker.cpp +++ b/clang/lib/Tooling/DependencyScanning/DependencyScanningWorker.cpp @@ -140,11 +140,12 @@ DependencyScanningAction( StringRef WorkingDirectory, DependencyConsumer &Consumer, llvm::IntrusiveRefCntPtr DepFS, - ScanningOutputFormat Format, bool OptimizeArgs, bool DisableFree, - llvm::Optional ModuleName = None) + ScanningOutputFormat Format, bool OptimizeArgs, bool EagerLoadModules, + bool DisableFree, llvm::Optional 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 Invocation, FileManager *FileMgr, @@ -231,7 +232,7 @@ case ScanningOutputFormat::Full: ScanInstance.addDependencyCollector(std::make_shared( std::move(Opts), ScanInstance, Consumer, - std::move(OriginalInvocation), OptimizeArgs)); + std::move(OriginalInvocation), OptimizeArgs, EagerLoadModules)); break; } @@ -261,6 +262,7 @@ llvm::IntrusiveRefCntPtr DepFS; ScanningOutputFormat Format; bool OptimizeArgs; + bool EagerLoadModules; bool DisableFree; llvm::Optional ModuleName; }; @@ -270,7 +272,8 @@ DependencyScanningWorker::DependencyScanningWorker( DependencyScanningService &Service, llvm::IntrusiveRefCntPtr FS) - : Format(Service.getFormat()), OptimizeArgs(Service.canOptimizeArgs()) { + : Format(Service.getFormat()), OptimizeArgs(Service.canOptimizeArgs()), + EagerLoadModules(Service.shouldEagerLoadModules()) { PCHContainerOps = std::make_shared(); PCHContainerOps->registerReader( std::make_unique()); @@ -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 diff --git a/clang/lib/Tooling/DependencyScanning/ModuleDepCollector.cpp b/clang/lib/Tooling/DependencyScanning/ModuleDepCollector.cpp --- a/clang/lib/Tooling/DependencyScanning/ModuleDepCollector.cpp +++ b/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 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(*this)); diff --git a/clang/test/ClangScanDeps/modules-dep-args.c b/clang/test/ClangScanDeps/modules-dep-args.c new file mode 100644 --- /dev/null +++ b/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 diff --git a/clang/test/ClangScanDeps/modules-fmodule-name-no-module-built.m b/clang/test/ClangScanDeps/modules-fmodule-name-no-module-built.m --- a/clang/test/ClangScanDeps/modules-fmodule-name-no-module-built.m +++ b/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" diff --git a/clang/test/ClangScanDeps/modules-full.cpp b/clang/test/ClangScanDeps/modules-full.cpp --- a/clang/test/ClangScanDeps/modules-full.cpp +++ b/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: ], diff --git a/clang/test/ClangScanDeps/modules-inferred.m b/clang/test/ClangScanDeps/modules-inferred.m --- a/clang/test/ClangScanDeps/modules-inferred.m +++ b/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: ], diff --git a/clang/test/ClangScanDeps/modules-pch-common-submodule.c b/clang/test/ClangScanDeps/modules-pch-common-submodule.c --- a/clang/test/ClangScanDeps/modules-pch-common-submodule.c +++ b/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" diff --git a/clang/test/ClangScanDeps/modules-pch-common-via-submodule.c b/clang/test/ClangScanDeps/modules-pch-common-via-submodule.c --- a/clang/test/ClangScanDeps/modules-pch-common-via-submodule.c +++ b/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" diff --git a/clang/test/ClangScanDeps/modules-pch.c b/clang/test/ClangScanDeps/modules-pch.c --- a/clang/test/ClangScanDeps/modules-pch.c +++ b/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" diff --git a/clang/tools/clang-scan-deps/ClangScanDeps.cpp b/clang/tools/clang-scan-deps/ClangScanDeps.cpp --- a/clang/tools/clang-scan-deps/ClangScanDeps.cpp +++ b/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 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 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> WorkerTools; for (unsigned I = 0; I < Pool.getThreadCount(); ++I)