Index: clang/lib/Serialization/ASTWriterDecl.cpp =================================================================== --- clang/lib/Serialization/ASTWriterDecl.cpp +++ clang/lib/Serialization/ASTWriterDecl.cpp @@ -1022,15 +1022,21 @@ if (Writer.WritingModule && !D->getDescribedVarTemplate() && !D->getMemberSpecializationInfo() && !isa(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.) - ModulesCodegen = - (Writer.WritingModule->Kind == Module::ModuleInterfaceUnit || - (D->hasAttr() && - Writer.Context->getLangOpts().BuildingPCHWithObjectFile)) && - Writer.Context->GetGVALinkageForVariable(D) == GVA_StrongExternal; + // [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 attached to a named module would be defined in the + // module unit no matter it is inline. + if (D->getLocalOwningModule() && + D->getLocalOwningModule()->isModulePurview()) + ModulesCodegen = true; + else + ModulesCodegen = + D->hasAttr() && + Writer.Context->getLangOpts().BuildingPCHWithObjectFile && + Writer.Context->GetGVALinkageForVariable(D) == GVA_StrongExternal; } Record.push_back(ModulesCodegen); if (ModulesCodegen) 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/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/CodeGenCXX/inline-variable-in-module.cpp =================================================================== --- /dev/null +++ clang/test/CodeGenCXX/inline-variable-in-module.cpp @@ -0,0 +1,19 @@ +// RUN: rm -fr %t +// RUN: mkdir %t +// RUN: %clang_cc1 -std=c++20 -I%t %s -triple %itanium_abi_triple -S -emit-llvm -o - | FileCheck %s +module; +# 3 __FILE__ 1 +struct S { + S(); +}; +inline S s = S(); +# 6 "" 2 +export module m; +class A { +public: + A(); +}; +export inline A a = A(); + +// CHECK: @s = linkonce_odr global %struct.S zeroinitializer +// CHECK: @a = linkonce_odr global %class.A zeroinitializer 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_cc1 -std=c++20 -I%t %s -triple %itanium_abi_triple -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/CodeGenCXX/use-inline-variable-in-module.cpp =================================================================== --- /dev/null +++ clang/test/CodeGenCXX/use-inline-variable-in-module.cpp @@ -0,0 +1,11 @@ +// RUN: rm -fr %t +// RUN: mkdir %t +// RUN: %clang_cc1 -std=c++20 -triple %itanium_abi_triple \ +// RUN: -emit-module-interface %S/inline-variable-in-module.cpp -o %t/m.pcm +// RUN: %clang_cc1 -std=c++20 -I%t %s -fprebuilt-module-path=%t \ +// RUN: -triple %itanium_abi_triple -S -emit-llvm -o - | FileCheck %s +import m; +void use() { + (void)&a; +} +// CHECK: @a = available_externally global %class.A zeroinitializer