Skip to content

Commit b18f36d

Browse files
committed
Translate static invoke for lambdas
1 parent b05d9e2 commit b18f36d

4 files changed

Lines changed: 54 additions & 5 deletions

File tree

‎cpp2rust/converter/converter.cpp‎

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
#include "converter/converter.h"
55

66
#include <clang/AST/APValue.h>
7+
#include <clang/AST/IgnoreExpr.h>
78
#include <clang/AST/ParentMapContext.h>
89
#include <clang/Basic/LangOptions.h>
910
#include <clang/Basic/SourceManager.h>
@@ -2004,6 +2005,16 @@ std::string Converter::GetFunctionRefName(const clang::FunctionDecl *fn_decl) {
20042005

20052006
void Converter::ConvertFunctionToFunctionPointer(
20062007
const clang::FunctionDecl *fn_decl) {
2008+
if (auto *method = clang::dyn_cast<clang::CXXMethodDecl>(fn_decl);
2009+
method && method->isLambdaStaticInvoker()) {
2010+
assert(!method->getParent()->isGenericLambda());
2011+
StrCat("Some");
2012+
PushParen paren(*this);
2013+
ConvertLambdaClosure(method->getParent(),
2014+
method->getParent()->getLambdaCallOperator());
2015+
computed_expr_type_ = ComputedExprType::FreshPointer;
2016+
return;
2017+
}
20072018
StrCat(std::format("Some({})", GetFunctionRefName(fn_decl)));
20082019
computed_expr_type_ = ComputedExprType::FreshPointer;
20092020
}
@@ -2055,7 +2066,11 @@ Converter::CallInfo Converter::CollectCallInfo(clang::CallExpr *expr) {
20552066
unsigned num_named_params =
20562067
function ? function->getNumParams() : proto->getNumParams();
20572068
info.is_variadic = function ? function->isVariadic() : proto->isVariadic();
2058-
info.is_fn_ptr_call = !function || AsLambdaClass(callee->getType());
2069+
info.is_fn_ptr_call =
2070+
!function || AsLambdaClass(callee->getType()) ||
2071+
clang::isa<clang::SubstNonTypeTemplateParmExpr>(
2072+
clang::IgnoreExprNodes(callee, clang::IgnoreParensSingleStep,
2073+
clang::IgnoreImplicitCastsSingleStep));
20592074
info.is_libc_passthrough = RuleRegistry::IsLibcPassthrough(ctx_, expr);
20602075

20612076
for (unsigned i = 0; i < num_named_params && i < num_args; ++i) {

‎cpp2rust/converter/models/converter_refcount.cpp‎

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1567,6 +1567,12 @@ void ConverterRefCount::ConvertLambdaToFunctionPointer(
15671567

15681568
void ConverterRefCount::ConvertFunctionToFunctionPointer(
15691569
const clang::FunctionDecl *fn_decl) {
1570+
if (auto *method = clang::dyn_cast<clang::CXXMethodDecl>(fn_decl);
1571+
method && method->isLambdaStaticInvoker()) {
1572+
ConvertCapturelessLambda(method->getParent());
1573+
computed_expr_type_ = ComputedExprType::FreshPointer;
1574+
return;
1575+
}
15701576
StrCat(std::format("FnPtr::<{}>::new({})",
15711577
ConvertFunctionPointerType(
15721578
fn_decl->getType()->getAs<clang::FunctionProtoType>()),

‎tests/unit/out/refcount/lambda_to_fn_ptr.rs‎

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,10 +10,24 @@ pub fn apply_0(mut x: i32, mut fn_: FnPtr<fn(i32) -> i32>) -> i32 {
1010
return ({ fn_.call(x) });
1111
}
1212
pub fn call_nttp_1(mut x: i32) -> i32 {
13-
return ({ (FnPtr::<fn(i32) -> i32>::new(int_operator___int__const::__invoke))(x) });
13+
return ({
14+
(FnPtr::<fn(i32) -> i32>::new(|mut x: i32| -> i32 {
15+
{
16+
return (x - 1);
17+
}
18+
}))
19+
.call(x)
20+
});
1421
}
1522
pub fn call_nttp_2(mut x: i32) -> i32 {
16-
return ({ (FnPtr::<fn(i32) -> i32>::new(int_operator___int__const::__invoke))(x) });
23+
return ({
24+
(FnPtr::<fn(i32) -> i32>::new(|mut x: i32| -> i32 {
25+
{
26+
return (x * 10);
27+
}
28+
}))
29+
.call(x)
30+
});
1731
}
1832
pub fn call_nttp_3(mut x: i32) -> i32 {
1933
return ({

‎tests/unit/out/unsafe/lambda_to_fn_ptr.rs‎

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,10 +10,24 @@ pub unsafe fn apply_0(mut x: i32, mut fn_: Option<unsafe fn(i32) -> i32>) -> i32
1010
return (unsafe { (fn_).unwrap()(x) });
1111
}
1212
pub unsafe fn call_nttp_1(mut x: i32) -> i32 {
13-
return (unsafe { (Some(int_operator___int__const::__invoke))(x) });
13+
return (unsafe {
14+
(Some(|mut x: i32| -> i32 {
15+
unsafe {
16+
return ((x) - (1));
17+
}
18+
}))
19+
.unwrap()(x)
20+
});
1421
}
1522
pub unsafe fn call_nttp_2(mut x: i32) -> i32 {
16-
return (unsafe { (Some(int_operator___int__const::__invoke))(x) });
23+
return (unsafe {
24+
(Some(|mut x: i32| -> i32 {
25+
unsafe {
26+
return ((x) * (10));
27+
}
28+
}))
29+
.unwrap()(x)
30+
});
1731
}
1832
pub unsafe fn call_nttp_3(mut x: i32) -> i32 {
1933
return (unsafe {

0 commit comments

Comments
 (0)