Skip to content

Commit 989890e

Browse files
committed
Fix naming clash between functoins and specializations
1 parent dab0234 commit 989890e

5 files changed

Lines changed: 219 additions & 20 deletions

File tree

‎cpp2rust/converter/converter_lib.cpp‎

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -535,13 +535,24 @@ static std::string GetParamSignature(const clang::Decl *decl) {
535535
}
536536

537537
static std::string GetLexicalSpecializationID(const clang::Decl *decl) {
538+
std::string id;
538539
if (const auto *spec =
539540
clang::dyn_cast<clang::ClassTemplateSpecializationDecl>(
540541
decl->getLexicalDeclContext());
541542
spec && decl->getLexicalDeclContext() != decl->getDeclContext()) {
542-
return Mapper::ToString(Mapper::GetTypeForDecl(spec));
543+
id += Mapper::ToString(Mapper::GetTypeForDecl(spec));
543544
}
544-
return {};
545+
for (const auto *dc = decl->getDeclContext(); dc; dc = dc->getParent()) {
546+
if (const auto *spec =
547+
clang::dyn_cast<clang::ClassTemplateSpecializationDecl>(dc)) {
548+
id += Mapper::ToString(Mapper::GetTypeForDecl(spec));
549+
}
550+
if (const auto *fn = clang::dyn_cast<clang::FunctionDecl>(dc);
551+
fn && fn->getTemplateSpecializationArgs()) {
552+
id += clang::ASTNameGenerator(fn->getASTContext()).getName(fn);
553+
}
554+
}
555+
return id;
545556
}
546557

547558
std::string GetID(const clang::Decl *decl) {
@@ -623,6 +634,10 @@ std::string GetNamedDeclAsString(const clang::NamedDecl *decl) {
623634
var && (var->isFileVarDecl() || var->isStaticLocal())) {
624635
id = GetDeclId(var->getCanonicalDecl(),
625636
var->getFormalLinkage() != clang::Linkage::External);
637+
} else if (auto *tag = clang::dyn_cast<clang::TagDecl>(decl);
638+
tag && tag->getDeclContext()->isFunctionOrMethod()) {
639+
id =
640+
type_mapping.try_emplace(GetID(tag), type_mapping.size()).first->second;
626641
}
627642
if (id) {
628643
name += '_';

‎cpp2rust/converter/mapper.cpp‎

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -882,6 +882,12 @@ std::string ToString(clang::QualType qual_type, ScalarSugar sugar) {
882882
return ToString(clang::cast<clang::NamedDecl>(tag));
883883
}
884884

885+
if (auto *tag = qual_type->getAsTagDecl();
886+
tag && tag->getIdentifier() &&
887+
tag->getDeclContext()->isFunctionOrMethod()) {
888+
return GetNamedDeclAsString(tag);
889+
}
890+
885891
if (auto renamed = DisambiguateAnonymousTag(qual_type->getAsTagDecl());
886892
!renamed.empty()) {
887893
return renamed;

‎tests/unit/local_record_template.cpp‎

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,12 +6,32 @@ namespace ns {
66
template <typename T> int twice(T t) { return t.x * 2; }
77
}
88

9+
template <typename T> int wrap(T v) {
10+
struct Local {
11+
T x;
12+
};
13+
Local l{v};
14+
return get(l);
15+
}
16+
17+
int other() {
18+
struct Local {
19+
long x;
20+
long y;
21+
};
22+
Local l{3, 4};
23+
return get(l) + (int)l.y;
24+
}
25+
926
int main() {
1027
struct Local {
1128
int x;
1229
};
1330
Local l{7};
1431
assert(get(l) == 7);
1532
assert(ns::twice(l) == 14);
33+
assert(other() == 7);
34+
assert(wrap(5) == 5);
35+
assert(wrap(6L) == 6);
1636
return 0;
1737
}

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

Lines changed: 130 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -6,39 +6,157 @@ use std::io::prelude::*;
66
use std::io::{Read, Seek, Write};
77
use std::os::fd::AsFd;
88
use std::rc::{Rc, Weak};
9-
pub fn get_0(t: Local) -> i32 {
10-
let t: Value<Local> = Rc::new(RefCell::new(t));
9+
pub fn get_0(t: Local_1) -> i32 {
10+
let t: Value<Local_1> = Rc::new(RefCell::new(t));
11+
return ((*(*t.borrow()).x.borrow()) as i32);
12+
}
13+
pub fn get_2(t: Local_3) -> i32 {
14+
let t: Value<Local_3> = Rc::new(RefCell::new(t));
15+
return (*(*t.borrow()).x.borrow());
16+
}
17+
pub fn get_4(t: Local_5) -> i32 {
18+
let t: Value<Local_5> = Rc::new(RefCell::new(t));
1119
return (*(*t.borrow()).x.borrow());
1220
}
13-
pub fn twice_1(t: Local) -> i32 {
14-
let t: Value<Local> = Rc::new(RefCell::new(t));
21+
pub fn get_6(t: Local_7) -> i32 {
22+
let t: Value<Local_7> = Rc::new(RefCell::new(t));
23+
return ((*(*t.borrow()).x.borrow()) as i32);
24+
}
25+
pub fn twice_8(t: Local_3) -> i32 {
26+
let t: Value<Local_3> = Rc::new(RefCell::new(t));
1527
return ((*(*t.borrow()).x.borrow()) * 2);
1628
}
29+
pub fn wrap_9(v: i32) -> i32 {
30+
let v: Value<i32> = Rc::new(RefCell::new(v));
31+
let l: Value<Local_5> = Rc::new(RefCell::new(Local_5 {
32+
x: Rc::new(RefCell::new((*v.borrow()))),
33+
}));
34+
return ({ get_4((*l.borrow()).clone()) });
35+
}
36+
pub fn wrap_10(v: i64) -> i32 {
37+
let v: Value<i64> = Rc::new(RefCell::new(v));
38+
let l: Value<Local_7> = Rc::new(RefCell::new(Local_7 {
39+
x: Rc::new(RefCell::new((*v.borrow()))),
40+
}));
41+
return ({ get_6((*l.borrow()).clone()) });
42+
}
43+
#[derive(Default)]
44+
pub struct Local_5 {
45+
pub x: Value<i32>,
46+
}
47+
impl Clone for Local_5 {
48+
fn clone(&self) -> Self {
49+
let __this: Value<Local_5> = Rc::new(RefCell::new(Self {
50+
x: Rc::new(RefCell::new((*self.x.borrow()))),
51+
}));
52+
let this: Ptr<Local_5> = __this.as_pointer();
53+
Rc::try_unwrap(__this).ok().unwrap().into_inner()
54+
}
55+
}
56+
impl ByteRepr for Local_5 {
57+
fn byte_size() -> usize {
58+
4
59+
}
60+
fn to_bytes(&self, buf: &mut [u8]) {
61+
(*self.x.borrow()).to_bytes(&mut buf[0..4]);
62+
}
63+
fn from_bytes(buf: &[u8]) -> Self {
64+
Self {
65+
x: Rc::new(RefCell::new(<i32>::from_bytes(&buf[0..4]))),
66+
}
67+
}
68+
}
69+
#[derive(Default)]
70+
pub struct Local_7 {
71+
pub x: Value<i64>,
72+
}
73+
impl Clone for Local_7 {
74+
fn clone(&self) -> Self {
75+
let __this: Value<Local_7> = Rc::new(RefCell::new(Self {
76+
x: Rc::new(RefCell::new((*self.x.borrow()))),
77+
}));
78+
let this: Ptr<Local_7> = __this.as_pointer();
79+
Rc::try_unwrap(__this).ok().unwrap().into_inner()
80+
}
81+
}
82+
impl ByteRepr for Local_7 {
83+
fn byte_size() -> usize {
84+
8
85+
}
86+
fn to_bytes(&self, buf: &mut [u8]) {
87+
(*self.x.borrow()).to_bytes(&mut buf[0..8]);
88+
}
89+
fn from_bytes(buf: &[u8]) -> Self {
90+
Self {
91+
x: Rc::new(RefCell::new(<i64>::from_bytes(&buf[0..8]))),
92+
}
93+
}
94+
}
95+
pub fn other_11() -> i32 {
96+
let l: Value<Local_1> = Rc::new(RefCell::new(Local_1 {
97+
x: Rc::new(RefCell::new(3_i64)),
98+
y: Rc::new(RefCell::new(4_i64)),
99+
}));
100+
return (({ get_0((*l.borrow()).clone()) }) + ((*(*l.borrow()).y.borrow()) as i32));
101+
}
102+
#[derive(Default)]
103+
pub struct Local_1 {
104+
pub x: Value<i64>,
105+
pub y: Value<i64>,
106+
}
107+
impl Clone for Local_1 {
108+
fn clone(&self) -> Self {
109+
let __this: Value<Local_1> = Rc::new(RefCell::new(Self {
110+
x: Rc::new(RefCell::new((*self.x.borrow()))),
111+
y: Rc::new(RefCell::new((*self.y.borrow()))),
112+
}));
113+
let this: Ptr<Local_1> = __this.as_pointer();
114+
Rc::try_unwrap(__this).ok().unwrap().into_inner()
115+
}
116+
}
117+
impl ByteRepr for Local_1 {
118+
fn byte_size() -> usize {
119+
16
120+
}
121+
fn to_bytes(&self, buf: &mut [u8]) {
122+
(*self.x.borrow()).to_bytes(&mut buf[0..8]);
123+
(*self.y.borrow()).to_bytes(&mut buf[8..16]);
124+
}
125+
fn from_bytes(buf: &[u8]) -> Self {
126+
Self {
127+
x: Rc::new(RefCell::new(<i64>::from_bytes(&buf[0..8]))),
128+
y: Rc::new(RefCell::new(<i64>::from_bytes(&buf[8..16]))),
129+
}
130+
}
131+
}
17132
pub fn main() {
18133
std::process::exit(main_0());
19134
}
20135
fn main_0() -> i32 {
21-
let l: Value<Local> = Rc::new(RefCell::new(Local {
136+
let l: Value<Local_3> = Rc::new(RefCell::new(Local_3 {
22137
x: Rc::new(RefCell::new(7)),
23138
}));
24-
assert!((({ get_0((*l.borrow()).clone(),) }) == 7));
25-
assert!((({ twice_1((*l.borrow()).clone(),) }) == 14));
139+
assert!((({ get_2((*l.borrow()).clone(),) }) == 7));
140+
assert!((({ twice_8((*l.borrow()).clone(),) }) == 14));
141+
assert!((({ other_11() }) == 7));
142+
assert!((({ wrap_9(5,) }) == 5));
143+
assert!((({ wrap_10(6_i64,) }) == 6));
26144
return 0;
27145
}
28146
#[derive(Default)]
29-
pub struct Local {
147+
pub struct Local_3 {
30148
pub x: Value<i32>,
31149
}
32-
impl Clone for Local {
150+
impl Clone for Local_3 {
33151
fn clone(&self) -> Self {
34-
let __this: Value<Local> = Rc::new(RefCell::new(Self {
152+
let __this: Value<Local_3> = Rc::new(RefCell::new(Self {
35153
x: Rc::new(RefCell::new((*self.x.borrow()))),
36154
}));
37-
let this: Ptr<Local> = __this.as_pointer();
155+
let this: Ptr<Local_3> = __this.as_pointer();
38156
Rc::try_unwrap(__this).ok().unwrap().into_inner()
39157
}
40158
}
41-
impl ByteRepr for Local {
159+
impl ByteRepr for Local_3 {
42160
fn byte_size() -> usize {
43161
4
44162
}

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

Lines changed: 46 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -6,25 +6,65 @@ use std::collections::BTreeMap;
66
use std::io::{Read, Seek, Write};
77
use std::os::fd::{AsFd, FromRawFd, IntoRawFd};
88
use std::rc::Rc;
9-
pub unsafe fn get_0(mut t: Local) -> i32 {
9+
pub unsafe fn get_0(mut t: Local_1) -> i32 {
10+
return (t.x as i32);
11+
}
12+
pub unsafe fn get_2(mut t: Local_3) -> i32 {
13+
return t.x;
14+
}
15+
pub unsafe fn get_4(mut t: Local_5) -> i32 {
1016
return t.x;
1117
}
12-
pub unsafe fn twice_1(mut t: Local) -> i32 {
18+
pub unsafe fn get_6(mut t: Local_7) -> i32 {
19+
return (t.x as i32);
20+
}
21+
pub unsafe fn twice_8(mut t: Local_3) -> i32 {
1322
return ((t.x) * (2));
1423
}
24+
pub unsafe fn wrap_9(mut v: i32) -> i32 {
25+
let mut l: Local_5 = Local_5 { x: v };
26+
return (unsafe { get_4(l) });
27+
}
28+
pub unsafe fn wrap_10(mut v: i64) -> i32 {
29+
let mut l: Local_7 = Local_7 { x: v };
30+
return (unsafe { get_6(l) });
31+
}
32+
#[repr(C)]
33+
#[derive(Copy, Clone, Default)]
34+
pub struct Local_5 {
35+
pub x: i32,
36+
}
37+
#[repr(C)]
38+
#[derive(Copy, Clone, Default)]
39+
pub struct Local_7 {
40+
pub x: i64,
41+
}
42+
pub unsafe fn other_11() -> i32 {
43+
let mut l: Local_1 = Local_1 { x: 3_i64, y: 4_i64 };
44+
return ((unsafe { get_0(l) }) + (l.y as i32));
45+
}
46+
#[repr(C)]
47+
#[derive(Copy, Clone, Default)]
48+
pub struct Local_1 {
49+
pub x: i64,
50+
pub y: i64,
51+
}
1552
pub fn main() {
1653
unsafe {
1754
std::process::exit(main_0() as i32);
1855
}
1956
}
2057
unsafe fn main_0() -> i32 {
21-
let mut l: Local = Local { x: 7 };
22-
assert!(((unsafe { get_0(l,) }) == (7)));
23-
assert!(((unsafe { twice_1(l,) }) == (14)));
58+
let mut l: Local_3 = Local_3 { x: 7 };
59+
assert!(((unsafe { get_2(l,) }) == (7)));
60+
assert!(((unsafe { twice_8(l,) }) == (14)));
61+
assert!(((unsafe { other_11() }) == (7)));
62+
assert!(((unsafe { wrap_9(5,) }) == (5)));
63+
assert!(((unsafe { wrap_10(6_i64,) }) == (6)));
2464
return 0;
2565
}
2666
#[repr(C)]
2767
#[derive(Copy, Clone, Default)]
28-
pub struct Local {
68+
pub struct Local_3 {
2969
pub x: i32,
3070
}

0 commit comments

Comments
 (0)