Skip to content

Commit 2944b7d

Browse files
committed
Fix class template translations
1 parent 6d484b8 commit 2944b7d

5 files changed

Lines changed: 180 additions & 15 deletions

File tree

cpp2rust/converter/converter.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3476,7 +3476,7 @@ std::string Converter::GetRecordName(const clang::NamedDecl *decl) const {
34763476
if (auto it = inner_structs_.find(ID); it != inner_structs_.end()) {
34773477
return it->second;
34783478
}
3479-
return ReplaceAll(Mapper::ToString(decl), "::", "_");
3479+
return Mapper::ToRustName(Mapper::ToString(Mapper::GetTypeForDecl(decl)));
34803480
}
34813481

34823482
std::vector<const char *>

cpp2rust/converter/mapper.cpp

Lines changed: 33 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -723,9 +723,30 @@ bool ParamIsPointer(const clang::Expr *expr, unsigned index) {
723723
return GetParamInfo(expr, index).is_pointer();
724724
}
725725

726+
clang::QualType GetTypeForDecl(const clang::NamedDecl *decl) {
727+
if (const auto *spec =
728+
llvm::dyn_cast<clang::ClassTemplateSpecializationDecl>(decl)) {
729+
llvm::ArrayRef<clang::TemplateArgument> args =
730+
spec->getTemplateArgs().asArray();
731+
llvm::SmallVector<clang::TemplateArgument, 4> canon(args.begin(),
732+
args.end());
733+
ctx_->canonicalizeTemplateArguments(canon);
734+
735+
return ctx_->getTemplateSpecializationType(
736+
clang::ElaboratedTypeKeyword::None,
737+
clang::TemplateName(spec->getSpecializedTemplate()), args, canon);
738+
}
739+
740+
const auto *rdecl = llvm::dyn_cast<clang::TagDecl>(decl);
741+
assert(rdecl && "Unsupported decl type");
742+
743+
return ctx_->getTagType(clang::ElaboratedTypeKeyword::None,
744+
rdecl->getQualifier(), rdecl, /*OwnsTag*/ false);
745+
}
746+
726747
void AddRuleForUserDefinedType(clang::NamedDecl *decl) {
727-
auto cpp_name = ToString(decl);
728-
auto rs_name = ReplaceAll(cpp_name, "::", "_");
748+
auto cpp_name = ToString(GetTypeForDecl(decl));
749+
auto rs_name = ToRustName(cpp_name);
729750

730751
AddTypeRule(cpp_name, TranslationRule::TypeRule::Plain(rs_name));
731752

@@ -767,6 +788,16 @@ void AddRuleForUserDefinedType(clang::NamedDecl *decl) {
767788
}
768789
}
769790

791+
std::string ToRustName(std::string name) {
792+
size_t pos = 0;
793+
std::string chars = "<>, ";
794+
while ((pos = name.find_first_of(chars, pos)) != std::string::npos) {
795+
name.replace(pos, 1, 1, '_');
796+
++pos;
797+
}
798+
return ReplaceAll(name, "::", "_");
799+
}
800+
770801
std::string ToString(clang::QualType qual_type, ScalarSugar sugar) {
771802
assert(ctx_);
772803

cpp2rust/converter/mapper.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,10 +43,12 @@ enum class ScalarSugar {
4343
kPreserve,
4444
};
4545

46+
clang::QualType GetTypeForDecl(const clang::NamedDecl *decl);
4647
std::string ToString(clang::QualType qual_type,
4748
ScalarSugar sugar = ScalarSugar::kDesugar);
4849
std::string ToString(const clang::Expr *expr);
4950
std::string ToString(const clang::NamedDecl *decl);
51+
std::string ToRustName(std::string name);
5052

5153
void LoadTranslationRules(Model model, clang::ASTContext &ctx,
5254
const std::string &rules_dir);

tests/unit/out/refcount/class_templates.rs

Lines changed: 81 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -7,10 +7,10 @@ use std::io::{Read, Seek, Write};
77
use std::os::fd::AsFd;
88
use std::rc::{Rc, Weak};
99
#[derive(Default)]
10-
pub struct MyContainer {
10+
pub struct MyContainer_int_ {
1111
vec_: Value<Vec<i32>>,
1212
}
13-
impl MyContainer {
13+
impl MyContainer_int_ {
1414
pub fn empty(&self) -> bool {
1515
return (*self.vec_.borrow()).is_empty();
1616
}
@@ -34,20 +34,94 @@ impl MyContainer {
3434
};
3535
}
3636
}
37-
impl Clone for MyContainer {
37+
impl Clone for MyContainer_int_ {
3838
fn clone(&self) -> Self {
3939
let mut this = Self {
4040
vec_: Rc::new(RefCell::new((*self.vec_.borrow()).clone())),
4141
};
4242
this
4343
}
4444
}
45-
impl ByteRepr for MyContainer {}
45+
impl ByteRepr for MyContainer_int_ {}
46+
#[derive(Default)]
47+
pub struct MyContainer_char_ {
48+
vec_: Value<Vec<u8>>,
49+
}
50+
impl MyContainer_char_ {
51+
pub fn empty(&self) -> bool {
52+
return (*self.vec_.borrow()).is_empty();
53+
}
54+
pub fn size(&self) -> usize {
55+
return (*self.vec_.borrow()).len();
56+
}
57+
pub fn back_const(&self) -> Ptr<u8> {
58+
return (self.vec_.as_pointer() as Ptr<u8>).to_last();
59+
}
60+
pub fn back(&self) -> Ptr<u8> {
61+
return (self.vec_.as_pointer() as Ptr<u8>).to_last();
62+
}
63+
pub fn pop_back(&self) {
64+
(*self.vec_.borrow_mut()).pop();
65+
return;
66+
}
67+
pub fn push_back(&self, item: Ptr<u8>) {
68+
{
69+
let a0_clone = (item.read()).clone();
70+
(*self.vec_.borrow_mut()).push(a0_clone)
71+
};
72+
}
73+
}
74+
impl Clone for MyContainer_char_ {
75+
fn clone(&self) -> Self {
76+
let mut this = Self {
77+
vec_: Rc::new(RefCell::new((*self.vec_.borrow()).clone())),
78+
};
79+
this
80+
}
81+
}
82+
impl ByteRepr for MyContainer_char_ {}
83+
#[derive(Default)]
84+
pub struct MyContainer_float_ {
85+
vec_: Value<Vec<f32>>,
86+
}
87+
impl MyContainer_float_ {
88+
pub fn empty(&self) -> bool {
89+
return (*self.vec_.borrow()).is_empty();
90+
}
91+
pub fn size(&self) -> usize {
92+
return (*self.vec_.borrow()).len();
93+
}
94+
pub fn back_const(&self) -> Ptr<f32> {
95+
return (self.vec_.as_pointer() as Ptr<f32>).to_last();
96+
}
97+
pub fn back(&self) -> Ptr<f32> {
98+
return (self.vec_.as_pointer() as Ptr<f32>).to_last();
99+
}
100+
pub fn pop_back(&self) {
101+
(*self.vec_.borrow_mut()).pop();
102+
return;
103+
}
104+
pub fn push_back(&self, item: Ptr<f32>) {
105+
{
106+
let a0_clone = (item.read()).clone();
107+
(*self.vec_.borrow_mut()).push(a0_clone)
108+
};
109+
}
110+
}
111+
impl Clone for MyContainer_float_ {
112+
fn clone(&self) -> Self {
113+
let mut this = Self {
114+
vec_: Rc::new(RefCell::new((*self.vec_.borrow()).clone())),
115+
};
116+
this
117+
}
118+
}
119+
impl ByteRepr for MyContainer_float_ {}
46120
pub fn main() {
47121
std::process::exit(main_0());
48122
}
49123
fn main_0() -> i32 {
50-
let imc: Value<MyContainer> = Rc::new(RefCell::new(<MyContainer>::default()));
124+
let imc: Value<MyContainer_int_> = Rc::new(RefCell::new(<MyContainer_int_>::default()));
51125
assert!(({ (*imc.borrow()).empty() }));
52126
({
53127
let _item: Value<i32> = Rc::new(RefCell::new(1));
@@ -58,7 +132,7 @@ fn main_0() -> i32 {
58132
);
59133
({ (*imc.borrow()).pop_back() });
60134
assert!(({ (*imc.borrow()).empty() }));
61-
let cmc: Value<MyContainer> = Rc::new(RefCell::new(<MyContainer>::default()));
135+
let cmc: Value<MyContainer_char_> = Rc::new(RefCell::new(<MyContainer_char_>::default()));
62136
assert!(({ (*cmc.borrow()).empty() }));
63137
({
64138
let _item: Value<u8> = Rc::new(RefCell::new(('a' as u8)));
@@ -70,7 +144,7 @@ fn main_0() -> i32 {
70144
);
71145
({ (*cmc.borrow()).pop_back() });
72146
assert!(({ (*cmc.borrow()).empty() }));
73-
let fmc: Value<MyContainer> = Rc::new(RefCell::new(<MyContainer>::default()));
147+
let fmc: Value<MyContainer_float_> = Rc::new(RefCell::new(<MyContainer_float_>::default()));
74148
assert!(({ (*fmc.borrow()).empty() }));
75149
({
76150
let _item: Value<f32> = Rc::new(RefCell::new((('a' as u8) as f32)));

tests/unit/out/unsafe/class_templates.rs

Lines changed: 63 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -8,10 +8,10 @@ use std::os::fd::{AsFd, FromRawFd, IntoRawFd};
88
use std::rc::Rc;
99
#[repr(C)]
1010
#[derive(Clone, Default)]
11-
pub struct MyContainer {
11+
pub struct MyContainer_int_ {
1212
vec_: Vec<i32>,
1313
}
14-
impl MyContainer {
14+
impl MyContainer_int_ {
1515
pub unsafe fn empty(&self) -> bool {
1616
return self.vec_.is_empty();
1717
}
@@ -35,13 +35,71 @@ impl MyContainer {
3535
};
3636
}
3737
}
38+
#[repr(C)]
39+
#[derive(Clone, Default)]
40+
pub struct MyContainer_char_ {
41+
vec_: Vec<u8>,
42+
}
43+
impl MyContainer_char_ {
44+
pub unsafe fn empty(&self) -> bool {
45+
return self.vec_.is_empty();
46+
}
47+
pub unsafe fn size(&self) -> usize {
48+
return self.vec_.len();
49+
}
50+
pub unsafe fn back_const(&self) -> *const u8 {
51+
return ((self.vec_).last().unwrap());
52+
}
53+
pub unsafe fn back(&mut self) -> *mut u8 {
54+
return ((self.vec_).last_mut().unwrap());
55+
}
56+
pub unsafe fn pop_back(&mut self) {
57+
self.vec_.pop();
58+
return;
59+
}
60+
pub unsafe fn push_back(&mut self, item: *const u8) {
61+
{
62+
let a0_clone = (*item).clone();
63+
self.vec_.push(a0_clone)
64+
};
65+
}
66+
}
67+
#[repr(C)]
68+
#[derive(Clone, Default)]
69+
pub struct MyContainer_float_ {
70+
vec_: Vec<f32>,
71+
}
72+
impl MyContainer_float_ {
73+
pub unsafe fn empty(&self) -> bool {
74+
return self.vec_.is_empty();
75+
}
76+
pub unsafe fn size(&self) -> usize {
77+
return self.vec_.len();
78+
}
79+
pub unsafe fn back_const(&self) -> *const f32 {
80+
return ((self.vec_).last().unwrap());
81+
}
82+
pub unsafe fn back(&mut self) -> *mut f32 {
83+
return ((self.vec_).last_mut().unwrap());
84+
}
85+
pub unsafe fn pop_back(&mut self) {
86+
self.vec_.pop();
87+
return;
88+
}
89+
pub unsafe fn push_back(&mut self, item: *const f32) {
90+
{
91+
let a0_clone = (*item).clone();
92+
self.vec_.push(a0_clone)
93+
};
94+
}
95+
}
3896
pub fn main() {
3997
unsafe {
4098
std::process::exit(main_0() as i32);
4199
}
42100
}
43101
unsafe fn main_0() -> i32 {
44-
let mut imc: MyContainer = <MyContainer>::default();
102+
let mut imc: MyContainer_int_ = <MyContainer_int_>::default();
45103
assert!((unsafe { imc.empty() }));
46104
(unsafe {
47105
let mut _item = 1;
@@ -50,7 +108,7 @@ unsafe fn main_0() -> i32 {
50108
assert!(((unsafe { imc.size() }) == (1_usize)) && ((*(unsafe { imc.back() })) == (1)));
51109
(unsafe { imc.pop_back() });
52110
assert!((unsafe { imc.empty() }));
53-
let mut cmc: MyContainer = <MyContainer>::default();
111+
let mut cmc: MyContainer_char_ = <MyContainer_char_>::default();
54112
assert!((unsafe { cmc.empty() }));
55113
(unsafe {
56114
let mut _item = ('a' as u8);
@@ -62,7 +120,7 @@ unsafe fn main_0() -> i32 {
62120
);
63121
(unsafe { cmc.pop_back() });
64122
assert!((unsafe { cmc.empty() }));
65-
let mut fmc: MyContainer = <MyContainer>::default();
123+
let mut fmc: MyContainer_float_ = <MyContainer_float_>::default();
66124
assert!((unsafe { fmc.empty() }));
67125
(unsafe {
68126
let mut _item = (('a' as u8) as f32);

0 commit comments

Comments
 (0)