Skip to content

Commit 3cc7e4f

Browse files
fix JitCall codegen for function with lambda as return value
1 parent dc6581c commit 3cc7e4f

File tree

2 files changed

+34
-3
lines changed

2 files changed

+34
-3
lines changed

lib/CppInterOp/CppInterOp.cpp

Lines changed: 21 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1935,9 +1935,27 @@ void collect_type_info(const FunctionDecl* FD, QualType& QT,
19351935
PrintingPolicy Policy(C.getPrintingPolicy());
19361936
Policy.SuppressElaboration = true;
19371937
refType = kNotReference;
1938-
if (QT->isRecordType() && forArgument) {
1939-
get_type_as_string(QT, type_name, C, Policy);
1940-
return;
1938+
if (QT->isRecordType()) {
1939+
if (forArgument) {
1940+
get_type_as_string(QT, type_name, C, Policy);
1941+
return;
1942+
}
1943+
if (auto* CXXRD = QT->getAsCXXRecordDecl()) {
1944+
if (CXXRD->isLambda()) {
1945+
DeclarationName DFunction = &getASTContext().Idents.get("function");
1946+
auto result = getSema().getStdNamespace()->lookup(DFunction);
1947+
if (result.empty())
1948+
Cpp::Declare("#include <functional>");
1949+
std::string fn_name;
1950+
llvm::raw_string_ostream stream(fn_name);
1951+
Policy.FullyQualifiedName = true;
1952+
Policy.SuppressUnwrittenScope = true;
1953+
FD->getNameForDiagnostic(stream, Policy,
1954+
/*Qualified=*/false);
1955+
type_name = "std::function<decltype(" + fn_name + ")>::result_type";
1956+
return;
1957+
}
1958+
}
19411959
}
19421960
if (QT->isFunctionPointerType()) {
19431961
std::string fp_typedef_name;

unittests/CppInterOp/FunctionReflectionTest.cpp

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2028,6 +2028,19 @@ TEST(FunctionReflectionTest, GetFunctionCallWrapper) {
20282028

20292029
auto consume_callable = Cpp::MakeFunctionCallable(consume);
20302030
EXPECT_EQ(consume_callable.getKind(), Cpp::JitCall::kGenericCall);
2031+
2032+
Cpp::Declare(R"(
2033+
auto get_fn(int x) { return [x](int y){ return x + y; }; }
2034+
)");
2035+
2036+
Cpp::TCppScope_t get_fn = Cpp::GetNamed("get_fn");
2037+
EXPECT_TRUE(get_fn);
2038+
2039+
auto get_fn_callable = Cpp::MakeFunctionCallable(get_fn);
2040+
EXPECT_EQ(get_fn_callable.getKind(), Cpp::JitCall::kGenericCall);
2041+
2042+
EXPECT_TRUE(Cpp::IsLambdaClass(Cpp::GetFunctionReturnType(get_fn)));
2043+
EXPECT_FALSE(Cpp::IsLambdaClass(Cpp::GetFunctionReturnType(bar)));
20312044
}
20322045

20332046
TEST(FunctionReflectionTest, IsConstMethod) {

0 commit comments

Comments
 (0)