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
39 changes: 12 additions & 27 deletions cpp2rust/converter/converter_lib.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -328,25 +328,6 @@ unsigned GetArraySize(clang::QualType array_type) {
return constant_array_ty->getSize().getZExtValue();
}

unsigned GetAnonIndex(const clang::NamedDecl *decl) {
if (auto *parent =
clang::dyn_cast<clang::RecordDecl>(decl->getDeclContext())) {
unsigned counter = 0;
for (auto *d : parent->decls()) {
if (d == decl) {
return counter;
}
auto *named = clang::dyn_cast<clang::NamedDecl>(d);
if (named && named->getKind() == decl->getKind() &&
named->getName().empty()) {
counter++;
}
}
return counter;
}
return 0;
}

static std::string GetLocationID(const clang::Decl *decl) {
return GetFileName(decl) + std::to_string(GetLineNumber(decl)) +
std::to_string(GetColumnNumber(decl));
Expand All @@ -373,15 +354,19 @@ std::string GetNamedDeclAsString(const clang::NamedDecl *decl) {
auto name = decl->getDeclName().isIdentifier() ? decl->getName().str()
: decl->getNameAsString();

// Anonymous record field
if (auto *field = clang::dyn_cast<clang::FieldDecl>(decl);
field && name.empty()) {
const clang::NamedDecl *target = field;
if (auto *record = field->getType()->getAsRecordDecl();
record && !record->getIdentifier()) {
target = record;
// Anonymous record
if (name.empty() && (clang::isa<clang::RecordDecl>(decl) ||
clang::isa<clang::FieldDecl>(decl))) {
const clang::NamedDecl *target = decl;
if (auto *field = clang::dyn_cast<clang::FieldDecl>(decl)) {
if (auto *record = field->getType()->getAsRecordDecl();
record && !record->getIdentifier()) {
target = record;
}
}
return std::format("anon_{}", GetAnonIndex(target));
return std::format(
"anon_{}", type_mapping.try_emplace(GetID(target), type_mapping.size())
.first->second);
}

if (auto *fn = clang::dyn_cast<clang::FunctionDecl>(decl)) {
Expand Down
2 changes: 0 additions & 2 deletions cpp2rust/converter/converter_lib.h
Original file line number Diff line number Diff line change
Expand Up @@ -87,8 +87,6 @@ std::string GetID(const clang::Decl *decl);

std::string GetNamedDeclAsString(const clang::NamedDecl *decl);

unsigned GetAnonIndex(const clang::NamedDecl *decl);

const char *AccessSpecifierAsString(clang::AccessSpecifier spec);

template <class T> llvm::SmallString<16> GetNumAsString(const T &num) {
Expand Down
14 changes: 1 addition & 13 deletions cpp2rust/converter/mapper.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -571,18 +571,6 @@ std::string normalizeTranslationRule(std::string rule) {
return rule;
}

static std::string synthesizeAnonRecordName(const clang::RecordDecl *record) {
std::string parent_name;
if (auto *parent =
clang::dyn_cast<clang::RecordDecl>(record->getDeclContext())) {
parent_name = parent->getIdentifier()
? parent->getIdentifier()->getName().str()
: synthesizeAnonRecordName(parent);
parent_name += '_';
}
return std::format("{}anon_{}", parent_name, GetAnonIndex(record));
}

} // namespace

PushASTContext::PushASTContext(clang::ASTContext &ctx) : prev_(ctx_) {
Expand Down Expand Up @@ -760,7 +748,7 @@ std::string ToString(const clang::NamedDecl *decl) {
if (auto *typedef_decl = record->getTypedefNameForAnonDecl()) {
return ToString(clang::cast<clang::NamedDecl>(typedef_decl));
}
return synthesizeAnonRecordName(record);
return GetNamedDeclAsString(record);
}

if (auto *enum_decl = clang::dyn_cast<clang::EnumDecl>(decl);
Expand Down
27 changes: 27 additions & 0 deletions tests/unit/local_anon_struct_collision.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
#include <assert.h>

int first(void) {
struct {
int x;
int y;
} p;
p.x = 1;
p.y = 2;
return p.x + p.y;
}

int second(void) {
struct {
long a;
long b;
} q;
q.a = 10;
q.b = 20;
return (int)(q.a + q.b);
}

int main(void) {
assert(first() == 3);
assert(second() == 30);
return 0;
}
74 changes: 37 additions & 37 deletions tests/unit/out/refcount/anonymous-struct.rs
Original file line number Diff line number Diff line change
Expand Up @@ -33,11 +33,11 @@ impl ByteRepr for Outer_Named {
}
}
#[derive(Default)]
pub struct Outer_anon_0 {
pub struct anon_0 {
pub c: Value<i32>,
pub d: Value<i32>,
}
impl Clone for Outer_anon_0 {
impl Clone for anon_0 {
fn clone(&self) -> Self {
let mut this = Self {
c: Rc::new(RefCell::new((*self.c.borrow()))),
Expand All @@ -46,7 +46,7 @@ impl Clone for Outer_anon_0 {
this
}
}
impl ByteRepr for Outer_anon_0 {
impl ByteRepr for anon_0 {
fn to_bytes(&self, buf: &mut [u8]) {
(*self.c.borrow()).to_bytes(&mut buf[0..4]);
(*self.d.borrow()).to_bytes(&mut buf[4..8]);
Expand All @@ -59,11 +59,11 @@ impl ByteRepr for Outer_anon_0 {
}
}
#[derive(Default)]
pub struct Outer_anon_1 {
pub struct anon_1 {
pub g: Value<i32>,
pub h: Value<i32>,
}
impl Clone for Outer_anon_1 {
impl Clone for anon_1 {
fn clone(&self) -> Self {
let mut this = Self {
g: Rc::new(RefCell::new((*self.g.borrow()))),
Expand All @@ -72,7 +72,7 @@ impl Clone for Outer_anon_1 {
this
}
}
impl ByteRepr for Outer_anon_1 {
impl ByteRepr for anon_1 {
fn to_bytes(&self, buf: &mut [u8]) {
(*self.g.borrow()).to_bytes(&mut buf[0..4]);
(*self.h.borrow()).to_bytes(&mut buf[4..8]);
Expand All @@ -85,11 +85,11 @@ impl ByteRepr for Outer_anon_1 {
}
}
#[derive(Default)]
pub struct Outer_anon_2 {
pub struct anon_2 {
pub e: Value<i32>,
pub f: Value<i32>,
}
impl Clone for Outer_anon_2 {
impl Clone for anon_2 {
fn clone(&self) -> Self {
let mut this = Self {
e: Rc::new(RefCell::new((*self.e.borrow()))),
Expand All @@ -98,7 +98,7 @@ impl Clone for Outer_anon_2 {
this
}
}
impl ByteRepr for Outer_anon_2 {
impl ByteRepr for anon_2 {
fn to_bytes(&self, buf: &mut [u8]) {
(*self.e.borrow()).to_bytes(&mut buf[0..4]);
(*self.f.borrow()).to_bytes(&mut buf[4..8]);
Expand All @@ -111,18 +111,18 @@ impl ByteRepr for Outer_anon_2 {
}
}
#[derive(Default)]
pub struct Outer_anon_3_anon_0 {
pub struct anon_4 {
pub j: Value<i32>,
}
impl Clone for Outer_anon_3_anon_0 {
impl Clone for anon_4 {
fn clone(&self) -> Self {
let mut this = Self {
j: Rc::new(RefCell::new((*self.j.borrow()))),
};
this
}
}
impl ByteRepr for Outer_anon_3_anon_0 {
impl ByteRepr for anon_4 {
fn to_bytes(&self, buf: &mut [u8]) {
(*self.j.borrow()).to_bytes(&mut buf[0..4]);
}
Expand All @@ -133,18 +133,18 @@ impl ByteRepr for Outer_anon_3_anon_0 {
}
}
#[derive(Default)]
pub struct Outer_anon_3_anon_1 {
pub struct anon_5 {
pub k: Value<i32>,
}
impl Clone for Outer_anon_3_anon_1 {
impl Clone for anon_5 {
fn clone(&self) -> Self {
let mut this = Self {
k: Rc::new(RefCell::new((*self.k.borrow()))),
};
this
}
}
impl ByteRepr for Outer_anon_3_anon_1 {
impl ByteRepr for anon_5 {
fn to_bytes(&self, buf: &mut [u8]) {
(*self.k.borrow()).to_bytes(&mut buf[0..4]);
}
Expand All @@ -155,29 +155,29 @@ impl ByteRepr for Outer_anon_3_anon_1 {
}
}
#[derive(Default)]
pub struct Outer_anon_3 {
pub struct anon_3 {
pub i: Value<i32>,
pub inner_named: Value<Outer_anon_3_anon_0>,
pub anon_1: Value<Outer_anon_3_anon_1>,
pub inner_named: Value<anon_4>,
pub anon_5: Value<anon_5>,
}
impl Clone for Outer_anon_3 {
impl Clone for anon_3 {
fn clone(&self) -> Self {
let mut this = Self {
i: Rc::new(RefCell::new((*self.i.borrow()))),
inner_named: Rc::new(RefCell::new((*self.inner_named.borrow()).clone())),
anon_1: Rc::new(RefCell::new((*self.anon_1.borrow()).clone())),
anon_5: Rc::new(RefCell::new((*self.anon_5.borrow()).clone())),
};
this
}
}
impl ByteRepr for Outer_anon_3 {}
impl ByteRepr for anon_3 {}
#[derive(Default)]
pub struct Outer {
pub named: Value<Outer_Named>,
pub anonymous_named_0: Value<Outer_anon_0>,
pub anonymous_named_1: Value<Outer_anon_1>,
pub anon_2: Value<Outer_anon_2>,
pub anon_3: Value<Outer_anon_3>,
pub anonymous_named_0: Value<anon_0>,
pub anonymous_named_1: Value<anon_1>,
pub anon_2: Value<anon_2>,
pub anon_3: Value<anon_3>,
}
impl Clone for Outer {
fn clone(&self) -> Self {
Expand All @@ -201,24 +201,24 @@ fn main_0() -> i32 {
a: Rc::new(RefCell::new(<i32>::default())),
b: Rc::new(RefCell::new(<i32>::default())),
})),
anonymous_named_0: Rc::new(RefCell::new(Outer_anon_0 {
anonymous_named_0: Rc::new(RefCell::new(anon_0 {
c: Rc::new(RefCell::new(<i32>::default())),
d: Rc::new(RefCell::new(<i32>::default())),
})),
anonymous_named_1: Rc::new(RefCell::new(Outer_anon_1 {
anonymous_named_1: Rc::new(RefCell::new(anon_1 {
g: Rc::new(RefCell::new(<i32>::default())),
h: Rc::new(RefCell::new(<i32>::default())),
})),
anon_2: Rc::new(RefCell::new(Outer_anon_2 {
anon_2: Rc::new(RefCell::new(anon_2 {
e: Rc::new(RefCell::new(<i32>::default())),
f: Rc::new(RefCell::new(<i32>::default())),
})),
anon_3: Rc::new(RefCell::new(Outer_anon_3 {
anon_3: Rc::new(RefCell::new(anon_3 {
i: Rc::new(RefCell::new(<i32>::default())),
inner_named: Rc::new(RefCell::new(Outer_anon_3_anon_0 {
inner_named: Rc::new(RefCell::new(anon_4 {
j: Rc::new(RefCell::new(<i32>::default())),
})),
anon_1: Rc::new(RefCell::new(Outer_anon_3_anon_1 {
anon_5: Rc::new(RefCell::new(anon_5 {
k: Rc::new(RefCell::new(<i32>::default())),
})),
})),
Expand All @@ -235,7 +235,7 @@ fn main_0() -> i32 {
(*(*(*(*o.borrow()).anon_3.borrow()).inner_named.borrow())
.j
.borrow_mut()) = 10;
(*(*(*(*o.borrow()).anon_3.borrow()).anon_1.borrow())
(*(*(*(*o.borrow()).anon_3.borrow()).anon_5.borrow())
.k
.borrow_mut()) = 11;
assert!(((*(*(*o.borrow()).named.borrow()).a.borrow()) == 1));
Expand All @@ -254,17 +254,17 @@ fn main_0() -> i32 {
== 10)
);
assert!(
((*(*(*(*o.borrow()).anon_3.borrow()).anon_1.borrow())
((*(*(*(*o.borrow()).anon_3.borrow()).anon_5.borrow())
.k
.borrow())
== 11)
);
#[derive(Default)]
pub struct anon_0 {
pub struct anon_6 {
pub x: Value<i32>,
pub z: Value<i32>,
}
impl Clone for anon_0 {
impl Clone for anon_6 {
fn clone(&self) -> Self {
let mut this = Self {
x: Rc::new(RefCell::new((*self.x.borrow()))),
Expand All @@ -273,7 +273,7 @@ fn main_0() -> i32 {
this
}
}
impl ByteRepr for anon_0 {
impl ByteRepr for anon_6 {
fn to_bytes(&self, buf: &mut [u8]) {
(*self.x.borrow()).to_bytes(&mut buf[0..4]);
(*self.z.borrow()).to_bytes(&mut buf[4..8]);
Expand All @@ -285,7 +285,7 @@ fn main_0() -> i32 {
}
}
};
let s: Value<anon_0> = Rc::new(RefCell::new(<anon_0>::default()));
let s: Value<anon_6> = Rc::new(RefCell::new(<anon_6>::default()));
(*(*s.borrow()).x.borrow_mut()) = 1;
(*(*s.borrow()).z.borrow_mut()) = 2;
assert!(
Expand Down
Loading
Loading