forked from OSchip/llvm-project
[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
This commit is contained in:
parent
f1033a3f47
commit
6d10733d44
|
@ -650,8 +650,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;
|
||||
|
@ -779,8 +779,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;
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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
|
Loading…
Reference in New Issue