// 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 --check-prefix=CHECK-REMARKS %s // RUN: rm -rf %t/modules-cache // RUN: %clang -std=c++23 \ // RUN: -fmodules-driver \ // RUN: -fmodules \ // RUN: -fmodule-map-file=%t/module.modulemap \ // RUN: -fmodules-cache-path=%t/modules-cache \ // RUN: -fsyntax-only %t/main.cpp \ // RUN: -### 2>&1 \ // RUN: | sed 's:\\\\\?:/:g' \ // RUN: | FileCheck --check-prefix=CHECK-CC1 %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]]/main.cpp:1:2: remark: importing module 'root' from // CHECK-REMARKS: [[PREFIX]]/main.cpp:1:2: remark: importing module 'direct1' into 'root' // CHECK-REMARKS: [[PREFIX]]/main.cpp:1:2: remark: importing module 'transitive1' into 'direct1' // CHECK-REMARKS: [[PREFIX]]/main.cpp:1:2: remark: importing module 'transitive2' into 'direct1' // CHECK-REMARKS: [[PREFIX]]/main.cpp:1:2: remark: importing module 'direct2' into 'root' // CHECK-REMARKS: [[PREFIX]]/main.cpp:1:2: remark: importing module 'transitive2' into 'direct2' // CHECK-CC1: "-cc1" // CHECK-CC1-SAME: "-o" "[[TRANSITIVE2PCM:[^"]+]]" // CHECK-CC1-SAME: "-emit-module" // CHECK-CC1-SAME: "-fmodule-name=transitive2" // CHECK-CC1-SAME: "-fno-implicit-modules" // CHECK-CC1: "-cc1" // CHECK-CC1-SAME: "-o" "[[DIRECT2PCM:[^"]+]]" // CHECK-CC1-SAME: "-emit-module" // CHECK-CC1-SAME: "-fmodule-file=transitive2=[[TRANSITIVE2PCM]]" // CHECK-CC1-SAME: "-fmodule-name=direct2" // CHECK-CC1-SAME: "-fno-implicit-modules" // CHECK-CC1: "-cc1" // CHECK-CC1-SAME: "-o" "[[TRANSITIVE1PCM:[^"]+]]" // CHECK-CC1-SAME: "-emit-module" // CHECK-CC1-SAME: "-fmodule-name=transitive1" // CHECK-CC1-SAME: "-fno-implicit-modules" // CHECK-CC1: "-cc1" // CHECK-CC1-SAME: "-o" "[[DIRECT1PCM:[^"]+]]" // CHECK-CC1-SAME: "-emit-module" // CHECK-CC1-SAME: "-fmodule-file=transitive1=[[TRANSITIVE1PCM]]" // CHECK-CC1-SAME: "-fmodule-file=transitive2=[[TRANSITIVE2PCM]]" // CHECK-CC1-SAME: "-fmodule-name=direct1" // CHECK-CC1-SAME: "-fno-implicit-modules" // CHECK-CC1: "-cc1" // CHECK-CC1-SAME: "-o" "[[ROOTPCM:[^"]+]]" // CHECK-CC1-SAME: "-emit-module" // CHECK-CC1-SAME: "-fmodule-file=direct1=[[DIRECT1PCM]]" // CHECK-CC1-SAME: "-fmodule-file=direct2=[[DIRECT2PCM]]" // CHECK-CC1-SAME: "-fmodule-name=root" // CHECK-CC1-SAME: "-fno-implicit-modules" // CHECK-CC1: "-cc1" // CHECK-CC1-SAME: "-fsyntax-only" // CHECK-CC1-SAME: "{{.*}}/main.cpp" // CHECK-CC1-SAME: "-fmodule-file=root=[[ROOTPCM]]" // CHECK-CC1-SAME: "-fno-implicit-modules" // (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(); }