Close https://github.com/llvm/llvm-project/issues/60693.
In this issue, we can find that the importer will try to generate the
template specialization again in the importer, which is not good and
wastes time. This patch tries to address the problem.
}
GVALinkage GetGVALinkageForFunction(const FunctionDecl *FD) const;
- GVALinkage GetGVALinkageForVariable(const VarDecl *VD);
+ GVALinkage GetGVALinkageForVariable(const VarDecl *VD) const;
/// Determines if the decl can be CodeGen'ed or deserialized from PCH
/// lazily, only when used; this is only relevant for function or file scoped
llvm_unreachable("Invalid Linkage!");
}
-GVALinkage ASTContext::GetGVALinkageForVariable(const VarDecl *VD) {
+GVALinkage ASTContext::GetGVALinkageForVariable(const VarDecl *VD) const {
return adjustGVALinkageForExternalDefinitionKind(*this, VD,
adjustGVALinkageForAttributes(*this, VD,
basicGVALinkageForVariable(*this, VD)));
if (D->getStorageDuration() == SD_Static) {
bool ModulesCodegen = false;
if (Writer.WritingModule &&
- !D->getDescribedVarTemplate() && !D->getMemberSpecializationInfo()) {
+ !D->getDescribedVarTemplate()) {
// When building a C++20 module interface unit or a partition unit, a
// strong definition in the module interface is provided by the
// compilation of that unit, not by its users. (Inline variables are still
(Writer.WritingModule->isInterfaceOrPartition() ||
(D->hasAttr<DLLExportAttr>() &&
Writer.Context->getLangOpts().BuildingPCHWithObjectFile)) &&
- Writer.Context->GetGVALinkageForVariable(D) == GVA_StrongExternal;
+ Writer.Context->GetGVALinkageForVariable(D) >= GVA_StrongExternal;
}
Record.push_back(ModulesCodegen);
if (ModulesCodegen)
// compilation of that unit, not by its users. (Inline functions are still
// emitted in module users.)
Linkage = Writer->Context->GetGVALinkageForFunction(FD);
- ModulesCodegen = *Linkage == GVA_StrongExternal;
+ ModulesCodegen = *Linkage >= GVA_StrongExternal;
}
if (Writer->Context->getLangOpts().ModulesCodegen ||
(FD->hasAttr<DLLExportAttr>() &&
int Y<int>::value = 0;
-// CHECK-NOT: @_ZW1a1xIiE = {{.*}}available_externally{{.*}}global
-// CHECK-NOT: @_ZNW1a1YIiE5valueE = {{.*}}available_externally{{.*}}global
+// CHECK-NOT: @_ZW1a1xIiE = {{.*}}external{{.*}}global
+// CHECK-NOT: @_ZNW1a1YIiE5valueE = {{.*}}external{{.*}}global
//--- use.cpp
import a;
return x<int> + Y<int>::value;
}
-// CHECK: @_ZW1a1xIiE = {{.*}}available_externally{{.*}}global
-// CHECK: @_ZNW1a1YIiE5valueE = {{.*}}available_externally{{.*}}global
+// CHECK: @_ZW1a1xIiE = {{.*}}external{{.*}}global
+// CHECK: @_ZNW1a1YIiE5valueE = {{.*}}external{{.*}}global
--- /dev/null
+// Address: https://github.com/llvm/llvm-project/issues/60693
+//
+// RUN: rm -rf %t
+// RUN: mkdir -p %t
+// RUN: split-file %s %t
+//
+// RUN: %clang_cc1 -std=c++20 -triple %itanium_abi_triple %t/a.cppm -emit-module-interface -o %t/a.pcm
+// RUN: %clang_cc1 -std=c++20 -triple %itanium_abi_triple -fmodule-file=a=%t/a.pcm %t/c.cpp -S -emit-llvm -disable-llvm-passes -o - | FileCheck %t/c.cpp
+
+//--- a.cppm
+export module a;
+
+constexpr bool f() {
+ for (unsigned n = 0; n != 10; ++n) {
+ }
+ return true;
+}
+
+export template<typename>
+struct s {
+ static constexpr auto a = f();
+ static constexpr auto b = f();
+ static constexpr auto c = f();
+ static constexpr auto d = f();
+ int foo() {
+ return 43;
+ }
+ int bar() {
+ return 44;
+ }
+};
+
+template struct s<int>;
+template struct s<long>;
+
+//--- c.cpp
+import a;
+
+extern "C" int use() {
+ s<int> _;
+ return _.a + _.b + _.c + _.d;
+}
+
+extern "C" long use2() {
+ s<long> _;
+ return _.foo();
+}
+
+// CHECK: define{{.*}}@use(
+// CHECK-NOT: }
+// CHECK: ret{{.*}} 4
+
+// CHECK: declare{{.*}}@_ZNW1a1sIlE3fooEv
+// CHECK-NOT: _ZNW1a1sIlE3barEv