diff --git a/clang/lib/Serialization/ASTWriterDecl.cpp b/clang/lib/Serialization/ASTWriterDecl.cpp index d04e1c781b4e2..86f64bf2a2425 100644 --- a/clang/lib/Serialization/ASTWriterDecl.cpp +++ b/clang/lib/Serialization/ASTWriterDecl.cpp @@ -281,11 +281,18 @@ bool clang::CanElideDeclDef(const Decl *D) { if (FD->isDependentContext()) return false; + + if (FD->getTemplateSpecializationKind() == TSK_ImplicitInstantiation) + return false; } if (auto *VD = dyn_cast(D)) { if (!VD->getDeclContext()->getRedeclContext()->isFileContext() || - VD->isInline() || VD->isConstexpr() || isa(VD)) + VD->isInline() || VD->isConstexpr() || isa(VD) || + // Constant initialized variable may not affect the ABI, but they + // may be used in constant evaluation in the frontend, so we have + // to remain them. + VD->hasConstantInitialization()) return false; if (VD->getTemplateSpecializationKind() == TSK_ImplicitInstantiation) diff --git a/clang/test/Modules/reduced-bmi-generating-codes.cppm b/clang/test/Modules/reduced-bmi-generating-codes.cppm new file mode 100644 index 0000000000000..13dcda06437b2 --- /dev/null +++ b/clang/test/Modules/reduced-bmi-generating-codes.cppm @@ -0,0 +1,40 @@ +// Although the reduced BMI are not designed to be generated, +// it is helpful for testing whether we've reduced the definitions. +// +// 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 \ +// RUN: -emit-reduced-module-interface -o %t/a.pcm +// RUN: %clang_cc1 -std=c++20 -triple %itanium_abi_triple %t/b.cpp \ +// RUN: -fmodule-file=a=%t/a.pcm -S -emit-llvm -o - \ +// RUN: | FileCheck %t/b.cpp + +//--- a.cppm +export module a; + +export template +class A { +public: + int member() { + return 43; + } +}; + +// Instantiate `A::member()`. +export int a_member = A().member(); + +export const int a = 43; + +//--- b.cpp +import a; + +static_assert(a == 43); + +int b() { + A a; + return a.member(); +} + +// CHECK: define{{.*}}@_ZNW1a1AIiE6memberEv