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

Reply via email to