ChuanqiXu created this revision.
ChuanqiXu added a reviewer: iains.
ChuanqiXu added a project: clang-modules.
Herald added a project: All.
ChuanqiXu requested review of this revision.
Herald added a project: clang.
Herald added a subscriber: cfe-commits.

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.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D130871

Files:
  clang/lib/CodeGen/CGDeclCXX.cpp
  clang/lib/CodeGen/CodeGenModule.cpp
  clang/test/CodeGenCXX/module-initializer-header.cppm

Index: clang/test/CodeGenCXX/module-initializer-header.cppm
===================================================================
--- /dev/null
+++ 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=x86_64-unknown-linux-gnu -xc++-user-header -emit-header-unit %t/header.h -o %t/header.pcm
+// RUN: %clang_cc1 -std=c++20 -triple=x86_64-unknown-linux-gnu -fmodule-file=%t/header.pcm %t/M.cppm -S -emit-llvm -o - | FileCheck %t/M.cppm
+// RUN: %clang_cc1 -std=c++20 -triple=x86_64-unknown-linux-gnu -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  
Index: clang/lib/CodeGen/CodeGenModule.cpp
===================================================================
--- clang/lib/CodeGen/CodeGenModule.cpp
+++ clang/lib/CodeGen/CodeGenModule.cpp
@@ -521,7 +521,7 @@
 
 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 @@
   // 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);
     }
   }
Index: clang/lib/CodeGen/CGDeclCXX.cpp
===================================================================
--- clang/lib/CodeGen/CGDeclCXX.cpp
+++ clang/lib/CodeGen/CGDeclCXX.cpp
@@ -649,8 +649,8 @@
 
   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 @@
   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;
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to