Author: Chuanqi Xu Date: 2022-08-02T10:27:02+08:00 New Revision: db6152ad66d7cf48f9f5c3eb28bf54c092978773
URL: https://github.com/llvm/llvm-project/commit/db6152ad66d7cf48f9f5c3eb28bf54c092978773 DIFF: https://github.com/llvm/llvm-project/commit/db6152ad66d7cf48f9f5c3eb28bf54c092978773.diff LOG: [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 Added: clang/test/CodeGenCXX/module-initializer-header.cppm Modified: clang/lib/CodeGen/CGDeclCXX.cpp clang/lib/CodeGen/CodeGenModule.cpp Removed: ################################################################################ diff --git a/clang/lib/CodeGen/CGDeclCXX.cpp b/clang/lib/CodeGen/CGDeclCXX.cpp index 620af1e633b7..420141362f0e 100644 --- a/clang/lib/CodeGen/CGDeclCXX.cpp +++ b/clang/lib/CodeGen/CGDeclCXX.cpp @@ -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; diff --git a/clang/lib/CodeGen/CodeGenModule.cpp b/clang/lib/CodeGen/CodeGenModule.cpp index 579ebba7736d..dc1122f3ab67 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 000000000000..d60ad45a0ab3 --- /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 _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits