Skip to content

Commit 786a4f4

Browse files
ChuanqiXu9tstellar
authored andcommitted
[C++20] [Modules] Handle initializer for Header Units
Previously when we add module initializer, we forget to handle header units. This results that we couldn't compile a Hello World Example with Header Units. This patch tries to fix this. Reviewed By: iains Differential Revision: https://reviews.llvm.org/D130871 (cherry picked from commit 6d10733)
1 parent b2a385f commit 786a4f4

File tree

3 files changed

+41
-8
lines changed

3 files changed

+41
-8
lines changed

clang/lib/CodeGen/CGDeclCXX.cpp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -649,8 +649,8 @@ void CodeGenModule::EmitCXXModuleInitFunc(Module *Primary) {
649649

650650
SmallVector<llvm::Function *, 8> ModuleInits;
651651
for (Module *M : AllImports) {
652-
// No Itanium initializer in module map modules.
653-
if (M->isModuleMapModule())
652+
// No Itanium initializer in header like modules.
653+
if (M->isHeaderLikeModule())
654654
continue; // TODO: warn of mixed use of module map modules and C++20?
655655
llvm::FunctionType *FTy = llvm::FunctionType::get(VoidTy, false);
656656
SmallString<256> FnName;
@@ -778,8 +778,8 @@ CodeGenModule::EmitCXXGlobalInitFunc() {
778778
SmallVector<llvm::Function *, 8> ModuleInits;
779779
if (CXX20ModuleInits)
780780
for (Module *M : ImportedModules) {
781-
// No Itanium initializer in module map modules.
782-
if (M->isModuleMapModule())
781+
// No Itanium initializer in header like modules.
782+
if (M->isHeaderLikeModule())
783783
continue;
784784
llvm::FunctionType *FTy = llvm::FunctionType::get(VoidTy, false);
785785
SmallString<256> FnName;

clang/lib/CodeGen/CodeGenModule.cpp

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -521,7 +521,7 @@ static void setVisibilityFromDLLStorageClass(const clang::LangOptions &LO,
521521

522522
void CodeGenModule::Release() {
523523
Module *Primary = getContext().getModuleForCodeGen();
524-
if (CXX20ModuleInits && Primary && !Primary->isModuleMapModule())
524+
if (CXX20ModuleInits && Primary && !Primary->isHeaderLikeModule())
525525
EmitModuleInitializers(Primary);
526526
EmitDeferred();
527527
DeferredDecls.insert(EmittedDeferredDecls.begin(),
@@ -2521,21 +2521,23 @@ void CodeGenModule::EmitModuleInitializers(clang::Module *Primary) {
25212521
// source, first Global Module Fragments, if present.
25222522
if (auto GMF = Primary->getGlobalModuleFragment()) {
25232523
for (Decl *D : getContext().getModuleInitializers(GMF)) {
2524-
assert(D->getKind() == Decl::Var && "GMF initializer decl is not a var?");
2524+
if (isa<ImportDecl>(D))
2525+
continue;
2526+
assert(isa<VarDecl>(D) && "GMF initializer decl is not a var?");
25252527
EmitTopLevelDecl(D);
25262528
}
25272529
}
25282530
// Second any associated with the module, itself.
25292531
for (Decl *D : getContext().getModuleInitializers(Primary)) {
25302532
// Skip import decls, the inits for those are called explicitly.
2531-
if (D->getKind() == Decl::Import)
2533+
if (isa<ImportDecl>(D))
25322534
continue;
25332535
EmitTopLevelDecl(D);
25342536
}
25352537
// Third any associated with the Privat eMOdule Fragment, if present.
25362538
if (auto PMF = Primary->getPrivateModuleFragment()) {
25372539
for (Decl *D : getContext().getModuleInitializers(PMF)) {
2538-
assert(D->getKind() == Decl::Var && "PMF initializer decl is not a var?");
2540+
assert(isa<VarDecl>(D) && "PMF initializer decl is not a var?");
25392541
EmitTopLevelDecl(D);
25402542
}
25412543
}
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
// NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py
2+
// RUN: rm -rf %t
3+
// RUN: split-file %s %t
4+
//
5+
// RUN: %clang_cc1 -std=c++20 -triple %itanium_abi_triple -xc++-user-header -emit-header-unit %t/header.h -o %t/header.pcm
6+
// RUN: %clang_cc1 -std=c++20 -triple %itanium_abi_triple -fmodule-file=%t/header.pcm %t/M.cppm -S -emit-llvm -o - | FileCheck %t/M.cppm
7+
// RUN: %clang_cc1 -std=c++20 -triple %itanium_abi_triple -fmodule-file=%t/header.pcm %t/Use.cpp -S -emit-llvm -o - | FileCheck %t/Use.cpp
8+
//
9+
//--- header.h
10+
int foo();
11+
int i = foo();
12+
13+
//--- M.cppm
14+
module;
15+
import "header.h";
16+
export module M;
17+
18+
// CHECK: @i = {{.*}}global i32 0
19+
// CHECK: void @__cxx_global_var_init()
20+
// CHECK-NEXT: entry:
21+
// CHECK-NEXT: %call = call noundef{{.*}} i32 @_Z3foov()
22+
// CHECK-NEXT: store i32 %call, ptr @i
23+
24+
//--- Use.cpp
25+
import "header.h";
26+
27+
// CHECK: @i = {{.*}}global i32 0
28+
// CHECK: void @__cxx_global_var_init()
29+
// CHECK-NEXT: entry:
30+
// CHECK-NEXT: %call = call noundef{{.*}} i32 @_Z3foov()
31+
// CHECK-NEXT: store i32 %call, ptr @i

0 commit comments

Comments
 (0)