Skip to content

Commit 95de6eb

Browse files
committed
transpile: Refactor pointer_offset for less duplication
1 parent 86400b6 commit 95de6eb

File tree

3 files changed

+76
-101
lines changed

3 files changed

+76
-101
lines changed

c2rust-transpile/src/translator/mod.rs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,6 @@ use crate::rust_ast::item_store::ItemStore;
2828
use crate::rust_ast::set_span::SetSpan;
2929
use crate::rust_ast::{pos_to_span, SpanExt};
3030
use crate::translator::named_references::NamedReference;
31-
use crate::translator::pointers::pointer_offset;
3231
use c2rust_ast_builder::{mk, properties::*, Builder};
3332
use c2rust_ast_printer::pprust;
3433

c2rust-transpile/src/translator/operators.rs

Lines changed: 39 additions & 62 deletions
Original file line numberDiff line numberDiff line change
@@ -513,60 +513,46 @@ impl<'c> Translation<'c> {
513513
}
514514

515515
// Everything else
516-
AssignAdd if pointer_lhs.is_some() => {
517-
let mul = self.compute_size_of_expr(pointer_lhs.unwrap().ctype);
518-
let ptr = pointer_offset(write.clone(), rhs, mul, false, false);
519-
WithStmts::new_unsafe_val(mk().assign_expr(write, ptr))
520-
}
521-
AssignSubtract if pointer_lhs.is_some() => {
522-
let mul = self.compute_size_of_expr(pointer_lhs.unwrap().ctype);
523-
let ptr = pointer_offset(write.clone(), rhs, mul, true, false);
524-
WithStmts::new_unsafe_val(mk().assign_expr(write, ptr))
516+
AssignAdd | AssignSubtract if pointer_lhs.is_some() => {
517+
let ptr = self.convert_pointer_offset(
518+
write.clone(),
519+
rhs,
520+
pointer_lhs.unwrap().ctype,
521+
op == AssignSubtract,
522+
false,
523+
);
524+
ptr.map(|ptr| mk().assign_expr(write, ptr))
525525
}
526526

527527
_ => {
528-
if let (AssignAdd | AssignSubtract, Some(pointer_lhs)) =
529-
(op, pointer_lhs)
530-
{
531-
let mul = self.compute_size_of_expr(pointer_lhs.ctype);
532-
let ptr = pointer_offset(
533-
write.clone(),
534-
rhs,
535-
mul,
536-
op == AssignSubtract,
537-
false,
538-
);
539-
WithStmts::new_unsafe_val(mk().assign_expr(write, ptr))
540-
} else {
541-
fn eq<Token: Default, F: Fn(Token) -> BinOp>(f: F) -> BinOp {
542-
f(Default::default())
543-
}
544-
545-
let (bin_op, bin_op_kind) = match op {
546-
AssignAdd => (Add, eq(BinOp::AddAssign)),
547-
AssignSubtract => (Subtract, eq(BinOp::SubAssign)),
548-
AssignMultiply => (Multiply, eq(BinOp::MulAssign)),
549-
AssignDivide => (Divide, eq(BinOp::DivAssign)),
550-
AssignModulus => (Modulus, eq(BinOp::RemAssign)),
551-
AssignBitXor => (BitXor, eq(BinOp::BitXorAssign)),
552-
AssignShiftLeft => (ShiftLeft, eq(BinOp::ShlAssign)),
553-
AssignShiftRight => (ShiftRight, eq(BinOp::ShrAssign)),
554-
AssignBitOr => (BitOr, eq(BinOp::BitOrAssign)),
555-
AssignBitAnd => (BitAnd, eq(BinOp::BitAndAssign)),
556-
_ => panic!("Cannot convert non-assignment operator"),
557-
};
558-
self.convert_assignment_operator_aux(
559-
bin_op_kind,
560-
bin_op,
561-
read.clone(),
562-
write,
563-
rhs,
564-
compute_lhs_type_id.unwrap(),
565-
compute_res_type_id.unwrap(),
566-
expr_type_id,
567-
rhs_type_id,
568-
)?
528+
fn eq<Token: Default, F: Fn(Token) -> BinOp>(f: F) -> BinOp {
529+
f(Default::default())
569530
}
531+
532+
let (bin_op, bin_op_kind) = match op {
533+
AssignAdd => (Add, eq(BinOp::AddAssign)),
534+
AssignSubtract => (Subtract, eq(BinOp::SubAssign)),
535+
AssignMultiply => (Multiply, eq(BinOp::MulAssign)),
536+
AssignDivide => (Divide, eq(BinOp::DivAssign)),
537+
AssignModulus => (Modulus, eq(BinOp::RemAssign)),
538+
AssignBitXor => (BitXor, eq(BinOp::BitXorAssign)),
539+
AssignShiftLeft => (ShiftLeft, eq(BinOp::ShlAssign)),
540+
AssignShiftRight => (ShiftRight, eq(BinOp::ShrAssign)),
541+
AssignBitOr => (BitOr, eq(BinOp::BitOrAssign)),
542+
AssignBitAnd => (BitAnd, eq(BinOp::BitAndAssign)),
543+
_ => panic!("Cannot convert non-assignment operator"),
544+
};
545+
self.convert_assignment_operator_aux(
546+
bin_op_kind,
547+
bin_op,
548+
read.clone(),
549+
write,
550+
rhs,
551+
compute_lhs_type_id.unwrap(),
552+
compute_res_type_id.unwrap(),
553+
expr_type_id,
554+
rhs_type_id,
555+
)?
570556
}
571557
};
572558

@@ -698,15 +684,9 @@ impl<'c> Translation<'c> {
698684
let rhs_type = &self.ast_context.resolve_type(rhs_type_id.ctype).kind;
699685

700686
if let &CTypeKind::Pointer(pointee) = lhs_type {
701-
let mul = self.compute_size_of_expr(pointee.ctype);
702-
Ok(WithStmts::new_unsafe_val(pointer_offset(
703-
lhs, rhs, mul, false, false,
704-
)))
687+
Ok(self.convert_pointer_offset(lhs, rhs, pointee.ctype, false, false))
705688
} else if let &CTypeKind::Pointer(pointee) = rhs_type {
706-
let mul = self.compute_size_of_expr(pointee.ctype);
707-
Ok(WithStmts::new_unsafe_val(pointer_offset(
708-
rhs, lhs, mul, false, false,
709-
)))
689+
Ok(self.convert_pointer_offset(rhs, lhs, pointee.ctype, false, false))
710690
} else if lhs_type.is_unsigned_integral_type() {
711691
Ok(WithStmts::new_val(mk().method_call_expr(
712692
lhs,
@@ -743,10 +723,7 @@ impl<'c> Translation<'c> {
743723

744724
Ok(WithStmts::new_unsafe_val(mk().cast_expr(offset, ty)))
745725
} else if let &CTypeKind::Pointer(pointee) = lhs_type {
746-
let mul = self.compute_size_of_expr(pointee.ctype);
747-
Ok(WithStmts::new_unsafe_val(pointer_offset(
748-
lhs, rhs, mul, true, false,
749-
)))
726+
Ok(self.convert_pointer_offset(lhs, rhs, pointee.ctype, true, false))
750727
} else if lhs_type.is_unsigned_integral_type() {
751728
Ok(WithStmts::new_val(mk().method_call_expr(
752729
lhs,

c2rust-transpile/src/translator/pointers.rs

Lines changed: 37 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -303,10 +303,7 @@ impl<'c> Translation<'c> {
303303

304304
// Don't dereference the offset if we're still within the variable portion
305305
if let Some(elt_type_id) = var_elt_type_id {
306-
let mul = self.compute_size_of_expr(elt_type_id);
307-
Ok(WithStmts::new_unsafe_val(pointer_offset(
308-
lhs, rhs, mul, false, true,
309-
)))
306+
Ok(self.convert_pointer_offset(lhs, rhs, elt_type_id, false, true))
310307
} else {
311308
Ok(WithStmts::new_val(
312309
mk().index_expr(lhs, cast_int(rhs, "usize", false)),
@@ -315,9 +312,8 @@ impl<'c> Translation<'c> {
315312
})
316313
} else {
317314
// LHS must be ref decayed for the offset method call's self param
318-
let mut lhs = self.convert_expr(ctx.used().decay_ref(), lhs, None)?;
319-
lhs.set_unsafe(); // `pointer_offset` is unsafe.
320-
lhs.result_map(|lhs| {
315+
let lhs = self.convert_expr(ctx.used().decay_ref(), lhs, None)?;
316+
lhs.and_then(|lhs| {
321317
// stmts.extend(lhs.stmts_mut());
322318
// is_unsafe = is_unsafe || lhs.is_unsafe();
323319

@@ -335,12 +331,13 @@ impl<'c> Translation<'c> {
335331
}
336332
};
337333

338-
let mul = self.compute_size_of_expr(pointee_type_id.ctype);
339-
let mut val = pointer_offset(lhs, rhs, mul, false, true);
334+
let mut val =
335+
self.convert_pointer_offset(lhs, rhs, pointee_type_id.ctype, false, true);
340336
// if the context wants a different type, add a cast
341337
if let Some(expected_ty) = override_ty {
342338
if expected_ty != pointee_type_id {
343-
val = mk().cast_expr(val, self.convert_type(expected_ty.ctype)?);
339+
let ty = self.convert_type(expected_ty.ctype)?;
340+
val = val.map(|val| mk().cast_expr(val, ty));
344341
}
345342
}
346343
Ok(val)
@@ -349,6 +346,36 @@ impl<'c> Translation<'c> {
349346
})
350347
}
351348

349+
/// Pointer offset that casts its argument to isize
350+
pub fn convert_pointer_offset(
351+
&self,
352+
ptr: Box<Expr>,
353+
offset: Box<Expr>,
354+
pointee_cty: CTypeId,
355+
neg: bool,
356+
mut deref: bool,
357+
) -> WithStmts<Box<Expr>> {
358+
let mut offset = cast_int(offset, "isize", false);
359+
360+
if let Some(mul) = self.compute_size_of_expr(pointee_cty) {
361+
let mul = cast_int(mul, "isize", false);
362+
offset = mk().binary_expr(BinOp::Mul(Default::default()), offset, mul);
363+
deref = false;
364+
}
365+
366+
if neg {
367+
offset = mk().unary_expr(UnOp::Neg(Default::default()), offset);
368+
}
369+
370+
let mut res = mk().method_call_expr(ptr, "offset", vec![offset]);
371+
372+
if deref {
373+
res = mk().unary_expr(UnOp::Deref(Default::default()), res);
374+
}
375+
376+
WithStmts::new_unsafe_val(res)
377+
}
378+
352379
/// Construct an expression for a NULL at any type, including forward declarations,
353380
/// function pointers, and normal pointers.
354381
pub fn null_ptr(&self, type_id: CTypeId, is_static: bool) -> TranslationResult<Box<Expr>> {
@@ -397,31 +424,3 @@ impl<'c> Translation<'c> {
397424
.convert_pointee(&self.ast_context, type_id)
398425
}
399426
}
400-
401-
/// Pointer offset that casts its argument to isize
402-
pub fn pointer_offset(
403-
ptr: Box<Expr>,
404-
offset: Box<Expr>,
405-
multiply_by: Option<Box<Expr>>,
406-
neg: bool,
407-
mut deref: bool,
408-
) -> Box<Expr> {
409-
let mut offset = cast_int(offset, "isize", false);
410-
411-
if let Some(mul) = multiply_by {
412-
let mul = cast_int(mul, "isize", false);
413-
offset = mk().binary_expr(BinOp::Mul(Default::default()), offset, mul);
414-
deref = false;
415-
}
416-
417-
if neg {
418-
offset = mk().unary_expr(UnOp::Neg(Default::default()), offset);
419-
}
420-
421-
let res = mk().method_call_expr(ptr, "offset", vec![offset]);
422-
if deref {
423-
mk().unary_expr(UnOp::Deref(Default::default()), res)
424-
} else {
425-
res
426-
}
427-
}

0 commit comments

Comments
 (0)