diff --git a/cpp2rust/converter/converter.cpp b/cpp2rust/converter/converter.cpp index dc59f0d05..677d54496 100644 --- a/cpp2rust/converter/converter.cpp +++ b/cpp2rust/converter/converter.cpp @@ -1364,7 +1364,11 @@ bool Converter::VisitDeclStmt(clang::DeclStmt *stmt) { hoisted_records_ += std::move(buf).str(); continue; } - Convert(decl); + if (var && var->isImplicit()) { + VisitVarDecl(var); + } else { + Convert(decl); + } StrCat(token::kSemiColon); } return false; diff --git a/cpp2rust/converter/converter_lib.cpp b/cpp2rust/converter/converter_lib.cpp index 8cbacc4eb..5e07cdb15 100644 --- a/cpp2rust/converter/converter_lib.cpp +++ b/cpp2rust/converter/converter_lib.cpp @@ -927,13 +927,24 @@ std::string GetNamedDeclAsString(const clang::NamedDecl *decl) { } } + auto *anonymous_record_var = clang::dyn_cast(decl); + if (anonymous_record_var) { + auto *record = anonymous_record_var->getType()->getAsRecordDecl(); + if (clang::isa(decl) || !record || + record->getIdentifier()) { + anonymous_record_var = nullptr; + } + } + // Anonymous record or enum - if (name.empty() && (clang::isa(decl) || - clang::isa(decl) || - clang::isa(decl))) { + if (name.empty() && + (clang::isa(decl) || + clang::isa(decl) || anonymous_record_var || + clang::isa(decl))) { const clang::NamedDecl *target = decl; - if (auto *field = clang::dyn_cast(decl)) { - if (auto *record = field->getType()->getAsRecordDecl(); + if (clang::isa(decl)) { + auto type = clang::cast(decl)->getType(); + if (auto *record = type->getAsRecordDecl(); record && !record->getIdentifier()) { target = record; } diff --git a/tests/unit/out/refcount/union_basic.rs b/tests/unit/out/refcount/union_basic.rs index 5c5ed59d7..4d60b4896 100644 --- a/tests/unit/out/refcount/union_basic.rs +++ b/tests/unit/out/refcount/union_basic.rs @@ -93,6 +93,13 @@ fn main_0() -> i32 { assert!(((basic::i(ru.clone()).read()) == 1065353216)); assert!(((pf.read()) == 1_f32)); assert!((((*buf.borrow())[(3) as usize] as i32) == 63)); + { + let anon_0: Value = Rc::new(RefCell::new(::default())); + anon_0::ai(anon_0.as_pointer()).write(11); + assert!(((anon_0::ai(anon_0.as_pointer()).read()) == 11)); + anon_0::ai(anon_0.as_pointer()).write(1065353216); + assert!(((anon_0::af(anon_0.as_pointer()).read()) == 1_f32)); + } let us: Value = Rc::new(RefCell::new(::default())); underscores::__(us.as_pointer()).write(5); assert!(((underscores::__(us.as_pointer()).read()) == 5)); @@ -103,4 +110,26 @@ fn main_0() -> i32 { assert!(((__ + ___) == 3)); return 0; } +#[derive(VaArg, FnPtrArg, ByteRepr, DeepClone)] +#[byte_size(4)] +pub struct anon_0 { + #[offset(0)] + #[byte_size(4)] + __bytes: Value>, +} +impl anon_0 { + pub fn ai(this: Ptr) -> Ptr { + this.reinterpret_cast() + } + pub fn af(this: Ptr) -> Ptr { + this.reinterpret_cast() + } +} +impl Default for anon_0 { + fn default() -> Self { + anon_0 { + __bytes: Rc::new(RefCell::new(Box::from([0u8; 4]))), + } + } +} pub fn __cpp2rust_init_globals() {} diff --git a/tests/unit/out/unsafe/union_basic.rs b/tests/unit/out/unsafe/union_basic.rs index eb1de9e12..999cd945e 100644 --- a/tests/unit/out/unsafe/union_basic.rs +++ b/tests/unit/out/unsafe/union_basic.rs @@ -69,6 +69,13 @@ unsafe fn main_0() -> i32 { assert!((((*ru).i) == (1065353216))); assert!(((*pf) == (1_f32))); assert!(((buf[(3) as usize] as i32) == (63))); + { + let mut anon_0: anon_0 = ::default(); + anon_0.ai = 11; + assert!(((anon_0.ai) == (11))); + anon_0.ai = 1065353216; + assert!(((anon_0.af) == (1_f32))); + } let mut us: underscores = ::default(); us.__ = 5; assert!(((us.__) == (5))); @@ -79,4 +86,15 @@ unsafe fn main_0() -> i32 { assert!((((__) + (___)) == (3))); return 0; } +#[repr(C)] +#[derive(Copy, Clone, FnPtrArg, VaArg)] +pub union anon_0 { + pub ai: i32, + pub af: f32, +} +impl Default for anon_0 { + fn default() -> Self { + unsafe { std::mem::zeroed() } + } +} pub unsafe fn __cpp2rust_init_globals() {} diff --git a/tests/unit/union_basic.cpp b/tests/unit/union_basic.cpp index 647a59edf..db7eb652e 100644 --- a/tests/unit/union_basic.cpp +++ b/tests/unit/union_basic.cpp @@ -38,6 +38,17 @@ int main(void) { assert(*pf == 1.0f); assert(buf[3] == 0x3F); + { + union { + int ai; + float af; + }; + ai = 11; + assert(ai == 11); + ai = 0x3F800000; + assert(af == 1.0f); + } + union underscores us; us._ = 5; assert(us._ == 5);