Skip to content

Commit ec897e1

Browse files
authored
Name anonymous records (#521)
1 parent 6c4c340 commit ec897e1

5 files changed

Lines changed: 79 additions & 6 deletions

File tree

‎cpp2rust/converter/converter.cpp‎

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1363,7 +1363,11 @@ bool Converter::VisitDeclStmt(clang::DeclStmt *stmt) {
13631363
hoisted_records_ += std::move(buf).str();
13641364
continue;
13651365
}
1366-
Convert(decl);
1366+
if (var && var->isImplicit()) {
1367+
VisitVarDecl(var);
1368+
} else {
1369+
Convert(decl);
1370+
}
13671371
StrCat(token::kSemiColon);
13681372
}
13691373
return false;

‎cpp2rust/converter/converter_lib.cpp‎

Lines changed: 16 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -952,13 +952,24 @@ std::string GetNamedDeclAsString(const clang::NamedDecl *decl) {
952952
}
953953
}
954954

955+
auto *anonymous_record_var = clang::dyn_cast<clang::VarDecl>(decl);
956+
if (anonymous_record_var) {
957+
auto *record = anonymous_record_var->getType()->getAsRecordDecl();
958+
if (clang::isa<clang::ParmVarDecl>(decl) || !record ||
959+
record->getIdentifier()) {
960+
anonymous_record_var = nullptr;
961+
}
962+
}
963+
955964
// Anonymous record or enum
956-
if (name.empty() && (clang::isa<clang::RecordDecl>(decl) ||
957-
clang::isa<clang::FieldDecl>(decl) ||
958-
clang::isa<clang::EnumDecl>(decl))) {
965+
if (name.empty() &&
966+
(clang::isa<clang::RecordDecl>(decl) ||
967+
clang::isa<clang::FieldDecl>(decl) || anonymous_record_var ||
968+
clang::isa<clang::EnumDecl>(decl))) {
959969
const clang::NamedDecl *target = decl;
960-
if (auto *field = clang::dyn_cast<clang::FieldDecl>(decl)) {
961-
if (auto *record = field->getType()->getAsRecordDecl();
970+
if (clang::isa<clang::FieldDecl, clang::VarDecl>(decl)) {
971+
auto type = clang::cast<clang::ValueDecl>(decl)->getType();
972+
if (auto *record = type->getAsRecordDecl();
962973
record && !record->getIdentifier()) {
963974
target = record;
964975
}

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

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,13 @@ fn main_0() -> i32 {
9393
assert!(((basic::i(ru.clone()).read()) == 1065353216));
9494
assert!(((pf.read()) == 1_f32));
9595
assert!((((*buf.borrow())[(3) as usize] as i32) == 63));
96+
{
97+
let anon_0: Value<anon_0> = Rc::new(RefCell::new(<anon_0>::default()));
98+
anon_0::ai(anon_0.as_pointer()).write(11);
99+
assert!(((anon_0::ai(anon_0.as_pointer()).read()) == 11));
100+
anon_0::ai(anon_0.as_pointer()).write(1065353216);
101+
assert!(((anon_0::af(anon_0.as_pointer()).read()) == 1_f32));
102+
}
96103
let us: Value<underscores> = Rc::new(RefCell::new(<underscores>::default()));
97104
underscores::__(us.as_pointer()).write(5);
98105
assert!(((underscores::__(us.as_pointer()).read()) == 5));
@@ -103,4 +110,26 @@ fn main_0() -> i32 {
103110
assert!(((__ + ___) == 3));
104111
return 0;
105112
}
113+
#[derive(VaArg, FnPtrArg, ByteRepr, DeepClone)]
114+
#[byte_size(4)]
115+
pub struct anon_0 {
116+
#[offset(0)]
117+
#[byte_size(4)]
118+
__bytes: Value<Box<[u8]>>,
119+
}
120+
impl anon_0 {
121+
pub fn ai(this: Ptr<Self>) -> Ptr<i32> {
122+
this.reinterpret_cast()
123+
}
124+
pub fn af(this: Ptr<Self>) -> Ptr<f32> {
125+
this.reinterpret_cast()
126+
}
127+
}
128+
impl Default for anon_0 {
129+
fn default() -> Self {
130+
anon_0 {
131+
__bytes: Rc::new(RefCell::new(Box::from([0u8; 4]))),
132+
}
133+
}
134+
}
106135
pub fn __cpp2rust_init_globals() {}

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

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,13 @@ unsafe fn main_0() -> i32 {
6969
assert!((((*ru).i) == (1065353216)));
7070
assert!(((*pf) == (1_f32)));
7171
assert!(((buf[(3) as usize] as i32) == (63)));
72+
{
73+
let mut anon_0: anon_0 = <anon_0>::default();
74+
anon_0.ai = 11;
75+
assert!(((anon_0.ai) == (11)));
76+
anon_0.ai = 1065353216;
77+
assert!(((anon_0.af) == (1_f32)));
78+
}
7279
let mut us: underscores = <underscores>::default();
7380
us.__ = 5;
7481
assert!(((us.__) == (5)));
@@ -79,4 +86,15 @@ unsafe fn main_0() -> i32 {
7986
assert!((((__) + (___)) == (3)));
8087
return 0;
8188
}
89+
#[repr(C)]
90+
#[derive(Copy, Clone, FnPtrArg, VaArg)]
91+
pub union anon_0 {
92+
pub ai: i32,
93+
pub af: f32,
94+
}
95+
impl Default for anon_0 {
96+
fn default() -> Self {
97+
unsafe { std::mem::zeroed() }
98+
}
99+
}
82100
pub unsafe fn __cpp2rust_init_globals() {}

‎tests/unit/union_basic.cpp‎

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,17 @@ int main(void) {
3838
assert(*pf == 1.0f);
3939
assert(buf[3] == 0x3F);
4040

41+
{
42+
union {
43+
int ai;
44+
float af;
45+
};
46+
ai = 11;
47+
assert(ai == 11);
48+
ai = 0x3F800000;
49+
assert(af == 1.0f);
50+
}
51+
4152
union underscores us;
4253
us._ = 5;
4354
assert(us._ == 5);

0 commit comments

Comments
 (0)