Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 6 additions & 6 deletions cpp2rust/converter/converter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,7 @@ bool Converter::VisitRecoveryExpr(clang::RecoveryExpr *expr) {
bool Converter::Convert(clang::QualType qual_type) {
// Catch va_list before desugaring
if (IsVaListType(qual_type)) {
StrCat("VaList");
StrCat("*const VaArg");
return false;
}

Expand Down Expand Up @@ -311,7 +311,7 @@ bool Converter::VisitPointerType(clang::PointerType *type) {
}

if (IsVaListType(clang::QualType(type, 0))) {
StrCat("VaList");
StrCat("*const VaArg");
return false;
}

Expand Down Expand Up @@ -480,7 +480,8 @@ void Converter::ConvertVaListVarDecl(clang::VarDecl *decl) {
// va_list local variable
StrCat(keyword::kLet);
}
StrCat(keyword_mut_, GetNamedDeclAsString(decl), token::kColon, "VaList");
StrCat(keyword_mut_, GetNamedDeclAsString(decl), token::kColon,
"*const VaArg");
}

bool Converter::NeedsMut(const clang::VarDecl *decl, clang::QualType type,
Expand Down Expand Up @@ -1838,8 +1839,7 @@ void Converter::ConvertVariadicArg(clang::Expr *arg) {

void Converter::ConvertVAArgCall(clang::CallExpr *expr) {
if (IsBuiltinVaStart(expr)) {
StrCat(ToString(expr->getArg(0)->IgnoreImpCasts()),
"= VaList::new(__args)");
StrCat(ToString(expr->getArg(0)->IgnoreImpCasts()), "= __args.as_ptr()");
return;
}
if (IsBuiltinVaEnd(expr)) {
Expand Down Expand Up @@ -4252,7 +4252,7 @@ std::string Converter::GetDefaultAsString(clang::QualType qual_type) {

if (IsVaListType(qual_type)) {
computed_expr_type_ = ComputedExprType::FreshValue;
return "VaList::default()";
return "::std::ptr::null()";
}

if (auto arr = GetArrayDefaultAsString(qual_type); !arr.empty()) {
Expand Down
41 changes: 28 additions & 13 deletions cpp2rust/converter/models/converter_refcount.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -259,7 +259,7 @@ std::string ConverterRefCount::BoxValue(std::string &&str) const {
bool ConverterRefCount::Convert(clang::QualType qual_type) {
// Catch va_list before desugaring
if (IsVaListType(qual_type)) {
StrCat(BoxType("VaList"));
StrCat(BoxType("Ptr<VaArg>"));
return false;
}

Expand Down Expand Up @@ -291,7 +291,7 @@ bool ConverterRefCount::VisitReferenceType(clang::ReferenceType *type) {
PushConversionKind push(*this, ConversionKind::Unboxed);
return Convert(ctx_.getPointerType(pointee_type));
}
if (pointee_type->isArrayType()) {
if (pointee_type->isArrayType() && !IsVaListType(pointee_type)) {
// A reference to an array decays straight to a pointer to its first
// element, the same way a by-value array parameter would, instead of
// going through a pointer to the whole boxed array.
Expand Down Expand Up @@ -325,7 +325,7 @@ bool ConverterRefCount::VisitPointerType(clang::PointerType *type) {
}

if (IsVaListType(clang::QualType(type, 0))) {
StrCat("VaList");
StrCat("Ptr<VaArg>");
return false;
}

Expand All @@ -335,10 +335,11 @@ bool ConverterRefCount::VisitPointerType(clang::PointerType *type) {
}

auto pointee_type = type->getPointeeType();
PushConversionKind push1(*this, ConversionKind::Ptr,
!pointee_type->isArrayType());
bool pointee_is_array =
pointee_type->isArrayType() && !IsVaListType(pointee_type);
PushConversionKind push1(*this, ConversionKind::Ptr, !pointee_is_array);
PushConversionKind push2(*this, ConversionKind::FullRefCount,
pointee_type->isArrayType());
pointee_is_array);
if (pointee_type->isRecordType() &&
abstract_structs_.contains(GetID(pointee_type->getAsRecordDecl()))) {
StrCat("PtrDyn<dyn");
Expand Down Expand Up @@ -791,6 +792,10 @@ void ConverterRefCount::EmitFunctionPreamble(clang::FunctionDecl *decl) {
// name_2)'. We want to get the parameters from the definition if possible,
// i.e. name_2.
PushConversionKind push(*this, ConversionKind::FullRefCount);
if (decl->isVariadic()) {
StrCat("let __args: Value<Box<[VaArg]>> = "
"Rc::new(RefCell::new(__args.into()));");
}
auto params = decl->getDefinition() ? decl->getDefinition()->parameters()
: decl->parameters();
for (auto *param : params) {
Expand Down Expand Up @@ -853,7 +858,7 @@ void ConverterRefCount::ConvertVaListVarDecl(clang::VarDecl *decl) {
StrCat(keyword::kLet);
}

StrCat(GetNamedDeclAsString(decl), token::kColon, "Value<VaList>");
StrCat(GetNamedDeclAsString(decl), token::kColon, "Value<Ptr<VaArg>>");
}

bool ConverterRefCount::ConvertVarDeclSkipInit(clang::VarDecl *decl) {
Expand Down Expand Up @@ -1291,7 +1296,12 @@ void ConverterRefCount::ConvertPrintf(clang::CallExpr *expr) {
}

bool ConverterRefCount::VisitCallExpr(clang::CallExpr *expr) {
if (IsBuiltinVaStart(expr) || IsBuiltinVaEnd(expr) || IsBuiltinVaCopy(expr)) {
if (IsBuiltinVaStart(expr)) {
StrCat(ToString(expr->getArg(0)->IgnoreImpCasts()),
"= __args.as_pointer()");
return false;
}
if (IsBuiltinVaEnd(expr) || IsBuiltinVaCopy(expr)) {
ConvertVAArgCall(expr);
return false;
}
Expand Down Expand Up @@ -2471,13 +2481,18 @@ bool ConverterRefCount::VisitVAArgExpr(clang::VAArgExpr *expr) {
if (auto *cast = clang::dyn_cast<clang::ImplicitCastExpr>(va_list_expr)) {
va_list_expr = cast->getSubExpr();
}
StrCat(ConvertLValue(va_list_expr));
StrCat(".arg::<");
auto str = ConvertLValue(va_list_expr);
std::string arg_type;
{
PushConversionKind push(*this, ConversionKind::Unboxed);
StrCat(ToString(expr->getType()));
arg_type = ToString(expr->getType());
}
if (!pending_deref_.empty()) {
StrCat(pending_deref_.take(), ".with_mut(|__v| __v.arg::<", arg_type,
">())");
} else {
StrCat(str, ".arg::<", arg_type, ">()");
}
StrCat(">()");
SetFreshType(expr->getType());
return false;
}
Expand Down Expand Up @@ -2529,7 +2544,7 @@ std::string ConverterRefCount::GetDefaultAsString(clang::QualType qual_type) {

if (IsVaListType(qual_type)) {
computed_expr_type_ = ComputedExprType::FreshValue;
return BoxValue("VaList::default()");
return BoxValue("Ptr::<VaArg>::default()");
}

if (auto arr = GetArrayDefaultAsString(qual_type); !arr.empty()) {
Expand Down
30 changes: 19 additions & 11 deletions libcc2rs/src/va_args.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ use std::any::Any;
use std::ffi::c_void;
use std::rc::Rc;

use crate::inc::PrefixInc;
use crate::rc::Ptr;
use crate::void::AnyPtr;

#[derive(Clone)]
Expand Down Expand Up @@ -52,21 +54,27 @@ impl<T: crate::reinterpret::ByteRepr + 'static> From<crate::rc::Ptr<T>> for VaAr
}
}

#[derive(Clone, Copy, Default)]
pub struct VaList<'a> {
args: &'a [VaArg],
pos: usize,
impl crate::reinterpret::ByteRepr for VaArg {}

pub trait VaArgs {
fn arg<T: VaArgGet>(&mut self) -> T;
}

impl<'a> VaList<'a> {
pub fn new(args: &'a [VaArg]) -> Self {
VaList { args, pos: 0 }
impl VaArgs for Ptr<VaArg> {
fn arg<T: VaArgGet>(&mut self) -> T {
let val = self.with(T::get);
self.prefix_inc();
val
}
}

pub fn arg<T: VaArgGet>(&mut self) -> T {
let val = &self.args[self.pos];
self.pos += 1;
T::get(val)
impl VaArgs for *const VaArg {
fn arg<T: VaArgGet>(&mut self) -> T {
unsafe {
let val = T::get(&**self);
*self = self.add(1);
val
}
}
}

Expand Down
13 changes: 7 additions & 6 deletions tests/unit/out/refcount/va_arg_chain.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,23 +6,24 @@ use std::io::prelude::*;
use std::io::{Read, Seek, Write};
use std::os::fd::AsFd;
use std::rc::{Rc, Weak};
pub fn extract_nth_0(mut n: i32, ap: VaList) -> i32 {
let ap: Value<VaList> = Rc::new(RefCell::new(ap));
pub fn extract_nth_0(mut n: i32, ap: Ptr<VaArg>) -> i32 {
let ap: Value<Ptr<VaArg>> = Rc::new(RefCell::new(ap));
let mut i: i32 = 0;
'loop_: while (((i < n) as i32) != 0) {
(*ap.borrow_mut()).arg::<i32>();
i.postfix_inc();
}
return (*ap.borrow_mut()).arg::<i32>();
}
pub fn middle_layer_1(mut n: i32, ap: VaList) -> i32 {
let ap: Value<VaList> = Rc::new(RefCell::new(ap));
pub fn middle_layer_1(mut n: i32, ap: Ptr<VaArg>) -> i32 {
let ap: Value<Ptr<VaArg>> = Rc::new(RefCell::new(ap));
return ({ extract_nth_0(n, (*ap.borrow()).clone()) });
}
pub fn top_level_2(n: i32, __args: &[VaArg]) -> i32 {
let __args: Value<Box<[VaArg]>> = Rc::new(RefCell::new(__args.into()));
let n: Value<i32> = Rc::new(RefCell::new(n));
let ap: Value<VaList> = Rc::new(RefCell::new(VaList::default()));
(*ap.borrow_mut()) = VaList::new(__args);
let ap: Value<Ptr<VaArg>> = Rc::new(RefCell::new(Ptr::<VaArg>::default()));
(*ap.borrow_mut()) = __args.as_pointer();
let mut result: i32 = ({ middle_layer_1((*n.borrow()), (*ap.borrow()).clone()) });
return result;
}
Expand Down
5 changes: 3 additions & 2 deletions tests/unit/out/refcount/va_arg_concat.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,11 @@ use std::io::{Read, Seek, Write};
use std::os::fd::AsFd;
use std::rc::{Rc, Weak};
pub fn sum_ints_0(first: i32, __args: &[VaArg]) -> i32 {
let __args: Value<Box<[VaArg]>> = Rc::new(RefCell::new(__args.into()));
let first: Value<i32> = Rc::new(RefCell::new(first));
let args: Value<VaList> = Rc::new(RefCell::new(VaList::default()));
let args: Value<Ptr<VaArg>> = Rc::new(RefCell::new(Ptr::<VaArg>::default()));
let mut total: i32 = (*first.borrow());
(*args.borrow_mut()) = VaList::new(__args);
(*args.borrow_mut()) = __args.as_pointer();
let mut val: i32 = 0_i32;
'loop_: while (((({
val = (*args.borrow_mut()).arg::<i32>();
Expand Down
5 changes: 3 additions & 2 deletions tests/unit/out/refcount/va_arg_conditional.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,11 @@ use std::io::{Read, Seek, Write};
use std::os::fd::AsFd;
use std::rc::{Rc, Weak};
pub fn conditional_log_0(mut verbose: i32, fmt: Ptr<i8>, __args: &[VaArg]) -> i32 {
let __args: Value<Box<[VaArg]>> = Rc::new(RefCell::new(__args.into()));
let fmt: Value<Ptr<i8>> = Rc::new(RefCell::new(fmt));
if (verbose != 0) {
let ap: Value<VaList> = Rc::new(RefCell::new(VaList::default()));
(*ap.borrow_mut()) = VaList::new(__args);
let ap: Value<Ptr<VaArg>> = Rc::new(RefCell::new(Ptr::<VaArg>::default()));
(*ap.borrow_mut()) = __args.as_pointer();
let mut result: i32 = (*ap.borrow_mut()).arg::<i32>();
return result;
}
Expand Down
7 changes: 4 additions & 3 deletions tests/unit/out/refcount/va_arg_copy.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,11 @@ use std::io::{Read, Seek, Write};
use std::os::fd::AsFd;
use std::rc::{Rc, Weak};
pub fn sum_with_copy_0(count: i32, __args: &[VaArg]) -> i32 {
let __args: Value<Box<[VaArg]>> = Rc::new(RefCell::new(__args.into()));
let count: Value<i32> = Rc::new(RefCell::new(count));
let ap: Value<VaList> = Rc::new(RefCell::new(VaList::default()));
let aq: Value<VaList> = Rc::new(RefCell::new(VaList::default()));
(*ap.borrow_mut()) = VaList::new(__args);
let ap: Value<Ptr<VaArg>> = Rc::new(RefCell::new(Ptr::<VaArg>::default()));
let aq: Value<Ptr<VaArg>> = Rc::new(RefCell::new(Ptr::<VaArg>::default()));
(*ap.borrow_mut()) = __args.as_pointer();
(*aq.borrow_mut()) = (*ap.borrow_mut()).clone();
let mut sum1: i32 = 0;
let mut i: i32 = 0;
Expand Down
10 changes: 6 additions & 4 deletions tests/unit/out/refcount/va_arg_fn_ptr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,17 +16,19 @@ pub fn add_2(mut a: i32, mut b: i32) -> i32 {
return (a + b);
}
pub fn apply_unary_3(x: i32, __args: &[VaArg]) -> i32 {
let __args: Value<Box<[VaArg]>> = Rc::new(RefCell::new(__args.into()));
let x: Value<i32> = Rc::new(RefCell::new(x));
let ap: Value<VaList> = Rc::new(RefCell::new(VaList::default()));
(*ap.borrow_mut()) = VaList::new(__args);
let ap: Value<Ptr<VaArg>> = Rc::new(RefCell::new(Ptr::<VaArg>::default()));
(*ap.borrow_mut()) = __args.as_pointer();
let mut fn_: FnPtr<fn(i32) -> i32> = (*ap.borrow_mut()).arg::<FnPtr<fn(i32) -> i32>>();
let mut result: i32 = ({ fn_.call((*x.borrow())) });
return result;
}
pub fn apply_binary_4(mut a: i32, b: i32, __args: &[VaArg]) -> i32 {
let __args: Value<Box<[VaArg]>> = Rc::new(RefCell::new(__args.into()));
let b: Value<i32> = Rc::new(RefCell::new(b));
let ap: Value<VaList> = Rc::new(RefCell::new(VaList::default()));
(*ap.borrow_mut()) = VaList::new(__args);
let ap: Value<Ptr<VaArg>> = Rc::new(RefCell::new(Ptr::<VaArg>::default()));
(*ap.borrow_mut()) = __args.as_pointer();
let mut fn_: FnPtr<fn(i32, i32) -> i32> =
(*ap.borrow_mut()).arg::<FnPtr<fn(i32, i32) -> i32>>();
let mut result: i32 = ({ fn_.call(a, (*b.borrow())) });
Expand Down
9 changes: 5 additions & 4 deletions tests/unit/out/refcount/va_arg_forward.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@ use std::io::prelude::*;
use std::io::{Read, Seek, Write};
use std::os::fd::AsFd;
use std::rc::{Rc, Weak};
pub fn inner_0(mut count: i32, ap: VaList) -> i32 {
let ap: Value<VaList> = Rc::new(RefCell::new(ap));
pub fn inner_0(mut count: i32, ap: Ptr<VaArg>) -> i32 {
let ap: Value<Ptr<VaArg>> = Rc::new(RefCell::new(ap));
let mut total: i32 = 0;
let mut i: i32 = 0;
'loop_: while (((i < count) as i32) != 0) {
Expand All @@ -17,9 +17,10 @@ pub fn inner_0(mut count: i32, ap: VaList) -> i32 {
return total;
}
pub fn outer_1(count: i32, __args: &[VaArg]) -> i32 {
let __args: Value<Box<[VaArg]>> = Rc::new(RefCell::new(__args.into()));
let count: Value<i32> = Rc::new(RefCell::new(count));
let ap: Value<VaList> = Rc::new(RefCell::new(VaList::default()));
(*ap.borrow_mut()) = VaList::new(__args);
let ap: Value<Ptr<VaArg>> = Rc::new(RefCell::new(Ptr::<VaArg>::default()));
(*ap.borrow_mut()) = __args.as_pointer();
let mut result: i32 = ({ inner_0((*count.borrow()), (*ap.borrow()).clone()) });
return result;
}
Expand Down
5 changes: 3 additions & 2 deletions tests/unit/out/refcount/va_arg_mixed_int_ptr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,10 @@ use std::io::{Read, Seek, Write};
use std::os::fd::AsFd;
use std::rc::{Rc, Weak};
pub fn mixed_args_0(count: i32, __args: &[VaArg]) -> i32 {
let __args: Value<Box<[VaArg]>> = Rc::new(RefCell::new(__args.into()));
let count: Value<i32> = Rc::new(RefCell::new(count));
let ap: Value<VaList> = Rc::new(RefCell::new(VaList::default()));
(*ap.borrow_mut()) = VaList::new(__args);
let ap: Value<Ptr<VaArg>> = Rc::new(RefCell::new(Ptr::<VaArg>::default()));
(*ap.borrow_mut()) = __args.as_pointer();
let mut total: i32 = 0;
let mut i: i32 = 0;
'loop_: while (((i < (*count.borrow())) as i32) != 0) {
Expand Down
5 changes: 3 additions & 2 deletions tests/unit/out/refcount/va_arg_mixed_types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,10 @@ pub struct pair {
pub b: i32,
}
pub fn sum_mixed_0(count: i32, __args: &[VaArg]) -> i32 {
let __args: Value<Box<[VaArg]>> = Rc::new(RefCell::new(__args.into()));
let count: Value<i32> = Rc::new(RefCell::new(count));
let ap: Value<VaList> = Rc::new(RefCell::new(VaList::default()));
(*ap.borrow_mut()) = VaList::new(__args);
let ap: Value<Ptr<VaArg>> = Rc::new(RefCell::new(Ptr::<VaArg>::default()));
(*ap.borrow_mut()) = __args.as_pointer();
let mut total: i32 = 0;
let mut i: i32 = 0;
'loop_: while (((i < (*count.borrow())) as i32) != 0) {
Expand Down
5 changes: 3 additions & 2 deletions tests/unit/out/refcount/va_arg_non_primitive_ptrs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,9 +21,10 @@ pub const opt_OPT_FILE: opt = 1;
pub const opt_OPT_NODE: opt = 2;
pub const opt_OPT_NODE_OUT: opt = 3;
pub fn dispatch_0(option: i32, __args: &[VaArg]) -> i32 {
let __args: Value<Box<[VaArg]>> = Rc::new(RefCell::new(__args.into()));
let option: Value<i32> = Rc::new(RefCell::new(option));
let ap: Value<VaList> = Rc::new(RefCell::new(VaList::default()));
(*ap.borrow_mut()) = VaList::new(__args);
let ap: Value<Ptr<VaArg>> = Rc::new(RefCell::new(Ptr::<VaArg>::default()));
(*ap.borrow_mut()) = __args.as_pointer();
let mut result: i32 = 0;
'switch: {
match { (*option.borrow()) } {
Expand Down
5 changes: 3 additions & 2 deletions tests/unit/out/refcount/va_arg_null_int_ptr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,10 @@ use std::io::{Read, Seek, Write};
use std::os::fd::AsFd;
use std::rc::{Rc, Weak};
pub fn first_nonnull_0(count: i32, __args: &[VaArg]) -> i32 {
let __args: Value<Box<[VaArg]>> = Rc::new(RefCell::new(__args.into()));
let count: Value<i32> = Rc::new(RefCell::new(count));
let ap: Value<VaList> = Rc::new(RefCell::new(VaList::default()));
(*ap.borrow_mut()) = VaList::new(__args);
let ap: Value<Ptr<VaArg>> = Rc::new(RefCell::new(Ptr::<VaArg>::default()));
(*ap.borrow_mut()) = __args.as_pointer();
let mut result: i32 = -1_i32;
let mut i: i32 = 0;
'loop_: while (((i < (*count.borrow())) as i32) != 0) {
Expand Down
Loading
Loading