aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChuanqi Xu <yedeng.yd@linux.alibaba.com>2022-08-02 10:26:07 +0800
committerTom Stellard <tstellar@redhat.com>2022-08-08 11:31:42 -0700
commit786a4f426c0f9402a802560cccd466a773e708ac (patch)
tree455037e53dd7e9f45441ef730437813677ef0119
parentb2a385f2613c497353a43f2053f897348af14dca (diff)
downloadllvm-786a4f426c0f9402a802560cccd466a773e708ac.zip
llvm-786a4f426c0f9402a802560cccd466a773e708ac.tar.gz
llvm-786a4f426c0f9402a802560cccd466a773e708ac.tar.bz2
[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 6d10733d445506c02ebec9faa54658431857bb49)
-rw-r--r--clang/lib/CodeGen/CGDeclCXX.cpp8
-rw-r--r--clang/lib/CodeGen/CodeGenModule.cpp10
-rw-r--r--clang/test/CodeGenCXX/module-initializer-header.cppm31
3 files changed, 41 insertions, 8 deletions
diff --git a/clang/lib/CodeGen/CGDeclCXX.cpp b/clang/lib/CodeGen/CGDeclCXX.cpp
index 949112c..6915f95 100644
--- a/clang/lib/CodeGen/CGDeclCXX.cpp
+++ b/clang/lib/CodeGen/CGDeclCXX.cpp
@@ -649,8 +649,8 @@ void CodeGenModule::EmitCXXModuleInitFunc(Module *Primary) {
SmallVector<llvm::Function *, 8> ModuleInits;
for (Module *M : AllImports) {
- // No Itanium initializer in module map modules.
- if (M->isModuleMapModule())
+ // No Itanium initializer in header like modules.
+ if (M->isHeaderLikeModule())
continue; // TODO: warn of mixed use of module map modules and C++20?
llvm::FunctionType *FTy = llvm::FunctionType::get(VoidTy, false);
SmallString<256> FnName;
@@ -778,8 +778,8 @@ CodeGenModule::EmitCXXGlobalInitFunc() {
SmallVector<llvm::Function *, 8> ModuleInits;
if (CXX20ModuleInits)
for (Module *M : ImportedModules) {
- // No Itanium initializer in module map modules.
- if (M->isModuleMapModule())
+ // No Itanium initializer in header like modules.
+ if (M->isHeaderLikeModule())
continue;
llvm::FunctionType *FTy = llvm::FunctionType::get(VoidTy, false);
SmallString<256> FnName;
diff --git a/clang/lib/CodeGen/CodeGenModule.cpp b/clang/lib/CodeGen/CodeGenModule.cpp
index 4e8e120d..d87692f 100644
--- a/clang/lib/CodeGen/CodeGenModule.cpp
+++ b/clang/lib/CodeGen/CodeGenModule.cpp
@@ -521,7 +521,7 @@ static void setVisibilityFromDLLStorageClass(const clang::LangOptions &LO,
void CodeGenModule::Release() {
Module *Primary = getContext().getModuleForCodeGen();
- if (CXX20ModuleInits && Primary && !Primary->isModuleMapModule())
+ if (CXX20ModuleInits && Primary && !Primary->isHeaderLikeModule())
EmitModuleInitializers(Primary);
EmitDeferred();
DeferredDecls.insert(EmittedDeferredDecls.begin(),
@@ -2521,21 +2521,23 @@ void CodeGenModule::EmitModuleInitializers(clang::Module *Primary) {
// source, first Global Module Fragments, if present.
if (auto GMF = Primary->getGlobalModuleFragment()) {
for (Decl *D : getContext().getModuleInitializers(GMF)) {
- assert(D->getKind() == Decl::Var && "GMF initializer decl is not a var?");
+ if (isa<ImportDecl>(D))
+ continue;
+ assert(isa<VarDecl>(D) && "GMF initializer decl is not a var?");
EmitTopLevelDecl(D);
}
}
// Second any associated with the module, itself.
for (Decl *D : getContext().getModuleInitializers(Primary)) {
// Skip import decls, the inits for those are called explicitly.
- if (D->getKind() == Decl::Import)
+ if (isa<ImportDecl>(D))
continue;
EmitTopLevelDecl(D);
}
// Third any associated with the Privat eMOdule Fragment, if present.
if (auto PMF = Primary->getPrivateModuleFragment()) {
for (Decl *D : getContext().getModuleInitializers(PMF)) {
- assert(D->getKind() == Decl::Var && "PMF initializer decl is not a var?");
+ assert(isa<VarDecl>(D) && "PMF initializer decl is not a var?");
EmitTopLevelDecl(D);
}
}
diff --git a/clang/test/CodeGenCXX/module-initializer-header.cppm b/clang/test/CodeGenCXX/module-initializer-header.cppm
new file mode 100644
index 0000000..253f096
--- /dev/null
+++ b/clang/test/CodeGenCXX/module-initializer-header.cppm
@@ -0,0 +1,31 @@
+// NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py
+// RUN: rm -rf %t
+// RUN: split-file %s %t
+//
+// RUN: %clang_cc1 -std=c++20 -triple %itanium_abi_triple -xc++-user-header -emit-header-unit %t/header.h -o %t/header.pcm
+// 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
+// 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
+//
+//--- header.h
+int foo();
+int i = foo();
+
+//--- M.cppm
+module;
+import "header.h";
+export module M;
+
+// CHECK: @i = {{.*}}global i32 0
+// CHECK: void @__cxx_global_var_init()
+// CHECK-NEXT: entry:
+// CHECK-NEXT: %call = call noundef{{.*}} i32 @_Z3foov()
+// CHECK-NEXT: store i32 %call, ptr @i
+
+//--- Use.cpp
+import "header.h";
+
+// CHECK: @i = {{.*}}global i32 0
+// CHECK: void @__cxx_global_var_init()
+// CHECK-NEXT: entry:
+// CHECK-NEXT: %call = call noundef{{.*}} i32 @_Z3foov()
+// CHECK-NEXT: store i32 %call, ptr @i