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
32 changes: 16 additions & 16 deletions cpp2rust/converter/converter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1165,8 +1165,11 @@ bool Converter::VisitCXXConstructorDecl(clang::CXXConstructorDecl *decl) {

void Converter::ConvertCXXConstructorBody(clang::CXXConstructorDecl *decl) {
EmitFunctionPreamble(decl);
StrCat(keyword::kLet, "mut", "this", token::kAssign, "Self");
{
StrCat(keyword::kLet, "mut", "this", token::kAssign);
if (decl->isDelegatingConstructor()) {
Convert((*decl->init_begin())->getInit());
} else {
StrCat("Self");
PushBrace this_init(*this);
EmitConstructorFieldInits(decl);
}
Expand All @@ -1182,26 +1185,23 @@ void Converter::EmitConstructorFieldInits(clang::CXXConstructorDecl *decl) {
assert(definition_or_null);
auto *definition = clang::cast<clang::CXXConstructorDecl>(definition_or_null);

bool has_inits = !definition->inits().empty();
auto **ctor_initializer_list = definition->inits().begin();
int curr_init =
has_inits ? (ctor_initializer_list[0]->isBaseInitializer() ? 1 : 0) : 0;

for (const auto *field : record_decl->fields()) {
auto field_name = GetNamedDeclAsString(field);
auto field_type = field->getType();
auto *ctor_initializer =
has_inits ? ctor_initializer_list[curr_init] : nullptr;
const clang::CXXCtorInitializer *ctor_initializer = nullptr;
for (const auto *init : definition->inits()) {
if (init->isMemberInitializer() && init->getMember() == field) {
ctor_initializer = init;
break;
}
}

if (has_inits &&
GetNamedDeclAsString(ctor_initializer->getMember()) == field_name) {
auto *ctor_init_expr = ctor_initializer->getInit();
if (ctor_initializer) {
StrCat(field_name, token::kColon);
ConvertVarInit(field_type, ctor_init_expr);
curr_init = (curr_init + 1) % definition->getNumCtorInitializers();
} else if (field->hasInClassInitializer()) {
ConvertVarInit(field_type, ctor_initializer->getInit());
} else if (auto *init = field->getInClassInitializer()) {
StrCat(field_name, token::kColon);
ConvertVarInit(field_type, field->getInClassInitializer());
ConvertVarInit(field_type, init);
} else {
StrCat(field_name, token::kColon, GetDefaultAsString(field_type));
}
Expand Down
7 changes: 5 additions & 2 deletions cpp2rust/converter/models/converter_refcount.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2959,8 +2959,11 @@ void ConverterRefCount::ConvertCXXConstructorBody(
auto record_name = GetRecordName(decl->getParent());
StrCat(keyword::kLet, "__this", token::kColon,
std::format("Value<{}>", record_name), token::kAssign,
"Rc::new(RefCell::new(Self");
{
"Rc::new(RefCell::new(");
if (decl->isDelegatingConstructor()) {
Convert((*decl->init_begin())->getInit());
} else {
StrCat("Self");
PushBrace this_init(*this);
EmitConstructorFieldInits(decl);
}
Expand Down
14 changes: 14 additions & 0 deletions tests/unit/constructor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,12 +18,26 @@ struct S {
}
};

struct Point {
int x;
int y;
Point(int x, int y) : x(x), y(y) {}
Point(int v) : Point(v, v + 1) { y *= 10; }
Point() : Point(4) { x += 100; }
};

int main() {
{
S s(3);
assert(s.v == 4);
assert(total == 8);
}
assert(total == 18);
Point p;
assert(p.x == 104);
assert(p.y == 50);
Point q(7);
assert(q.x == 7);
assert(q.y == 80);
return 0;
}
68 changes: 68 additions & 0 deletions tests/unit/out/refcount/constructor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,68 @@ impl ByteRepr for S {
}
}
}
#[derive()]
pub struct Point {
pub x: Value<i32>,
pub y: Value<i32>,
}
impl Point {
pub fn Point1(x: i32, y: i32) -> Self {
let x: Value<i32> = Rc::new(RefCell::new(x));
let y: Value<i32> = Rc::new(RefCell::new(y));
let __this: Value<Point> = Rc::new(RefCell::new(Self {
x: Rc::new(RefCell::new((*x.borrow()))),
y: Rc::new(RefCell::new((*y.borrow()))),
}));
let this: Ptr<Point> = __this.as_pointer();
Rc::try_unwrap(__this).ok().unwrap().into_inner()
}
pub fn Point2(v: i32) -> Self {
let v: Value<i32> = Rc::new(RefCell::new(v));
let __this: Value<Point> = Rc::new(RefCell::new(Point::Point1({ (*v.borrow()) }, {
((*v.borrow()) + 1)
})));
let this: Ptr<Point> = __this.as_pointer();
(*(*this.upgrade().deref()).y.borrow_mut()) *= 10;
Rc::try_unwrap(__this).ok().unwrap().into_inner()
}
pub fn Point3() -> Self {
let __this: Value<Point> = Rc::new(RefCell::new(Point::Point2({ 4 })));
let this: Ptr<Point> = __this.as_pointer();
(*(*this.upgrade().deref()).x.borrow_mut()) += 100;
Rc::try_unwrap(__this).ok().unwrap().into_inner()
}
}
impl Clone for Point {
fn clone(&self) -> Self {
let __this: Value<Point> = Rc::new(RefCell::new(Self {
x: Rc::new(RefCell::new((*self.x.borrow()))),
y: Rc::new(RefCell::new((*self.y.borrow()))),
}));
let this: Ptr<Point> = __this.as_pointer();
Rc::try_unwrap(__this).ok().unwrap().into_inner()
}
}
impl Default for Point {
fn default() -> Self {
{ Point::Point3() }
}
}
impl ByteRepr for Point {
fn byte_size() -> usize {
8
}
fn to_bytes(&self, buf: &mut [u8]) {
(*self.x.borrow()).to_bytes(&mut buf[0..4]);
(*self.y.borrow()).to_bytes(&mut buf[4..8]);
}
fn from_bytes(buf: &[u8]) -> Self {
Self {
x: Rc::new(RefCell::new(<i32>::from_bytes(&buf[0..4]))),
y: Rc::new(RefCell::new(<i32>::from_bytes(&buf[4..8]))),
}
}
}
pub fn main() {
__cpp2rust_init_globals();
std::process::exit(main_0());
Expand All @@ -59,6 +121,12 @@ fn main_0() -> i32 {
assert!((total_0.with(|rc| *rc.borrow()) == 8));
}
assert!((total_0.with(|rc| *rc.borrow()) == 18));
let p: Value<Point> = Rc::new(RefCell::new(Point::Point3()));
assert!(((*(*p.borrow()).x.borrow()) == 104));
assert!(((*(*p.borrow()).y.borrow()) == 50));
let q: Value<Point> = Rc::new(RefCell::new(Point::Point2({ 7 })));
assert!(((*(*q.borrow()).x.borrow()) == 7));
assert!(((*(*q.borrow()).y.borrow()) == 80));
return 0;
}
pub trait SImpl {
Expand Down
33 changes: 33 additions & 0 deletions tests/unit/out/unsafe/constructor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,33 @@ impl S {
(unsafe { S::const_method(self) });
}
}
#[repr(C)]
#[derive(Copy, Clone)]
pub struct Point {
pub x: i32,
pub y: i32,
}
impl Point {
pub unsafe fn Point1(mut x: i32, mut y: i32) -> Self {
let mut this = Self { x: x, y: y };
this
}
pub unsafe fn Point2(mut v: i32) -> Self {
let mut this = Point::Point1({ v }, { ((v) + (1)) });
this.y *= 10;
this
}
pub unsafe fn Point3() -> Self {
let mut this = Point::Point2({ 4 });
this.x += 100;
this
}
}
impl Default for Point {
fn default() -> Self {
unsafe { Point::Point3() }
}
}
pub fn main() {
unsafe {
__cpp2rust_init_globals();
Expand All @@ -46,6 +73,12 @@ unsafe fn main_0() -> i32 {
assert!(((*std::cell::LazyCell::force_mut(&mut *&raw mut total_0)) == (8)));
}
assert!(((*std::cell::LazyCell::force_mut(&mut *&raw mut total_0)) == (18)));
let mut p: Point = Point::Point3();
assert!(((p.x) == (104)));
assert!(((p.y) == (50)));
let mut q: Point = Point::Point2({ 7 });
assert!(((q.x) == (7)));
assert!(((q.y) == (80)));
return 0;
}
pub unsafe fn __cpp2rust_init_globals() {
Expand Down
Loading