Skip to content

Commit 242c5be

Browse files
authored
Translate inner templates (#400)
1 parent d3cec4b commit 242c5be

5 files changed

Lines changed: 323 additions & 0 deletions

File tree

‎cpp2rust/converter/converter.cpp‎

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -823,6 +823,12 @@ void Converter::EmitRustStructOrUnion(clang::RecordDecl *decl) {
823823
}
824824
}
825825
}
826+
if (auto *nested_tmpl = clang::dyn_cast<clang::ClassTemplateDecl>(d)) {
827+
for (auto *spec : nested_tmpl->specializations()) {
828+
inner_structs_[GetID(spec)] = GetRecordName(spec);
829+
VisitCXXRecordDecl(spec);
830+
}
831+
}
826832
}
827833

828834
if (decl->isUnion()) {

‎cpp2rust/converter/converter_lib.cpp‎

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -599,6 +599,10 @@ static std::string GetLexicalSpecializationID(const clang::Decl *decl) {
599599
clang::dyn_cast<clang::VarTemplateSpecializationDecl>(decl)) {
600600
id += clang::ASTNameGenerator(var->getASTContext()).getName(var);
601601
}
602+
if (const auto *self =
603+
clang::dyn_cast<clang::ClassTemplateSpecializationDecl>(decl)) {
604+
id += Mapper::ToString(Mapper::GetTypeForDecl(self));
605+
}
602606
if (const auto *spec =
603607
clang::dyn_cast<clang::ClassTemplateSpecializationDecl>(
604608
decl->getLexicalDeclContext());

‎tests/unit/class_templates.cpp‎

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,25 @@ template <typename T> T Boxed<T>::twice(T v) { return v + v; }
2828

2929
template <typename T> T Boxed<T>::plus(T other) const { return value + other; }
3030

31+
template <typename T> struct Outer {
32+
template <typename U> struct Inner {
33+
T t;
34+
U u;
35+
int sum() const { return (int)t + (int)u; }
36+
};
37+
38+
T v;
39+
Inner<int> with(int n) const { return Inner<int>{v, n}; }
40+
};
41+
3142
int main() {
43+
Outer<int> oi{3};
44+
assert(oi.with(4).sum() == 7);
45+
Outer<long> ol{5};
46+
Outer<long>::Inner<char> ic{6, 'a'};
47+
assert(ol.with(2).sum() == 7);
48+
assert(ic.sum() == 6 + 'a');
49+
3250
assert(Boxed<int>::twice(3) == 6);
3351
Boxed<int> bi{4};
3452
assert(bi.plus(5) == 9);

‎tests/unit/out/refcount/class_templates.rs‎

Lines changed: 226 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -148,11 +148,186 @@ impl ByteRepr for Boxed_long_ {
148148
}
149149
}
150150
}
151+
#[derive(Default)]
152+
pub struct Outer_int__Inner_int_ {
153+
pub t: Value<i32>,
154+
pub u: Value<i32>,
155+
}
156+
impl Clone for Outer_int__Inner_int_ {
157+
fn clone(&self) -> Self {
158+
let __this: Value<Outer_int__Inner_int_> = Rc::new(RefCell::new(Self {
159+
t: Rc::new(RefCell::new((*self.t.borrow()))),
160+
u: Rc::new(RefCell::new((*self.u.borrow()))),
161+
}));
162+
let this: Ptr<Outer_int__Inner_int_> = __this.as_pointer();
163+
Rc::try_unwrap(__this).ok().unwrap().into_inner()
164+
}
165+
}
166+
impl ByteRepr for Outer_int__Inner_int_ {
167+
fn byte_size() -> usize {
168+
8
169+
}
170+
fn to_bytes(&self, buf: &mut [u8]) {
171+
(*self.t.borrow()).to_bytes(&mut buf[0..4]);
172+
(*self.u.borrow()).to_bytes(&mut buf[4..8]);
173+
}
174+
fn from_bytes(buf: &[u8]) -> Self {
175+
Self {
176+
t: Rc::new(RefCell::new(<i32>::from_bytes(&buf[0..4]))),
177+
u: Rc::new(RefCell::new(<i32>::from_bytes(&buf[4..8]))),
178+
}
179+
}
180+
}
181+
#[derive(Default)]
182+
pub struct Outer_int_ {
183+
pub v: Value<i32>,
184+
}
185+
impl Clone for Outer_int_ {
186+
fn clone(&self) -> Self {
187+
let __this: Value<Outer_int_> = Rc::new(RefCell::new(Self {
188+
v: Rc::new(RefCell::new((*self.v.borrow()))),
189+
}));
190+
let this: Ptr<Outer_int_> = __this.as_pointer();
191+
Rc::try_unwrap(__this).ok().unwrap().into_inner()
192+
}
193+
}
194+
impl ByteRepr for Outer_int_ {
195+
fn byte_size() -> usize {
196+
4
197+
}
198+
fn to_bytes(&self, buf: &mut [u8]) {
199+
(*self.v.borrow()).to_bytes(&mut buf[0..4]);
200+
}
201+
fn from_bytes(buf: &[u8]) -> Self {
202+
Self {
203+
v: Rc::new(RefCell::new(<i32>::from_bytes(&buf[0..4]))),
204+
}
205+
}
206+
}
207+
#[derive(Default)]
208+
pub struct Outer_long__Inner_int_ {
209+
pub t: Value<i64>,
210+
pub u: Value<i32>,
211+
}
212+
impl Clone for Outer_long__Inner_int_ {
213+
fn clone(&self) -> Self {
214+
let __this: Value<Outer_long__Inner_int_> = Rc::new(RefCell::new(Self {
215+
t: Rc::new(RefCell::new((*self.t.borrow()))),
216+
u: Rc::new(RefCell::new((*self.u.borrow()))),
217+
}));
218+
let this: Ptr<Outer_long__Inner_int_> = __this.as_pointer();
219+
Rc::try_unwrap(__this).ok().unwrap().into_inner()
220+
}
221+
}
222+
impl ByteRepr for Outer_long__Inner_int_ {
223+
fn byte_size() -> usize {
224+
16
225+
}
226+
fn to_bytes(&self, buf: &mut [u8]) {
227+
(*self.t.borrow()).to_bytes(&mut buf[0..8]);
228+
(*self.u.borrow()).to_bytes(&mut buf[8..12]);
229+
}
230+
fn from_bytes(buf: &[u8]) -> Self {
231+
Self {
232+
t: Rc::new(RefCell::new(<i64>::from_bytes(&buf[0..8]))),
233+
u: Rc::new(RefCell::new(<i32>::from_bytes(&buf[8..12]))),
234+
}
235+
}
236+
}
237+
#[derive(Default)]
238+
pub struct Outer_long__Inner_char_ {
239+
pub t: Value<i64>,
240+
pub u: Value<u8>,
241+
}
242+
impl Clone for Outer_long__Inner_char_ {
243+
fn clone(&self) -> Self {
244+
let __this: Value<Outer_long__Inner_char_> = Rc::new(RefCell::new(Self {
245+
t: Rc::new(RefCell::new((*self.t.borrow()))),
246+
u: Rc::new(RefCell::new((*self.u.borrow()))),
247+
}));
248+
let this: Ptr<Outer_long__Inner_char_> = __this.as_pointer();
249+
Rc::try_unwrap(__this).ok().unwrap().into_inner()
250+
}
251+
}
252+
impl ByteRepr for Outer_long__Inner_char_ {
253+
fn byte_size() -> usize {
254+
16
255+
}
256+
fn to_bytes(&self, buf: &mut [u8]) {
257+
(*self.t.borrow()).to_bytes(&mut buf[0..8]);
258+
(*self.u.borrow()).to_bytes(&mut buf[8..9]);
259+
}
260+
fn from_bytes(buf: &[u8]) -> Self {
261+
Self {
262+
t: Rc::new(RefCell::new(<i64>::from_bytes(&buf[0..8]))),
263+
u: Rc::new(RefCell::new(<u8>::from_bytes(&buf[8..9]))),
264+
}
265+
}
266+
}
267+
#[derive(Default)]
268+
pub struct Outer_long_ {
269+
pub v: Value<i64>,
270+
}
271+
impl Clone for Outer_long_ {
272+
fn clone(&self) -> Self {
273+
let __this: Value<Outer_long_> = Rc::new(RefCell::new(Self {
274+
v: Rc::new(RefCell::new((*self.v.borrow()))),
275+
}));
276+
let this: Ptr<Outer_long_> = __this.as_pointer();
277+
Rc::try_unwrap(__this).ok().unwrap().into_inner()
278+
}
279+
}
280+
impl ByteRepr for Outer_long_ {
281+
fn byte_size() -> usize {
282+
8
283+
}
284+
fn to_bytes(&self, buf: &mut [u8]) {
285+
(*self.v.borrow()).to_bytes(&mut buf[0..8]);
286+
}
287+
fn from_bytes(buf: &[u8]) -> Self {
288+
Self {
289+
v: Rc::new(RefCell::new(<i64>::from_bytes(&buf[0..8]))),
290+
}
291+
}
292+
}
151293
pub fn main() {
152294
__cpp2rust_init_globals();
153295
std::process::exit(main_0());
154296
}
155297
fn main_0() -> i32 {
298+
let oi: Value<Outer_int_> = Rc::new(RefCell::new(Outer_int_ {
299+
v: Rc::new(RefCell::new(3)),
300+
}));
301+
assert!(
302+
(({
303+
Outer_int__Inner_int_Impl::sum(
304+
&Rc::new(RefCell::new(
305+
({ Outer_int_Impl::with(&oi.as_pointer(), 4) }),
306+
))
307+
.as_pointer(),
308+
)
309+
}) == 7)
310+
);
311+
let ol: Value<Outer_long_> = Rc::new(RefCell::new(Outer_long_ {
312+
v: Rc::new(RefCell::new(5_i64)),
313+
}));
314+
let ic: Value<Outer_long__Inner_char_> = Rc::new(RefCell::new(Outer_long__Inner_char_ {
315+
t: Rc::new(RefCell::new(6_i64)),
316+
u: Rc::new(RefCell::new(('a' as u8))),
317+
}));
318+
assert!(
319+
(({
320+
Outer_long__Inner_int_Impl::sum(
321+
&Rc::new(RefCell::new(
322+
({ Outer_long_Impl::with(&ol.as_pointer(), 2) }),
323+
))
324+
.as_pointer(),
325+
)
326+
}) == 7)
327+
);
328+
assert!(
329+
(({ Outer_long__Inner_char_Impl::sum(&ic.as_pointer(),) }) == (6 + (('a' as u8) as i32)))
330+
);
156331
assert!((({ Boxed_int_::twice(3,) }) == 6));
157332
let bi: Value<Boxed_int_> = Rc::new(RefCell::new(Boxed_int_ {
158333
value: Rc::new(RefCell::new(4)),
@@ -313,4 +488,55 @@ impl MyContainer_int_Impl for Ptr<MyContainer_int_> {
313488
};
314489
}
315490
}
491+
pub trait Outer_int_Impl {
492+
fn with(&self, n: i32) -> Outer_int__Inner_int_;
493+
}
494+
impl Outer_int_Impl for Ptr<Outer_int_> {
495+
fn with(&self, n: i32) -> Outer_int__Inner_int_ {
496+
let n: Value<i32> = Rc::new(RefCell::new(n));
497+
return Outer_int__Inner_int_ {
498+
t: Rc::new(RefCell::new((*(*(*self).upgrade().deref()).v.borrow()))),
499+
u: Rc::new(RefCell::new((*n.borrow()))),
500+
};
501+
}
502+
}
503+
pub trait Outer_int__Inner_int_Impl {
504+
fn sum(&self) -> i32;
505+
}
506+
impl Outer_int__Inner_int_Impl for Ptr<Outer_int__Inner_int_> {
507+
fn sum(&self) -> i32 {
508+
return (((*(*(*self).upgrade().deref()).t.borrow()) as i32)
509+
+ ((*(*(*self).upgrade().deref()).u.borrow()) as i32));
510+
}
511+
}
512+
pub trait Outer_long_Impl {
513+
fn with(&self, n: i32) -> Outer_long__Inner_int_;
514+
}
515+
impl Outer_long_Impl for Ptr<Outer_long_> {
516+
fn with(&self, n: i32) -> Outer_long__Inner_int_ {
517+
let n: Value<i32> = Rc::new(RefCell::new(n));
518+
return Outer_long__Inner_int_ {
519+
t: Rc::new(RefCell::new((*(*(*self).upgrade().deref()).v.borrow()))),
520+
u: Rc::new(RefCell::new((*n.borrow()))),
521+
};
522+
}
523+
}
524+
pub trait Outer_long__Inner_char_Impl {
525+
fn sum(&self) -> i32;
526+
}
527+
impl Outer_long__Inner_char_Impl for Ptr<Outer_long__Inner_char_> {
528+
fn sum(&self) -> i32 {
529+
return (((*(*(*self).upgrade().deref()).t.borrow()) as i32)
530+
+ ((*(*(*self).upgrade().deref()).u.borrow()) as i32));
531+
}
532+
}
533+
pub trait Outer_long__Inner_int_Impl {
534+
fn sum(&self) -> i32;
535+
}
536+
impl Outer_long__Inner_int_Impl for Ptr<Outer_long__Inner_int_> {
537+
fn sum(&self) -> i32 {
538+
return (((*(*(*self).upgrade().deref()).t.borrow()) as i32)
539+
+ ((*(*(*self).upgrade().deref()).u.borrow()) as i32));
540+
}
541+
}
316542
pub fn __cpp2rust_init_globals() {}

‎tests/unit/out/unsafe/class_templates.rs‎

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -110,13 +110,82 @@ impl Boxed_long_ {
110110
return ((self.value) + (other));
111111
}
112112
}
113+
#[repr(C)]
114+
#[derive(Copy, Clone, Default)]
115+
pub struct Outer_int__Inner_int_ {
116+
pub t: i32,
117+
pub u: i32,
118+
}
119+
impl Outer_int__Inner_int_ {
120+
pub unsafe fn sum(&self) -> i32 {
121+
return ((self.t as i32) + (self.u as i32));
122+
}
123+
}
124+
#[repr(C)]
125+
#[derive(Copy, Clone, Default)]
126+
pub struct Outer_int_ {
127+
pub v: i32,
128+
}
129+
impl Outer_int_ {
130+
pub unsafe fn with(&self, mut n: i32) -> Outer_int__Inner_int_ {
131+
return Outer_int__Inner_int_ { t: self.v, u: n };
132+
}
133+
}
134+
#[repr(C)]
135+
#[derive(Copy, Clone, Default)]
136+
pub struct Outer_long__Inner_int_ {
137+
pub t: i64,
138+
pub u: i32,
139+
}
140+
impl Outer_long__Inner_int_ {
141+
pub unsafe fn sum(&self) -> i32 {
142+
return ((self.t as i32) + (self.u as i32));
143+
}
144+
}
145+
#[repr(C)]
146+
#[derive(Copy, Clone, Default)]
147+
pub struct Outer_long__Inner_char_ {
148+
pub t: i64,
149+
pub u: libc::c_char,
150+
}
151+
impl Outer_long__Inner_char_ {
152+
pub unsafe fn sum(&self) -> i32 {
153+
return ((self.t as i32) + (self.u as i32));
154+
}
155+
}
156+
#[repr(C)]
157+
#[derive(Copy, Clone, Default)]
158+
pub struct Outer_long_ {
159+
pub v: i64,
160+
}
161+
impl Outer_long_ {
162+
pub unsafe fn with(&self, mut n: i32) -> Outer_long__Inner_int_ {
163+
return Outer_long__Inner_int_ { t: self.v, u: n };
164+
}
165+
}
113166
pub fn main() {
114167
unsafe {
115168
__cpp2rust_init_globals();
116169
std::process::exit(main_0() as i32);
117170
}
118171
}
119172
unsafe fn main_0() -> i32 {
173+
let mut oi: Outer_int_ = Outer_int_ { v: 3 };
174+
assert!(
175+
((unsafe { Outer_int__Inner_int_::sum(&(unsafe { Outer_int_::with(&oi, 4,) }),) }) == (7))
176+
);
177+
let mut ol: Outer_long_ = Outer_long_ { v: 5_i64 };
178+
let mut ic: Outer_long__Inner_char_ = Outer_long__Inner_char_ {
179+
t: 6_i64,
180+
u: ('a' as libc::c_char),
181+
};
182+
assert!(
183+
((unsafe { Outer_long__Inner_int_::sum(&(unsafe { Outer_long_::with(&ol, 2,) }),) })
184+
== (7))
185+
);
186+
assert!(
187+
((unsafe { Outer_long__Inner_char_::sum(&ic,) }) == ((6) + (('a' as libc::c_char) as i32)))
188+
);
120189
assert!(((unsafe { Boxed_int_::twice(3,) }) == (6)));
121190
let mut bi: Boxed_int_ = Boxed_int_ { value: 4 };
122191
assert!(((unsafe { Boxed_int_::plus(&bi, 5,) }) == (9)));

0 commit comments

Comments
 (0)