Skip to content

Commit 2723395

Browse files
committed
Handle std::forward in converter
1 parent eed9c25 commit 2723395

10 files changed

Lines changed: 100 additions & 124 deletions

File tree

‎cpp2rust/converter/converter.cpp‎

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1850,7 +1850,7 @@ bool Converter::VisitCallExpr(clang::CallExpr *expr) {
18501850
return false;
18511851
}
18521852

1853-
if (expr->isCallToStdMove()) {
1853+
if (expr->isCallToStdMove() || IsCallToStdForward(expr)) {
18541854
Convert(expr->getArg(0));
18551855
return false;
18561856
}
@@ -2173,7 +2173,7 @@ Converter::ConvertCallExpr(clang::CallExpr *expr) {
21732173
if (auto fn = Mapper::ToString(callee);
21742174
fn.starts_with("int printf") || fn.starts_with("int fprintf")) {
21752175
ConvertPrintf(expr);
2176-
} else if (expr->isCallToStdMove()) {
2176+
} else if (expr->isCallToStdMove() || IsCallToStdForward(expr)) {
21772177
Convert(expr->getArg(0));
21782178
} else if (IsBuiltinConstantP(callee)) {
21792179
StrCat(expr->getArg(0)->isCXX11ConstantExpr(ctx_) ? token::kOne
@@ -2833,7 +2833,7 @@ void Converter::ConvertGenericBinaryOperator(clang::BinaryOperator *expr) {
28332833
}
28342834

28352835
bool Converter::IsReferenceType(const clang::Expr *expr) const {
2836-
const auto *e = IgnoreStdMove(expr->IgnoreCasts())->IgnoreCasts();
2836+
const auto *e = IgnoreStdMoveAndForward(expr->IgnoreCasts())->IgnoreCasts();
28372837
if (const auto *call = clang::dyn_cast<clang::CallExpr>(e)) {
28382838
return !clang::isa<clang::CXXOperatorCallExpr>(call) &&
28392839
GetReturnTypeOfFunction(call)->isReferenceType();

‎cpp2rust/converter/converter_lib.cpp‎

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1435,17 +1435,27 @@ bool IsBuiltinVaCopy(const clang::CallExpr *expr) {
14351435
return false;
14361436
}
14371437

1438-
const clang::Expr *IgnoreStdMove(const clang::Expr *expr) {
1438+
bool IsCallToStdForward(const clang::CallExpr *expr) {
1439+
const auto *callee = expr->getDirectCallee();
1440+
if (!callee) {
1441+
return false;
1442+
}
1443+
const auto builtin_id = callee->getBuiltinID();
1444+
return builtin_id == clang::Builtin::BIforward ||
1445+
builtin_id == clang::Builtin::BIforward_like;
1446+
}
1447+
1448+
const clang::Expr *IgnoreStdMoveAndForward(const clang::Expr *expr) {
14391449
if (const auto *call =
14401450
clang::dyn_cast<clang::CallExpr>(expr->IgnoreParenImpCasts());
1441-
call && call->isCallToStdMove()) {
1451+
call && (call->isCallToStdMove() || IsCallToStdForward(call))) {
14421452
return call->getArg(0);
14431453
}
14441454
return expr;
14451455
}
14461456

14471457
bool IsTemporaryObject(const clang::Expr *expr) {
1448-
const auto *operand = IgnoreStdMove(expr);
1458+
const auto *operand = IgnoreStdMoveAndForward(expr);
14491459
if (operand != expr) {
14501460
return !operand->isGLValue();
14511461
}

‎cpp2rust/converter/converter_lib.h‎

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -262,7 +262,9 @@ bool IsBuiltinVaEnd(const clang::CallExpr *expr);
262262

263263
bool IsBuiltinVaCopy(const clang::CallExpr *expr);
264264

265-
const clang::Expr *IgnoreStdMove(const clang::Expr *expr);
265+
bool IsCallToStdForward(const clang::CallExpr *expr);
266+
267+
const clang::Expr *IgnoreStdMoveAndForward(const clang::Expr *expr);
266268

267269
bool IsTemporaryObject(const clang::Expr *expr);
268270

‎cpp2rust/converter/models/converter_refcount.cpp‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1170,7 +1170,7 @@ bool ConverterRefCount::VisitCallExpr(clang::CallExpr *expr) {
11701170
return false;
11711171
}
11721172

1173-
if (expr->isCallToStdMove()) {
1173+
if (expr->isCallToStdMove() || IsCallToStdForward(expr)) {
11741174
return Converter::VisitCallExpr(expr);
11751175
}
11761176

@@ -2772,7 +2772,7 @@ std::string ConverterRefCount::ConvertMappedMethodCall(
27722772
auto arg_idx = receiver_ph->n;
27732773
auto *arg = BuildUnifiedArgs(expr, args, num_args)[arg_idx];
27742774
if (auto *call = clang::dyn_cast<clang::CallExpr>(arg->IgnoreCasts());
2775-
call && call->isCallToStdMove()) {
2775+
call && (call->isCallToStdMove() || IsCallToStdForward(call))) {
27762776
arg = call->getArg(0);
27772777
}
27782778

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

Lines changed: 14 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -82,21 +82,21 @@ pub fn chosen_overload_1(_a0: Ptr<Tracked>) -> Overload {
8282
return Overload_kRvalueOverload;
8383
}
8484
pub fn forward_by_decltype_2(x: Ptr<Tracked>) -> Overload {
85-
return ({ chosen_overload_0(({ forward_3((x).clone()) })) });
85+
return ({ chosen_overload_0((x).clone()) });
8686
}
87-
pub fn forward_by_decltype_4(x: Ptr<Tracked>) -> Overload {
88-
return ({ chosen_overload_1(({ forward_5((x).clone()) })) });
87+
pub fn forward_by_decltype_3(x: Ptr<Tracked>) -> Overload {
88+
return ({ chosen_overload_1((x).clone()) });
8989
}
90-
pub fn forward_abbreviated_6(x: Ptr<Tracked>) -> Overload {
91-
return ({ chosen_overload_0(({ forward_3((x).clone()) })) });
90+
pub fn forward_abbreviated_4(x: Ptr<Tracked>) -> Overload {
91+
return ({ chosen_overload_0((x).clone()) });
9292
}
93-
pub fn forward_abbreviated_7(x: Ptr<Tracked>) -> Overload {
94-
return ({ chosen_overload_1(({ forward_5((x).clone()) })) });
93+
pub fn forward_abbreviated_5(x: Ptr<Tracked>) -> Overload {
94+
return ({ chosen_overload_1((x).clone()) });
9595
}
96-
pub fn forward_abbreviated_pack_8(args_0: Ptr<Tracked>, args_1: Ptr<Tracked>) -> i32 {
96+
pub fn forward_abbreviated_pack_6(args_0: Ptr<Tracked>, args_1: Ptr<Tracked>) -> i32 {
9797
return {
98-
let _lhs = (({ chosen_overload_0(({ forward_3((args_0).clone()) })) }) as i32);
99-
_lhs + (({ chosen_overload_1(({ forward_5((args_1).clone()) })) }) as i32)
98+
let _lhs = (({ chosen_overload_0((args_0).clone()) }) as i32);
99+
_lhs + (({ chosen_overload_1((args_1).clone()) }) as i32)
100100
};
101101
}
102102
pub fn main() {
@@ -113,28 +113,28 @@ fn main_0() -> i32 {
113113
assert!(
114114
((({
115115
let _x: Value<Tracked> = Rc::new(RefCell::new(Tracked::Tracked({ 4 })));
116-
forward_by_decltype_4(_x.as_pointer())
116+
forward_by_decltype_3(_x.as_pointer())
117117
}) as i32)
118118
== (Overload_kRvalueOverload as i32))
119119
);
120120
let b: Value<Tracked> = Rc::new(RefCell::new(Tracked::Tracked({ 5 })));
121121
assert!(
122-
((({ forward_abbreviated_6(b.as_pointer(),) }) as i32)
122+
((({ forward_abbreviated_4(b.as_pointer(),) }) as i32)
123123
== (Overload_kLvalueOverload as i32))
124124
);
125125
assert!(((*(*b.borrow()).v.borrow()) == 5));
126126
assert!(
127127
((({
128128
let _x: Value<Tracked> = Rc::new(RefCell::new(Tracked::Tracked({ 6 })));
129-
forward_abbreviated_7(_x.as_pointer())
129+
forward_abbreviated_5(_x.as_pointer())
130130
}) as i32)
131131
== (Overload_kRvalueOverload as i32))
132132
);
133133
let c: Value<Tracked> = Rc::new(RefCell::new(Tracked::Tracked({ 7 })));
134134
assert!(
135135
(({
136136
let _args: Value<Tracked> = Rc::new(RefCell::new(Tracked::Tracked({ 8 })));
137-
forward_abbreviated_pack_8(c.as_pointer(), _args.as_pointer())
137+
forward_abbreviated_pack_6(c.as_pointer(), _args.as_pointer())
138138
}) == ((Overload_kLvalueOverload as i32) + (Overload_kRvalueOverload as i32)))
139139
);
140140
assert!(((*(*c.borrow()).v.borrow()) == 7));

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

Lines changed: 7 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -100,51 +100,38 @@ pub fn main() {
100100
fn main_0() -> i32 {
101101
let a: Value<Tracked> = Rc::new(RefCell::new(Tracked::Tracked({ 5 })));
102102
assert!(
103-
((({ chosen_overload_0(({ forward_5(a.as_pointer(),) }),) }) as i32)
104-
== (Overload_kLvalueOverload as i32))
103+
((({ chosen_overload_0(a.as_pointer(),) }) as i32) == (Overload_kLvalueOverload as i32))
105104
);
106105
assert!(((*(*a.borrow()).v.borrow()) == 5));
107106
assert!(
108-
((({ chosen_overload_1(({ forward_6(a.as_pointer(),) }),) }) as i32)
109-
== (Overload_kRvalueOverload as i32))
107+
((({ chosen_overload_1(a.as_pointer(),) }) as i32) == (Overload_kRvalueOverload as i32))
110108
);
111109
assert!(((*(*a.borrow()).v.borrow()) == 5));
112110
let b: Value<Tracked> = Rc::new(RefCell::new(Tracked::Tracked({ 6 })));
113111
let moved: Value<Tracked> = Rc::new(RefCell::new(
114-
({
115-
copy_or_move_into_param_4(Tracked::Tracked_pmutTracked_rv({
116-
({ forward_6(b.as_pointer()) })
117-
}))
118-
}),
112+
({ copy_or_move_into_param_4(Tracked::Tracked_pmutTracked_rv({ b.as_pointer() })) }),
119113
));
120114
assert!(((*(*moved.borrow()).v.borrow()) == 6));
121115
assert!(((*(*moved.borrow()).copies.borrow()) == 0));
122116
assert!(((*(*moved.borrow()).moves.borrow()) == 2));
123117
assert!(((*(*b.borrow()).v.borrow()) == 0));
124118
let c: Value<Tracked> = Rc::new(RefCell::new(Tracked::Tracked({ 7 })));
125119
let copied: Value<Tracked> = Rc::new(RefCell::new(
126-
({
127-
copy_or_move_into_param_4(Tracked::Tracked_pconstTracked({
128-
({ forward_5(c.as_pointer()) })
129-
}))
130-
}),
120+
({ copy_or_move_into_param_4(Tracked::Tracked_pconstTracked({ c.as_pointer() })) }),
131121
));
132122
assert!(((*(*copied.borrow()).v.borrow()) == 7));
133123
assert!(((*(*copied.borrow()).copies.borrow()) == 1));
134124
assert!(((*(*copied.borrow()).moves.borrow()) == 1));
135125
assert!(((*(*c.borrow()).v.borrow()) == 7));
136126
let i: Value<i32> = Rc::new(RefCell::new(8));
137127
assert!(
138-
((({ chosen_overload_2(({ forward_7(i.as_pointer(),) }),) }) as i32)
139-
== (Overload_kIntLvalueOverload as i32))
128+
((({ chosen_overload_2(i.as_pointer(),) }) as i32) == (Overload_kIntLvalueOverload as i32))
140129
);
141130
assert!(
142-
((({ chosen_overload_3(({ forward_8(i.as_pointer(),) }),) }) as i32)
143-
== (Overload_kIntRvalueOverload as i32))
131+
((({ chosen_overload_3(i.as_pointer(),) }) as i32) == (Overload_kIntRvalueOverload as i32))
144132
);
145133
assert!(
146-
((({ chosen_overload_3(({ forward_9(i.as_pointer(),) }),) }) as i32)
147-
== (Overload_kIntRvalueOverload as i32))
134+
((({ chosen_overload_3(i.as_pointer(),) }) as i32) == (Overload_kIntRvalueOverload as i32))
148135
);
149136
assert!(((*i.borrow()) == 8));
150137
return 0;

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

Lines changed: 20 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -57,15 +57,15 @@ pub unsafe fn chosen_overload_1(_a0: *mut Tracked) -> Overload {
5757
impl Holder {
5858
pub unsafe fn Holder1(x: *mut Tracked) -> Self {
5959
let mut this = Self {
60-
t: Tracked::Tracked_pconstTracked({ (unsafe { forward_2(x) }) }),
60+
t: Tracked::Tracked_pconstTracked({ x }),
6161
};
6262
this
6363
}
6464
}
6565
impl Holder {
6666
pub unsafe fn Holder2(x: *mut Tracked) -> Self {
6767
let mut this = Self {
68-
t: Tracked::Tracked_pmutTracked_rv({ (unsafe { forward_3(x) }) }),
68+
t: Tracked::Tracked_pmutTracked_rv({ x }),
6969
};
7070
this
7171
}
@@ -75,23 +75,23 @@ impl Holder {
7575
pub struct Holder {
7676
pub t: Tracked,
7777
}
78-
pub unsafe fn forward_once_4(x: *mut Tracked) -> Overload {
79-
return (unsafe { chosen_overload_0((unsafe { forward_2(x) })) });
78+
pub unsafe fn forward_once_2(x: *mut Tracked) -> Overload {
79+
return (unsafe { chosen_overload_0(x) });
8080
}
81-
pub unsafe fn forward_once_5(x: *mut Tracked) -> Overload {
82-
return (unsafe { chosen_overload_1((unsafe { forward_3(x) })) });
81+
pub unsafe fn forward_once_3(x: *mut Tracked) -> Overload {
82+
return (unsafe { chosen_overload_1(x) });
8383
}
84-
pub unsafe fn forward_twice_6(x: *mut Tracked) -> Overload {
85-
return (unsafe { forward_once_4((unsafe { forward_2(x) })) });
84+
pub unsafe fn forward_twice_4(x: *mut Tracked) -> Overload {
85+
return (unsafe { forward_once_2(x) });
8686
}
87-
pub unsafe fn forward_twice_7(x: *mut Tracked) -> Overload {
88-
return (unsafe { forward_once_5((unsafe { forward_3(x) })) });
87+
pub unsafe fn forward_twice_5(x: *mut Tracked) -> Overload {
88+
return (unsafe { forward_once_3(x) });
8989
}
90-
pub unsafe fn forward_into_ctor_8(x: *mut Tracked) -> Holder {
91-
return Holder::Holder1({ (unsafe { forward_2(x) }) });
90+
pub unsafe fn forward_into_ctor_6(x: *mut Tracked) -> Holder {
91+
return Holder::Holder1({ x });
9292
}
93-
pub unsafe fn forward_into_ctor_9(x: *mut Tracked) -> Holder {
94-
return (*(unsafe { forward_3(x) }));
93+
pub unsafe fn forward_into_ctor_7(x: *mut Tracked) -> Holder {
94+
return (*x);
9595
}
9696
pub fn main() {
9797
unsafe {
@@ -102,37 +102,37 @@ pub fn main() {
102102
unsafe fn main_0() -> i32 {
103103
let mut lvalue: Tracked = Tracked::Tracked({ 7 });
104104
assert!(
105-
(((unsafe { forward_once_4(&mut lvalue,) }) as i32) == (Overload_kLvalueOverload as i32))
105+
(((unsafe { forward_once_2(&mut lvalue,) }) as i32) == (Overload_kLvalueOverload as i32))
106106
);
107107
assert!(((lvalue.v) == (7)));
108108
assert!(
109109
(((unsafe {
110110
let mut _x: Tracked = Tracked::Tracked({ 8 });
111-
forward_once_5(&mut _x)
111+
forward_once_3(&mut _x)
112112
}) as i32)
113113
== (Overload_kRvalueOverload as i32))
114114
);
115115
let mut relayed: Tracked = Tracked::Tracked({ 9 });
116116
assert!(
117-
(((unsafe { forward_twice_6(&mut relayed,) }) as i32) == (Overload_kLvalueOverload as i32))
117+
(((unsafe { forward_twice_4(&mut relayed,) }) as i32) == (Overload_kLvalueOverload as i32))
118118
);
119119
assert!(((relayed.v) == (9)));
120120
assert!(
121121
(((unsafe {
122122
let mut _x: Tracked = Tracked::Tracked({ 10 });
123-
forward_twice_7(&mut _x)
123+
forward_twice_5(&mut _x)
124124
}) as i32)
125125
== (Overload_kRvalueOverload as i32))
126126
);
127127
let mut kept: Tracked = Tracked::Tracked({ 11 });
128-
let mut from_lvalue: Holder = (unsafe { forward_into_ctor_8(&mut kept) });
128+
let mut from_lvalue: Holder = (unsafe { forward_into_ctor_6(&mut kept) });
129129
assert!(((from_lvalue.t.v) == (11)));
130130
assert!(((from_lvalue.t.copies) == (1)));
131131
assert!(((from_lvalue.t.moves) == (0)));
132132
assert!(((kept.v) == (11)));
133133
let mut from_rvalue: Holder = (unsafe {
134134
let mut _x: Tracked = Tracked::Tracked({ 12 });
135-
forward_into_ctor_9(&mut _x)
135+
forward_into_ctor_7(&mut _x)
136136
});
137137
assert!(((from_rvalue.t.v) == (12)));
138138
assert!(((from_rvalue.t.copies) == (0)));

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

Lines changed: 14 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -55,20 +55,20 @@ pub unsafe fn chosen_overload_1(_a0: *mut Tracked) -> Overload {
5555
return Overload_kRvalueOverload;
5656
}
5757
pub unsafe fn forward_by_decltype_2(x: *mut Tracked) -> Overload {
58-
return (unsafe { chosen_overload_0((unsafe { forward_3(x) })) });
58+
return (unsafe { chosen_overload_0(x) });
5959
}
60-
pub unsafe fn forward_by_decltype_4(x: *mut Tracked) -> Overload {
61-
return (unsafe { chosen_overload_1((unsafe { forward_5(x) })) });
60+
pub unsafe fn forward_by_decltype_3(x: *mut Tracked) -> Overload {
61+
return (unsafe { chosen_overload_1(x) });
6262
}
63-
pub unsafe fn forward_abbreviated_6(x: *mut Tracked) -> Overload {
64-
return (unsafe { chosen_overload_0((unsafe { forward_3(x) })) });
63+
pub unsafe fn forward_abbreviated_4(x: *mut Tracked) -> Overload {
64+
return (unsafe { chosen_overload_0(x) });
6565
}
66-
pub unsafe fn forward_abbreviated_7(x: *mut Tracked) -> Overload {
67-
return (unsafe { chosen_overload_1((unsafe { forward_5(x) })) });
66+
pub unsafe fn forward_abbreviated_5(x: *mut Tracked) -> Overload {
67+
return (unsafe { chosen_overload_1(x) });
6868
}
69-
pub unsafe fn forward_abbreviated_pack_8(args_0: *mut Tracked, args_1: *mut Tracked) -> i32 {
70-
return (((unsafe { chosen_overload_0((unsafe { forward_3(args_0) })) }) as i32)
71-
+ ((unsafe { chosen_overload_1((unsafe { forward_5(args_1) })) }) as i32));
69+
pub unsafe fn forward_abbreviated_pack_6(args_0: *mut Tracked, args_1: *mut Tracked) -> i32 {
70+
return (((unsafe { chosen_overload_0(args_0) }) as i32)
71+
+ ((unsafe { chosen_overload_1(args_1) }) as i32));
7272
}
7373
pub fn main() {
7474
unsafe {
@@ -85,27 +85,27 @@ unsafe fn main_0() -> i32 {
8585
assert!(
8686
(((unsafe {
8787
let mut _x: Tracked = Tracked::Tracked({ 4 });
88-
forward_by_decltype_4(&mut _x)
88+
forward_by_decltype_3(&mut _x)
8989
}) as i32)
9090
== (Overload_kRvalueOverload as i32))
9191
);
9292
let mut b: Tracked = Tracked::Tracked({ 5 });
9393
assert!(
94-
(((unsafe { forward_abbreviated_6(&mut b,) }) as i32) == (Overload_kLvalueOverload as i32))
94+
(((unsafe { forward_abbreviated_4(&mut b,) }) as i32) == (Overload_kLvalueOverload as i32))
9595
);
9696
assert!(((b.v) == (5)));
9797
assert!(
9898
(((unsafe {
9999
let mut _x: Tracked = Tracked::Tracked({ 6 });
100-
forward_abbreviated_7(&mut _x)
100+
forward_abbreviated_5(&mut _x)
101101
}) as i32)
102102
== (Overload_kRvalueOverload as i32))
103103
);
104104
let mut c: Tracked = Tracked::Tracked({ 7 });
105105
assert!(
106106
((unsafe {
107107
let mut _args: Tracked = Tracked::Tracked({ 8 });
108-
forward_abbreviated_pack_8(&mut c, &mut _args)
108+
forward_abbreviated_pack_6(&mut c, &mut _args)
109109
}) == ((Overload_kLvalueOverload as i32) + (Overload_kRvalueOverload as i32)))
110110
);
111111
assert!(((c.v) == (7)));

0 commit comments

Comments
 (0)