Skip to content

Commit 5570307

Browse files
fix: codegen need not instantiate func body if it can be resolved
This is the case where the the instantiated function is present in one of the libraries loaded or the host application.
1 parent ad1dab7 commit 5570307

File tree

2 files changed

+41
-14
lines changed

2 files changed

+41
-14
lines changed

lib/CppInterOp/CppInterOp.cpp

Lines changed: 22 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1250,10 +1250,8 @@ TCppFuncAddr_t GetFunctionAddress(const char* mangled_name) {
12501250
return nullptr;
12511251
}
12521252

1253-
TCppFuncAddr_t GetFunctionAddress(TCppFunction_t method) {
1254-
auto* D = (Decl*)method;
1255-
1256-
const auto get_mangled_name = [](FunctionDecl* FD) {
1253+
static TCppFuncAddr_t GetFunctionAddress(const FunctionDecl* FD) {
1254+
const auto get_mangled_name = [](const FunctionDecl* FD) {
12571255
auto MangleCtxt = getASTContext().createMangleContext();
12581256

12591257
if (!MangleCtxt->shouldMangleDeclName(FD)) {
@@ -1271,12 +1269,20 @@ TCppFuncAddr_t GetFunctionAddress(TCppFunction_t method) {
12711269
return mangled_name;
12721270
};
12731271

1274-
if (auto* FD = llvm::dyn_cast_or_null<FunctionDecl>(D))
1272+
// Constructor and Destructors needs to be handled differently
1273+
if (!llvm::isa<CXXConstructorDecl>(FD) && !llvm::isa<CXXDestructorDecl>(FD))
12751274
return GetFunctionAddress(get_mangled_name(FD).c_str());
12761275

12771276
return 0;
12781277
}
12791278

1279+
TCppFuncAddr_t GetFunctionAddress(TCppFunction_t method) {
1280+
auto* D = static_cast<Decl*>(method);
1281+
if (auto* FD = llvm::dyn_cast_or_null<FunctionDecl>(D))
1282+
return GetFunctionAddress(FD);
1283+
return nullptr;
1284+
}
1285+
12801286
bool IsVirtualMethod(TCppFunction_t method) {
12811287
auto* D = (Decl*)method;
12821288
if (auto* CXXMD = llvm::dyn_cast_or_null<CXXMethodDecl>(D)) {
@@ -2363,15 +2369,17 @@ int get_wrapper_code(compat::Interpreter& I, const FunctionDecl* FD,
23632369
// header file.
23642370
break;
23652371
}
2366-
if (!Pattern->hasBody()) {
2367-
llvm::errs() << "TClingCallFunc::make_wrapper"
2368-
<< ":"
2369-
<< "Cannot make wrapper for a function template"
2370-
"instantiation with no body!";
2371-
return 0;
2372-
}
2373-
if (FD->isImplicitlyInstantiable()) {
2374-
needInstantiation = true;
2372+
if (!GetFunctionAddress(FD)) {
2373+
if (!Pattern->hasBody()) {
2374+
llvm::errs() << "TClingCallFunc::make_wrapper"
2375+
<< ":"
2376+
<< "Cannot make wrapper for a function template "
2377+
<< "instantiation with no body!";
2378+
return 0;
2379+
}
2380+
if (FD->isImplicitlyInstantiable()) {
2381+
needInstantiation = true;
2382+
}
23752383
}
23762384
} break;
23772385
case FunctionDecl::TK_DependentFunctionTemplateSpecialization: {

unittests/CppInterOp/FunctionReflectionTest.cpp

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1479,6 +1479,8 @@ TEST(FunctionReflectionTest, JitCallAdvanced) {
14791479
clang_Interpreter_dispose(I);
14801480
}
14811481

1482+
template <typename T> T instantiation_in_host() { return T(0); }
1483+
template int instantiation_in_host<int>();
14821484

14831485
TEST(FunctionReflectionTest, GetFunctionCallWrapper) {
14841486
#ifdef EMSCRIPTEN
@@ -1814,6 +1816,23 @@ TEST(FunctionReflectionTest, GetFunctionCallWrapper) {
18141816

18151817
auto fn_callable = Cpp::MakeFunctionCallable(fn);
18161818
EXPECT_EQ(fn_callable.getKind(), Cpp::JitCall::kGenericCall);
1819+
1820+
// instantiation in host, no template function body
1821+
Interp->process("template<typename T> T instantiation_in_host();");
1822+
1823+
unresolved_candidate_methods.clear();
1824+
Cpp::GetClassTemplatedMethods("instantiation_in_host", Cpp::GetGlobalScope(),
1825+
unresolved_candidate_methods);
1826+
EXPECT_EQ(unresolved_candidate_methods.size(), 1);
1827+
1828+
Cpp::TCppScope_t instantiation_in_host = Cpp::BestOverloadFunctionMatch(
1829+
unresolved_candidate_methods, {Cpp::GetType("int")}, {});
1830+
EXPECT_TRUE(instantiation_in_host);
1831+
1832+
auto instantiation_in_host_callable =
1833+
Cpp::MakeFunctionCallable(instantiation_in_host);
1834+
EXPECT_EQ(instantiation_in_host_callable.getKind(),
1835+
Cpp::JitCall::kGenericCall);
18171836
}
18181837

18191838
TEST(FunctionReflectionTest, IsConstMethod) {

0 commit comments

Comments
 (0)