[PATCH] D119409: [C++20] [Modules] Remain variable's definition in module interface
Chuanqi Xu via Phabricator via cfe-commits
cfe-commits at lists.llvm.org
Wed Feb 9 22:52:02 PST 2022
ChuanqiXu created this revision.
ChuanqiXu added reviewers: rsmith, iains, urnathan, dblaikie.
ChuanqiXu added a project: clang.
ChuanqiXu requested review of this revision.
Herald added a subscriber: cfe-commits.
This fixes issue51873 <https://github.com/llvm/llvm-project/issues/51873>. The issue reports that we couldn't run hello world example in C++20 module. Then I found that the reason is that libstdc++ uses static variable to initialize resources for streams like std::cout. And it would be good if we use libc++.
So the key point here is that wether or not the definition of static variables should be remained in module interface. First I thought the reduction makes sense. Since static variable shouldn't be able to be referred outside the module. Then @rsmith pointed out that this one should be a bug.
This patch tries to remain variable's definition in the module interface no matter what the kind it is. This violates ModuleTS. It wouldn't define inline variables in the module. But I think we don't need to keep compatibility for ModuleTS. It would be deprecated someday.
Repository:
rG LLVM Github Monorepo
https://reviews.llvm.org/D119409
Files:
clang/lib/Serialization/ASTWriterDecl.cpp
clang/test/CXX/modules-ts/basic/basic.def.odr/p4/module.cpp
clang/test/CXX/modules-ts/basic/basic.def.odr/p4/user.cpp
clang/test/CodeGenCXX/static-variable-in-module.cpp
Index: clang/test/CodeGenCXX/static-variable-in-module.cpp
===================================================================
--- /dev/null
+++ clang/test/CodeGenCXX/static-variable-in-module.cpp
@@ -0,0 +1,24 @@
+// RUN: rm -fr %t
+// RUN: mkdir %t
+// RUN: echo "struct S { S(); };" >> %t/foo.h
+// RUN: echo "static S s = S();" >> %t/foo.h
+// RUN: %clang -std=c++20 -I%t %s -S -emit-llvm -o - | FileCheck %s
+module;
+#include "foo.h"
+export module m;
+class A {
+public:
+ A();
+};
+static A a = A();
+
+// CHECK: @_ZL1s = internal global %struct.S zeroinitializer
+// CHECK: @_ZW1mE1a = dso_local global %class.A zeroinitializer
+// CHECK: @llvm.global_ctors = appending global{{.*}}@_GLOBAL__sub_I_static_variable_in_module.cpp
+// CHECK: define {{.*}}__cxx_global_var_init[[SUFFIX:[^)]*]]
+// CHECK: call void @_ZN1SC1Ev
+// CHECK: define {{.*}}__cxx_global_var_init[[SUFFIX2:[^)]*]]
+// CHECK: call void @_ZW1mEN1AC1Ev
+// CHECK: define {{.*}}@_GLOBAL__sub_I_static_variable_in_module.cpp
+// CHECK: call void @__cxx_global_var_init[[SUFFIX]]
+// CHECK: call void @__cxx_global_var_init[[SUFFIX2]]
Index: clang/test/CXX/modules-ts/basic/basic.def.odr/p4/user.cpp
===================================================================
--- clang/test/CXX/modules-ts/basic/basic.def.odr/p4/user.cpp
+++ clang/test/CXX/modules-ts/basic/basic.def.odr/p4/user.cpp
@@ -2,7 +2,7 @@
// RUN: %clang_cc1 -fmodules-ts %s -triple %itanium_abi_triple -fmodule-file=%t -emit-llvm -o - | FileCheck %s --implicit-check-not=unused --implicit-check-not=global_module
// CHECK-DAG: @extern_var_exported = external {{(dso_local )?}}global
-// CHECK-DAG: @inline_var_exported = linkonce_odr {{(dso_local )?}}global
+// CHECK-DAG: @inline_var_exported = available_externally {{(dso_local )?}}global
// CHECK-DAG: @const_var_exported = available_externally {{(dso_local )?}}constant i32 3
import Module;
Index: clang/test/CXX/modules-ts/basic/basic.def.odr/p4/module.cpp
===================================================================
--- clang/test/CXX/modules-ts/basic/basic.def.odr/p4/module.cpp
+++ clang/test/CXX/modules-ts/basic/basic.def.odr/p4/module.cpp
@@ -2,11 +2,11 @@
// RUN: %clang_cc1 -fmodules-ts %s -triple %itanium_abi_triple -fmodule-file=%t -emit-llvm -o - | FileCheck %s --implicit-check-not=unused --implicit-check-not=global_module
// CHECK-DAG: @extern_var_exported = external {{(dso_local )?}}global
-// CHECK-DAG: @inline_var_exported = linkonce_odr {{(dso_local )?}}global
+// CHECK-DAG: @inline_var_exported = available_externally {{(dso_local )?}}global
// CHECK-DAG: @const_var_exported = available_externally {{(dso_local )?}}constant i32 3,
//
// CHECK-DAG: @_ZW6ModuleE25extern_var_module_linkage = external {{(dso_local )?}}global
-// CHECK-DAG: @_ZW6ModuleE25inline_var_module_linkage = linkonce_odr {{(dso_local )?}}global
+// CHECK-DAG: @_ZW6ModuleE25inline_var_module_linkage = available_externally {{(dso_local )?}}global
// CHECK-DAG: @_ZW6ModuleE25static_var_module_linkage = available_externally {{(dso_local )?}}global i32 0,
// CHECK-DAG: @_ZW6ModuleE24const_var_module_linkage = available_externally {{(dso_local )?}}constant i32 3,
Index: clang/lib/Serialization/ASTWriterDecl.cpp
===================================================================
--- clang/lib/Serialization/ASTWriterDecl.cpp
+++ clang/lib/Serialization/ASTWriterDecl.cpp
@@ -1022,15 +1022,17 @@
if (Writer.WritingModule &&
!D->getDescribedVarTemplate() && !D->getMemberSpecializationInfo() &&
!isa<VarTemplateSpecializationDecl>(D)) {
- // When building a C++ Modules TS module interface unit, a strong
- // definition in the module interface is provided by the compilation of
- // that module interface unit, not by its users. (Inline variables are
- // still emitted in module users.)
+ // [dcl.inline]p7:
+ // If an inline function or variable that is attached to a named module
+ // is declared in a definition domain, it shall be defined in that
+ // domain.
+ //
+ // So the variable would be defined in the module unit no matter it is inline.
ModulesCodegen =
- (Writer.WritingModule->Kind == Module::ModuleInterfaceUnit ||
+ Writer.WritingModule->Kind == Module::ModuleInterfaceUnit ||
(D->hasAttr<DLLExportAttr>() &&
- Writer.Context->getLangOpts().BuildingPCHWithObjectFile)) &&
- Writer.Context->GetGVALinkageForVariable(D) == GVA_StrongExternal;
+ Writer.Context->getLangOpts().BuildingPCHWithObjectFile &&
+ Writer.Context->GetGVALinkageForVariable(D) == GVA_StrongExternal);
}
Record.push_back(ModulesCodegen);
if (ModulesCodegen)
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D119409.407396.patch
Type: text/x-patch
Size: 4745 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20220210/cdbdbd8a/attachment.bin>
More information about the cfe-commits
mailing list