[clang] [clang][clang-scan-deps] Add named modules to format 'experimental-full' (PR #145221)

via cfe-commits cfe-commits at lists.llvm.org
Sun Jun 22 01:37:35 PDT 2025


llvmbot wrote:


<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-clang

Author: Naveen Seth Hanig (naveen-seth)

<details>
<summary>Changes</summary>

This adds standard C++ named modules to the scanning output format 'experimental-full'.

This is motivated by an effort to provide native support for explicit module builds from the Clang driver.
The driver support for explicit module builds is planned to support combined usage of Clang modules and C++ named modules. With this, only a single scan is required to capture dependencies for both module types.

---

Patch is 42.13 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/145221.diff


29 Files Affected:

- (modified) clang/include/clang/Tooling/DependencyScanning/DependencyScanningTool.h (+14) 
- (modified) clang/lib/Tooling/DependencyScanning/DependencyScanningTool.cpp (+2) 
- (modified) clang/lib/Tooling/DependencyScanning/ModuleDepCollector.cpp (+3-1) 
- (modified) clang/test/ClangScanDeps/diagnostics.c (+1-1) 
- (modified) clang/test/ClangScanDeps/header-search-pruning-transitive.c (+2-2) 
- (modified) clang/test/ClangScanDeps/modules-context-hash-cwd.c (+9-9) 
- (modified) clang/test/ClangScanDeps/modules-context-hash.c (+2-2) 
- (modified) clang/test/ClangScanDeps/modules-dep-args.c (+1-1) 
- (modified) clang/test/ClangScanDeps/modules-extern-submodule.c (+1-1) 
- (modified) clang/test/ClangScanDeps/modules-extern-unrelated.m (+1-1) 
- (modified) clang/test/ClangScanDeps/modules-fmodule-name-no-module-built.m (+1-1) 
- (added) clang/test/ClangScanDeps/modules-full-named-modules.cppm (+347) 
- (modified) clang/test/ClangScanDeps/modules-full-output-tu-order.c (+2-2) 
- (modified) clang/test/ClangScanDeps/modules-full.cpp (+4-4) 
- (modified) clang/test/ClangScanDeps/modules-has-include-umbrella-header.c (+1-1) 
- (modified) clang/test/ClangScanDeps/modules-implementation-private.m (+1-1) 
- (modified) clang/test/ClangScanDeps/modules-implicit-dot-private.m (+1-1) 
- (modified) clang/test/ClangScanDeps/modules-incomplete-umbrella.c (+2-2) 
- (modified) clang/test/ClangScanDeps/modules-inferred.m (+1-1) 
- (modified) clang/test/ClangScanDeps/modules-no-undeclared-includes.c (+1-1) 
- (modified) clang/test/ClangScanDeps/modules-pch-common-stale.c (+2-2) 
- (modified) clang/test/ClangScanDeps/modules-pch-common-submodule.c (+2-2) 
- (modified) clang/test/ClangScanDeps/modules-pch-common-via-submodule.c (+2-2) 
- (modified) clang/test/ClangScanDeps/modules-pch.c (+3-3) 
- (modified) clang/test/ClangScanDeps/modules-priv-fw-from-pub.m (+1-1) 
- (modified) clang/test/ClangScanDeps/multiple-commands.c (+2-2) 
- (modified) clang/test/ClangScanDeps/removed-args.c (+1-1) 
- (modified) clang/test/ClangScanDeps/tu-buffer.c (+1-1) 
- (modified) clang/tools/clang-scan-deps/ClangScanDeps.cpp (+20-4) 


``````````diff
diff --git a/clang/include/clang/Tooling/DependencyScanning/DependencyScanningTool.h b/clang/include/clang/Tooling/DependencyScanning/DependencyScanningTool.h
index cb5d7e36d21c9..ee24e5d1543d3 100644
--- a/clang/include/clang/Tooling/DependencyScanning/DependencyScanningTool.h
+++ b/clang/include/clang/Tooling/DependencyScanning/DependencyScanningTool.h
@@ -15,6 +15,7 @@
 #include "clang/Tooling/JSONCompilationDatabase.h"
 #include "llvm/ADT/DenseSet.h"
 #include "llvm/ADT/MapVector.h"
+#include "llvm/ADT/STLExtras.h"
 #include <functional>
 #include <optional>
 #include <string>
@@ -56,6 +57,9 @@ struct TranslationUnitDeps {
   /// determined that the differences are benign for this compilation.
   std::vector<ModuleID> ClangModuleDeps;
 
+  /// A list of the C++20 named modules this translation unit depends on.
+  std::vector<std::string> NamedModuleDeps;
+
   /// The sequence of commands required to build the translation unit. Commands
   /// should be executed in order.
   ///
@@ -188,6 +192,14 @@ class FullDependencyConsumer : public DependencyConsumer {
     ContextHash = std::move(Hash);
   }
 
+  void handleProvidedAndRequiredStdCXXModules(
+      std::optional<P1689ModuleInfo> Provided,
+      std::vector<P1689ModuleInfo> Requires) override {
+    ModuleName = Provided ? Provided->ModuleName : "";
+    llvm::transform(Requires, std::back_inserter(NamedModuleDeps),
+                    [](const auto &Module) { return Module.ModuleName; });
+  }
+
   TranslationUnitDeps takeTranslationUnitDeps();
   ModuleDepsGraph takeModuleGraphDeps();
 
@@ -195,6 +207,8 @@ class FullDependencyConsumer : public DependencyConsumer {
   std::vector<std::string> Dependencies;
   std::vector<PrebuiltModuleDep> PrebuiltModuleDeps;
   llvm::MapVector<ModuleID, ModuleDeps> ClangModuleDeps;
+  std::string ModuleName;
+  std::vector<std::string> NamedModuleDeps;
   std::vector<ModuleID> DirectModuleDeps;
   std::vector<Command> Commands;
   std::string ContextHash;
diff --git a/clang/lib/Tooling/DependencyScanning/DependencyScanningTool.cpp b/clang/lib/Tooling/DependencyScanning/DependencyScanningTool.cpp
index b015e79f400cf..515211d47b348 100644
--- a/clang/lib/Tooling/DependencyScanning/DependencyScanningTool.cpp
+++ b/clang/lib/Tooling/DependencyScanning/DependencyScanningTool.cpp
@@ -171,6 +171,8 @@ TranslationUnitDeps FullDependencyConsumer::takeTranslationUnitDeps() {
   TranslationUnitDeps TU;
 
   TU.ID.ContextHash = std::move(ContextHash);
+  TU.ID.ModuleName = std::move(ModuleName);
+  TU.NamedModuleDeps = std::move(NamedModuleDeps);
   TU.FileDeps = std::move(Dependencies);
   TU.PrebuiltModuleDeps = std::move(PrebuiltModuleDeps);
   TU.Commands = std::move(Commands);
diff --git a/clang/lib/Tooling/DependencyScanning/ModuleDepCollector.cpp b/clang/lib/Tooling/DependencyScanning/ModuleDepCollector.cpp
index b1495163ccc24..894b52a0a5673 100644
--- a/clang/lib/Tooling/DependencyScanning/ModuleDepCollector.cpp
+++ b/clang/lib/Tooling/DependencyScanning/ModuleDepCollector.cpp
@@ -714,7 +714,9 @@ void ModuleDepCollectorPP::EndOfMainFile() {
 
   MDC.Consumer.handleDependencyOutputOpts(*MDC.Opts);
 
-  if (MDC.Service.getFormat() == ScanningOutputFormat::P1689)
+  if (const auto Format = MDC.Service.getFormat();
+      Format == ScanningOutputFormat::P1689 ||
+      Format == ScanningOutputFormat::Full)
     MDC.Consumer.handleProvidedAndRequiredStdCXXModules(
         MDC.ProvidedStdCXXModule, MDC.RequiredStdCXXModules);
 
diff --git a/clang/test/ClangScanDeps/diagnostics.c b/clang/test/ClangScanDeps/diagnostics.c
index 8e3cf4c9f9fa6..5e99ba10b89f2 100644
--- a/clang/test/ClangScanDeps/diagnostics.c
+++ b/clang/test/ClangScanDeps/diagnostics.c
@@ -44,7 +44,7 @@ module mod { header "mod.h" }
 // CHECK-NEXT:   "translation-units": [
 // CHECK-NEXT:     {
 // CHECK:            "clang-context-hash": "[[HASH_TU:.*]],
-// CHECK-NEXT:       "clang-module-deps": [
+// CHECK:            "clang-module-deps": [
 // CHECK-NEXT:         {
 // CHECK-NEXT:           "context-hash": "[[HASH_MOD]]",
 // CHECK-NEXT:           "module-name": "mod"
diff --git a/clang/test/ClangScanDeps/header-search-pruning-transitive.c b/clang/test/ClangScanDeps/header-search-pruning-transitive.c
index 1e829bb02ddc4..09a746e9af26b 100644
--- a/clang/test/ClangScanDeps/header-search-pruning-transitive.c
+++ b/clang/test/ClangScanDeps/header-search-pruning-transitive.c
@@ -98,7 +98,7 @@ module X { header "X.h" }
 // CHECK-NEXT:   "translation-units": [
 // CHECK-NEXT:     {
 // CHECK:            "clang-context-hash": "{{.*}}",
-// CHECK-NEXT:       "clang-module-deps": [
+// CHECK:            "clang-module-deps": [
 // CHECK-NEXT:         {
 // CHECK-NEXT:           "context-hash": "[[HASH_X]]",
 // CHECK-NEXT:           "module-name": "X"
@@ -153,7 +153,7 @@ module X { header "X.h" }
 // CHECK-NEXT:   "translation-units": [
 // CHECK-NEXT:     {
 // CHECK:            "clang-context-hash": "{{.*}}",
-// CHECK-NEXT:       "clang-module-deps": [
+// CHECK:            "clang-module-deps": [
 // CHECK-NEXT:         {
 // CHECK-NEXT:           "context-hash": "{{.*}}",
 // CHECK-NEXT:           "module-name": "X"
diff --git a/clang/test/ClangScanDeps/modules-context-hash-cwd.c b/clang/test/ClangScanDeps/modules-context-hash-cwd.c
index c609a7dcbc80e..82cee2a19e2dc 100644
--- a/clang/test/ClangScanDeps/modules-context-hash-cwd.c
+++ b/clang/test/ClangScanDeps/modules-context-hash-cwd.c
@@ -75,7 +75,7 @@ module mod {
 // CHECK:     {
 // CHECK-NEXT:  "modules": [
 // CHECK-NEXT:   {
-// CHECK-NEXT:     "clang-module-deps": [],
+// CHECK:          "clang-module-deps": [],
 // CHECK:          "context-hash": "[[HASH:.*]]",
 // CHECK:        }
 // CHECK:       "translation-units": [
@@ -83,7 +83,7 @@ module mod {
 // CHECK:          "commands": [
 // CHECK:          {
 // CHECK-NEXT:        "clang-context-hash": "{{.*}}",
-// CHECK-NEXT:        "clang-module-deps": [
+// CHECK:             "clang-module-deps": [
 // CHECK-NEXT:          {
 // CHECK-NEXT:            "context-hash": "[[HASH]]",
 // CHECK-NEXT:            "module-name": "mod"
@@ -100,7 +100,7 @@ module mod {
 // CHECK:           "commands": [
 // CHECK:           {
 // CHECK-NEXT:         "clang-context-hash": "{{.*}}",
-// CHECK-NEXT:         "clang-module-deps": [
+// CHECK:              "clang-module-deps": [
 // CHECK-NEXT:           {
 // CHECK-NEXT:             "context-hash": "[[HASH]]",
 // CHECK-NEXT:             "module-name": "mod"
@@ -112,7 +112,7 @@ module mod {
 // SKIPOPT:      {
 // SKIPOPT-NEXT:   "modules": [
 // SKIPOPT-NEXT:    {
-// SKIPOPT-NEXT:      "clang-module-deps": [],
+// SKIPOPT:           "clang-module-deps": [],
 // SKIPOPT:           "context-hash": "[[HASH0:.*]]",
 // SKIPOPT:         }
 // SKIPOPT:        "translation-units": [
@@ -120,7 +120,7 @@ module mod {
 // SKIPOPT:            "commands": [
 // SKIPOPT:             {
 // SKIPOPT-NEXT:          "clang-context-hash": "{{.*}}",
-// SKIPOPT-NEXT:          "clang-module-deps": [
+// SKIPOPT:               "clang-module-deps": [
 // SKIPOPT-NEXT:            {
 // SKIPOPT-NEXT:              "context-hash": "[[HASH0]]",
 // SKIPOPT-NEXT:              "module-name": "mod"
@@ -129,7 +129,7 @@ module mod {
 // SKIPOPT:      {
 // SKIPOPT-NEXT:   "modules": [
 // SKIPOPT-NEXT:     {
-// SKIPOPT-NEXT:       "clang-module-deps": [],
+// SKIPOPT:            "clang-module-deps": [],
 // SKIPOPT-NOT:        "context-hash": "[[HASH0]]",
 // SKIPOPT:            "context-hash": "[[HASH2:.*]]",
 // SKIPOPT:          }
@@ -138,7 +138,7 @@ module mod {
 // SKIPOPT:           "commands": [
 // SKIPOPT:             {
 // SKIPOPT-NEXT:          "clang-context-hash": "{{.*}}",
-// SKIPOPT-NEXT:          "clang-module-deps": [
+// SKIPOPT:               "clang-module-deps": [
 // SKIPOPT-NEXT:            {
 // SKIPOPT-NOT:              "context-hash": "[[HASH0]]",
 // SKIPOPT-NEXT:             "context-hash": "[[HASH2]]"
@@ -160,7 +160,7 @@ module mod {
 // RELPATH:            "commands": [
 // RELPATH:             {
 // RELPATH-NEXT:          "clang-context-hash": "{{.*}}",
-// RELPATH-NEXT:          "clang-module-deps": [
+// RELPATH:               "clang-module-deps": [
 // RELPATH-NEXT:            {
 // RELPATH-NEXT:              "context-hash": "[[HASH3]]",
 // RELPATH-NEXT:              "module-name": "mod"
@@ -178,7 +178,7 @@ module mod {
 // RELPATH:           "commands": [
 // RELPATH:             {
 // RELPATH-NEXT:          "clang-context-hash": "{{.*}}",
-// RELPATH-NEXT:          "clang-module-deps": [
+// RELPATH:               "clang-module-deps": [
 // RELPATH-NEXT:            {
 // RELPATH-NOT:              "context-hash": "[[HASH3]]",
 // RELPATH-NEXT:             "context-hash": "[[HASH4]]"
diff --git a/clang/test/ClangScanDeps/modules-context-hash.c b/clang/test/ClangScanDeps/modules-context-hash.c
index 9489563576d3b..0622e1dd96974 100644
--- a/clang/test/ClangScanDeps/modules-context-hash.c
+++ b/clang/test/ClangScanDeps/modules-context-hash.c
@@ -45,7 +45,7 @@
 // CHECK-NEXT:   "translation-units": [
 // CHECK-NEXT:     {
 // CHECK:            "clang-context-hash": "{{.*}}",
-// CHECK-NEXT:       "clang-module-deps": [
+// CHECK:            "clang-module-deps": [
 // CHECK-NEXT:         {
 // CHECK-NEXT:           "context-hash": "[[HASH_MOD_A]]",
 // CHECK-NEXT:           "module-name": "mod"
@@ -83,7 +83,7 @@
 // CHECK-NEXT:   "translation-units": [
 // CHECK-NEXT:     {
 // CHECK:            "clang-context-hash": "{{.*}}",
-// CHECK-NEXT:       "clang-module-deps": [
+// CHECK:            "clang-module-deps": [
 // CHECK-NEXT:         {
 // CHECK-NOT:            "context-hash": "[[HASH_MOD_A]]",
 // CHECK:                "module-name": "mod"
diff --git a/clang/test/ClangScanDeps/modules-dep-args.c b/clang/test/ClangScanDeps/modules-dep-args.c
index 19f915923b84c..41b06580fabb7 100644
--- a/clang/test/ClangScanDeps/modules-dep-args.c
+++ b/clang/test/ClangScanDeps/modules-dep-args.c
@@ -81,7 +81,7 @@ module Direct { header "direct.h" }
 // CHECK-NEXT:   "translation-units": [
 // CHECK-NEXT:     {
 // CHECK:            "clang-context-hash": "{{.*}}",
-// CHECK-NEXT:       "clang-module-deps": [
+// CHECK:            "clang-module-deps": [
 // CHECK-NEXT:         {
 // CHECK-NEXT:           "context-hash": "{{.*}}",
 // CHECK-NEXT:           "module-name": "Direct"
diff --git a/clang/test/ClangScanDeps/modules-extern-submodule.c b/clang/test/ClangScanDeps/modules-extern-submodule.c
index 01d3d6ba5e0d3..757bcdf46edac 100644
--- a/clang/test/ClangScanDeps/modules-extern-submodule.c
+++ b/clang/test/ClangScanDeps/modules-extern-submodule.c
@@ -101,7 +101,7 @@ module third {}
 // CHECK-NEXT:       "commands": [
 // CHECK-NEXT:         {
 // CHECK-NEXT:           "clang-context-hash": "{{.*}}",
-// CHECK-NEXT:           "clang-module-deps": [
+// CHECK:                "clang-module-deps": [
 // CHECK-NEXT:             {
 // CHECK-NEXT:               "context-hash": "{{.*}}",
 // CHECK-NEXT:               "module-name": "first"
diff --git a/clang/test/ClangScanDeps/modules-extern-unrelated.m b/clang/test/ClangScanDeps/modules-extern-unrelated.m
index c003f0d9a2ee8..b81dad896c1ff 100644
--- a/clang/test/ClangScanDeps/modules-extern-unrelated.m
+++ b/clang/test/ClangScanDeps/modules-extern-unrelated.m
@@ -107,7 +107,7 @@
 // CHECK-NEXT:       "commands": [
 // CHECK-NEXT:         {
 // CHECK-NEXT:           "clang-context-hash": "{{.*}}",
-// CHECK-NEXT:           "clang-module-deps": [
+// CHECK:                "clang-module-deps": [
 // CHECK-NEXT:             {
 // CHECK-NEXT:               "context-hash": "{{.*}}",
 // CHECK-NEXT:               "module-name": "zeroth"
diff --git a/clang/test/ClangScanDeps/modules-fmodule-name-no-module-built.m b/clang/test/ClangScanDeps/modules-fmodule-name-no-module-built.m
index cfe29c2bf7cdb..1078545848f20 100644
--- a/clang/test/ClangScanDeps/modules-fmodule-name-no-module-built.m
+++ b/clang/test/ClangScanDeps/modules-fmodule-name-no-module-built.m
@@ -35,7 +35,7 @@
 // CHECK-NEXT:   "translation-units": [
 // CHECK-NEXT:     {
 // CHECK:            "clang-context-hash": "[[HASH_TU:[A-Z0-9]+]]",
-// CHECK-NEXT:       "clang-module-deps": [
+// CHECK:            "clang-module-deps": [
 // CHECK-NEXT:         {
 // CHECK-NEXT:           "context-hash": "[[HASH_H2]]",
 // CHECK-NEXT:           "module-name": "header2"
diff --git a/clang/test/ClangScanDeps/modules-full-named-modules.cppm b/clang/test/ClangScanDeps/modules-full-named-modules.cppm
new file mode 100644
index 0000000000000..e042b702a1fa7
--- /dev/null
+++ b/clang/test/ClangScanDeps/modules-full-named-modules.cppm
@@ -0,0 +1,347 @@
+// This check that clang-scan-deps properly outputs named module dependencies 
+// when using the the scanning output format 'experimental-full'.
+//
+// See commit 72304.
+// UNSUPPORTED: target={{.*}}-aix{{.*}}
+//
+// The slash direction in linux and windows are different.
+// UNSUPPORTED: system-windows
+//
+// RUN: rm -fr %t
+// RUN: mkdir -p %t
+// RUN: split-file %s %t
+//
+// Check the separated dependency format.
+// RUN: sed "s|DIR|%/t|g" %t/compile_commands.json.in > %t/compile_commands.json
+// RUN: clang-scan-deps -format=experimental-full \
+// RUN:   -- %clang++ -std=c++20 -c -fprebuilt-module-path=%t %t/M.cppm -o %t/M.o \
+// RUN:   | FileCheck %t/M.cppm -DPREFIX=%/t
+// RUN: clang-scan-deps -format=experimental-full \
+// RUN:   -- %clang++ -std=c++20 -c -fprebuilt-module-path=%t %t/Impl.cpp -o %t/Impl.o \
+// RUN:   | FileCheck %t/Impl.cpp -DPREFIX=%/t
+// RUN: clang-scan-deps -format=experimental-full \
+// RUN:   -- %clang++ -std=c++20 -c -fprebuilt-module-path=%t %t/impl_part.cppm -o %t/impl_part.o \
+// RUN:   | FileCheck %t/impl_part.cppm -DPREFIX=%/t
+// RUN: clang-scan-deps -format=experimental-full \
+// RUN:   -- %clang++ -std=c++20 -c -fprebuilt-module-path=%t %t/interface_part.cppm -o %t/interface_part.o \
+// RUN:   | FileCheck %t/interface_part.cppm -DPREFIX=%/t
+// RUN: clang-scan-deps -format=experimental-full \
+// RUN:   -- %clang++ -std=c++20 -c -fprebuilt-module-path=%t %t/User.cpp -o %t/User.o \
+// RUN:   | FileCheck %t/User.cpp -DPREFIX=%/t
+//
+// Check the combined dependency format.
+// RUN: clang-scan-deps -compilation-database %t/compile_commands.json -format=experimental-full \
+// RUN:   | FileCheck %t/Checks.cpp -DPREFIX=%/t
+// RUN: clang-scan-deps --mode=preprocess-dependency-directives -compilation-database %t/compile_commands.json -format=experimental-full \
+// RUN:   | FileCheck %t/Checks.cpp -DPREFIX=%/t
+
+//--- compile_commands.json.in
+[
+{
+  "directory": "DIR",
+  "command": "clang++ -std=c++20 DIR/M.cppm -c -o DIR/M.o -MT DIR/M.o.ddi -MD -MF DIR/P1689.dep",
+  "file": "DIR/M.cppm",
+  "output": "DIR/M.o"
+},
+{
+  "directory": "DIR",
+  "command": "clang++ -std=c++20 DIR/Impl.cpp -c -o DIR/Impl.o -MT DIR/Impl.o.ddi -MD -MF DIR/P1689.dep",
+  "file": "DIR/Impl.cpp",
+  "output": "DIR/Impl.o"
+},
+{
+  "directory": "DIR",
+  "command": "clang++ -std=c++20 DIR/impl_part.cppm -c -o DIR/impl_part.o -MT DIR/impl_part.o.ddi -MD -MF DIR/P1689.dep",
+  "file": "DIR/impl_part.cppm",
+  "output": "DIR/impl_part.o"
+},
+{
+  "directory": "DIR",
+  "command": "clang++ -std=c++20 DIR/interface_part.cppm -c -o DIR/interface_part.o -MT DIR/interface_part.o.ddi -MD -MF DIR/P1689.dep",
+  "file": "DIR/interface_part.cppm",
+  "output": "DIR/interface_part.o"
+},
+{
+  "directory": "DIR",
+  "command": "clang++ -std=c++20 DIR/User.cpp -c -o DIR/User.o -MT DIR/User.o.ddi -MD -MF DIR/P1689.dep",
+  "file": "DIR/User.cpp",
+  "output": "DIR/User.o"
+}
+]
+
+//--- M.cppm
+export module M;
+export import :interface_part;
+import :impl_part;
+export void Hello();
+
+// CHECK:       {
+// CHECK:         "modules": []
+// CHECK:         "translation-units": [
+// CHECK-NEXT:      {
+// CHECK:             "commands": [
+// CHECK-NEXT:          {
+// CHECK:                 "module-name": "M"
+// CHECK-NEXT:            "named-module-deps": [
+// CHECK-NEXT:              "M:interface_part",
+// CHECK-NEXT:              "M:impl_part"
+// CHECK-NEXT:             ]
+// CHECK:                 "command-line": [
+// CHECK:                   "-o",
+// CHECK-NEXT:              "{{.*}}/M-{{.*}}.pcm"
+// CHECK:                 ]
+// CHECK:                 "input-file": "[[PREFIX]]/M.cppm"
+// CHECK:               },
+// CHECK-NEXT:          {
+// CHECK:                 "command-line": [
+// CHECK:                   "-o",
+// CHECK-NEXT:              "[[PREFIX]]/M.o"
+// CHECK:                 ]
+// CHECK:                 "input-file": "[[PREFIX]]/M.cppm"
+// CHECK:               }
+// CHECK:             ]
+// CHECK:           }
+// CHECK:         ]
+// CHECK:       }
+
+//--- Impl.cpp
+module;
+#include "header.mock"
+module M;
+void Hello() {
+    std::cout << "Hello ";
+}
+
+// CHECK:       {
+// CHECK:         "modules": []
+// CHECK:         "translation-units": [
+// CHECK-NEXT:      {
+// CHECK:             "commands": [
+// CHECK-NEXT:          {
+// CHECK-NOT:             "module-name":
+// CHECK:                 "named-module-deps": [
+// CHECK-NEXT:              "M"
+// CHECK-NEXT:             ]
+// CHECK:                 "command-line": [
+// CHECK:                   "-o",
+// CHECK-NEXT:              "[[PREFIX]]/Impl.o"
+// CHECK:                 ]
+// CHECK:                 "input-file": "[[PREFIX]]/Impl.cpp"
+// CHECK:               }
+// CHECK:             ]
+// CHECK:           }
+// CHECK:         ]
+// CHECK:       }
+
+//--- impl_part.cppm
+module;
+#include "header.mock"
+module M:impl_part;
+import :interface_part;
+
+std::string W = "World.";
+void World() {
+    std::cout << W << std::endl;
+}
+
+// CHECK:       {
+// CHECK:         "modules": [],
+// CHECK:         "translation-units": [
+// CHECK-NEXT:      {
+// CHECK:             "commands": [
+// CHECK-NEXT:          {
+// CHECK:                 "module-name": "M:impl_part"
+// CHECK-NEXT:            "named-module-deps": [
+// CHECK-NEXT:              "M:interface_part"
+// CHECK-NEXT:             ]
+// CHECK:                 "command-line": [
+// CHECK:                   "-o",
+// CHECK-NEXT:              "{{.*}}/impl_part-{{.*}}.pcm",
+// CHECK:                 ]
+// CHECK:                 "input-file": "[[PREFIX]]/impl_part.cppm"
+// CHECK:               },
+// CHECK-NEXT:          {
+// CHECK:                 "module-name": "M:impl_part"
+// CHECK-NEXT:            "named-module-deps": [
+// CHECK-NEXT:              "M:interface_part"
+// CHECK-NEXT:             ]
+// CHECK:                 "command-line": [
+// CHECK:                   "-o",
+// CHECK-NEXT:              "[[PREFIX]]/impl_part.o",
+// CHECK:                 ]
+// CHECK:                 "input-file": "[[PREFIX]]/impl_part.cppm"
+// CHECK:               }
+// CHECK:             ]
+// CHECK:           }
+// CHECK:         ]
+// CHECK:       }
+
+//--- interface_part.cppm
+export module M:interface_part;
+export void World();
+
+// CHECK:       {
+// CHECK:         "modules": []
+// CHECK:         "translation-units": [
+// CHECK-NEXT:      {
+// CHECK:             "commands": [
+// CHECK-NEXT:          {
+// CHECK:                 "module-name": "M:interface_part"
+// CHECK-NEXT:            "named-module-deps": []
+// CHECK:                 "command-line": [
+// CHECK:                   "-o",
+// CHECK-NEXT:              "{{.*}}/interface_part-{{.*}}.pcm",
+// CHECK:                 ]
+// CHECK:                 "input-file": "[[PREFIX]]/interface_part.cppm"
+// CHECK:               },
+// CHECK-NEXT:          {
+// CHECK:                 "module-name": "M:interface_part"
+// CHECK-NEXT:            "named-module-deps": []
+// CHECK:                 "command-line": [
+// CHECK:                   "-o",
+// CHECK-NEXT:              "[[PREFIX]]/interface_part.o",
+// CHECK:                 ]
+// CHECK:                 "input-file": "[[PREFIX]]/interface_part.cppm"
+// CHECK:               }
+// CHECK:             ]
+// CHECK:           }
+// CHECK:         ]
+// CHECK:       }
+
+//--- User.cpp
+import M;
+import third_party_module;
+int main() {
+    Hello();
+    World();
+    return 0;
+}
+
+// CHECK:       {
+// CHECK-NEXT:    "modules": []
+// CHECK-NEXT:    "translation-units": [
+// CHECK-NEXT:      {
+// CHECK-NEXT:        "commands": [
+// CHECK-NEXT:          {
+// CHECK-NOT:             "module-name":
+// CHECK:                 "named-module-deps": [
+// CHECK-NEXT:              "M"
+// CHECK-NEXT:   ...
[truncated]

``````````

</details>


https://github.com/llvm/llvm-project/pull/145221


More information about the cfe-commits mailing list