https://github.com/naveen-seth updated 
https://github.com/llvm/llvm-project/pull/199289

>From 5a248a2f7d905673b5c8fd03b11d52c9bc41e2e8 Mon Sep 17 00:00:00 2001
From: Naveen Seth Hanig <[email protected]>
Date: Fri, 22 May 2026 23:05:50 +0200
Subject: [PATCH 1/9] [clang][modules-driver] Precompile std modules
 independently of -o and final phase

Standard library modules are now always precompiled as the primary output of
their -cc1 invocation (instead of being produced as a byproduct of compiling
the Standard library modules to object files).

This also keeps std module precompilation independent of the final phase
specified on the command line, so imports keep working under -fsyntax-only (and
other command-line options that select the final phase).

This also makes the Standard library module precompilation independent of the -o
flag, so a command like 'clang -std=c++23 -fmodules-driver main.cpp -o main' no
longer redirects the Standard library module outputs to 'main', breaking the
compilation.
---
 clang/include/clang/Driver/Types.def          |  2 +
 clang/lib/Driver/Driver.cpp                   | 57 +++++++++++----
 clang/lib/Driver/ModulesDriver.cpp            | 21 +++++-
 clang/lib/Driver/ToolChains/Clang.cpp         |  6 +-
 clang/lib/Driver/Types.cpp                    | 42 ++++++++---
 .../InterpolatingCompilationDatabase.cpp      |  2 +
 .../test/Driver/modules-driver-import-std.cpp | 71 +++++++++++++++++++
 7 files changed, 176 insertions(+), 25 deletions(-)

diff --git a/clang/include/clang/Driver/Types.def 
b/clang/include/clang/Driver/Types.def
index 76944ec656917..5c325f5685c44 100644
--- a/clang/include/clang/Driver/Types.def
+++ b/clang/include/clang/Driver/Types.def
@@ -73,6 +73,8 @@ TYPE("objective-c++-header-cpp-output", PP_ObjCXXHeader, 
INVALID,"mii",   phases
 TYPE("objective-c++-header",     ObjCXXHeader, PP_ObjCXXHeader, "h",      
phases::Preprocess, phases::Precompile)
 TYPE("c++-module",               CXXModule,    PP_CXXModule,    "cppm",   
phases::Preprocess, phases::Precompile, phases::Compile, phases::Backend, 
phases::Assemble, phases::Link)
 TYPE("c++-module-cpp-output",    PP_CXXModule, INVALID,         "iim",    
phases::Precompile, phases::Compile, phases::Backend, phases::Assemble, 
phases::Link)
+TYPE("c++-std-module",           CXXStdModule, PP_CXXStdModule, "cppm",   
phases::Preprocess, phases::Precompile)
+TYPE("c++-std-module-output",    PP_CXXStdModule, INVALID,      "iim",    
phases::Precompile)
 
 // Other languages.
 TYPE("ada",                      Ada,          INVALID,         nullptr,  
phases::Compile, phases::Backend, phases::Assemble, phases::Link)
diff --git a/clang/lib/Driver/Driver.cpp b/clang/lib/Driver/Driver.cpp
index 4a968a4ce5cc0..398f40920c15e 100644
--- a/clang/lib/Driver/Driver.cpp
+++ b/clang/lib/Driver/Driver.cpp
@@ -5275,6 +5275,13 @@ Action *Driver::ConstructPhaseAction(
     if (Args.hasArg(options::OPT_extract_api))
       return C.MakeAction<ExtractAPIJobAction>(Input, types::TY_API_INFO);
 
+    // Standard library modules always precompile in -fmodules-driver mode,
+    // even when -fsyntax-only is specified.
+    if (Input->getType() == types::TY_CXXStdModule ||
+        Input->getType() == types::TY_PP_CXXStdModule)
+      return C.MakeAction<PrecompileJobAction>(
+          Input, getPrecompiledType(Input->getType()));
+
     // With 'fmodules-reduced-bmi', we don't want to run the
     // precompile phase unless the user specified '--precompile' or
     // '--precompile-reduced-bmi'. If '--precompile' is specified, we will try
@@ -5471,6 +5478,14 @@ void Driver::BuildJobs(Compilation &C) const {
           A->getKind() == clang::driver::Action::BinaryTranslatorJobClass)
         continue;
 
+      if (isa<PrecompileJobAction>(A) && !A->getInputs().empty()) {
+        const Action *Input = A->getInputs().front();
+        types::ID InputType = Input->getType();
+        if (InputType == types::TY_CXXStdModule ||
+            InputType == types::TY_PP_CXXStdModule)
+          continue;
+      }
+
       if (A->getType() != types::TY_Nothing &&
           !(A->getKind() == Action::IfsMergeJobClass ||
             (A->getType() == clang::driver::types::TY_IFS_CPP &&
@@ -6472,6 +6487,34 @@ const char *Driver::GetNamedOutputPath(Compilation &C, 
const JobAction &JA,
   std::string BoundArch = sanitizeTargetIDInFileName(OrigBoundArch);
 
   llvm::PrettyStackTraceString CrashInfo("Computing output path");
+
+  auto CreateTempOutputPath = [&](StringRef Prefix) {
+    const char *Suffix =
+        types::getTypeTempSuffix(JA.getType(), IsCLMode() || IsDXCMode());
+    // The non-offloading toolchain on Darwin requires deterministic input
+    // file name for binaries to be deterministic, therefore it needs unique
+    // directory.
+    llvm::Triple Triple(C.getDriver().getTargetTriple());
+    bool NeedUniqueDirectory =
+        (JA.getOffloadingDeviceKind() == Action::OFK_None ||
+         JA.getOffloadingDeviceKind() == Action::OFK_Host) &&
+        Triple.isOSDarwin();
+    return CreateTempFile(C, Prefix, Suffix, MultipleArchs, BoundArch,
+                          NeedUniqueDirectory);
+  };
+
+  const bool IsModulesDriver = 
C.getArgs().hasArg(options::OPT_fmodules_driver);
+
+  // Standard library output in -fmodules-driver?
+  if (IsModulesDriver && isa<PrecompileJobAction>(JA) &&
+      !JA.getInputs().empty() &&
+      (JA.getInputs().front()->getType() == types::TY_CXXStdModule ||
+       JA.getInputs().front()->getType() == types::TY_PP_CXXStdModule)) {
+    StringRef Filename = llvm::sys::path::filename(BaseInput);
+    StringRef Stem = llvm::sys::path::stem(Filename);
+    return CreateTempOutputPath(Stem);
+  }
+
   // Output to a user requested destination?
   if (AtTopLevel && !isa<DsymutilJobAction>(JA) && !isa<VerifyJobAction>(JA)) {
     if (Arg *FinalOutput = C.getArgs().getLastArg(options::OPT_o))
@@ -6570,19 +6613,7 @@ const char *Driver::GetNamedOutputPath(Compilation &C, 
const JobAction &JA,
        !C.getArgs().hasArg(options::OPT__SLASH_Fo)) ||
       CCGenDiagnostics) {
     StringRef Name = llvm::sys::path::filename(BaseInput);
-    std::pair<StringRef, StringRef> Split = Name.split('.');
-    const char *Suffix =
-        types::getTypeTempSuffix(JA.getType(), IsCLMode() || IsDXCMode());
-    // The non-offloading toolchain on Darwin requires deterministic input
-    // file name for binaries to be deterministic, therefore it needs unique
-    // directory.
-    llvm::Triple Triple(C.getDriver().getTargetTriple());
-    bool NeedUniqueDirectory =
-        (JA.getOffloadingDeviceKind() == Action::OFK_None ||
-         JA.getOffloadingDeviceKind() == Action::OFK_Host) &&
-        Triple.isOSDarwin();
-    return CreateTempFile(C, Split.first, Suffix, MultipleArchs, BoundArch,
-                          NeedUniqueDirectory);
+    return CreateTempOutputPath(Name.split('.').first);
   }
 
   SmallString<128> BasePath(BaseInput);
diff --git a/clang/lib/Driver/ModulesDriver.cpp 
b/clang/lib/Driver/ModulesDriver.cpp
index 3f7a9f346accd..a09f69d6aad4e 100644
--- a/clang/lib/Driver/ModulesDriver.cpp
+++ b/clang/lib/Driver/ModulesDriver.cpp
@@ -146,7 +146,7 @@ void driver::modules::buildStdModuleManifestInputs(
   for (const auto &Entry : ManifestEntries) {
     auto *InputArg =
         makeInputArg(Args, Opts, Args.MakeArgString(Entry.SourcePath));
-    Inputs.emplace_back(types::TY_CXXModule, InputArg);
+    Inputs.emplace_back(types::TY_CXXStdModule, InputArg);
   }
 }
 
@@ -1213,7 +1213,8 @@ static bool validateScannedJobInputKinds(
     const auto &MainInput = Job.getInputInfos().front();
     const bool DefinesNamedModule = !InputDeps.ModuleName.empty();
 
-    if (DefinesNamedModule && MainInput.getType() != types::TY_CXXModule) {
+    if (DefinesNamedModule && MainInput.getType() != types::TY_CXXModule &&
+        MainInput.getType() != types::TY_CXXStdModule) {
       Diags.Report(diag::err_module_defined_outside_of_module_source)
           << InputDeps.ModuleName << MainInput.getFilename();
       return false;
@@ -1597,6 +1598,22 @@ static void fixupNamedModuleCommandLines(Compilation &C,
       llvm::CastTo<NamedModuleJobNode>);
 
   for (NamedModuleJobNode *Node : NamedModuleNodes) {
+    const auto &Job = *Node->Job;
+
+    // For Standard library modules, the driver already creates the module
+    // output as a temp file, so we can use that path directly.
+    const bool IsStdModule =
+        Job.getInputInfos().front().getType() == types::TY_CXXStdModule;
+    if (IsStdModule) {
+      const auto &OutputFilenames = Job.getOutputFilenames();
+      if (OutputFilenames.empty())
+        continue;
+
+      StringRef ModuleOutputPath = Job.getOutputFilenames().front();
+      propagateModuleFileMappingArg(C, *Node, ModuleOutputPath);
+      continue;
+    }
+
     const StringRef ModuleName = Node->InputDeps.ModuleName;
     const auto ModuleOutputPath = createModuleOutputPath(C, ModuleName);
     C.addTempFile(C.getArgs().MakeArgString(ModuleOutputPath));
diff --git a/clang/lib/Driver/ToolChains/Clang.cpp 
b/clang/lib/Driver/ToolChains/Clang.cpp
index 2b415e60d5331..bf467b8fb0fab 100644
--- a/clang/lib/Driver/ToolChains/Clang.cpp
+++ b/clang/lib/Driver/ToolChains/Clang.cpp
@@ -349,6 +349,7 @@ static void addDashXForInput(const ArgList &Args, const 
InputInfo &Input,
     const char *ClangType;
     switch (Input.getType()) {
     case types::TY_CXXModule:
+    case types::TY_CXXStdModule:
       ClangType = "c++";
       break;
     case types::TY_PP_CXXModule:
@@ -5270,7 +5271,10 @@ void Clang::ConstructJob(Compilation &C, const JobAction 
&JA,
     if (JA.getType() == types::TY_Nothing)
       CmdArgs.push_back("-fsyntax-only");
     else if (JA.getType() == types::TY_ModuleFile) {
-      if (Args.hasArg(options::OPT__precompile_reduced_bmi))
+      if (Args.hasArg(options::OPT__precompile_reduced_bmi) ||
+          ((Input.getType() == types::TY_CXXStdModule ||
+            Input.getType() == types::TY_PP_CXXStdModule) &&
+           !Args.hasArg(options::OPT_fno_modules_reduced_bmi)))
         CmdArgs.push_back("-emit-reduced-module-interface");
       else
         CmdArgs.push_back("-emit-module-interface");
diff --git a/clang/lib/Driver/Types.cpp b/clang/lib/Driver/Types.cpp
index 08866e89ea447..7cf8af1d1af92 100644
--- a/clang/lib/Driver/Types.cpp
+++ b/clang/lib/Driver/Types.cpp
@@ -59,7 +59,8 @@ types::ID types::getPreprocessedType(ID Id) {
 }
 
 static bool isPreprocessedModuleType(ID Id) {
-  return Id == TY_CXXModule || Id == TY_PP_CXXModule;
+  return Id == TY_CXXModule || Id == TY_PP_CXXModule || Id == TY_CXXStdModule 
||
+         Id == TY_PP_CXXStdModule;
 }
 
 static bool isPreprocessedHeaderUnitType(ID Id) {
@@ -101,13 +102,28 @@ bool types::onlyPrecompileType(ID Id) {
 
 bool types::canTypeBeUserSpecified(ID Id) {
   static const clang::driver::types::ID kStaticLangageTypes[] = {
-      TY_CUDA_DEVICE,   TY_HIP_DEVICE,    TY_PP_CHeader,
-      TY_PP_ObjCHeader, TY_PP_CXXHeader,  TY_PP_ObjCXXHeader,
-      TY_PP_CXXModule,  TY_LTO_IR,        TY_LTO_BC,
-      TY_Plist,         TY_RewrittenObjC, TY_RewrittenLegacyObjC,
-      TY_Remap,         TY_PCH,           TY_Object,
-      TY_Image,         TY_dSYM,          TY_Dependencies,
-      TY_CUDA_FATBIN,   TY_HIP_FATBIN};
+      TY_CUDA_DEVICE,
+      TY_HIP_DEVICE,
+      TY_PP_CHeader,
+      TY_PP_ObjCHeader,
+      TY_PP_CXXHeader,
+      TY_PP_ObjCXXHeader,
+      TY_PP_CXXModule,
+      TY_CXXStdModule,
+      TY_PP_CXXStdModule,
+      TY_LTO_IR,
+      TY_LTO_BC,
+      TY_Plist,
+      TY_RewrittenObjC,
+      TY_RewrittenLegacyObjC,
+      TY_Remap,
+      TY_PCH,
+      TY_Object,
+      TY_Image,
+      TY_dSYM,
+      TY_Dependencies,
+      TY_CUDA_FATBIN,
+      TY_HIP_FATBIN};
   return !llvm::is_contained(kStaticLangageTypes, Id);
 }
 
@@ -148,7 +164,10 @@ bool types::isAcceptedByClang(ID Id) {
   case TY_CXXHUHeader:
   case TY_PP_CXXHeaderUnit:
   case TY_ObjCXXHeader: case TY_PP_ObjCXXHeader:
-  case TY_CXXModule: case TY_PP_CXXModule:
+  case TY_CXXModule:
+  case TY_PP_CXXModule:
+  case TY_CXXStdModule:
+  case TY_PP_CXXStdModule:
   case TY_AST: case TY_ModuleFile: case TY_PCH:
   case TY_LLVM_IR: case TY_LLVM_BC:
   case TY_API_INFO:
@@ -209,6 +228,8 @@ bool types::isDerivedFromC(ID Id) {
   case TY_ObjCXXHeader:
   case TY_CXXModule:
   case TY_PP_CXXModule:
+  case TY_CXXStdModule:
+  case TY_PP_CXXStdModule:
     return true;
   }
 }
@@ -253,6 +274,8 @@ bool types::isCXX(ID Id) {
   case TY_ObjCXXHeader: case TY_PP_ObjCXXHeader:
   case TY_CXXModule:
   case TY_PP_CXXModule:
+  case TY_CXXStdModule:
+  case TY_PP_CXXStdModule:
   case TY_ModuleFile:
   case TY_PP_CLCXX:
   case TY_CUDA: case TY_PP_CUDA: case TY_CUDA_DEVICE:
@@ -435,6 +458,7 @@ ID types::lookupHeaderTypeForSourceType(ID Id) {
     return types::TY_CHeader;
   case types::TY_CXX:
   case types::TY_CXXModule:
+  case types::TY_CXXStdModule:
     return types::TY_CXXHeader;
   case types::TY_ObjC:
     return types::TY_ObjCHeader;
diff --git a/clang/lib/Tooling/InterpolatingCompilationDatabase.cpp 
b/clang/lib/Tooling/InterpolatingCompilationDatabase.cpp
index 08ee02f639a4f..36d0775a80708 100644
--- a/clang/lib/Tooling/InterpolatingCompilationDatabase.cpp
+++ b/clang/lib/Tooling/InterpolatingCompilationDatabase.cpp
@@ -113,6 +113,8 @@ static types::ID foldType(types::ID Lang) {
   case types::TY_CXXHeader:
   case types::TY_CXXModule:
   case types::TY_PP_CXXModule:
+  case types::TY_CXXStdModule:
+  case types::TY_PP_CXXStdModule:
     return types::TY_CXX;
   case types::TY_ObjCXX:
   case types::TY_ObjCXXHeader:
diff --git a/clang/test/Driver/modules-driver-import-std.cpp 
b/clang/test/Driver/modules-driver-import-std.cpp
index 3a51cab0406b2..0ce2a5d36af50 100644
--- a/clang/test/Driver/modules-driver-import-std.cpp
+++ b/clang/test/Driver/modules-driver-import-std.cpp
@@ -57,9 +57,80 @@ int main() {}
 // RUN:   -L%t/Inputs/usr/lib/x86_64-linux-gnu \
 // RUN:   --target=x86_64-linux-gnu \
 // RUN:   -c %t/main.cpp 2>&1 \
+// RUN:   --verbose \
 // RUN:   | sed 's:\\\\\?:/:g' \
 // RUN:   | FileCheck -DPREFIX=%/t %s
 
+// Skip past diagnostics omitted during the dependency scan.
+// CHECK: clang: remark: printing module dependency graph [-Rmodules-driver]
+
+// Checks that the standard library modules are primary outputs.
+// TODO: Test the same for -fno-modules-reduced-bmi when supported by 
+// -fmodules-driver.
+// CHECK: -o {{.*std-[^ ]*\.pcm}}
+// CHECK-SAME: -emit-reduced-module-interface
+// CHECK-SAME: -main-file-name std.cppm
+// CHECK: -o {{.*std\.compat-[^ ]*\.pcm}}
+// CHECK-SAME: -emit-reduced-module-interface
+// CHECK-SAME: -main-file-name std.compat.cppm
+
+// Checks that the object file is generated for the main TU.
+// CHECK: -emit-obj
+// CHECK-SAME: -main-file-name main.cpp
+
+// Checks that the standard library modules are successfully imported.
 // 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
+
+// Checks that standard library modules are still precompiled with -emit-llvm.
+// RUN: %clang -std=c++23 -stdlib=libc++ \
+// RUN:   -fmodules-driver -Rmodules-driver -Rmodule-import \
+// RUN:   -stdlib=libc++ \
+// RUN:   -resource-dir=%t/FakeSysroot/usr/lib/x86_64-linux-gnu \
+// RUN:   --sysroot=%t/FakeSysroot \
+// RUN:   -L%t/Inputs/usr/lib/x86_64-linux-gnu \
+// RUN:   --target=x86_64-linux-gnu \
+// RUN:   %t/main.cpp -S -emit-llvm -o out.ll \
+// RUN:   --verbose 2>&1 \
+// RUN:   | sed 's:\\\\\?:/:g' \
+// RUN:   | FileCheck -DPREFIX=%/t --check-prefix=CHECK-EMIT-LLVM %s
+
+// Skip past diagnostics omitted during the dependency scan.
+// CHECK-EMIT-LLVM: clang: remark: printing module dependency graph 
[-Rmodules-driver]
+
+// CHECK-EMIT-LLVM: -o {{.*std-[^ ]*\.pcm}}
+// CHECK-EMIT-LLVM-SAME: -emit-reduced-module-interface
+// CHECK-EMIT-LLVM-SAME: -main-file-name std.cppm
+// CHECK-EMIT-LLVM: -o {{.*std\.compat-[^ ]*\.pcm}}
+// CHECK-EMIT-LLVM-SAME: -emit-reduced-module-interface
+// CHECK-EMIT-LLVM-SAME: -main-file-name std.compat.cppm
+// CHECK-EMIT-LLVM: -emit-llvm
+// CHECK-EMIT-LLVM-SAME: -main-file-name main.cpp
+
+// Checks that standard library modules are still precompiled with 
-fsyntax-only.
+// RUN: %clang -std=c++23 -stdlib=libc++ \
+// RUN:   -fmodules-driver -Rmodules-driver -Rmodule-import \
+// RUN:   -stdlib=libc++ \
+// RUN:   -resource-dir=%t/FakeSysroot/usr/lib/x86_64-linux-gnu \
+// RUN:   --sysroot=%t/FakeSysroot \
+// RUN:   -L%t/Inputs/usr/lib/x86_64-linux-gnu \
+// RUN:   --target=x86_64-linux-gnu \
+// RUN:   -fsyntax-only \
+// RUN:   %t/main.cpp \
+// RUN:   --verbose 2>&1 \
+// RUN:   | sed 's:\\\\\?:/:g' \
+// RUN:   | FileCheck -DPREFIX=%/t --check-prefix=CHECK-SYNTAX-ONLY %s
+
+// Skip past diagnostics omitted during the dependency scan.
+// CHECK-SYNTAX-ONLY: clang: remark: printing module dependency graph 
[-Rmodules-driver]
+
+// CHECK-SYNTAX-ONLY: -o {{.*std-[^ ]*\.pcm}}
+// CHECK-SYNTAX-ONLY-SAME: -emit-reduced-module-interface
+// CHECK-SYNTAX-ONLY-SAME: -main-file-name std.cppm
+// CHECK-SYNTAX-ONLY: -o {{.*std\.compat-[^ ]*\.pcm}}
+// CHECK-SYNTAX-ONLY-SAME: -emit-reduced-module-interface
+// CHECK-SYNTAX-ONLY-SAME: -main-file-name std.compat.cppm
+
+// CHECK-SYNTAX-ONLY: -cc1 {{.*}} -Rmodules-driver
+// CHECK-SYNTAX-ONLY-NOT: {{ -o }}

>From 44a06c1987ade9bcace7bdf47152f940c11456f0 Mon Sep 17 00:00:00 2001
From: Naveen Seth Hanig <[email protected]>
Date: Sat, 23 May 2026 00:01:02 +0200
Subject: [PATCH 2/9] Make failing test more robust

---
 ...odules-driver-dep-graph-stdlib-modules.cpp | 23 ++++++++++---------
 1 file changed, 12 insertions(+), 11 deletions(-)

diff --git a/clang/test/Driver/modules-driver-dep-graph-stdlib-modules.cpp 
b/clang/test/Driver/modules-driver-dep-graph-stdlib-modules.cpp
index 04108cfabea89..a96eaab15eec9 100644
--- a/clang/test/Driver/modules-driver-dep-graph-stdlib-modules.cpp
+++ b/clang/test/Driver/modules-driver-dep-graph-stdlib-modules.cpp
@@ -34,18 +34,18 @@
 
 // CHECK:      digraph "Module Dependency Graph" {
 //
-// CHECK:              "[[PREFIX]]/main.cpp-x86_64-unknown-linux-gnu" 
[fillcolor=3, label="{ Filename: [[PREFIX]]/main.cpp | Triple: 
x86_64-unknown-linux-gnu }"];
-// CHECK-NEXT:         "[[PREFIX]]/foo.cpp-x86_64-unknown-linux-gnu" 
[fillcolor=3, label="{ Filename: [[PREFIX]]/foo.cpp | Triple: 
x86_64-unknown-linux-gnu }"];
-// CHECK-NEXT:         "std-x86_64-unknown-linux-gnu" [fillcolor=2, label="{ 
Filename: {{.*}} | Module type: Named module | Module name: std | Triple: 
x86_64-unknown-linux-gnu }"];
-// CHECK-NEXT:         "std.compat-x86_64-unknown-linux-gnu" [fillcolor=2, 
label="{ Filename: {{.*}} | Module type: Named module | Module name: std.compat 
| Triple: x86_64-unknown-linux-gnu }"];
-// CHECK-NEXT:         "core-x86_64-unknown-linux-gnu" [fillcolor=2, label="{ 
Filename: {{.*}} | Module type: Named module | Module name: core | Triple: 
x86_64-unknown-linux-gnu }"];
+// CHECK-DAG:          "[[PREFIX]]/main.cpp-x86_64-unknown-linux-gnu" 
[fillcolor=3, label="{ Filename: [[PREFIX]]/main.cpp | Triple: 
x86_64-unknown-linux-gnu }"];
+// CHECK-DAG:          "[[PREFIX]]/foo.cpp-x86_64-unknown-linux-gnu" 
[fillcolor=3, label="{ Filename: [[PREFIX]]/foo.cpp | Triple: 
x86_64-unknown-linux-gnu }"];
+// CHECK-DAG:          "std-x86_64-unknown-linux-gnu" [fillcolor=2, label="{ 
Filename: {{.*}} | Module type: Named module | Module name: std | Triple: 
x86_64-unknown-linux-gnu }"];
+// CHECK-DAG:          "std.compat-x86_64-unknown-linux-gnu" [fillcolor=2, 
label="{ Filename: {{.*}} | Module type: Named module | Module name: std.compat 
| Triple: x86_64-unknown-linux-gnu }"];
+// CHECK-DAG:          "core-x86_64-unknown-linux-gnu" [fillcolor=2, label="{ 
Filename: {{.*}} | Module type: Named module | Module name: core | Triple: 
x86_64-unknown-linux-gnu }"];
 //
-// CHECK:              "std-x86_64-unknown-linux-gnu" -> 
"[[PREFIX]]/main.cpp-x86_64-unknown-linux-gnu";
-// CHECK-NEXT:         "std-x86_64-unknown-linux-gnu" -> 
"[[PREFIX]]/foo.cpp-x86_64-unknown-linux-gnu";
-// CHECK-NEXT:         "std-x86_64-unknown-linux-gnu" -> 
"std.compat-x86_64-unknown-linux-gnu";
-// CHECK-NEXT:         "std.compat-x86_64-unknown-linux-gnu" -> 
"[[PREFIX]]/main.cpp-x86_64-unknown-linux-gnu";
-// CHECK-NEXT:         "core-x86_64-unknown-linux-gnu" -> 
"[[PREFIX]]/foo.cpp-x86_64-unknown-linux-gnu";
-// CHECK-NEXT: }
+// CHECK-DAG:          "std-x86_64-unknown-linux-gnu" -> 
"[[PREFIX]]/main.cpp-x86_64-unknown-linux-gnu";
+// CHECK-DAG:          "std-x86_64-unknown-linux-gnu" -> 
"[[PREFIX]]/foo.cpp-x86_64-unknown-linux-gnu";
+// CHECK-DAG:          "std-x86_64-unknown-linux-gnu" -> 
"std.compat-x86_64-unknown-linux-gnu";
+// CHECK-DAG:          "std.compat-x86_64-unknown-linux-gnu" -> 
"[[PREFIX]]/main.cpp-x86_64-unknown-linux-gnu";
+// CHECK-DAG:          "core-x86_64-unknown-linux-gnu" -> 
"[[PREFIX]]/foo.cpp-x86_64-unknown-linux-gnu";
+// CHECK:      }
 
 
 //--- main.cpp
@@ -99,3 +99,4 @@ export module unused;
     }
   ]
 }
+

>From 031988d400e7fa05b578e8f45b6750523ddce550 Mon Sep 17 00:00:00 2001
From: Naveen Seth Hanig <[email protected]>
Date: Sat, 23 May 2026 01:38:29 +0200
Subject: [PATCH 3/9] Cleanup (NFC)

---
 clang/lib/Driver/Driver.cpp                                 | 6 ++----
 .../test/Driver/modules-driver-dep-graph-stdlib-modules.cpp | 1 -
 2 files changed, 2 insertions(+), 5 deletions(-)

diff --git a/clang/lib/Driver/Driver.cpp b/clang/lib/Driver/Driver.cpp
index 398f40920c15e..29b84ba139141 100644
--- a/clang/lib/Driver/Driver.cpp
+++ b/clang/lib/Driver/Driver.cpp
@@ -6503,11 +6503,9 @@ const char *Driver::GetNamedOutputPath(Compilation &C, 
const JobAction &JA,
                           NeedUniqueDirectory);
   };
 
-  const bool IsModulesDriver = 
C.getArgs().hasArg(options::OPT_fmodules_driver);
-
   // Standard library output in -fmodules-driver?
-  if (IsModulesDriver && isa<PrecompileJobAction>(JA) &&
-      !JA.getInputs().empty() &&
+  if (C.getArgs().hasArg(options::OPT_fmodules_driver) &&
+      isa<PrecompileJobAction>(JA) && !JA.getInputs().empty() &&
       (JA.getInputs().front()->getType() == types::TY_CXXStdModule ||
        JA.getInputs().front()->getType() == types::TY_PP_CXXStdModule)) {
     StringRef Filename = llvm::sys::path::filename(BaseInput);
diff --git a/clang/test/Driver/modules-driver-dep-graph-stdlib-modules.cpp 
b/clang/test/Driver/modules-driver-dep-graph-stdlib-modules.cpp
index a96eaab15eec9..de6e917e115d4 100644
--- a/clang/test/Driver/modules-driver-dep-graph-stdlib-modules.cpp
+++ b/clang/test/Driver/modules-driver-dep-graph-stdlib-modules.cpp
@@ -99,4 +99,3 @@ export module unused;
     }
   ]
 }
-

>From 7d263fd9fd40125a450c7c69313f5238281fff90 Mon Sep 17 00:00:00 2001
From: Naveen Seth Hanig <[email protected]>
Date: Sat, 23 May 2026 01:45:55 +0200
Subject: [PATCH 4/9] Futher cleanups (NFC)

---
 clang/lib/Driver/Driver.cpp | 11 +++++------
 1 file changed, 5 insertions(+), 6 deletions(-)

diff --git a/clang/lib/Driver/Driver.cpp b/clang/lib/Driver/Driver.cpp
index 29b84ba139141..f310349f91364 100644
--- a/clang/lib/Driver/Driver.cpp
+++ b/clang/lib/Driver/Driver.cpp
@@ -5479,10 +5479,9 @@ void Driver::BuildJobs(Compilation &C) const {
         continue;
 
       if (isa<PrecompileJobAction>(A) && !A->getInputs().empty()) {
-        const Action *Input = A->getInputs().front();
-        types::ID InputType = Input->getType();
-        if (InputType == types::TY_CXXStdModule ||
-            InputType == types::TY_PP_CXXStdModule)
+        const Action *FirstAction = A->getInputs().front();
+        if (FirstAction->getType() == types::TY_CXXStdModule ||
+            FirstAction->getType() == types::TY_PP_CXXStdModule)
           continue;
       }
 
@@ -6494,8 +6493,8 @@ const char *Driver::GetNamedOutputPath(Compilation &C, 
const JobAction &JA,
     // The non-offloading toolchain on Darwin requires deterministic input
     // file name for binaries to be deterministic, therefore it needs unique
     // directory.
-    llvm::Triple Triple(C.getDriver().getTargetTriple());
-    bool NeedUniqueDirectory =
+    const llvm::Triple Triple(C.getDriver().getTargetTriple());
+    const bool NeedUniqueDirectory =
         (JA.getOffloadingDeviceKind() == Action::OFK_None ||
          JA.getOffloadingDeviceKind() == Action::OFK_Host) &&
         Triple.isOSDarwin();

>From bf069ec743588b52d3329691113fec9a237f8c7d Mon Sep 17 00:00:00 2001
From: Naveen Seth Hanig <[email protected]>
Date: Sat, 23 May 2026 03:01:28 +0200
Subject: [PATCH 5/9] Remove duplicate -stdlib=libc++

---
 clang/test/Driver/modules-driver-import-std.cpp | 3 ---
 1 file changed, 3 deletions(-)

diff --git a/clang/test/Driver/modules-driver-import-std.cpp 
b/clang/test/Driver/modules-driver-import-std.cpp
index 0ce2a5d36af50..a97ec84c716f6 100644
--- a/clang/test/Driver/modules-driver-import-std.cpp
+++ b/clang/test/Driver/modules-driver-import-std.cpp
@@ -51,7 +51,6 @@ int main() {}
 
 // RUN: %clang -std=c++23 -stdlib=libc++ \
 // RUN:   -fmodules-driver -Rmodules-driver -Rmodule-import \
-// RUN:   -stdlib=libc++ \
 // RUN:   -resource-dir=%t/FakeSysroot/usr/lib/x86_64-linux-gnu \
 // RUN:   --sysroot=%t/FakeSysroot \
 // RUN:   -L%t/Inputs/usr/lib/x86_64-linux-gnu \
@@ -86,7 +85,6 @@ int main() {}
 // Checks that standard library modules are still precompiled with -emit-llvm.
 // RUN: %clang -std=c++23 -stdlib=libc++ \
 // RUN:   -fmodules-driver -Rmodules-driver -Rmodule-import \
-// RUN:   -stdlib=libc++ \
 // RUN:   -resource-dir=%t/FakeSysroot/usr/lib/x86_64-linux-gnu \
 // RUN:   --sysroot=%t/FakeSysroot \
 // RUN:   -L%t/Inputs/usr/lib/x86_64-linux-gnu \
@@ -111,7 +109,6 @@ int main() {}
 // Checks that standard library modules are still precompiled with 
-fsyntax-only.
 // RUN: %clang -std=c++23 -stdlib=libc++ \
 // RUN:   -fmodules-driver -Rmodules-driver -Rmodule-import \
-// RUN:   -stdlib=libc++ \
 // RUN:   -resource-dir=%t/FakeSysroot/usr/lib/x86_64-linux-gnu \
 // RUN:   --sysroot=%t/FakeSysroot \
 // RUN:   -L%t/Inputs/usr/lib/x86_64-linux-gnu \

>From 1394f67d335d0914431afd14cd0c0cb9d18305f0 Mon Sep 17 00:00:00 2001
From: Naveen Seth Hanig <[email protected]>
Date: Wed, 27 May 2026 14:04:53 +0200
Subject: [PATCH 6/9] Add comment regarding skipping of std modules during
 input count

---
 clang/lib/Driver/Driver.cpp | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/clang/lib/Driver/Driver.cpp b/clang/lib/Driver/Driver.cpp
index f310349f91364..695d9d13f4c7e 100644
--- a/clang/lib/Driver/Driver.cpp
+++ b/clang/lib/Driver/Driver.cpp
@@ -5478,6 +5478,8 @@ void Driver::BuildJobs(Compilation &C) const {
           A->getKind() == clang::driver::Action::BinaryTranslatorJobClass)
         continue;
 
+      // With -fmodules-driver, the Standard library modules should not count
+      // towards the number of outputs either.
       if (isa<PrecompileJobAction>(A) && !A->getInputs().empty()) {
         const Action *FirstAction = A->getInputs().front();
         if (FirstAction->getType() == types::TY_CXXStdModule ||

>From 27f8f9a369525cd977cb6f497cd670255cf1f555 Mon Sep 17 00:00:00 2001
From: Naveen Seth Hanig <[email protected]>
Date: Wed, 27 May 2026 14:06:08 +0200
Subject: [PATCH 7/9] Add comment on not counting std modules towards the input
 count

---
 clang/lib/Driver/Driver.cpp | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/clang/lib/Driver/Driver.cpp b/clang/lib/Driver/Driver.cpp
index 695d9d13f4c7e..72601257301dd 100644
--- a/clang/lib/Driver/Driver.cpp
+++ b/clang/lib/Driver/Driver.cpp
@@ -5478,8 +5478,9 @@ void Driver::BuildJobs(Compilation &C) const {
           A->getKind() == clang::driver::Action::BinaryTranslatorJobClass)
         continue;
 
-      // With -fmodules-driver, the Standard library modules should not count
-      // towards the number of outputs either.
+      // With -fmodules-driver, Standard library modules should not count 
toward
+      // the number of outputs, since they are implicitly added to the input
+      // list.
       if (isa<PrecompileJobAction>(A) && !A->getInputs().empty()) {
         const Action *FirstAction = A->getInputs().front();
         if (FirstAction->getType() == types::TY_CXXStdModule ||

>From 8eab412ee4d1166ee125dfcf6879aa36ed8fd94e Mon Sep 17 00:00:00 2001
From: Naveen Seth Hanig <[email protected]>
Date: Wed, 27 May 2026 16:05:19 +0200
Subject: [PATCH 8/9] Simplify and align ifs

---
 clang/lib/Driver/Driver.cpp | 13 +++++--------
 1 file changed, 5 insertions(+), 8 deletions(-)

diff --git a/clang/lib/Driver/Driver.cpp b/clang/lib/Driver/Driver.cpp
index 72601257301dd..82e8977648b92 100644
--- a/clang/lib/Driver/Driver.cpp
+++ b/clang/lib/Driver/Driver.cpp
@@ -5481,12 +5481,10 @@ void Driver::BuildJobs(Compilation &C) const {
       // With -fmodules-driver, Standard library modules should not count 
toward
       // the number of outputs, since they are implicitly added to the input
       // list.
-      if (isa<PrecompileJobAction>(A) && !A->getInputs().empty()) {
-        const Action *FirstAction = A->getInputs().front();
-        if (FirstAction->getType() == types::TY_CXXStdModule ||
-            FirstAction->getType() == types::TY_PP_CXXStdModule)
-          continue;
-      }
+      if (isa<PrecompileJobAction>(A) && !A->getInputs().empty() &&
+          (A->getInputs().front()->getType() == types::TY_CXXStdModule ||
+           A->getInputs().front()->getType() == types::TY_PP_CXXStdModule))
+        continue;
 
       if (A->getType() != types::TY_Nothing &&
           !(A->getKind() == Action::IfsMergeJobClass ||
@@ -6506,8 +6504,7 @@ const char *Driver::GetNamedOutputPath(Compilation &C, 
const JobAction &JA,
   };
 
   // Standard library output in -fmodules-driver?
-  if (C.getArgs().hasArg(options::OPT_fmodules_driver) &&
-      isa<PrecompileJobAction>(JA) && !JA.getInputs().empty() &&
+  if (isa<PrecompileJobAction>(JA) && !JA.getInputs().empty() &&
       (JA.getInputs().front()->getType() == types::TY_CXXStdModule ||
        JA.getInputs().front()->getType() == types::TY_PP_CXXStdModule)) {
     StringRef Filename = llvm::sys::path::filename(BaseInput);

>From 1d2321979a95cedb87956fbec6063bcce14952f1 Mon Sep 17 00:00:00 2001
From: Naveen Seth Hanig <[email protected]>
Date: Thu, 28 May 2026 10:18:23 +0200
Subject: [PATCH 9/9] Cleanup in fixupNamedModuleCommandLines

---
 clang/lib/Driver/ModulesDriver.cpp | 4 ----
 1 file changed, 4 deletions(-)

diff --git a/clang/lib/Driver/ModulesDriver.cpp 
b/clang/lib/Driver/ModulesDriver.cpp
index a09f69d6aad4e..e0a4503857871 100644
--- a/clang/lib/Driver/ModulesDriver.cpp
+++ b/clang/lib/Driver/ModulesDriver.cpp
@@ -1605,10 +1605,6 @@ static void fixupNamedModuleCommandLines(Compilation &C,
     const bool IsStdModule =
         Job.getInputInfos().front().getType() == types::TY_CXXStdModule;
     if (IsStdModule) {
-      const auto &OutputFilenames = Job.getOutputFilenames();
-      if (OutputFilenames.empty())
-        continue;
-
       StringRef ModuleOutputPath = Job.getOutputFilenames().front();
       propagateModuleFileMappingArg(C, *Node, ModuleOutputPath);
       continue;

_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to