https://github.com/naveen-seth updated https://github.com/llvm/llvm-project/pull/187606
>From c48ed203a98e7aa881d35306fac3b7715f570306 Mon Sep 17 00:00:00 2001 From: Naveen Seth Hanig <[email protected]> Date: Thu, 19 Mar 2026 23:35:41 +0100 Subject: [PATCH] [clang][ModulesDriver] Add support for Clang modules to -fmodules-driver This PR adds basic support for Clang modules to the -fmodules-driver feature, enabling compilations with Clang modules managed natively by the Clang driver. Caching is not included in this PR. RFC for driver-managed module builds: https://discourse.llvm.org/t/rfc-modules-support-simple-c-20-modules-use-from-the-clang-driver-without-a-build-system --- clang/lib/Driver/ModulesDriver.cpp | 14 ++-- .../modules-driver-clang-modules-only.cpp | 75 +++++++++++++++++++ .../modules-driver-manifest-input-args.cpp | 14 +--- 3 files changed, 88 insertions(+), 15 deletions(-) create mode 100644 clang/test/Driver/modules-driver-clang-modules-only.cpp diff --git a/clang/lib/Driver/ModulesDriver.cpp b/clang/lib/Driver/ModulesDriver.cpp index 8740f9615d304..166c7749245c6 100644 --- a/clang/lib/Driver/ModulesDriver.cpp +++ b/clang/lib/Driver/ModulesDriver.cpp @@ -25,6 +25,7 @@ #include "llvm/ADT/DenseSet.h" #include "llvm/ADT/DepthFirstIterator.h" #include "llvm/ADT/DirectedGraph.h" +#include "llvm/ADT/PostOrderIterator.h" #include "llvm/ADT/STLExtras.h" #include "llvm/ADT/SmallVectorExtras.h" #include "llvm/ADT/TypeSwitch.h" @@ -1528,9 +1529,12 @@ void driver::modules::runModulesDriver( // TODO: Install all updated command-lines produced by the dependency scan. // TODO: Fix-up command-lines for named module imports. - // TODO: Sort the graph topologically before adding jobs back to the - // Compilation being built. - for (auto *N : Graph) - if (auto *JN = dyn_cast<JobNode>(N)) - C.addCommand(std::move(JN->Job)); + llvm::ReversePostOrderTraversal<CompilationGraph *> TopologicallySortedNodes( + &Graph); + assert(isa<RootNode>(*TopologicallySortedNodes.begin()) && + "First node in topological order must be the root!"); + auto TopologicallySortedJobNodes = llvm::map_range( + llvm::drop_begin(TopologicallySortedNodes), llvm::CastTo<JobNode>); + for (auto *JN : TopologicallySortedJobNodes) + C.addCommand(std::move(JN->Job)); } diff --git a/clang/test/Driver/modules-driver-clang-modules-only.cpp b/clang/test/Driver/modules-driver-clang-modules-only.cpp new file mode 100644 index 0000000000000..e99ce7883afba --- /dev/null +++ b/clang/test/Driver/modules-driver-clang-modules-only.cpp @@ -0,0 +1,75 @@ +// Checks that -fmodules-driver correctly handles compilations using Clang modules. + +// RUN: split-file %s %t +// RUN: rm -rf %t/modules-cache +// 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: -fsyntax-only %t/main.cpp 2>&1 \ +// RUN: | sed 's:\\\\\?:/:g' \ +// RUN: | FileCheck -DPREFIX=%/t %s + +// The scan itself will also produce [-Rmodule-import] remarks. +// Let's skip past them, we only care about the final -cc1 commands. +// CHECK: clang: remark: printing module dependency graph [-Rmodules-driver] +// CHECK-NEXT: digraph "Module Dependency Graph" { +// CHECK: } + +// CHECK: [[PREFIX]]/main.cpp:1:2: remark: importing module 'root' from +// CHECK: [[PREFIX]]/main.cpp:1:2: remark: importing module 'direct1' into 'root' +// CHECK: [[PREFIX]]/main.cpp:1:2: remark: importing module 'transitive1' into 'direct1' +// CHECK: [[PREFIX]]/main.cpp:1:2: remark: importing module 'transitive2' into 'direct1' +// CHECK: [[PREFIX]]/main.cpp:1:2: remark: importing module 'direct2' into 'root' +// CHECK: [[PREFIX]]/main.cpp:1:2: remark: importing module 'transitive2' into 'direct2' + +// (Because of missing include guards, this example would also run into +// redefinition errors when compiling without modules.) + +/--- module.modulemap +module root { header "root.h"} +module transitive1 { header "transitive1.h" } +module transitive2 { header "transitive2.h" } +module direct1 { header "direct1.h" } +module direct2 { header "direct2.h" } + +//--- root.h +#include "direct1.h" +#include "direct2.h" +int fromRoot() { + return fromDirect1() + fromDirect2(); +} + +//--- direct1.h +#include "transitive1.h" +#include "transitive2.h" + +int fromDirect1() { + return fromTransitive1() + fromTransitive2(); +} + +//--- direct2.h +#include "transitive2.h" + +int fromDirect2() { + return fromTransitive2() + 2; +} + +//--- transitive1.h +int fromTransitive1() { + return 20; +} + +//--- transitive2.h + +int fromTransitive2() { + return 10; +} + +//--- main.cpp +#include "root.h" + +int main() { + fromRoot(); +} diff --git a/clang/test/Driver/modules-driver-manifest-input-args.cpp b/clang/test/Driver/modules-driver-manifest-input-args.cpp index 99765a1943faf..d1c2938a73fb5 100644 --- a/clang/test/Driver/modules-driver-manifest-input-args.cpp +++ b/clang/test/Driver/modules-driver-manifest-input-args.cpp @@ -26,17 +26,11 @@ // RUN: %t/main.cpp \ // RUN: -### 2>&1 \ // RUN: | sed 's:\\\\\?:/:g' \ -// RUN: | FileCheck %s -check-prefix=MAIN-CC1 -check-prefix=STDLIB-MOD-CC1 -DPREFIX=%/t +// RUN: | FileCheck %s -DPREFIX=%/t -// MAIN-CC1: "-cc1" -// MAIN-CC1-SAME: "main.cpp" -// MAIN-CC1-NOT: "-Wno-reserved-module-identifier" -// MAIN-CC1-NOT: "-internal-isystem" "[[PREFIX]]/Inputs/usr/lib/x86_64-linux-gnu/../share/libc++/v1/" - -// STDLIB-MOD-CC1: "-cc1" -// STDLIB-MOD-CC1-SAME: "[[PREFIX]]/Inputs/usr/lib/x86_64-linux-gnu/../share/libc++/v1/std.cppm" -// STDLIB-MOD-CC1-SAME: "-Wno-reserved-module-identifier" -// STDLIB-MOD-CC1-SAME: "-internal-isystem" "[[PREFIX]]/Inputs/usr/lib/x86_64-linux-gnu/../share/libc++/v1/" +// CHECK: "-cc1" {{.*}} "[[PREFIX]]/Inputs/usr/lib/x86_64-linux-gnu/../share/libc++/v1/std.cppm" +// CHECK-SAME: "-Wno-reserved-module-identifier" +// CHECK-SAME: "-internal-isystem" "[[PREFIX]]/Inputs/usr/lib/x86_64-linux-gnu/../share/libc++/v1/" //--- main.cpp import std; _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
