Skip to content

Commit 2582965

Browse files
committed
[C++20] [Modules] [Reduced BMI] Generate the function body from implicitly instantiated class and constant variables
After this patch, we will generate the function body from implicitly instantiated class. This is important for consumers with same template arguments. Otherwise the consumers won't see the function body. Since the consumers won't instantiate the templates again if they find an instantiation. Also we will generate the variable definition if the variable is non-inline but known as constant. Such variables may not affect the ABI, but they may get involved into the compile time constant computation in the consumer's code. So we have to generate such definitions.
1 parent 34ba907 commit 2582965

File tree

2 files changed

+48
-1
lines changed

2 files changed

+48
-1
lines changed

clang/lib/Serialization/ASTWriterDecl.cpp

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -281,11 +281,18 @@ bool clang::CanElideDeclDef(const Decl *D) {
281281

282282
if (FD->isDependentContext())
283283
return false;
284+
285+
if (FD->getTemplateSpecializationKind() == TSK_ImplicitInstantiation)
286+
return false;
284287
}
285288

286289
if (auto *VD = dyn_cast<VarDecl>(D)) {
287290
if (!VD->getDeclContext()->getRedeclContext()->isFileContext() ||
288-
VD->isInline() || VD->isConstexpr() || isa<ParmVarDecl>(VD))
291+
VD->isInline() || VD->isConstexpr() || isa<ParmVarDecl>(VD) ||
292+
// Constant initialized variable may not affect the ABI, but they
293+
// may be used in constant evaluation in the frontend, so we have
294+
// to remain them.
295+
VD->hasConstantInitialization())
289296
return false;
290297

291298
if (VD->getTemplateSpecializationKind() == TSK_ImplicitInstantiation)
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
// Although the reduced BMI are not designed to be generated,
2+
// it is helpful for testing whether we've reduced the definitions.
3+
//
4+
// RUN: rm -rf %t
5+
// RUN: mkdir -p %t
6+
// RUN: split-file %s %t
7+
//
8+
// RUN: %clang_cc1 -std=c++20 -triple %itanium_abi_triple %t/a.cppm \
9+
// RUN: -emit-reduced-module-interface -o %t/a.pcm
10+
// RUN: %clang_cc1 -std=c++20 -triple %itanium_abi_triple %t/b.cpp \
11+
// RUN: -fmodule-file=a=%t/a.pcm -S -emit-llvm -o - \
12+
// RUN: | FileCheck %t/b.cpp
13+
14+
//--- a.cppm
15+
export module a;
16+
17+
export template <class T>
18+
class A {
19+
public:
20+
int member() {
21+
return 43;
22+
}
23+
};
24+
25+
// Instantiate `A<int>::member()`.
26+
export int a_member = A<int>().member();
27+
28+
export const int a = 43;
29+
30+
//--- b.cpp
31+
import a;
32+
33+
static_assert(a == 43);
34+
35+
int b() {
36+
A<int> a;
37+
return a.member();
38+
}
39+
40+
// CHECK: define{{.*}}@_ZNW1a1AIiE6memberEv

0 commit comments

Comments
 (0)