Skip to content

Commit

Permalink
[C++20] [Modules] [Reduced BMI] Generate the function body from impli…
Browse files Browse the repository at this point in the history
…citly 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.
  • Loading branch information
ChuanqiXu9 committed Mar 14, 2024
1 parent 34ba907 commit 2582965
Show file tree
Hide file tree
Showing 2 changed files with 48 additions and 1 deletion.
9 changes: 8 additions & 1 deletion clang/lib/Serialization/ASTWriterDecl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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<VarDecl>(D)) {
if (!VD->getDeclContext()->getRedeclContext()->isFileContext() ||
VD->isInline() || VD->isConstexpr() || isa<ParmVarDecl>(VD))
VD->isInline() || VD->isConstexpr() || isa<ParmVarDecl>(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)
Expand Down
40 changes: 40 additions & 0 deletions clang/test/Modules/reduced-bmi-generating-codes.cppm
Original file line number Diff line number Diff line change
@@ -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 T>
class A {
public:
int member() {
return 43;
}
};

// Instantiate `A<int>::member()`.
export int a_member = A<int>().member();

export const int a = 43;

//--- b.cpp
import a;

static_assert(a == 43);

int b() {
A<int> a;
return a.member();
}

// CHECK: define{{.*}}@_ZNW1a1AIiE6memberEv

0 comments on commit 2582965

Please sign in to comment.