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
2 changes: 1 addition & 1 deletion cpp2rust/converter/converter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -819,9 +819,9 @@ void Converter::EmitRustStructOrUnion(clang::RecordDecl *decl) {
// Traits
if (auto *cxx = clang::dyn_cast<clang::CXXRecordDecl>(decl)) {
AddOrdTrait(cxx);
AddCloneTrait(cxx);
AddDropTrait(cxx);
}
AddCloneTrait(decl);
AddDefaultTrait(decl);
AddByteReprTrait(decl);
}
Expand Down
17 changes: 16 additions & 1 deletion cpp2rust/converter/models/converter_refcount.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -465,7 +465,22 @@ void ConverterRefCount::AddCloneTrait(const clang::RecordDecl *decl) {
}

auto *cxx = clang::dyn_cast<clang::CXXRecordDecl>(decl);
if (!cxx || cxx->defaultedCopyConstructorIsDeleted()) {
if (!cxx) {
StrCat(keyword::kImpl, "Clone for", record_name);
PushBrace impl_brace(*this);
StrCat("fn clone(&self) -> Self");
PushBrace fn_brace(*this);
StrCat("Self");
PushBrace init_brace(*this);
for (auto *field : decl->fields()) {
auto name = GetNamedDeclAsString(field);
StrCat(std::format(
"{0}: Rc::new(RefCell::new((*self.{0}.borrow()).clone())),", name));
}
return;
}

if (cxx->defaultedCopyConstructorIsDeleted()) {
return;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,13 @@ use std::rc::{Rc, Weak};
pub struct widget {
pub id: Value<i32>,
}
impl Clone for widget {
fn clone(&self) -> Self {
Self {
id: Rc::new(RefCell::new((*self.id.borrow()).clone())),
}
}
}
impl ByteRepr for widget {
fn byte_size() -> usize {
4
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,14 @@ pub struct container {
pub p: Value<Ptr<opaque>>,
pub x: Value<i32>,
}
impl Clone for container {
fn clone(&self) -> Self {
Self {
p: Rc::new(RefCell::new((*self.p.borrow()).clone())),
x: Rc::new(RefCell::new((*self.x.borrow()).clone())),
}
}
}
impl ByteRepr for container {
fn byte_size() -> usize {
16
Expand Down
6 changes: 6 additions & 0 deletions tests/unit/c_struct.c
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,12 @@ int main() {
assert(p.x == 10);
assert(p.y == 20);

struct Point q = p;
q.x = 99;
assert(p.x == 10);
assert(q.x == 99);
assert(q.y == 20);

struct Line l = {{1, 2}, {3, 4}};
assert(l.start.x == 1);
assert(l.end.y == 4);
Expand Down
74 changes: 74 additions & 0 deletions tests/unit/out/refcount/anonymous-struct_c.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,14 @@ pub struct Named {
pub a: Value<i32>,
pub b: Value<i32>,
}
impl Clone for Named {
fn clone(&self) -> Self {
Self {
a: Rc::new(RefCell::new((*self.a.borrow()).clone())),
b: Rc::new(RefCell::new((*self.b.borrow()).clone())),
}
}
}
impl ByteRepr for Named {
fn byte_size() -> usize {
8
Expand All @@ -31,6 +39,14 @@ pub struct anon_0 {
pub c: Value<i32>,
pub d: Value<i32>,
}
impl Clone for anon_0 {
fn clone(&self) -> Self {
Self {
c: Rc::new(RefCell::new((*self.c.borrow()).clone())),
d: Rc::new(RefCell::new((*self.d.borrow()).clone())),
}
}
}
impl ByteRepr for anon_0 {
fn byte_size() -> usize {
8
Expand All @@ -51,6 +67,14 @@ pub struct anon_1 {
pub g: Value<i32>,
pub h: Value<i32>,
}
impl Clone for anon_1 {
fn clone(&self) -> Self {
Self {
g: Rc::new(RefCell::new((*self.g.borrow()).clone())),
h: Rc::new(RefCell::new((*self.h.borrow()).clone())),
}
}
}
impl ByteRepr for anon_1 {
fn byte_size() -> usize {
8
Expand All @@ -71,6 +95,14 @@ pub struct anon_2 {
pub e: Value<i32>,
pub f: Value<i32>,
}
impl Clone for anon_2 {
fn clone(&self) -> Self {
Self {
e: Rc::new(RefCell::new((*self.e.borrow()).clone())),
f: Rc::new(RefCell::new((*self.f.borrow()).clone())),
}
}
}
impl ByteRepr for anon_2 {
fn byte_size() -> usize {
8
Expand All @@ -90,6 +122,13 @@ impl ByteRepr for anon_2 {
pub struct anon_4 {
pub j: Value<i32>,
}
impl Clone for anon_4 {
fn clone(&self) -> Self {
Self {
j: Rc::new(RefCell::new((*self.j.borrow()).clone())),
}
}
}
impl ByteRepr for anon_4 {
fn byte_size() -> usize {
4
Expand All @@ -107,6 +146,13 @@ impl ByteRepr for anon_4 {
pub struct anon_5 {
pub k: Value<i32>,
}
impl Clone for anon_5 {
fn clone(&self) -> Self {
Self {
k: Rc::new(RefCell::new((*self.k.borrow()).clone())),
}
}
}
impl ByteRepr for anon_5 {
fn byte_size() -> usize {
4
Expand All @@ -126,6 +172,15 @@ pub struct anon_3 {
pub inner_named: Value<anon_4>,
pub anon_5: Value<anon_5>,
}
impl Clone for anon_3 {
fn clone(&self) -> Self {
Self {
i: Rc::new(RefCell::new((*self.i.borrow()).clone())),
inner_named: Rc::new(RefCell::new((*self.inner_named.borrow()).clone())),
anon_5: Rc::new(RefCell::new((*self.anon_5.borrow()).clone())),
}
}
}
impl ByteRepr for anon_3 {
fn byte_size() -> usize {
12
Expand All @@ -151,6 +206,17 @@ pub struct Outer {
pub anon_2: Value<anon_2>,
pub anon_3: Value<anon_3>,
}
impl Clone for Outer {
fn clone(&self) -> Self {
Self {
named: Rc::new(RefCell::new((*self.named.borrow()).clone())),
anon0: Rc::new(RefCell::new((*self.anon0.borrow()).clone())),
anon1: Rc::new(RefCell::new((*self.anon1.borrow()).clone())),
anon_2: Rc::new(RefCell::new((*self.anon_2.borrow()).clone())),
anon_3: Rc::new(RefCell::new((*self.anon_3.borrow()).clone())),
}
}
}
impl ByteRepr for Outer {
fn byte_size() -> usize {
44
Expand Down Expand Up @@ -229,6 +295,14 @@ fn main_0() -> i32 {
pub x: Value<i32>,
pub z: Value<i32>,
}
impl Clone for anon_6 {
fn clone(&self) -> Self {
Self {
x: Rc::new(RefCell::new((*self.x.borrow()).clone())),
z: Rc::new(RefCell::new((*self.z.borrow()).clone())),
}
}
}
impl ByteRepr for anon_6 {
fn byte_size() -> usize {
8
Expand Down
15 changes: 15 additions & 0 deletions tests/unit/out/refcount/anonymous_enum_c.rs
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,13 @@ impl ByteRepr for anon_1 {
pub struct S {
pub a: Value<i32>,
}
impl Clone for S {
fn clone(&self) -> Self {
Self {
a: Rc::new(RefCell::new((*self.a.borrow()).clone())),
}
}
}
impl ByteRepr for S {
fn byte_size() -> usize {
4
Expand Down Expand Up @@ -124,6 +131,14 @@ pub struct WithAnonField {
pub a: Value<i32>,
pub field: Value<anon_2>,
}
impl Clone for WithAnonField {
fn clone(&self) -> Self {
Self {
a: Rc::new(RefCell::new((*self.a.borrow()).clone())),
field: Rc::new(RefCell::new((*self.field.borrow()).clone())),
}
}
}
impl ByteRepr for WithAnonField {
fn byte_size() -> usize {
8
Expand Down
9 changes: 9 additions & 0 deletions tests/unit/out/refcount/array_const_init.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,15 @@ pub struct S {
pub tail: Value<Box<[i32]>>,
pub buf: Value<Box<[u8]>>,
}
impl Clone for S {
fn clone(&self) -> Self {
Self {
head: Rc::new(RefCell::new((*self.head.borrow()).clone())),
tail: Rc::new(RefCell::new((*self.tail.borrow()).clone())),
buf: Rc::new(RefCell::new((*self.buf.borrow()).clone())),
}
}
}
impl Default for S {
fn default() -> Self {
S {
Expand Down
46 changes: 46 additions & 0 deletions tests/unit/out/refcount/c_struct.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,14 @@ pub struct Point {
pub x: Value<i32>,
pub y: Value<i32>,
}
impl Clone for Point {
fn clone(&self) -> Self {
Self {
x: Rc::new(RefCell::new((*self.x.borrow()).clone())),
y: Rc::new(RefCell::new((*self.y.borrow()).clone())),
}
}
}
impl ByteRepr for Point {
fn byte_size() -> usize {
8
Expand All @@ -31,6 +39,14 @@ pub struct Line {
pub start: Value<Point>,
pub end: Value<Point>,
}
impl Clone for Line {
fn clone(&self) -> Self {
Self {
start: Rc::new(RefCell::new((*self.start.borrow()).clone())),
end: Rc::new(RefCell::new((*self.end.borrow()).clone())),
}
}
}
impl ByteRepr for Line {
fn byte_size() -> usize {
16
Expand All @@ -51,6 +67,14 @@ pub struct Node {
pub value: Value<i32>,
pub next: Value<Ptr<Node>>,
}
impl Clone for Node {
fn clone(&self) -> Self {
Self {
value: Rc::new(RefCell::new((*self.value.borrow()).clone())),
next: Rc::new(RefCell::new((*self.next.borrow()).clone())),
}
}
}
impl ByteRepr for Node {
fn byte_size() -> usize {
16
Expand Down Expand Up @@ -97,6 +121,14 @@ pub struct Inner {
pub a: Value<i32>,
pub b: Value<i32>,
}
impl Clone for Inner {
fn clone(&self) -> Self {
Self {
a: Rc::new(RefCell::new((*self.a.borrow()).clone())),
b: Rc::new(RefCell::new((*self.b.borrow()).clone())),
}
}
}
impl ByteRepr for Inner {
fn byte_size() -> usize {
8
Expand All @@ -118,6 +150,15 @@ pub struct Container {
pub color: Value<Color>,
pub count: Value<i32>,
}
impl Clone for Container {
fn clone(&self) -> Self {
Self {
inner: Rc::new(RefCell::new((*self.inner.borrow()).clone())),
color: Rc::new(RefCell::new((*self.color.borrow()).clone())),
count: Rc::new(RefCell::new((*self.count.borrow()).clone())),
}
}
}
impl ByteRepr for Container {
fn byte_size() -> usize {
16
Expand Down Expand Up @@ -145,6 +186,11 @@ fn main_0() -> i32 {
}));
assert!(((((*(*p.borrow()).x.borrow()) == 10) as i32) != 0));
assert!(((((*(*p.borrow()).y.borrow()) == 20) as i32) != 0));
let q: Value<Point> = Rc::new(RefCell::new((*p.borrow()).clone()));
(*(*q.borrow()).x.borrow_mut()) = 99;
assert!(((((*(*p.borrow()).x.borrow()) == 10) as i32) != 0));
assert!(((((*(*q.borrow()).x.borrow()) == 99) as i32) != 0));
assert!(((((*(*q.borrow()).y.borrow()) == 20) as i32) != 0));
let l: Value<Line> = Rc::new(RefCell::new(Line {
start: Rc::new(RefCell::new(Point {
x: Rc::new(RefCell::new(1)),
Expand Down
8 changes: 8 additions & 0 deletions tests/unit/out/refcount/enum_default_in_static.rs
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,14 @@ pub struct Config {
pub count: Value<i32>,
pub mode: Value<Mode>,
}
impl Clone for Config {
fn clone(&self) -> Self {
Self {
count: Rc::new(RefCell::new((*self.count.borrow()).clone())),
mode: Rc::new(RefCell::new((*self.mode.borrow()).clone())),
}
}
}
impl ByteRepr for Config {
fn byte_size() -> usize {
8
Expand Down
9 changes: 9 additions & 0 deletions tests/unit/out/refcount/enum_int_interop_c.rs
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,15 @@ pub struct Entry {
pub color: Value<Color>,
pub opt: Value<Option>,
}
impl Clone for Entry {
fn clone(&self) -> Self {
Self {
name: Rc::new(RefCell::new((*self.name.borrow()).clone())),
color: Rc::new(RefCell::new((*self.color.borrow()).clone())),
opt: Rc::new(RefCell::new((*self.opt.borrow()).clone())),
}
}
}
impl ByteRepr for Entry {
fn byte_size() -> usize {
16
Expand Down
8 changes: 8 additions & 0 deletions tests/unit/out/refcount/goto_aggregate_default.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,14 @@ pub struct Point {
pub x: Value<i32>,
pub y: Value<i32>,
}
impl Clone for Point {
fn clone(&self) -> Self {
Self {
x: Rc::new(RefCell::new((*self.x.borrow()).clone())),
y: Rc::new(RefCell::new((*self.y.borrow()).clone())),
}
}
}
impl ByteRepr for Point {
fn byte_size() -> usize {
8
Expand Down
Loading
Loading