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
7 changes: 7 additions & 0 deletions cpp2rust/converter/mapper.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
#include <clang/Lex/Lexer.h>
#include <llvm/Support/ThreadPool.h>

#include <algorithm>
#include <cctype>
#include <cstdlib>
#include <format>
Expand Down Expand Up @@ -737,6 +738,12 @@ std::string ToRustName(std::string name) {
c = '_';
}
}

std::string_view stem(name);
stem = stem.substr(0, stem.find_last_not_of('_') + 1);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why is this needed? If the name doesn't match ptr/Value exactly, then there's no clash

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's a safety net. We transform Ptr -> Ptr_. If there is an user defined Ptr_ then it must transform into Ptr__

if (stem == "Ptr" || stem == "Value") {
name += '_';
}
return name;
}

Expand Down
84 changes: 84 additions & 0 deletions tests/unit/out/refcount/struct_ctor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,87 @@ impl ByteRepr for StructWithCtor {
pub fn foo_0(x: Ptr<i32>) -> Ptr<i32> {
return (x).clone();
}
#[derive(Default)]
pub struct Value_ {
pub v: Value<i32>,
}
impl Value_ {
pub fn new(u: i32) -> Self {
let u: Value<i32> = Rc::new(RefCell::new(u));
let __this: Value<Value_> = Rc::new(RefCell::new(Self {
v: Rc::new(RefCell::new((*u.borrow()))),
}));
let this: Ptr<Value_> = __this.as_pointer();
Rc::try_unwrap(__this).ok().unwrap().into_inner()
}
}
impl Clone for Value_ {
fn clone(&self) -> Self {
let __this: Value<Value_> = Rc::new(RefCell::new(Self {
v: Rc::new(RefCell::new((*self.v.borrow()))),
}));
let this: Ptr<Value_> = __this.as_pointer();
Rc::try_unwrap(__this).ok().unwrap().into_inner()
}
}
impl ByteRepr for Value_ {
fn byte_size() -> usize {
4
}
fn to_bytes(&self, buf: &mut [u8]) {
(*self.v.borrow()).to_bytes(&mut buf[0..4]);
}
fn from_bytes(buf: &[u8]) -> Self {
Self {
v: Rc::new(RefCell::new(<i32>::from_bytes(&buf[0..4]))),
}
}
}
#[derive()]
pub struct Ptr_ {
pub v1: Value<Value_>,
pub v2: Value<Value_>,
}
impl Ptr_ {
pub fn new() -> Self {
let __this: Value<Ptr_> = Rc::new(RefCell::new(Self {
v1: Rc::new(RefCell::new(Value_::new({ 11 }))),
v2: Rc::new(RefCell::new(Value_::new({ 22 }))),
}));
let this: Ptr<Ptr_> = __this.as_pointer();
Rc::try_unwrap(__this).ok().unwrap().into_inner()
}
}
impl Clone for Ptr_ {
fn clone(&self) -> Self {
let __this: Value<Ptr_> = Rc::new(RefCell::new(Self {
v1: Rc::new(RefCell::new((*self.v1.borrow()).clone())),
v2: Rc::new(RefCell::new((*self.v2.borrow()).clone())),
}));
let this: Ptr<Ptr_> = __this.as_pointer();
Rc::try_unwrap(__this).ok().unwrap().into_inner()
}
}
impl Default for Ptr_ {
fn default() -> Self {
{ Ptr_::new() }
}
}
impl ByteRepr for Ptr_ {
fn byte_size() -> usize {
8
}
fn to_bytes(&self, buf: &mut [u8]) {
(*self.v1.borrow()).to_bytes(&mut buf[0..4]);
(*self.v2.borrow()).to_bytes(&mut buf[4..8]);
}
fn from_bytes(buf: &[u8]) -> Self {
Self {
v1: Rc::new(RefCell::new(<Value_>::from_bytes(&buf[0..4]))),
v2: Rc::new(RefCell::new(<Value_>::from_bytes(&buf[4..8]))),
}
}
}
pub fn main() {
__cpp2rust_init_globals();
std::process::exit(main_0());
Expand All @@ -66,6 +147,9 @@ fn main_0() -> i32 {
&& ((({ StructWithCtorImpl::x1(&struct_with_ctor.as_pointer(),) }).read()) == 2))
&& ((({ StructWithCtorImpl::x2(&struct_with_ctor.as_pointer(),) }).read()) == 1)
);
let p: Value<Ptr_> = Rc::new(RefCell::new(Ptr_::new()));
assert!(((*(*(*p.borrow()).v1.borrow()).v.borrow()) == 11));
assert!(((*(*(*p.borrow()).v2.borrow()).v.borrow()) == 22));
return 0;
}
pub trait StructWithCtorImpl {
Expand Down
34 changes: 34 additions & 0 deletions tests/unit/out/unsafe/struct_ctor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,37 @@ impl StructWithCtor {
pub unsafe fn foo_0(x: *mut i32) -> *mut i32 {
return x;
}
#[repr(C)]
#[derive(Copy, Clone, Default)]
pub struct Value_ {
pub v: i32,
}
impl Value_ {
pub unsafe fn new(mut u: i32) -> Self {
let mut this = Self { v: u };
this
}
}
#[repr(C)]
#[derive(Copy, Clone)]
pub struct Ptr_ {
pub v1: Value_,
pub v2: Value_,
}
impl Ptr_ {
pub unsafe fn new() -> Self {
let mut this = Self {
v1: Value_::new({ 11 }),
v2: Value_::new({ 22 }),
};
this
}
}
impl Default for Ptr_ {
fn default() -> Self {
unsafe { Ptr_::new() }
}
}
pub fn main() {
unsafe {
__cpp2rust_init_globals();
Expand All @@ -43,6 +74,9 @@ unsafe fn main_0() -> i32 {
&& ((*(unsafe { StructWithCtor::x1(&struct_with_ctor,) })) == (2)))
&& ((*(unsafe { StructWithCtor::x2(&struct_with_ctor,) })) == (1))
);
let mut p: Ptr_ = Ptr_::new();
assert!(((p.v1.v) == (11)));
assert!(((p.v2.v) == (22)));
return 0;
}
pub unsafe fn __cpp2rust_init_globals() {}
17 changes: 17 additions & 0 deletions tests/unit/struct_ctor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,27 @@ struct StructWithCtor {
const int &x2() const { return x2_; }
};
int &foo(int &x) { return x; }

struct Value {
int v;
Value(int u) : v(u) {}
};

struct Ptr {
Value v1;
Value v2;

Ptr() : v1(11), v2(22) {}
};

int main() {
StructWithCtor struct_with_ctor(1, 2);
int x = 3;
assert(foo(x) == 3 && struct_with_ctor.x1() == 2 &&
struct_with_ctor.x2() == 1);

auto p = Ptr();
assert(p.v1.v == 11);
assert(p.v2.v == 22);
return 0;
}
Loading