Skip to content

[clang][modules-driver] Add support for C++ named modules and import std - #193312

Merged
naveen-seth merged 8 commits into
llvm:mainfrom
naveen-seth:modules-driver-cxx-named-modules
Apr 23, 2026
Merged

[clang][modules-driver] Add support for C++ named modules and import std#193312
naveen-seth merged 8 commits into
llvm:mainfrom
naveen-seth:modules-driver-cxx-named-modules

Conversation

@naveen-seth

@naveen-seth naveen-seth commented Apr 21, 2026

Copy link
Copy Markdown
Contributor

This patch adds basic support for explicit C++ named module builds, managed natively by the Clang driver, including support for use of the Standard library modules.

This follows #187606, which adds the same for Clang modules.

Current limitations:

  • Standard library modules are still compiled to object files instead of using the provided shared library. (This will be addressed in a follow-up soon.)
  • Caching is not supported yet (but likely to be added during the upcoming GSoC cycle).
  • Importing C++ standard library modules into Clang modules is not supported (and not expected in the near term).

RFC: https://discourse.llvm.org/t/rfc-modules-support-simple-c-20-modules-use-from-the-clang-driver-without-a-build-system

… std`

This patch adds basic support for explicit module builds using C++ named
modules, managed natively by the Clang driver, including the use of Standard
library modules.
This follows llvm#187606, which adds the same support for explicit Clang module
builds.

This currently compiles object files even for Standard library modules, which
will be addressed in a follow-up patch.

RFC:
https://discourse.llvm.org/t/rfc-modules-support-simple-c-20-modules-use-from-the-clang-driver-without-a-build-system

(Caching of built modules is not included in this patch.)
@llvmbot llvmbot added clang Clang issues not falling into any other category clang:driver 'clang' and 'clang++' user-facing binaries. Not 'clang-cl' clang:frontend Language frontend issues, e.g. anything involving "Sema" labels Apr 21, 2026
@llvmbot

llvmbot commented Apr 21, 2026

Copy link
Copy Markdown
Member

@llvm/pr-subscribers-clang-driver

@llvm/pr-subscribers-clang

Author: Naveen Seth Hanig (naveen-seth)

Changes

This patch adds basic support for explicit module builds using C++ named modules, managed natively by the Clang driver, including the use of Standard library modules.
This follows #187606, which adds the same support for explicit Clang module builds.

This currently compiles object files even for Standard library modules, which will be addressed in a follow-up patch.

RFC:
https://discourse.llvm.org/t/rfc-modules-support-simple-c-20-modules-use-from-the-clang-driver-without-a-build-system

(Caching of built modules is not included in this patch.)


Full diff: https://github.com/llvm/llvm-project/pull/193312.diff

8 Files Affected:

  • (modified) clang/include/clang/Basic/DiagnosticDriverKinds.td (+2)
  • (modified) clang/include/clang/Driver/ModulesDriver.h (+4)
  • (modified) clang/lib/Driver/Driver.cpp (+2)
  • (modified) clang/lib/Driver/ModulesDriver.cpp (+95-10)
  • (added) clang/test/Driver/modules-driver-both-modules-types.cpp (+111)
  • (added) clang/test/Driver/modules-driver-cxx-modules-only.cpp (+89)
  • (added) clang/test/Driver/modules-driver-import-std.cpp (+60)
  • (added) clang/test/Driver/modules-driver-incompatible-options.cpp (+10)
diff --git a/clang/include/clang/Basic/DiagnosticDriverKinds.td b/clang/include/clang/Basic/DiagnosticDriverKinds.td
index f217180933b9b..724b639c4889f 100644
--- a/clang/include/clang/Basic/DiagnosticDriverKinds.td
+++ b/clang/include/clang/Basic/DiagnosticDriverKinds.td
@@ -613,6 +613,8 @@ def err_drv_reduced_module_output_overrided : Warning<
   "please consider use '-fmodule-output=' to specify the output file for reduced BMI explicitly">,
   InGroup<DiagGroup<"reduced-bmi-output-overrided">>;
 
+def err_drv_modules_driver_requires_reduced_bmi : Error<
+  "-fmodules-driver' is incompatible with '-fno-modules-reduced-bmi">;
 def remark_performing_driver_managed_module_build : Remark<
   "performing driver managed module build">, InGroup<ModulesDriver>;
 def remark_modules_manifest_not_found : Remark<
diff --git a/clang/include/clang/Driver/ModulesDriver.h b/clang/include/clang/Driver/ModulesDriver.h
index 4f5fe7a7dfc1a..7146d2f6b143f 100644
--- a/clang/include/clang/Driver/ModulesDriver.h
+++ b/clang/include/clang/Driver/ModulesDriver.h
@@ -32,6 +32,10 @@ class Compilation;
 
 namespace clang::driver::modules {
 
+/// Emits diagnostics for arguments incompatible with -fmodules-driver.
+void diagnoseModulesDriverArgs(llvm::opt::DerivedArgList &DAL,
+                               DiagnosticsEngine &Diags);
+
 /// The parsed Standard library module manifest.
 struct StdModuleManifest {
   struct Module {
diff --git a/clang/lib/Driver/Driver.cpp b/clang/lib/Driver/Driver.cpp
index 2cbe3179892ff..1e6a7b5e59d0f 100644
--- a/clang/lib/Driver/Driver.cpp
+++ b/clang/lib/Driver/Driver.cpp
@@ -1832,6 +1832,8 @@ Compilation *Driver::BuildCompilation(ArrayRef<const char *> ArgList) {
   if (UseModulesDriver) {
     Diags.Report(diag::remark_performing_driver_managed_module_build);
 
+    modules::diagnoseModulesDriverArgs(C->getArgs(), Diags);
+
     // Read the Standard library module manifest and, if available, add all
     // discovered modules to this Compilation. Jobs for modules specified in
     // the manifest that are not required by any command-line input are pruned
diff --git a/clang/lib/Driver/ModulesDriver.cpp b/clang/lib/Driver/ModulesDriver.cpp
index 82865f903590f..f2b994720b411 100644
--- a/clang/lib/Driver/ModulesDriver.cpp
+++ b/clang/lib/Driver/ModulesDriver.cpp
@@ -21,6 +21,7 @@
 #include "clang/Driver/Job.h"
 #include "clang/Driver/Tool.h"
 #include "clang/Driver/ToolChain.h"
+#include "clang/Driver/Types.h"
 #include "clang/Frontend/StandaloneDiagnostic.h"
 #include "llvm/ADT/DenseSet.h"
 #include "llvm/ADT/DepthFirstIterator.h"
@@ -47,6 +48,14 @@ using namespace clang;
 using namespace driver;
 using namespace modules;
 
+void driver::modules::diagnoseModulesDriverArgs(llvm::opt::DerivedArgList &DAL,
+                                                DiagnosticsEngine &Diags) {
+  if (!DAL.hasFlag(options::OPT_fmodules_reduced_bmi,
+                   options::OPT_fno_modules_reduced_bmi, true)) {
+    Diags.Report(diag::err_drv_modules_driver_requires_reduced_bmi);
+  }
+}
+
 namespace clang::driver::modules {
 static bool fromJSON(const llvm::json::Value &Params,
                      StdModuleManifest::Module::LocalArguments &LocalArgs,
@@ -1231,6 +1240,16 @@ static SmallVector<JobNode *> createNodesForUnusedStdlibModuleJobs(
   return StdlibModuleNodesToPrune;
 }
 
+// Returns the derived argument list for the tool chain responsible
+// for creating \p Job.
+static const DerivedArgList &getToolChainArgs(Compilation &C,
+                                              const Command &Job) {
+  const auto &TC = Job.getCreator().getToolChain();
+  const auto &SourceAction = Job.getSource();
+  return C.getArgsForToolChain(&TC, SourceAction.getOffloadingArch(),
+                               SourceAction.getOffloadingDeviceKind());
+}
+
 /// Creates a job for the Clang module described by \p MD.
 static std::unique_ptr<Command>
 createClangModulePrecompileJob(Compilation &C, const Command &ImportingJob,
@@ -1242,9 +1261,7 @@ createClangModulePrecompileJob(Compilation &C, const Command &ImportingJob,
   Action *PA = C.MakeAction<PrecompileJobAction>(IA, types::ID::TY_ModuleFile);
   PA->propagateOffloadInfo(&ImportingJob.getSource());
 
-  const auto &TC = ImportingJob.getCreator().getToolChain();
-  const auto &TCArgs = C.getArgsForToolChain(&TC, PA->getOffloadingArch(),
-                                             PA->getOffloadingDeviceKind());
+  const auto &TCArgs = getToolChainArgs(C, ImportingJob);
 
   const auto &BuildArgs = MD.getBuildArguments();
   ArgStringList JobArgs;
@@ -1298,12 +1315,7 @@ installScanCommandLines(Compilation &C,
     ArgStringList JobArgs;
     JobArgs.reserve(BuildArgs.size());
 
-    const auto &SourceAction = Job.getSource();
-    const auto &TC = Job.getCreator().getToolChain();
-    auto &TCArgs =
-        C.getArgsForToolChain(&TC, SourceAction.getOffloadingArch(),
-                              SourceAction.getOffloadingDeviceKind());
-
+    auto &TCArgs = getToolChainArgs(C, Job);
     for (const auto &Arg : BuildArgs)
       JobArgs.push_back(TCArgs.MakeArgString(Arg));
 
@@ -1506,6 +1518,79 @@ static void createAndConnectRoot(CompilationGraph &Graph) {
   }
 }
 
+/// Creates a temporary output path for \p ModuleName.
+static std::string createModuleOutputPath(const Compilation &C,
+                                          StringRef ModuleName) {
+  auto ModuleOutputPath = C.getDriver().GetTemporaryPath(
+      ModuleName, types::getTypeTempSuffix(types::TY_ModuleFile));
+  // Sanitize the ':' included in parition names. It is illegal for filenames on
+  // Windows.
+  llvm::replace(ModuleOutputPath, ':', '_');
+  return ModuleOutputPath;
+}
+
+/// Adds arguments to output the module produced by \p Node at \p OutputPath.
+static void configureNamedModuleOutputArgs(Compilation &C,
+                                           NamedModuleJobNode &Node,
+                                           StringRef ModuleOutputPath) {
+  auto &Job = *Node.Job;
+  const auto &TCArgs = getToolChainArgs(C, Job);
+  auto JobArgs = Job.getArguments();
+
+  JobArgs.push_back(
+      TCArgs.MakeArgString("-fmodule-output=" + ModuleOutputPath));
+  // Ensure that this job will emit a module. If the main input for this job
+  // is not of types::CXXModule, we need to explicitly add this.
+  if (Job.getInputInfos().front().getType() != types::TY_CXXModule) {
+    JobArgs.push_back(TCArgs.MakeArgString("-fmodules-reduced-bmi"));
+  }
+
+  Job.replaceArguments(std::move(JobArgs));
+}
+
+/// Propagates -fmodule-file mappings to dependent jobs of the named module
+/// described by \p Node.
+static void propagateModuleFileMappingArgs(Compilation &C,
+                                           NamedModuleJobNode &Node,
+                                           StringRef ModuleOutputPath) {
+  const StringRef ModuleName = Node.InputDeps.ModuleName;
+
+  auto DependentNodes = llvm::drop_begin(llvm::depth_first<CGNode *>(&Node));
+  auto DependentScannedNodes = llvm::map_range(
+      llvm::make_filter_range(DependentNodes, llvm::IsaPred<ScannedJobNode>),
+      llvm::CastTo<ScannedJobNode>);
+
+  for (ScannedJobNode *DependentNode : DependentScannedNodes) {
+    auto &DependentJob = *DependentNode->Job;
+    const auto &TCArgs = getToolChainArgs(C, DependentJob);
+    auto JobArgs = DependentJob.getArguments();
+    JobArgs.push_back(TCArgs.MakeArgString("-fmodule-file=" + ModuleName + "=" +
+                                           ModuleOutputPath));
+    DependentJob.replaceArguments(std::move(JobArgs));
+  }
+}
+
+/// Finalizes command lines for C++20 named module dependencies.
+///
+/// The command lines produced by dependency scanning are only adjusted to
+/// handle discovered Clang modules. For C++20 named modules, we update the
+/// command-lines here.
+static void fixupNamedModuleCommandLines(Compilation &C,
+                                         CompilationGraph &Graph) {
+  const auto NamedModuleNodes = llvm::map_range(
+      llvm::make_filter_range(Graph, llvm::IsaPred<NamedModuleJobNode>),
+      llvm::CastTo<NamedModuleJobNode>);
+
+  for (NamedModuleJobNode *Node : NamedModuleNodes) {
+    const StringRef ModuleName = Node->InputDeps.ModuleName;
+    const auto ModuleOutputPath = createModuleOutputPath(C, ModuleName);
+    C.addTempFile(C.getArgs().MakeArgString(ModuleOutputPath));
+
+    configureNamedModuleOutputArgs(C, *Node, ModuleOutputPath);
+    propagateModuleFileMappingArgs(C, *Node, ModuleOutputPath);
+  }
+}
+
 /// Moves jobs from \p Graph into \p C in the graph's topological order.
 static void feedJobsBackIntoCompilation(Compilation &C,
                                         CompilationGraph &&Graph) {
@@ -1575,7 +1660,7 @@ void driver::modules::runModulesDriver(
   if (!Diags.isLastDiagnosticIgnored())
     llvm::WriteGraph<const CompilationGraph *>(llvm::errs(), &Graph);
 
-  // TODO: Fix-up command-lines for named module imports.
+  fixupNamedModuleCommandLines(C, Graph);
 
   feedJobsBackIntoCompilation(C, std::move(Graph));
 }
diff --git a/clang/test/Driver/modules-driver-both-modules-types.cpp b/clang/test/Driver/modules-driver-both-modules-types.cpp
new file mode 100644
index 0000000000000..3c42261914c4d
--- /dev/null
+++ b/clang/test/Driver/modules-driver-both-modules-types.cpp
@@ -0,0 +1,111 @@
+// Checks that -fmodules-driver correctly handles compilations using both
+// Standard C++20 modules and Clang modules.
+// Importing a Standard C++20 module into Clang module is not supported yet.
+
+// RUN: split-file %s %t
+// RUN: rm -rf %t/modules-cache
+
+// RUN: %clang -c -std=c++23 \
+// RUN:   -fmodules-driver -Rmodules-driver \
+// RUN:   -fmodules -Rmodule-import \
+// RUN:   -fmodule-map-file=%t/module.modulemap \
+// RUN:   -fmodules-cache-path=%t/modules-cache \
+// RUN:   %t/main.cpp %t/A.cppm %t/A-part1.cppm %t/A-part1-impl.cpp 2>&1 \
+// RUN:   | sed 's:\\\\\?:/:g' \
+// RUN:   | FileCheck -DPREFIX=%/t --check-prefix=CHECK-REMARKS %s
+
+// The scan itself will also produce [-Rmodule-import] remarks.
+// Let's skip past them, we only care about the final -cc1 commands.
+// CHECK-REMARKS:       clang: remark: printing module dependency graph [-Rmodules-driver]
+// CHECK-REMARKS-NEXT:  digraph "Module Dependency Graph" {
+// CHECK-REMARKS:       }
+
+// CHECK-REMARKS: [[PREFIX]]/A-part1-impl.cpp:2:2: remark: importing module 'root' from
+// CHECK-REMARKS: [[PREFIX]]/A-part1.cppm:2:2: remark: importing module 'root' from
+// CHECK-REMARKS: [[PREFIX]]/A.cppm:2:2: remark: importing module 'root' from
+// CHECK-REMARKS: [[PREFIX]]/A.cppm:4:8: remark: importing module 'A:part1' from
+// CHECK-REMARKS: [[PREFIX]]/A.cppm:4:8: remark: importing module 'root' into 'A:part1' from
+// CHECK-REMARKS: [[PREFIX]]/main.cpp:1:1: remark: importing module 'A' from
+// CHECK-REMARKS: [[PREFIX]]/main.cpp:1:1: remark: importing module 'root' into 'A' from
+// CHECK-REMARKS: [[PREFIX]]/main.cpp:1:1: remark: importing module 'A:part1' into 'A' from
+// CHECK-REMARKS: [[PREFIX]]/main.cpp:1:1: remark: importing module 'root' into 'A:part1' from
+
+// RUN: %clang -std=c++23 \
+// RUN:   -fmodules-driver -Rmodules-driver \
+// RUN:   -fmodules -Rmodule-import \
+// RUN:   -fmodule-map-file=%t/module.modulemap \
+// RUN:   -fmodules-cache-path=%t/modules-cache \
+// RUN:   %t/main.cpp %t/A.cppm %t/A-part1.cppm %t/A-part1-impl.cpp \
+// RUN:   -### 2>&1 \
+// RUN:   | sed 's:\\\\\?:/:g' \
+// RUN:   | FileCheck -DPREFIX=%/t --check-prefix=CHECK-CC1 %s
+
+// CHECK-CC1: "-cc1"
+// CHECK-CC1-SAME: "-o" "[[ROOTPCM:[^"]+]]"
+// CHECK-CC1-SAME: "-emit-module"
+// CHECK-CC1-SAME: "[[PREFIX]]/module.modulemap"
+// CHECK-CC1-SAME: "-fmodule-name=root"
+// CHECK-CC1-SAME: "-fno-implicit-modules"
+
+// CHECK-CC1: "-cc1"
+// CHECK-CC1-SAME: "[[PREFIX]]/A-part1-impl.cpp"
+// CHECK-CC1-SAME: "-fmodule-file=root=[[ROOTPCM]]"
+// CHECK-CC1-SAME: "-fno-implicit-modules"
+// CHECK-CC1-SAME: "-fmodule-output=[[A_PART1_IMPL_PCM:[^"]+]]"
+
+// CHECK-CC1: "-cc1"
+// CHECK-CC1-SAME: "[[PREFIX]]/A-part1.cppm"
+// CHECK-CC1-SAME: "-fmodule-file=root=[[ROOTPCM]]"
+// CHECK-CC1-SAME: "-fno-implicit-modules"
+// CHECK-CC1-SAME: "-fmodule-output=[[A_PART1_PCM:[^"]+]]"
+
+// CHECK-CC1: "-cc1"
+// CHECK-CC1-SAME: "[[PREFIX]]/A.cppm"
+// CHECK-CC1-SAME: "-fmodule-file=root=[[ROOTPCM]]"
+// CHECK-CC1-SAME: "-fno-implicit-modules"
+// CHECK-CC1-SAME: "-fmodule-output=[[A_PCM:[^"]+]]"
+// CHECK-CC1-SAME: "-fmodule-file=A:part1=[[A_PART1_PCM]]"
+
+// CHECK-CC1: "-cc1"
+// CHECK-CC1-SAME: "[[PREFIX]]/main.cpp"
+// CHECK-CC1-SAME: "-fno-implicit-modules"
+// CHECK-CC1-SAME: "-fmodule-file=A=[[A_PCM]]"
+// CHECK-CC1-SAME: "-fmodule-file=A:part1=[[A_PART1_PCM]]"
+
+//--- main.cpp
+import A;
+
+int main() {
+  a();
+}
+
+//--- A.cppm
+module;
+#include "root.h"
+export module A;
+export import :part1;
+
+export int a() {
+  return part1() + root();
+}
+
+//--- A-part1.cppm
+module;
+#include "root.h"
+export module A:part1;
+export int part1();
+
+//--- A-part1-impl.cpp
+module;
+#include "root.h"
+module A:part1_impl;
+
+int part1() {
+  return root();
+}
+
+//--- module.modulemap
+module root { header "root.h" export * }
+
+//--- root.h
+inline int root() { return 1; }
diff --git a/clang/test/Driver/modules-driver-cxx-modules-only.cpp b/clang/test/Driver/modules-driver-cxx-modules-only.cpp
new file mode 100644
index 0000000000000..b3a3cef9a8ee0
--- /dev/null
+++ b/clang/test/Driver/modules-driver-cxx-modules-only.cpp
@@ -0,0 +1,89 @@
+// Checks that -fmodules-driver correctly handles compilations using
+// Standard C++20 modules.
+
+// RUN: split-file %s %t
+
+// RUN: %clang -c -std=c++23 \
+// RUN:   -fmodules-driver -Rmodules-driver -Rmodule-import \
+// RUN:   %t/main.cpp %t/A.cppm %t/A-part1.cppm %t/A-part1-impl.cpp %t/B.cppm 2>&1 \
+// RUN:   | sed 's:\\\\\?:/:g' \
+// RUN:   | FileCheck -DPREFIX=%/t --check-prefix=CHECK-REMARKS %s
+
+// CHECK-REMARKS: [[PREFIX]]/A.cppm:2:8: remark: importing module 'A:part1' from
+// CHECK-REMARKS: [[PREFIX]]/A.cppm:3:1: remark: importing module 'B' from
+// CHECK-REMARKS: [[PREFIX]]/main.cpp:1:1: remark: importing module 'A' from
+// CHECK-REMARKS: [[PREFIX]]/main.cpp:1:1: remark: importing module 'A:part1' into 'A' from
+// CHECK-REMARKS: [[PREFIX]]/main.cpp:1:1: remark: importing module 'B' into 'A' from
+// CHECK-REMARKS: [[PREFIX]]/main.cpp:2:1: remark: importing module 'B' from
+
+// RUN: %clang -std=c++23 \
+// RUN:   -fmodules-driver -Rmodules-driver -Rmodule-import \
+// RUN:   %t/main.cpp %t/A.cppm %t/A-part1.cppm %t/A-part1-impl.cpp %t/B.cppm \
+// RUN:   -### 2>&1 \
+// RUN:   | sed 's:\\\\\?:/:g' \
+// RUN:   | FileCheck --check-prefix=CHECK-CC1 %s
+
+// CHECK-CC1: "-cc1"
+// CHECK-CC1-SAME: "{{.*}}/B.cppm"
+// CHECK-CC1-SAME: "-fno-implicit-modules"
+// CHECK-CC1-SAME: "-fmodule-output=[[B_PCM:[^"]+]]"
+
+// CHECK-CC1: "-cc1"
+// CHECK-CC1-SAME: "{{.*}}/A-part1-impl.cpp"
+// CHECK-CC1-SAME: "-fno-implicit-modules"
+// CHECK-CC1-SAME: "-fmodule-output=[[A_PART1_IMPL_PCM:[^"]+]]"
+// CHECK-CC1-SAME: "-fmodules-reduced-bmi"
+
+// CHECK-CC1: "-cc1"
+// CHECK-CC1-SAME: "{{.*}}/A-part1.cppm"
+// CHECK-CC1-SAME: "-fno-implicit-modules"
+// CHECK-CC1-SAME: "-fmodule-output=[[A_PART1_PCM:[^"]+]]"
+
+// CHECK-CC1: "-cc1"
+// CHECK-CC1-SAME: "{{.*}}/A.cppm"
+// CHECK-CC1-SAME: "-fno-implicit-modules"
+// CHECK-CC1-SAME: "-fmodule-output=[[A_PCM:[^"]+]]"
+// CHECK-CC1-SAME: "-fmodule-file=A:part1=[[A_PART1_PCM]]"
+// CHECK-CC1-SAME: "-fmodule-file=B=[[B_PCM]]"
+
+// CHECK-CC1: "-cc1"
+// CHECK-CC1-SAME: "{{.*}}/main.cpp"
+// CHECK-CC1-SAME: "-fno-implicit-modules"
+// CHECK-CC1-SAME: "-fmodule-file=A=[[A_PCM]]"
+// CHECK-CC1-SAME: "-fmodule-file=A:part1=[[A_PART1_PCM]]"
+// CHECK-CC1-SAME: "-fmodule-file=B=[[B_PCM]]"
+
+//--- main.cpp
+import A;
+import B;
+
+int main() {
+  return a() + b();
+}
+
+//--- A.cppm
+export module A;
+export import :part1;
+import B;
+
+export int a() {
+  return part1() + b();
+}
+
+//--- A-part1.cppm
+export module A:part1;
+export int part1();
+
+//--- A-part1-impl.cpp
+module A:part1_impl;
+
+int part1() {
+  return 30;
+}
+
+//--- B.cppm
+export module B;
+
+export int b() {
+  return 12;
+}
diff --git a/clang/test/Driver/modules-driver-import-std.cpp b/clang/test/Driver/modules-driver-import-std.cpp
new file mode 100644
index 0000000000000..25dc059b73ec7
--- /dev/null
+++ b/clang/test/Driver/modules-driver-import-std.cpp
@@ -0,0 +1,60 @@
+// Checks that -fmodules-driver correctly handles the import of Standard library
+// modules.
+
+// The standard library modules manifest (libc++.modules.json) is discovered
+// relative to the installed C++ standard library runtime libraries
+// We need to create them in order for Clang to find the manifest.
+// RUN: rm -rf %t && split-file %s %t
+// RUN: mkdir -p %t/Inputs/usr/lib/x86_64-linux-gnu
+// RUN: touch %t/Inputs/usr/lib/x86_64-linux-gnu/libc++.so
+// RUN: touch %t/Inputs/usr/lib/x86_64-linux-gnu/libc++.a
+
+// RUN: sed "s|DIR|%/t|g" %t/libc++.modules.json.in > \
+// RUN:   %t/Inputs/usr/lib/x86_64-linux-gnu/libc++.modules.json
+
+// RUN: mkdir -p %t/Inputs/usr/lib/share/libc++/v1
+// RUN: cat %t/std.cppm > %t/Inputs/usr/lib/share/libc++/v1/std.cppm
+// RUN: cat %t/std.compat.cppm > %t/Inputs/usr/lib/share/libc++/v1/std.compat.cppm
+
+//--- libc++.modules.json.in
+{
+  "version": 1,
+  "revision": 1,
+  "modules": [
+    {
+      "logical-name": "std",
+      "source-path": "../share/libc++/v1/std.cppm",
+      "is-std-library": true
+    },
+    {
+      "logical-name": "std.compat",
+      "source-path": "../share/libc++/v1/std.compat.cppm",
+      "is-std-library": true
+    }
+  ]
+}
+
+//--- std.cppm
+export module std;
+
+//--- std.compat.cppm
+export module std.compat;
+import std;
+
+//--- main.cpp
+import std.compat;
+import std;
+
+int main() {}
+
+// RUN: %clang -std=c++23 -c -fmodules-driver -Rmodules-driver -Rmodule-import \
+// RUN:   -stdlib=libc++ \
+// RUN:   -resource-dir=%t/Inputs/usr/lib/x86_64-linux-gnu \
+// RUN:   --target=x86_64-linux-gnu \
+// RUN:   %t/main.cpp 2>&1 \
+// RUN:   | sed 's:\\\\\?:/:g' \
+// RUN:   | FileCheck -DPREFIX=%/t %s
+
+// CHECK: [[PREFIX]]/main.cpp:1:1: remark: importing module 'std.compat' from
+// CHECK: [[PREFIX]]/main.cpp:1:1: remark: importing module 'std' into 'std.compat' from
+// CHECK: [[PREFIX]]/main.cpp:2:1: remark: importing module 'std' from
diff --git a/clang/test/Driver/modules-driver-incompatible-options.cpp b/clang/test/Driver/modules-driver-incompatible-options.cpp
new file mode 100644
index 0000000000000..0d1cae94f8975
--- /dev/null
+++ b/clang/test/Driver/modules-driver-incompatible-options.cpp
@@ -0,0 +1,10 @@
+// Checks for diagnostics that report incompatibilities between
+// -fmodules-driver and other options.
+
+// RUN: split-file %s %t
+// RUN: not %clang -std=c++20 -fmodules-driver -fno-modules-reduced-bmi main.cpp -###
+
+// CHECK: clang: error: -fmodules-driver' is incompatible with '-fno-modules-reduced-bmi'
+
+//--- main.cpp
+int main() {}

@github-actions

github-actions Bot commented Apr 21, 2026

Copy link
Copy Markdown

🪟 Windows x64 Test Results

  • 55328 tests passed
  • 2464 tests skipped

✅ The build succeeded and all tests passed.

@naveen-seth

Copy link
Copy Markdown
Contributor Author

When testing locally with -std=libc++ and -fmodules, you might run into a crash.
This is because Clang does not yet handle imports correctly when a Clang module has the same name as the importing Standard C++ module. This will be fixed soon.

RE documentation, I plan to update
https://clang.llvm.org/docs/StandardCPlusPlusModules.html#how-to-enable-standard-c-modules
and the release notes once the shared-library issue for standard library modules is resolved.
I’m not exactly sure yet where to add to the StandardCPlusPlusModules doc.

@ChuanqiXu9

Copy link
Copy Markdown
Member

This is because Clang does not yet handle imports correctly when a Clang module has the same name as the importing Standard C++ module. This will be fixed soon.

I am interested in this. I feel the current status consistent with my impression. Why do you think it is a clang bug? Instead of a user (build system) bug?

I’m not exactly sure yet where to add to the StandardCPlusPlusModules doc.

It is clang/docs/StandardCPlusPlusModules.rst


The title and the summary make me confused. The title said "add support for .. and import std" but the summary shows import std is not supported.

@naveen-seth

naveen-seth commented Apr 22, 2026

Copy link
Copy Markdown
Contributor Author

This is because Clang does not yet handle imports correctly when a Clang module has the same name as the importing Standard C++ module. This will be fixed soon.

I am interested in this. I feel the current status consistent with my impression. Why do you think it is a clang bug? Instead of a user (build system) bug?

For a minimal reproducer, modify clang/test/Modules/named-module-with-fmodules.cppm such that the exported module from A.cppm is also named foo. This should crash.

A fix can be applied here, by checking that the Existing is not a named module.

if (Module *Existing = Map.lookupModuleQualified(ModuleName, ActiveModule)) {

I'll create a good-first-issue for this later today!

I’m not exactly sure yet where to add to the StandardCPlusPlusModules doc.

It is clang/docs/StandardCPlusPlusModules.rst

Oh sorry, I should have worded this better! I meant that I'm not yet sure how to go about adding this; if it should go somewhere in `How to build projects using modules or in a section at the bottom.

The title and the summary make me confused. The title said "add support for .. and import std" but the summary shows import std is not supported.

import std is supported, but when using it we currently also produce an object file from the std.cppm and link against it (as if we had -static). I'm working on a fix for this but would like to do it as a follow-up.

@ChuanqiXu9

Copy link
Copy Markdown
Member

This is because Clang does not yet handle imports correctly when a Clang module has the same name as the importing Standard C++ module. This will be fixed soon.

I am interested in this. I feel the current status consistent with my impression. Why do you think it is a clang bug? Instead of a user (build system) bug?

For a minimal reproducer, modify clang/test/Modules/named-module-with-fmodules.cppm such that the exported module from A.cppm is also named foo. This should crash.

A fix can be applied here, by checking that the Existing is not a named module.

if (Module *Existing = Map.lookupModuleQualified(ModuleName, ActiveModule)) {

I'll create a good-first-issue for this later today!

Crash is bad. But I think if the name are duplicated we should try to diagnose and reject instead of accept it. Named module has names and clang header modules has name too. So this is a user/build system problem to me. Naturally duplicated module name issue.

I’m not exactly sure yet where to add to the StandardCPlusPlusModules doc.

It is clang/docs/StandardCPlusPlusModules.rst

Oh sorry, I should have worded this better! I meant that I'm not yet sure how to go about adding this; if it should go somewhere in `How to build projects using modules or in a section at the bottom.

We can discuss this in other patch.

The title and the summary make me confused. The title said "add support for .. and import std" but the summary shows import std is not supported.

import std is supported, but when using it we currently also produce an object file from the std.cppm and link against it (as if we had -static). I'm working on a fix for this but would like to do it as a follow-up.

This is slightly stricky as it is an ecosystem problem. As we always know, the ecosystem of C++ is almost always a mess. You may have to hard code some dirty information in the driver like the version of libstdc++. I like to remain the behavior to produce an object file from the std.cppm for older libstdc++. We don't need this for libc++ as far as I know.

Comment thread clang/include/clang/Basic/DiagnosticDriverKinds.td Outdated
Comment thread clang/lib/Driver/ModulesDriver.cpp Outdated
Comment thread clang/lib/Driver/ModulesDriver.cpp Outdated
@naveen-seth

naveen-seth commented Apr 22, 2026

Copy link
Copy Markdown
Contributor Author

Crash is bad. But I think if the name are duplicated we should try to diagnose and reject instead of accept it. Named module has names and clang header modules has name too. So this is a user/build system problem to me. Naturally duplicated module name issue.

I feel that it coould be acceptable for a named module and a Clang module to share the same name. libc++ currently implements the std named module using a Clang module also named std, and that feels reasonable to me.

graphviz

This is slightly stricky as it is an ecosystem problem. As we always know, the ecosystem of C++ is almost always a mess. You may have to hard code some dirty information in the driver like the version of libstdc++. I like to remain the behavior to produce an object file from the std.cppm for older libstdc++. We don't need this for libc++ as far as I know.

This is good to know! Thanks!

@ChuanqiXu9

Copy link
Copy Markdown
Member

Crash is bad. But I think if the name are duplicated we should try to diagnose and reject instead of accept it. Named module has names and clang header modules has name too. So this is a user/build system problem to me. Naturally duplicated module name issue.

I feel that it coould be acceptable for a named module and a Clang module to share the same name. libc++ currently implements the std named module using a Clang module also named std, and that feels reasonable to me.

No. Strongly No. It is bad to handle such cases. The fact that the semantics of libc++'s std module is similar with the C++20 named 'std' module is just a coincidence. I believe if we allow such cases, it will be super confusing one day more people mixed the use of clang header modules and C++20 named modules.

Strongly against again.

@naveen-seth
naveen-seth requested a review from ChuanqiXu9 April 23, 2026 00:09
naveen-seth added a commit that referenced this pull request Apr 23, 2026
#193629)

This changes the modules driver to only allow files of type `-x
c++module` to define a module.
This makes it easier to add support for `-fno-modules-reduced-bmi` later
on and better follows Clang conventions.

Addresses:
#193312 (comment)
@naveen-seth
naveen-seth enabled auto-merge (squash) April 23, 2026 06:18
@naveen-seth
naveen-seth merged commit 739c459 into llvm:main Apr 23, 2026
9 of 10 checks passed
llvm-sync Bot pushed a commit to arm/arm-toolchain that referenced this pull request Apr 23, 2026
…odule inputs (#193629)

This changes the modules driver to only allow files of type `-x
c++module` to define a module.
This makes it easier to add support for `-fno-modules-reduced-bmi` later
on and better follows Clang conventions.

Addresses:
llvm/llvm-project#193312 (comment)
@llvm-ci

llvm-ci commented Apr 23, 2026

Copy link
Copy Markdown

LLVM Buildbot has detected a new failure on builder lldb-x86_64-debian running on lldb-x86_64-debian while building clang at step 6 "test".

Full details are available at: https://lab.llvm.org/buildbot/#/builders/162/builds/46116

Here is the relevant piece of the build log for the reference
Step 6 (test) failure: build (failure)
...
18.329 [1/1/84] Linking CXX executable bin/lldb-test
18.330 [0/1/84] Running lldb lit test suite
llvm-lit: /home/worker/2.0.1/lldb-x86_64-debian/llvm-project/llvm/utils/lit/lit/llvm/config.py:569: note: using clang: /home/worker/2.0.1/lldb-x86_64-debian/build/bin/clang
llvm-lit: /home/worker/2.0.1/lldb-x86_64-debian/llvm-project/llvm/utils/lit/lit/llvm/config.py:569: note: using ld.lld: /home/worker/2.0.1/lldb-x86_64-debian/build/bin/ld.lld
llvm-lit: /home/worker/2.0.1/lldb-x86_64-debian/llvm-project/llvm/utils/lit/lit/llvm/config.py:569: note: using lld-link: /home/worker/2.0.1/lldb-x86_64-debian/build/bin/lld-link
llvm-lit: /home/worker/2.0.1/lldb-x86_64-debian/llvm-project/llvm/utils/lit/lit/llvm/config.py:569: note: using ld64.lld: /home/worker/2.0.1/lldb-x86_64-debian/build/bin/ld64.lld
llvm-lit: /home/worker/2.0.1/lldb-x86_64-debian/llvm-project/llvm/utils/lit/lit/llvm/config.py:569: note: using wasm-ld: /home/worker/2.0.1/lldb-x86_64-debian/build/bin/wasm-ld
llvm-lit: /home/worker/2.0.1/lldb-x86_64-debian/llvm-project/lldb/test/Shell/lit.cfg.py:115: note: Deleting module cache at /home/worker/2.0.1/lldb-x86_64-debian/build/lldb-test-build.noindex/module-cache-clang/lldb-shell.
-- Testing: 3436 tests, 72 workers --
UNRESOLVED: lldb-api :: commands/gui/spawn-threads/TestGuiSpawnThreads.py (1 of 3436)
******************** TEST 'lldb-api :: commands/gui/spawn-threads/TestGuiSpawnThreads.py' FAILED ********************
Script:
--
/usr/bin/python3 /home/worker/2.0.1/lldb-x86_64-debian/llvm-project/lldb/test/API/dotest.py -u CXXFLAGS -u CFLAGS --env LLVM_LIBS_DIR=/home/worker/2.0.1/lldb-x86_64-debian/build/./lib --env LLVM_INCLUDE_DIR=/home/worker/2.0.1/lldb-x86_64-debian/build/include --env LLVM_TOOLS_DIR=/home/worker/2.0.1/lldb-x86_64-debian/build/./bin --triple x86_64-unknown-linux-gnu --build-dir /home/worker/2.0.1/lldb-x86_64-debian/build/lldb-test-build.noindex --lldb-module-cache-dir /home/worker/2.0.1/lldb-x86_64-debian/build/lldb-test-build.noindex/module-cache-lldb/lldb-api --clang-module-cache-dir /home/worker/2.0.1/lldb-x86_64-debian/build/lldb-test-build.noindex/module-cache-clang/lldb-api --executable /home/worker/2.0.1/lldb-x86_64-debian/build/./bin/lldb --compiler /home/worker/2.0.1/lldb-x86_64-debian/build/./bin/clang --dsymutil /home/worker/2.0.1/lldb-x86_64-debian/build/./bin/dsymutil --make /usr/bin/gmake --llvm-tools-dir /home/worker/2.0.1/lldb-x86_64-debian/build/./bin --lldb-obj-root /home/worker/2.0.1/lldb-x86_64-debian/build/tools/lldb --lldb-libs-dir /home/worker/2.0.1/lldb-x86_64-debian/build/./lib --cmake-build-type Release -t /home/worker/2.0.1/lldb-x86_64-debian/llvm-project/lldb/test/API/commands/gui/spawn-threads -p TestGuiSpawnThreads.py
--
Exit Code: 1

Command Output (stdout):
--
lldb version 23.0.0git (https://github.com/llvm/llvm-project.git revision 739c45916d4c6d3c64e9d4e215e12f8f8a917a72)
  clang revision 739c45916d4c6d3c64e9d4e215e12f8f8a917a72
  llvm revision 739c45916d4c6d3c64e9d4e215e12f8f8a917a72

�[1A�7�[1;99r�8(lldb) settings clear --all
�7
�[7mno target                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                           �[0m�8(lldb) settings set symbols.enable-external-lookup false
(lldb) settings set target.inherit-tcc true
(lldb) settings set target.disable-aslr false
(lldb) settings set target.detach-on-error false
(lldb) settings set target.auto-apply-fixits false
(lldb) settings set plugin.process.gdb-remote.packet-timeout 60
(lldb) settings set symbols.clang-modules-cache-path "/home/worker/2.0.1/lldb-x86_64-debian/build/lldb-test-build.noindex/module-cache-lldb/lldb-api"
(lldb) settings set use-color false
(lldb) settings set show-statusline false
�7�[1;100r�8�[J(lldb) settings set target.check-vo-ownership true
(lldb) target create "/home/worker/2.0.1/lldb-x86_64-debian/build/lldb-test-build.noindex/commands/gui/spawn-threads/TestGuiSpawnThreads/a.out"
Current executable set to '/home/worker/2.0.1/lldb-x86_64-debian/build/lldb-test-build.noindex/commands/gui/spawn-threads/TestGuiSpawnThreads/a.out' (x86_64).

�[K(lldb) breakpoint set -f main.cpp -p "break here"
breakpoint set -f main.cpp -p "break here"
Breakpoint 1: where = a.out`test_thread() + 33 at main.cpp:14:20, address = 0x0000000000001291

�[K(lldb) breakpoint set -f main.cpp -p "before join"
breakpoint set -f main.cpp -p "before join"
Breakpoint 2: where = a.out`test_thread() + 129 at main.cpp:16:3, address = 0x00000000000012f1

�[K(lldb) run
run
Process 3350768 launched: '/home/worker/2.0.1/lldb-x86_64-debian/build/lldb-test-build.noindex/commands/gui/spawn-threads/TestGuiSpawnThreads/a.out' (x86_64)

@llvm-ci

llvm-ci commented Apr 23, 2026

Copy link
Copy Markdown

LLVM Buildbot has detected a new failure on builder llvm-clang-aarch64-darwin running on doug-worker-4 while building clang at step 6 "test-build-unified-tree-check-all".

Full details are available at: https://lab.llvm.org/buildbot/#/builders/190/builds/41170

Here is the relevant piece of the build log for the reference
Step 6 (test-build-unified-tree-check-all) failure: test (failure)
******************** TEST 'Clang :: Driver/modules-driver-import-std.cpp' FAILED ********************
Exit Code: 1

Command Output (stdout):
--
# RUN: at line 7
rm -rf /Volumes/RAMDisk/buildbot-root/aarch64-darwin/build/tools/clang/test/Driver/Output/modules-driver-import-std.cpp.tmp && split-file /Users/buildbot/buildbot-root/llvm-project/clang/test/Driver/modules-driver-import-std.cpp /Volumes/RAMDisk/buildbot-root/aarch64-darwin/build/tools/clang/test/Driver/Output/modules-driver-import-std.cpp.tmp
# executed command: rm -rf /Volumes/RAMDisk/buildbot-root/aarch64-darwin/build/tools/clang/test/Driver/Output/modules-driver-import-std.cpp.tmp
# note: command had no output on stdout or stderr
# executed command: split-file /Users/buildbot/buildbot-root/llvm-project/clang/test/Driver/modules-driver-import-std.cpp /Volumes/RAMDisk/buildbot-root/aarch64-darwin/build/tools/clang/test/Driver/Output/modules-driver-import-std.cpp.tmp
# note: command had no output on stdout or stderr
# RUN: at line 8
mkdir -p /Volumes/RAMDisk/buildbot-root/aarch64-darwin/build/tools/clang/test/Driver/Output/modules-driver-import-std.cpp.tmp/Inputs/usr/lib/x86_64-linux-gnu
# executed command: mkdir -p /Volumes/RAMDisk/buildbot-root/aarch64-darwin/build/tools/clang/test/Driver/Output/modules-driver-import-std.cpp.tmp/Inputs/usr/lib/x86_64-linux-gnu
# note: command had no output on stdout or stderr
# RUN: at line 9
touch /Volumes/RAMDisk/buildbot-root/aarch64-darwin/build/tools/clang/test/Driver/Output/modules-driver-import-std.cpp.tmp/Inputs/usr/lib/x86_64-linux-gnu/libc++.so
# executed command: touch /Volumes/RAMDisk/buildbot-root/aarch64-darwin/build/tools/clang/test/Driver/Output/modules-driver-import-std.cpp.tmp/Inputs/usr/lib/x86_64-linux-gnu/libc++.so
# note: command had no output on stdout or stderr
# RUN: at line 10
touch /Volumes/RAMDisk/buildbot-root/aarch64-darwin/build/tools/clang/test/Driver/Output/modules-driver-import-std.cpp.tmp/Inputs/usr/lib/x86_64-linux-gnu/libc++.a
# executed command: touch /Volumes/RAMDisk/buildbot-root/aarch64-darwin/build/tools/clang/test/Driver/Output/modules-driver-import-std.cpp.tmp/Inputs/usr/lib/x86_64-linux-gnu/libc++.a
# note: command had no output on stdout or stderr
# RUN: at line 12
sed "s|DIR|/Volumes/RAMDisk/buildbot-root/aarch64-darwin/build/tools/clang/test/Driver/Output/modules-driver-import-std.cpp.tmp|g" /Volumes/RAMDisk/buildbot-root/aarch64-darwin/build/tools/clang/test/Driver/Output/modules-driver-import-std.cpp.tmp/libc++.modules.json.in >    /Volumes/RAMDisk/buildbot-root/aarch64-darwin/build/tools/clang/test/Driver/Output/modules-driver-import-std.cpp.tmp/Inputs/usr/lib/x86_64-linux-gnu/libc++.modules.json
# executed command: sed 's|DIR|/Volumes/RAMDisk/buildbot-root/aarch64-darwin/build/tools/clang/test/Driver/Output/modules-driver-import-std.cpp.tmp|g' /Volumes/RAMDisk/buildbot-root/aarch64-darwin/build/tools/clang/test/Driver/Output/modules-driver-import-std.cpp.tmp/libc++.modules.json.in
# note: command had no output on stdout or stderr
# RUN: at line 15
mkdir -p /Volumes/RAMDisk/buildbot-root/aarch64-darwin/build/tools/clang/test/Driver/Output/modules-driver-import-std.cpp.tmp/Inputs/usr/lib/share/libc++/v1
# executed command: mkdir -p /Volumes/RAMDisk/buildbot-root/aarch64-darwin/build/tools/clang/test/Driver/Output/modules-driver-import-std.cpp.tmp/Inputs/usr/lib/share/libc++/v1
# note: command had no output on stdout or stderr
# RUN: at line 16
cat /Volumes/RAMDisk/buildbot-root/aarch64-darwin/build/tools/clang/test/Driver/Output/modules-driver-import-std.cpp.tmp/std.cppm > /Volumes/RAMDisk/buildbot-root/aarch64-darwin/build/tools/clang/test/Driver/Output/modules-driver-import-std.cpp.tmp/Inputs/usr/lib/share/libc++/v1/std.cppm
# executed command: cat /Volumes/RAMDisk/buildbot-root/aarch64-darwin/build/tools/clang/test/Driver/Output/modules-driver-import-std.cpp.tmp/std.cppm
# note: command had no output on stdout or stderr
# RUN: at line 17
cat /Volumes/RAMDisk/buildbot-root/aarch64-darwin/build/tools/clang/test/Driver/Output/modules-driver-import-std.cpp.tmp/std.compat.cppm > /Volumes/RAMDisk/buildbot-root/aarch64-darwin/build/tools/clang/test/Driver/Output/modules-driver-import-std.cpp.tmp/Inputs/usr/lib/share/libc++/v1/std.compat.cppm
# executed command: cat /Volumes/RAMDisk/buildbot-root/aarch64-darwin/build/tools/clang/test/Driver/Output/modules-driver-import-std.cpp.tmp/std.compat.cppm
# note: command had no output on stdout or stderr
# RUN: at line 50
/Volumes/RAMDisk/buildbot-root/aarch64-darwin/build/bin/clang -std=c++23 -c -fmodules-driver -Rmodules-driver -Rmodule-import    -stdlib=libc++    -resource-dir=/Volumes/RAMDisk/buildbot-root/aarch64-darwin/build/tools/clang/test/Driver/Output/modules-driver-import-std.cpp.tmp/Inputs/usr/lib/x86_64-linux-gnu    --target=x86_64-linux-gnu    /Volumes/RAMDisk/buildbot-root/aarch64-darwin/build/tools/clang/test/Driver/Output/modules-driver-import-std.cpp.tmp/main.cpp 2>&1    | sed 's:\\\\\?:/:g'    | /Volumes/RAMDisk/buildbot-root/aarch64-darwin/build/bin/FileCheck -DPREFIX=/Volumes/RAMDisk/buildbot-root/aarch64-darwin/build/tools/clang/test/Driver/Output/modules-driver-import-std.cpp.tmp /Users/buildbot/buildbot-root/llvm-project/clang/test/Driver/modules-driver-import-std.cpp
# executed command: /Volumes/RAMDisk/buildbot-root/aarch64-darwin/build/bin/clang -std=c++23 -c -fmodules-driver -Rmodules-driver -Rmodule-import -stdlib=libc++ -resource-dir=/Volumes/RAMDisk/buildbot-root/aarch64-darwin/build/tools/clang/test/Driver/Output/modules-driver-import-std.cpp.tmp/Inputs/usr/lib/x86_64-linux-gnu --target=x86_64-linux-gnu /Volumes/RAMDisk/buildbot-root/aarch64-darwin/build/tools/clang/test/Driver/Output/modules-driver-import-std.cpp.tmp/main.cpp
# note: command had no output on stdout or stderr
# error: command failed with exit status: 1
# executed command: sed 's:\\\\\?:/:g'
# note: command had no output on stdout or stderr
# executed command: /Volumes/RAMDisk/buildbot-root/aarch64-darwin/build/bin/FileCheck -DPREFIX=/Volumes/RAMDisk/buildbot-root/aarch64-darwin/build/tools/clang/test/Driver/Output/modules-driver-import-std.cpp.tmp /Users/buildbot/buildbot-root/llvm-project/clang/test/Driver/modules-driver-import-std.cpp
# note: command had no output on stdout or stderr

--
...

@llvm-ci

llvm-ci commented Apr 23, 2026

Copy link
Copy Markdown

LLVM Buildbot has detected a new failure on builder clang-aarch64-quick running on linaro-clang-aarch64-quick while building clang at step 5 "ninja check 1".

Full details are available at: https://lab.llvm.org/buildbot/#/builders/65/builds/33442

Here is the relevant piece of the build log for the reference
Step 5 (ninja check 1) failure: stage 1 checked (failure)
******************** TEST 'Clang :: Driver/modules-driver-import-std.cpp' FAILED ********************
Exit Code: 1

Command Output (stdout):
--
# RUN: at line 7
rm -rf /home/tcwg-buildbot/worker/clang-aarch64-quick/stage1/tools/clang/test/Driver/Output/modules-driver-import-std.cpp.tmp && split-file /home/tcwg-buildbot/worker/clang-aarch64-quick/llvm/clang/test/Driver/modules-driver-import-std.cpp /home/tcwg-buildbot/worker/clang-aarch64-quick/stage1/tools/clang/test/Driver/Output/modules-driver-import-std.cpp.tmp
# executed command: rm -rf /home/tcwg-buildbot/worker/clang-aarch64-quick/stage1/tools/clang/test/Driver/Output/modules-driver-import-std.cpp.tmp
# executed command: split-file /home/tcwg-buildbot/worker/clang-aarch64-quick/llvm/clang/test/Driver/modules-driver-import-std.cpp /home/tcwg-buildbot/worker/clang-aarch64-quick/stage1/tools/clang/test/Driver/Output/modules-driver-import-std.cpp.tmp
# RUN: at line 8
mkdir -p /home/tcwg-buildbot/worker/clang-aarch64-quick/stage1/tools/clang/test/Driver/Output/modules-driver-import-std.cpp.tmp/Inputs/usr/lib/x86_64-linux-gnu
# executed command: mkdir -p /home/tcwg-buildbot/worker/clang-aarch64-quick/stage1/tools/clang/test/Driver/Output/modules-driver-import-std.cpp.tmp/Inputs/usr/lib/x86_64-linux-gnu
# RUN: at line 9
touch /home/tcwg-buildbot/worker/clang-aarch64-quick/stage1/tools/clang/test/Driver/Output/modules-driver-import-std.cpp.tmp/Inputs/usr/lib/x86_64-linux-gnu/libc++.so
# executed command: touch /home/tcwg-buildbot/worker/clang-aarch64-quick/stage1/tools/clang/test/Driver/Output/modules-driver-import-std.cpp.tmp/Inputs/usr/lib/x86_64-linux-gnu/libc++.so
# RUN: at line 10
touch /home/tcwg-buildbot/worker/clang-aarch64-quick/stage1/tools/clang/test/Driver/Output/modules-driver-import-std.cpp.tmp/Inputs/usr/lib/x86_64-linux-gnu/libc++.a
# executed command: touch /home/tcwg-buildbot/worker/clang-aarch64-quick/stage1/tools/clang/test/Driver/Output/modules-driver-import-std.cpp.tmp/Inputs/usr/lib/x86_64-linux-gnu/libc++.a
# RUN: at line 12
sed "s|DIR|/home/tcwg-buildbot/worker/clang-aarch64-quick/stage1/tools/clang/test/Driver/Output/modules-driver-import-std.cpp.tmp|g" /home/tcwg-buildbot/worker/clang-aarch64-quick/stage1/tools/clang/test/Driver/Output/modules-driver-import-std.cpp.tmp/libc++.modules.json.in >    /home/tcwg-buildbot/worker/clang-aarch64-quick/stage1/tools/clang/test/Driver/Output/modules-driver-import-std.cpp.tmp/Inputs/usr/lib/x86_64-linux-gnu/libc++.modules.json
# executed command: sed 's|DIR|/home/tcwg-buildbot/worker/clang-aarch64-quick/stage1/tools/clang/test/Driver/Output/modules-driver-import-std.cpp.tmp|g' /home/tcwg-buildbot/worker/clang-aarch64-quick/stage1/tools/clang/test/Driver/Output/modules-driver-import-std.cpp.tmp/libc++.modules.json.in
# RUN: at line 15
mkdir -p /home/tcwg-buildbot/worker/clang-aarch64-quick/stage1/tools/clang/test/Driver/Output/modules-driver-import-std.cpp.tmp/Inputs/usr/lib/share/libc++/v1
# executed command: mkdir -p /home/tcwg-buildbot/worker/clang-aarch64-quick/stage1/tools/clang/test/Driver/Output/modules-driver-import-std.cpp.tmp/Inputs/usr/lib/share/libc++/v1
# RUN: at line 16
cat /home/tcwg-buildbot/worker/clang-aarch64-quick/stage1/tools/clang/test/Driver/Output/modules-driver-import-std.cpp.tmp/std.cppm > /home/tcwg-buildbot/worker/clang-aarch64-quick/stage1/tools/clang/test/Driver/Output/modules-driver-import-std.cpp.tmp/Inputs/usr/lib/share/libc++/v1/std.cppm
# executed command: cat /home/tcwg-buildbot/worker/clang-aarch64-quick/stage1/tools/clang/test/Driver/Output/modules-driver-import-std.cpp.tmp/std.cppm
# RUN: at line 17
cat /home/tcwg-buildbot/worker/clang-aarch64-quick/stage1/tools/clang/test/Driver/Output/modules-driver-import-std.cpp.tmp/std.compat.cppm > /home/tcwg-buildbot/worker/clang-aarch64-quick/stage1/tools/clang/test/Driver/Output/modules-driver-import-std.cpp.tmp/Inputs/usr/lib/share/libc++/v1/std.compat.cppm
# executed command: cat /home/tcwg-buildbot/worker/clang-aarch64-quick/stage1/tools/clang/test/Driver/Output/modules-driver-import-std.cpp.tmp/std.compat.cppm
# RUN: at line 50
/home/tcwg-buildbot/worker/clang-aarch64-quick/stage1/bin/clang -std=c++23 -c -fmodules-driver -Rmodules-driver -Rmodule-import    -stdlib=libc++    -resource-dir=/home/tcwg-buildbot/worker/clang-aarch64-quick/stage1/tools/clang/test/Driver/Output/modules-driver-import-std.cpp.tmp/Inputs/usr/lib/x86_64-linux-gnu    --target=x86_64-linux-gnu    /home/tcwg-buildbot/worker/clang-aarch64-quick/stage1/tools/clang/test/Driver/Output/modules-driver-import-std.cpp.tmp/main.cpp 2>&1    | sed 's:\\\\\?:/:g'    | /home/tcwg-buildbot/worker/clang-aarch64-quick/stage1/bin/FileCheck -DPREFIX=/home/tcwg-buildbot/worker/clang-aarch64-quick/stage1/tools/clang/test/Driver/Output/modules-driver-import-std.cpp.tmp /home/tcwg-buildbot/worker/clang-aarch64-quick/llvm/clang/test/Driver/modules-driver-import-std.cpp
# executed command: /home/tcwg-buildbot/worker/clang-aarch64-quick/stage1/bin/clang -std=c++23 -c -fmodules-driver -Rmodules-driver -Rmodule-import -stdlib=libc++ -resource-dir=/home/tcwg-buildbot/worker/clang-aarch64-quick/stage1/tools/clang/test/Driver/Output/modules-driver-import-std.cpp.tmp/Inputs/usr/lib/x86_64-linux-gnu --target=x86_64-linux-gnu /home/tcwg-buildbot/worker/clang-aarch64-quick/stage1/tools/clang/test/Driver/Output/modules-driver-import-std.cpp.tmp/main.cpp
# note: command had no output on stdout or stderr
# error: command failed with exit status: 1
# executed command: sed 's:\\\\\?:/:g'
# executed command: /home/tcwg-buildbot/worker/clang-aarch64-quick/stage1/bin/FileCheck -DPREFIX=/home/tcwg-buildbot/worker/clang-aarch64-quick/stage1/tools/clang/test/Driver/Output/modules-driver-import-std.cpp.tmp /home/tcwg-buildbot/worker/clang-aarch64-quick/llvm/clang/test/Driver/modules-driver-import-std.cpp

--

********************


naveen-seth added a commit that referenced this pull request Apr 23, 2026
… `import std`" (#193677)

Reverts #193312 due to a failing test
(Driver/modules-driver-import-std.cpp)
llvm-sync Bot pushed a commit to arm/arm-toolchain that referenced this pull request Apr 23, 2026
…modules and `import std`" (#193677)

Reverts llvm/llvm-project#193312 due to a failing test
(Driver/modules-driver-import-std.cpp)
cpullvm-upstream-sync Bot pushed a commit to navaneethshan/cpullvm-toolchain-1 that referenced this pull request Apr 23, 2026
…odule inputs (#193629)

This changes the modules driver to only allow files of type `-x
c++module` to define a module.
This makes it easier to add support for `-fno-modules-reduced-bmi` later
on and better follows Clang conventions.

Addresses:
llvm/llvm-project#193312 (comment)
cpullvm-upstream-sync Bot pushed a commit to navaneethshan/cpullvm-toolchain-1 that referenced this pull request Apr 23, 2026
…modules and `import std`" (#193677)

Reverts llvm/llvm-project#193312 due to a failing test
(Driver/modules-driver-import-std.cpp)
@Bigcheese

Copy link
Copy Markdown
Contributor

No. Strongly No. It is bad to handle such cases. The fact that the semantics of libc++'s std module is similar with the C++20 named 'std' module is just a coincidence. I believe if we allow such cases, it will be super confusing one day more people mixed the use of clang header modules and C++20 named modules.

Strongly against again.

We can't change the name of the Clang module, it's been in use since before WG21 picked std. My plan has been to namespace the names. @import std; will pick the Clang module, and import std; will pick the standard module. In this mode the standard module is a tiny wrapper around the Clang module that just re-exports specific names.

Also, this only applies to ObjectiveC++. C++20 modules shouldn't be able to observe Clang module names (there's no syntax to import by name including macros). Mixing #include, @import, and import works fine here, I've tested it with a renamed Clang module.

naveen-seth added a commit that referenced this pull request Apr 23, 2026
…d `import std`" (#193815)

This reverts #193677 and relands #193312.

This adds basic support for explicit C++ named module builds, managed
natively by the Clang driver, including support for use of the Standard
library modules. This follows #187606, which adds the same for Clang
modules.

Current limitations:
- Standard library modules are still compiled to object files instead of
using the provided shared library. (This will be addressed in a
follow-up soon.)
- Caching is not supported yet (but likely to be added during the
upcoming GSoC cycle).
- Importing C++ standard library modules into Clang modules is not
supported (and not expected in the near term).

RFC:

https://discourse.llvm.org/t/rfc-modules-support-simple-c-20-modules-use-from-the-clang-driver-without-a-build-system
@ChuanqiXu9

Copy link
Copy Markdown
Member

No. Strongly No. It is bad to handle such cases. The fact that the semantics of libc++'s std module is similar with the C++20 named 'std' module is just a coincidence. I believe if we allow such cases, it will be super confusing one day more people mixed the use of clang header modules and C++20 named modules.
Strongly against again.

We can't change the name of the Clang module, it's been in use since before WG21 picked std. My plan has been to namespace the names. @import std; will pick the Clang module, and import std; will pick the standard module. In this mode the standard module is a tiny wrapper around the Clang module that just re-exports specific names.

The problem is the modules mechanism in clang itself. Currently the interface -fmodule-file=...=... works equally for all the modules.

Also, this only applies to ObjectiveC++. C++20 modules shouldn't be able to observe Clang module names (there's no syntax to import by name including macros). Mixing #include, @import, and import works fine here, I've tested it with a renamed Clang module.

But with explicit clang header modules, it depends on -fmodule-file=...=..., right?


A plain fix will be introducing a new abstract layer to the module name. e.g., the build system and the compiler will add a prefix "clang_module::" to clang header modules implicitly so that the users don't have to update anything.

llvm-upstreamsync Bot pushed a commit to qualcomm/cpullvm-toolchain that referenced this pull request Apr 24, 2026
…odule inputs (#193629)

This changes the modules driver to only allow files of type `-x
c++module` to define a module.
This makes it easier to add support for `-fno-modules-reduced-bmi` later
on and better follows Clang conventions.

Addresses:
llvm/llvm-project#193312 (comment)
llvm-upstreamsync Bot pushed a commit to qualcomm/cpullvm-toolchain that referenced this pull request Apr 24, 2026
…modules and `import std`" (#193677)

Reverts llvm/llvm-project#193312 due to a failing test
(Driver/modules-driver-import-std.cpp)
naveen-seth pushed a commit to naveen-seth/llvm-project that referenced this pull request Apr 27, 2026
…d `import std`"

This reverts llvm#193677 and relands llvm#193312.

This adds basic support for explicit C++ named module builds, managed natively
by the Clang driver, including support for use of the Standard library modules.
This follows llvm#187606, which adds the same for Clang modules.

Current limitations:
- Standard library modules are still compiled to object files instead of
using the provided shared library. (This will be addressed in a
follow-up soon.)
- Caching is not supported yet (but likely to be added during the
upcoming GSoC cycle).
- Importing C++ standard library modules into Clang modules is not
supported (and not expected in the near term).

RFC:
https://discourse.llvm.org/t/rfc-modules-support-simple-c-20-modules-use-from-the-clang-driver-without-a-build-system
naveen-seth added a commit that referenced this pull request Apr 27, 2026
… import std" (2nd attempt) (#194475)

This reverts #193857 and relands #193312.

This adds basic support for explicit C++ named module builds, managed
natively by the Clang driver, including support for use of the Standard
library modules. This follows #187606, which adds the same for Clang
modules.

Current limitations:
- Standard library modules are still compiled to object files instead of
using the provided shared library. (This will be addressed in a
follow-up soon.)
- Caching is not supported yet (but likely to be added during the
upcoming GSoC cycle).
- Importing C++ standard library modules into Clang modules is not
supported (and not expected in the near term).

RFC:

https://discourse.llvm.org/t/rfc-modules-support-simple-c-20-modules-use-from-the-clang-driver-without-a-build-system
yingopq pushed a commit to yingopq/llvm-project that referenced this pull request Apr 29, 2026
llvm#193629)

This changes the modules driver to only allow files of type `-x
c++module` to define a module.
This makes it easier to add support for `-fno-modules-reduced-bmi` later
on and better follows Clang conventions.

Addresses:
llvm#193312 (comment)
yingopq pushed a commit to yingopq/llvm-project that referenced this pull request Apr 29, 2026
… std` (llvm#193312)

This patch adds basic support for explicit C++ named module builds,
managed natively by the Clang driver, including support for use of the
Standard library modules.

This follows llvm#187606, which adds the same for Clang modules.

Current limitations:
- Standard library modules are still compiled to object files instead of
using the provided shared library. (This will be addressed in a
follow-up soon.)
- Caching is not supported yet (but likely to be added during the
upcoming GSoC cycle).
- Importing C++ standard library modules into Clang modules is not
supported (and not expected in the near term).

RFC:
https://discourse.llvm.org/t/rfc-modules-support-simple-c-20-modules-use-from-the-clang-driver-without-a-build-system
yingopq pushed a commit to yingopq/llvm-project that referenced this pull request Apr 29, 2026
… `import std`" (llvm#193677)

Reverts llvm#193312 due to a failing test
(Driver/modules-driver-import-std.cpp)
yingopq pushed a commit to yingopq/llvm-project that referenced this pull request Apr 29, 2026
…d `import std`" (llvm#193815)

This reverts llvm#193677 and relands llvm#193312.

This adds basic support for explicit C++ named module builds, managed
natively by the Clang driver, including support for use of the Standard
library modules. This follows llvm#187606, which adds the same for Clang
modules.

Current limitations:
- Standard library modules are still compiled to object files instead of
using the provided shared library. (This will be addressed in a
follow-up soon.)
- Caching is not supported yet (but likely to be added during the
upcoming GSoC cycle).
- Importing C++ standard library modules into Clang modules is not
supported (and not expected in the near term).

RFC:

https://discourse.llvm.org/t/rfc-modules-support-simple-c-20-modules-use-from-the-clang-driver-without-a-build-system
yingopq pushed a commit to yingopq/llvm-project that referenced this pull request Apr 29, 2026
… import std" (2nd attempt) (llvm#194475)

This reverts llvm#193857 and relands llvm#193312.

This adds basic support for explicit C++ named module builds, managed
natively by the Clang driver, including support for use of the Standard
library modules. This follows llvm#187606, which adds the same for Clang
modules.

Current limitations:
- Standard library modules are still compiled to object files instead of
using the provided shared library. (This will be addressed in a
follow-up soon.)
- Caching is not supported yet (but likely to be added during the
upcoming GSoC cycle).
- Importing C++ standard library modules into Clang modules is not
supported (and not expected in the near term).

RFC:

https://discourse.llvm.org/t/rfc-modules-support-simple-c-20-modules-use-from-the-clang-driver-without-a-build-system
KHicketts pushed a commit to KHicketts/llvm-project that referenced this pull request Apr 30, 2026
llvm#193629)

This changes the modules driver to only allow files of type `-x
c++module` to define a module.
This makes it easier to add support for `-fno-modules-reduced-bmi` later
on and better follows Clang conventions.

Addresses:
llvm#193312 (comment)
KHicketts pushed a commit to KHicketts/llvm-project that referenced this pull request Apr 30, 2026
… std` (llvm#193312)

This patch adds basic support for explicit C++ named module builds,
managed natively by the Clang driver, including support for use of the
Standard library modules.

This follows llvm#187606, which adds the same for Clang modules.

Current limitations:
- Standard library modules are still compiled to object files instead of
using the provided shared library. (This will be addressed in a
follow-up soon.)
- Caching is not supported yet (but likely to be added during the
upcoming GSoC cycle).
- Importing C++ standard library modules into Clang modules is not
supported (and not expected in the near term).

RFC:
https://discourse.llvm.org/t/rfc-modules-support-simple-c-20-modules-use-from-the-clang-driver-without-a-build-system
KHicketts pushed a commit to KHicketts/llvm-project that referenced this pull request Apr 30, 2026
… `import std`" (llvm#193677)

Reverts llvm#193312 due to a failing test
(Driver/modules-driver-import-std.cpp)
KHicketts pushed a commit to KHicketts/llvm-project that referenced this pull request Apr 30, 2026
…d `import std`" (llvm#193815)

This reverts llvm#193677 and relands llvm#193312.

This adds basic support for explicit C++ named module builds, managed
natively by the Clang driver, including support for use of the Standard
library modules. This follows llvm#187606, which adds the same for Clang
modules.

Current limitations:
- Standard library modules are still compiled to object files instead of
using the provided shared library. (This will be addressed in a
follow-up soon.)
- Caching is not supported yet (but likely to be added during the
upcoming GSoC cycle).
- Importing C++ standard library modules into Clang modules is not
supported (and not expected in the near term).

RFC:

https://discourse.llvm.org/t/rfc-modules-support-simple-c-20-modules-use-from-the-clang-driver-without-a-build-system
KHicketts pushed a commit to KHicketts/llvm-project that referenced this pull request Apr 30, 2026
… import std" (2nd attempt) (llvm#194475)

This reverts llvm#193857 and relands llvm#193312.

This adds basic support for explicit C++ named module builds, managed
natively by the Clang driver, including support for use of the Standard
library modules. This follows llvm#187606, which adds the same for Clang
modules.

Current limitations:
- Standard library modules are still compiled to object files instead of
using the provided shared library. (This will be addressed in a
follow-up soon.)
- Caching is not supported yet (but likely to be added during the
upcoming GSoC cycle).
- Importing C++ standard library modules into Clang modules is not
supported (and not expected in the near term).

RFC:

https://discourse.llvm.org/t/rfc-modules-support-simple-c-20-modules-use-from-the-clang-driver-without-a-build-system
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

clang:driver 'clang' and 'clang++' user-facing binaries. Not 'clang-cl' clang:frontend Language frontend issues, e.g. anything involving "Sema" clang Clang issues not falling into any other category

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants