[clang] cbbe555 - [C++20] [Modules] Generate init calls for the modules imported in GMF or PMF
Chuanqi Xu via cfe-commits
cfe-commits at lists.llvm.org
Fri Sep 29 07:17:26 PDT 2023
Author: Chuanqi Xu
Date: 2023-09-29T22:16:31+08:00
New Revision: cbbe55590414d5b698dcb7f7125f0508b29cadf8
URL: https://github.com/llvm/llvm-project/commit/cbbe55590414d5b698dcb7f7125f0508b29cadf8
DIFF: https://github.com/llvm/llvm-project/commit/cbbe55590414d5b698dcb7f7125f0508b29cadf8.diff
LOG: [C++20] [Modules] Generate init calls for the modules imported in GMF or PMF
I just found that we didn't handle the imports in GMF of PMF when we're
generating the init functions for the current module unit. This looks
like a simple oversight and I'm going to fix that in this patch
directly.
Added:
Modified:
clang/lib/CodeGen/CGDeclCXX.cpp
clang/test/CodeGenCXX/module-initializer-guard-elision.cpp
Removed:
################################################################################
diff --git a/clang/lib/CodeGen/CGDeclCXX.cpp b/clang/lib/CodeGen/CGDeclCXX.cpp
index c576128e8eb6c62..8a05e4893196ad2 100644
--- a/clang/lib/CodeGen/CGDeclCXX.cpp
+++ b/clang/lib/CodeGen/CGDeclCXX.cpp
@@ -655,6 +655,10 @@ void CodeGenModule::EmitCXXThreadLocalInitFunc() {
*/
void CodeGenModule::EmitCXXModuleInitFunc(Module *Primary) {
+ assert(Primary->isInterfaceOrPartition() &&
+ "The function should only be called for C++20 named module interface"
+ " or partition.");
+
while (!CXXGlobalInits.empty() && !CXXGlobalInits.back())
CXXGlobalInits.pop_back();
@@ -669,6 +673,18 @@ void CodeGenModule::EmitCXXModuleInitFunc(Module *Primary) {
// Ones that we only import.
for (Module *M : Primary->Imports)
AllImports.push_back(M);
+ // Ones that we import in the global module fragment or the private module
+ // fragment.
+ llvm::for_each(Primary->submodules(), [&AllImports](Module *SubM) {
+ assert((SubM->isGlobalModule() || SubM->isPrivateModule()) &&
+ "The sub modules of C++20 module unit should only be global module "
+ "fragments or private module framents.");
+ assert(SubM->Exports.empty() &&
+ "The global mdoule fragments and the private module fragments are "
+ "not allowed to export import modules.");
+ for (Module *M : SubM->Imports)
+ AllImports.push_back(M);
+ });
SmallVector<llvm::Function *, 8> ModuleInits;
for (Module *M : AllImports) {
diff --git a/clang/test/CodeGenCXX/module-initializer-guard-elision.cpp b/clang/test/CodeGenCXX/module-initializer-guard-elision.cpp
index 58189ca949d8e01..bae7c930b51029c 100644
--- a/clang/test/CodeGenCXX/module-initializer-guard-elision.cpp
+++ b/clang/test/CodeGenCXX/module-initializer-guard-elision.cpp
@@ -27,6 +27,16 @@
// RUN: %clang_cc1 -triple %itanium_abi_triple -std=c++20 S.pcm -S -emit-llvm \
// RUN: -o - | FileCheck %s --check-prefix=CHECK-S
+// RUN: %clang_cc1 -triple %itanium_abi_triple -std=c++20 T.cpp \
+// RUN: -emit-module-interface -fmodule-file=S=S.pcm -fmodule-file=R=R.pcm -o T.pcm
+// RUN: %clang_cc1 -triple %itanium_abi_triple -std=c++20 T.pcm -S -emit-llvm \
+// RUN: -o - | FileCheck %s --check-prefix=CHECK-T
+
+// RUN: %clang_cc1 -triple %itanium_abi_triple -std=c++20 U.cpp \
+// RUN: -emit-module-interface -fmodule-file=T=T.pcm -fmodule-file=R=R.pcm -o U.pcm
+// RUN: %clang_cc1 -triple %itanium_abi_triple -std=c++20 U.pcm -S -emit-llvm \
+// RUN: -o - | FileCheck %s --check-prefix=CHECK-U
+
// Testing cases where we can elide the module initializer guard variable.
// This module has no global inits and does not import any other module
@@ -96,3 +106,25 @@ export import R;
// CHECK-S: define void @_ZGIW1S
// CHECK-S: store i8 1, ptr @_ZGIW1S__in_chrg
// CHECK-S: call{{.*}}@_ZGIW1R
+
+// The module itself doesn't have a global init and it doesn't import any module.
+// But the global module fragment imports a module that needs an init. So needs a guard.
+//--- T.cpp
+module;
+import S;
+export module T;
+
+// CHECK-T: define void @_ZGIW1T
+// CHECK-T: store i8 1, ptr @_ZGIW1T__in_chrg
+// CHECK-T: call{{.*}}@_ZGIW1S
+
+// The module itself doesn't have a global init and it doesn't import any module.
+// But the private module fragment imports a module that needs an init. So needs a guard.
+//--- U.cpp
+export module U;
+module :private;
+import T;
+
+// CHECK-U: define void @_ZGIW1U
+// CHECK-U: store i8 1, ptr @_ZGIW1U__in_chrg
+// CHECK-U: call{{.*}}@_ZGIW1T
More information about the cfe-commits
mailing list