From 4981456aa7ff2c3ee723667cd7d2f4f42f08cceb Mon Sep 17 00:00:00 2001 From: Lucian Popescu Date: Wed, 29 Apr 2026 19:55:57 +0100 Subject: [PATCH 1/6] Translate anonymous enums --- cpp2rust/converter/converter.cpp | 2 +- cpp2rust/converter/mapper.cpp | 6 +++ tests/unit/anonymous-enum.cpp | 21 +++++++++++ tests/unit/out/refcount/anonymous-enum.rs | 45 +++++++++++++++++++++++ tests/unit/out/unsafe/anonymous-enum.rs | 39 ++++++++++++++++++++ 5 files changed, 112 insertions(+), 1 deletion(-) create mode 100644 tests/unit/anonymous-enum.cpp create mode 100644 tests/unit/out/refcount/anonymous-enum.rs create mode 100644 tests/unit/out/unsafe/anonymous-enum.rs diff --git a/cpp2rust/converter/converter.cpp b/cpp2rust/converter/converter.cpp index ec3fca19..0bac32da 100644 --- a/cpp2rust/converter/converter.cpp +++ b/cpp2rust/converter/converter.cpp @@ -2672,7 +2672,7 @@ bool Converter::VisitEnumDecl(clang::EnumDecl *decl) { } Mapper::AddRuleForUserDefinedType(decl); StrCat("#[derive(Clone, Copy, PartialEq, Debug, Default)]"); - StrCat(std::format("enum {}", Mapper::Map(ctx_.getCanonicalTagType(decl)))); + StrCat(std::format("enum {}", GetRecordName(decl))); StrCat("{"); bool first_enumerator = true; for (auto e : decl->enumerators()) { diff --git a/cpp2rust/converter/mapper.cpp b/cpp2rust/converter/mapper.cpp index 45d88bae..3a7406b1 100644 --- a/cpp2rust/converter/mapper.cpp +++ b/cpp2rust/converter/mapper.cpp @@ -736,6 +736,12 @@ std::string ToString(const clang::NamedDecl *decl) { return synthesizeAnonRecordName(record); } + if (auto *enum_decl = clang::dyn_cast(decl); + enum_decl && !enum_decl->getIdentifier() && + enum_decl->getTypedefNameForAnonDecl() == nullptr) { + return std::format("anon_enum_{}", GetLineNumber(enum_decl)); + } + std::string out; llvm::raw_string_ostream os(out); diff --git a/tests/unit/anonymous-enum.cpp b/tests/unit/anonymous-enum.cpp new file mode 100644 index 00000000..def0bc0f --- /dev/null +++ b/tests/unit/anonymous-enum.cpp @@ -0,0 +1,21 @@ +enum { + FIRST_A, + FIRST_B, +}; + +struct S { + int a; + + enum { + SECOND_A, + SECOND_B, + }; +}; + +int main() { + enum { + THIRD_A, + THIRD_B, + }; + return 0; +}; diff --git a/tests/unit/out/refcount/anonymous-enum.rs b/tests/unit/out/refcount/anonymous-enum.rs new file mode 100644 index 00000000..ce77fd3b --- /dev/null +++ b/tests/unit/out/refcount/anonymous-enum.rs @@ -0,0 +1,45 @@ +extern crate libcc2rs; +use libcc2rs::*; +use std::cell::RefCell; +use std::collections::BTreeMap; +use std::io::prelude::*; +use std::io::{Read, Seek, Write}; +use std::os::fd::AsFd; +use std::rc::{Rc, Weak}; +#[derive(Clone, Copy, PartialEq, Debug, Default)] +enum anon_enum_1 { + #[default] + FIRST_A = 0, + FIRST_B = 1, +} +#[derive(Clone, Copy, PartialEq, Debug, Default)] +enum anon_enum_9 { + #[default] + SECOND_A = 0, + SECOND_B = 1, +} +#[derive(Default)] +pub struct S { + pub a: Value, +} +impl Clone for S { + fn clone(&self) -> Self { + let mut this = Self { + a: Rc::new(RefCell::new((*self.a.borrow()))), + }; + this + } +} +impl ByteRepr for S {} +pub fn main() { + std::process::exit(main_0()); +} +fn main_0() -> i32 { + #[derive(Clone, Copy, PartialEq, Debug, Default)] + enum anon_enum_16 { + #[default] + THIRD_A = 0, + THIRD_B = 1, + }; + return 0; +} diff --git a/tests/unit/out/unsafe/anonymous-enum.rs b/tests/unit/out/unsafe/anonymous-enum.rs new file mode 100644 index 00000000..e210e116 --- /dev/null +++ b/tests/unit/out/unsafe/anonymous-enum.rs @@ -0,0 +1,39 @@ +extern crate libc; +use libc::*; +extern crate libcc2rs; +use libcc2rs::*; +use std::collections::BTreeMap; +use std::io::{Read, Seek, Write}; +use std::os::fd::{AsFd, FromRawFd, IntoRawFd}; +use std::rc::Rc; +#[derive(Clone, Copy, PartialEq, Debug, Default)] +enum anon_enum_1 { + #[default] + FIRST_A = 0, + FIRST_B = 1, +} +#[derive(Clone, Copy, PartialEq, Debug, Default)] +enum anon_enum_9 { + #[default] + SECOND_A = 0, + SECOND_B = 1, +} +#[repr(C)] +#[derive(Copy, Clone, Default)] +pub struct S { + pub a: i32, +} +pub fn main() { + unsafe { + std::process::exit(main_0() as i32); + } +} +unsafe fn main_0() -> i32 { + #[derive(Clone, Copy, PartialEq, Debug, Default)] + enum anon_enum_16 { + #[default] + THIRD_A = 0, + THIRD_B = 1, + }; + return 0; +} From b1a397493a5c7534e55aad9ad9edbc58e82bfa86 Mon Sep 17 00:00:00 2001 From: Lucian Popescu Date: Wed, 29 Apr 2026 19:59:43 +0100 Subject: [PATCH 2/6] Use anonymous enums --- tests/unit/anonymous-enum.cpp | 12 ++++++++++++ tests/unit/out/refcount/anonymous-enum.rs | 12 +++++++++--- tests/unit/out/unsafe/anonymous-enum.rs | 12 +++++++++--- 3 files changed, 30 insertions(+), 6 deletions(-) diff --git a/tests/unit/anonymous-enum.cpp b/tests/unit/anonymous-enum.cpp index def0bc0f..fc89ae47 100644 --- a/tests/unit/anonymous-enum.cpp +++ b/tests/unit/anonymous-enum.cpp @@ -1,3 +1,5 @@ +#include + enum { FIRST_A, FIRST_B, @@ -17,5 +19,15 @@ int main() { THIRD_A, THIRD_B, }; + + assert(FIRST_A == 0); + assert(FIRST_B == 1); + + assert(S::SECOND_A == 0); + assert(S::SECOND_B == 1); + + assert(THIRD_A == 0); + assert(THIRD_B == 1); + return 0; }; diff --git a/tests/unit/out/refcount/anonymous-enum.rs b/tests/unit/out/refcount/anonymous-enum.rs index ce77fd3b..00a282f7 100644 --- a/tests/unit/out/refcount/anonymous-enum.rs +++ b/tests/unit/out/refcount/anonymous-enum.rs @@ -7,13 +7,13 @@ use std::io::{Read, Seek, Write}; use std::os::fd::AsFd; use std::rc::{Rc, Weak}; #[derive(Clone, Copy, PartialEq, Debug, Default)] -enum anon_enum_1 { +enum anon_enum_3 { #[default] FIRST_A = 0, FIRST_B = 1, } #[derive(Clone, Copy, PartialEq, Debug, Default)] -enum anon_enum_9 { +enum anon_enum_11 { #[default] SECOND_A = 0, SECOND_B = 1, @@ -36,10 +36,16 @@ pub fn main() { } fn main_0() -> i32 { #[derive(Clone, Copy, PartialEq, Debug, Default)] - enum anon_enum_16 { + enum anon_enum_18 { #[default] THIRD_A = 0, THIRD_B = 1, }; + assert!(((anon_enum_3::FIRST_A as i32) == 0)); + assert!(((anon_enum_3::FIRST_B as i32) == 1)); + assert!(((anon_enum_11::SECOND_A as i32) == 0)); + assert!(((anon_enum_11::SECOND_B as i32) == 1)); + assert!(((anon_enum_18::THIRD_A as i32) == 0)); + assert!(((anon_enum_18::THIRD_B as i32) == 1)); return 0; } diff --git a/tests/unit/out/unsafe/anonymous-enum.rs b/tests/unit/out/unsafe/anonymous-enum.rs index e210e116..3d7c7013 100644 --- a/tests/unit/out/unsafe/anonymous-enum.rs +++ b/tests/unit/out/unsafe/anonymous-enum.rs @@ -7,13 +7,13 @@ use std::io::{Read, Seek, Write}; use std::os::fd::{AsFd, FromRawFd, IntoRawFd}; use std::rc::Rc; #[derive(Clone, Copy, PartialEq, Debug, Default)] -enum anon_enum_1 { +enum anon_enum_3 { #[default] FIRST_A = 0, FIRST_B = 1, } #[derive(Clone, Copy, PartialEq, Debug, Default)] -enum anon_enum_9 { +enum anon_enum_11 { #[default] SECOND_A = 0, SECOND_B = 1, @@ -30,10 +30,16 @@ pub fn main() { } unsafe fn main_0() -> i32 { #[derive(Clone, Copy, PartialEq, Debug, Default)] - enum anon_enum_16 { + enum anon_enum_18 { #[default] THIRD_A = 0, THIRD_B = 1, }; + assert!(((anon_enum_3::FIRST_A as i32) == (0))); + assert!(((anon_enum_3::FIRST_B as i32) == (1))); + assert!(((anon_enum_11::SECOND_A as i32) == (0))); + assert!(((anon_enum_11::SECOND_B as i32) == (1))); + assert!(((anon_enum_18::THIRD_A as i32) == (0))); + assert!(((anon_enum_18::THIRD_B as i32) == (1))); return 0; } From f9b0f034468f5cc73379eb1d466b6e5f66a59530 Mon Sep 17 00:00:00 2001 From: Lucian Popescu Date: Wed, 29 Apr 2026 20:32:04 +0100 Subject: [PATCH 3/6] Add anonymous field inside struct --- tests/unit/anonymous-enum.cpp | 33 ------------- tests/unit/anonymous_enum.cpp | 57 +++++++++++++++++++++++ tests/unit/anonymous_enum_c.c | 57 +++++++++++++++++++++++ tests/unit/out/refcount/anonymous-enum.rs | 51 -------------------- tests/unit/out/unsafe/anonymous-enum.rs | 45 ------------------ 5 files changed, 114 insertions(+), 129 deletions(-) delete mode 100644 tests/unit/anonymous-enum.cpp create mode 100644 tests/unit/anonymous_enum.cpp create mode 100644 tests/unit/anonymous_enum_c.c delete mode 100644 tests/unit/out/refcount/anonymous-enum.rs delete mode 100644 tests/unit/out/unsafe/anonymous-enum.rs diff --git a/tests/unit/anonymous-enum.cpp b/tests/unit/anonymous-enum.cpp deleted file mode 100644 index fc89ae47..00000000 --- a/tests/unit/anonymous-enum.cpp +++ /dev/null @@ -1,33 +0,0 @@ -#include - -enum { - FIRST_A, - FIRST_B, -}; - -struct S { - int a; - - enum { - SECOND_A, - SECOND_B, - }; -}; - -int main() { - enum { - THIRD_A, - THIRD_B, - }; - - assert(FIRST_A == 0); - assert(FIRST_B == 1); - - assert(S::SECOND_A == 0); - assert(S::SECOND_B == 1); - - assert(THIRD_A == 0); - assert(THIRD_B == 1); - - return 0; -}; diff --git a/tests/unit/anonymous_enum.cpp b/tests/unit/anonymous_enum.cpp new file mode 100644 index 00000000..13bd0c25 --- /dev/null +++ b/tests/unit/anonymous_enum.cpp @@ -0,0 +1,57 @@ +#include + +enum { + FIRST_A, + FIRST_B, +}; + +struct S { + int a; + + enum { + SECOND_A, + SECOND_B, + }; +}; + +typedef enum { + TD_A, + TD_B, +} TdEnum; + +struct WithAnonField { + int a; + enum { + FIELD_A, + FIELD_B, + } field; +}; + +int main() { + enum { + THIRD_A, + THIRD_B, + }; + + assert(FIRST_A == 0); + assert(FIRST_B == 1); + + assert(S::SECOND_A == 0); + assert(S::SECOND_B == 1); + + assert(THIRD_A == 0); + assert(THIRD_B == 1); + + TdEnum td = TD_A; + assert(td == TD_A); + td = TD_B; + assert(td == TD_B); + + WithAnonField w; + w.field = WithAnonField::FIELD_A; + assert(w.field == WithAnonField::FIELD_A); + w.field = WithAnonField::FIELD_B; + assert(w.field == WithAnonField::FIELD_B); + + return 0; +}; diff --git a/tests/unit/anonymous_enum_c.c b/tests/unit/anonymous_enum_c.c new file mode 100644 index 00000000..0e507a44 --- /dev/null +++ b/tests/unit/anonymous_enum_c.c @@ -0,0 +1,57 @@ +#include + +enum { + FIRST_A, + FIRST_B, +}; + +struct S { + int a; + + enum { + SECOND_A, + SECOND_B, + }; +}; + +typedef enum { + TD_A, + TD_B, +} TdEnum; + +struct WithAnonField { + int a; + enum { + FIELD_A, + FIELD_B, + } field; +}; + +int main() { + enum { + THIRD_A, + THIRD_B, + }; + + assert(FIRST_A == 0); + assert(FIRST_B == 1); + + assert(SECOND_A == 0); + assert(SECOND_B == 1); + + assert(THIRD_A == 0); + assert(THIRD_B == 1); + + TdEnum td = TD_A; + assert(td == TD_A); + td = TD_B; + assert(td == TD_B); + + struct WithAnonField w; + w.field = FIELD_A; + assert(w.field == FIELD_A); + w.field = FIELD_B; + assert(w.field == FIELD_B); + + return 0; +}; diff --git a/tests/unit/out/refcount/anonymous-enum.rs b/tests/unit/out/refcount/anonymous-enum.rs deleted file mode 100644 index 00a282f7..00000000 --- a/tests/unit/out/refcount/anonymous-enum.rs +++ /dev/null @@ -1,51 +0,0 @@ -extern crate libcc2rs; -use libcc2rs::*; -use std::cell::RefCell; -use std::collections::BTreeMap; -use std::io::prelude::*; -use std::io::{Read, Seek, Write}; -use std::os::fd::AsFd; -use std::rc::{Rc, Weak}; -#[derive(Clone, Copy, PartialEq, Debug, Default)] -enum anon_enum_3 { - #[default] - FIRST_A = 0, - FIRST_B = 1, -} -#[derive(Clone, Copy, PartialEq, Debug, Default)] -enum anon_enum_11 { - #[default] - SECOND_A = 0, - SECOND_B = 1, -} -#[derive(Default)] -pub struct S { - pub a: Value, -} -impl Clone for S { - fn clone(&self) -> Self { - let mut this = Self { - a: Rc::new(RefCell::new((*self.a.borrow()))), - }; - this - } -} -impl ByteRepr for S {} -pub fn main() { - std::process::exit(main_0()); -} -fn main_0() -> i32 { - #[derive(Clone, Copy, PartialEq, Debug, Default)] - enum anon_enum_18 { - #[default] - THIRD_A = 0, - THIRD_B = 1, - }; - assert!(((anon_enum_3::FIRST_A as i32) == 0)); - assert!(((anon_enum_3::FIRST_B as i32) == 1)); - assert!(((anon_enum_11::SECOND_A as i32) == 0)); - assert!(((anon_enum_11::SECOND_B as i32) == 1)); - assert!(((anon_enum_18::THIRD_A as i32) == 0)); - assert!(((anon_enum_18::THIRD_B as i32) == 1)); - return 0; -} diff --git a/tests/unit/out/unsafe/anonymous-enum.rs b/tests/unit/out/unsafe/anonymous-enum.rs deleted file mode 100644 index 3d7c7013..00000000 --- a/tests/unit/out/unsafe/anonymous-enum.rs +++ /dev/null @@ -1,45 +0,0 @@ -extern crate libc; -use libc::*; -extern crate libcc2rs; -use libcc2rs::*; -use std::collections::BTreeMap; -use std::io::{Read, Seek, Write}; -use std::os::fd::{AsFd, FromRawFd, IntoRawFd}; -use std::rc::Rc; -#[derive(Clone, Copy, PartialEq, Debug, Default)] -enum anon_enum_3 { - #[default] - FIRST_A = 0, - FIRST_B = 1, -} -#[derive(Clone, Copy, PartialEq, Debug, Default)] -enum anon_enum_11 { - #[default] - SECOND_A = 0, - SECOND_B = 1, -} -#[repr(C)] -#[derive(Copy, Clone, Default)] -pub struct S { - pub a: i32, -} -pub fn main() { - unsafe { - std::process::exit(main_0() as i32); - } -} -unsafe fn main_0() -> i32 { - #[derive(Clone, Copy, PartialEq, Debug, Default)] - enum anon_enum_18 { - #[default] - THIRD_A = 0, - THIRD_B = 1, - }; - assert!(((anon_enum_3::FIRST_A as i32) == (0))); - assert!(((anon_enum_3::FIRST_B as i32) == (1))); - assert!(((anon_enum_11::SECOND_A as i32) == (0))); - assert!(((anon_enum_11::SECOND_B as i32) == (1))); - assert!(((anon_enum_18::THIRD_A as i32) == (0))); - assert!(((anon_enum_18::THIRD_B as i32) == (1))); - return 0; -} From cf578ebea8c7318ce59f202262e7a14f6fc43b04 Mon Sep 17 00:00:00 2001 From: Lucian Popescu Date: Thu, 30 Apr 2026 10:02:39 +0100 Subject: [PATCH 4/6] Fix translation of type of anon enum --- cpp2rust/converter/mapper.cpp | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/cpp2rust/converter/mapper.cpp b/cpp2rust/converter/mapper.cpp index 3a7406b1..fb160715 100644 --- a/cpp2rust/converter/mapper.cpp +++ b/cpp2rust/converter/mapper.cpp @@ -724,6 +724,11 @@ std::string ToString(clang::QualType qual_type) { } } + if (auto *tag = qual_type->getAsTagDecl(); + tag && !tag->getIdentifier() && !tag->getTypedefNameForAnonDecl()) { + return ToString(clang::cast(tag)); + } + std::string type; llvm::raw_string_ostream os(type); normalizeQualType(qual_type).print(os, getPrintPolicy()); @@ -738,7 +743,7 @@ std::string ToString(const clang::NamedDecl *decl) { if (auto *enum_decl = clang::dyn_cast(decl); enum_decl && !enum_decl->getIdentifier() && - enum_decl->getTypedefNameForAnonDecl() == nullptr) { + !enum_decl->getTypedefNameForAnonDecl()) { return std::format("anon_enum_{}", GetLineNumber(enum_decl)); } From 8f9164568a1929c43ba0face026c66bdfbde2083 Mon Sep 17 00:00:00 2001 From: Lucian Popescu Date: Thu, 30 Apr 2026 10:25:44 +0100 Subject: [PATCH 5/6] Avoid comparison between enum and intger in C for now --- tests/unit/anonymous_enum.cpp | 11 +++-------- tests/unit/anonymous_enum_c.c | 11 +++-------- 2 files changed, 6 insertions(+), 16 deletions(-) diff --git a/tests/unit/anonymous_enum.cpp b/tests/unit/anonymous_enum.cpp index 13bd0c25..3ec0e86e 100644 --- a/tests/unit/anonymous_enum.cpp +++ b/tests/unit/anonymous_enum.cpp @@ -33,14 +33,9 @@ int main() { THIRD_B, }; - assert(FIRST_A == 0); - assert(FIRST_B == 1); - - assert(S::SECOND_A == 0); - assert(S::SECOND_B == 1); - - assert(THIRD_A == 0); - assert(THIRD_B == 1); + assert(FIRST_A != FIRST_B); + assert(S::SECOND_A != S::SECOND_B); + assert(THIRD_A != THIRD_B); TdEnum td = TD_A; assert(td == TD_A); diff --git a/tests/unit/anonymous_enum_c.c b/tests/unit/anonymous_enum_c.c index 0e507a44..5a2d0c12 100644 --- a/tests/unit/anonymous_enum_c.c +++ b/tests/unit/anonymous_enum_c.c @@ -33,14 +33,9 @@ int main() { THIRD_B, }; - assert(FIRST_A == 0); - assert(FIRST_B == 1); - - assert(SECOND_A == 0); - assert(SECOND_B == 1); - - assert(THIRD_A == 0); - assert(THIRD_B == 1); + assert(FIRST_A != FIRST_B); + assert(SECOND_A != SECOND_B); + assert(THIRD_A != THIRD_B); TdEnum td = TD_A; assert(td == TD_A); From d8ddec54708697bdce25b09a191630d37c337f13 Mon Sep 17 00:00:00 2001 From: Lucian Popescu Date: Thu, 30 Apr 2026 10:30:23 +0100 Subject: [PATCH 6/6] Update tests --- tests/unit/out/refcount/anonymous_enum.rs | 84 +++++++++++++++++++++ tests/unit/out/refcount/anonymous_enum_c.rs | 67 ++++++++++++++++ tests/unit/out/unsafe/anonymous_enum.rs | 69 +++++++++++++++++ tests/unit/out/unsafe/anonymous_enum_c.rs | 69 +++++++++++++++++ 4 files changed, 289 insertions(+) create mode 100644 tests/unit/out/refcount/anonymous_enum.rs create mode 100644 tests/unit/out/refcount/anonymous_enum_c.rs create mode 100644 tests/unit/out/unsafe/anonymous_enum.rs create mode 100644 tests/unit/out/unsafe/anonymous_enum_c.rs diff --git a/tests/unit/out/refcount/anonymous_enum.rs b/tests/unit/out/refcount/anonymous_enum.rs new file mode 100644 index 00000000..47dcf325 --- /dev/null +++ b/tests/unit/out/refcount/anonymous_enum.rs @@ -0,0 +1,84 @@ +extern crate libcc2rs; +use libcc2rs::*; +use std::cell::RefCell; +use std::collections::BTreeMap; +use std::io::prelude::*; +use std::io::{Read, Seek, Write}; +use std::os::fd::AsFd; +use std::rc::{Rc, Weak}; +#[derive(Clone, Copy, PartialEq, Debug, Default)] +enum anon_enum_3 { + #[default] + FIRST_A = 0, + FIRST_B = 1, +} +#[derive(Clone, Copy, PartialEq, Debug, Default)] +enum anon_enum_11 { + #[default] + SECOND_A = 0, + SECOND_B = 1, +} +#[derive(Default)] +pub struct S { + pub a: Value, +} +impl Clone for S { + fn clone(&self) -> Self { + let mut this = Self { + a: Rc::new(RefCell::new((*self.a.borrow()))), + }; + this + } +} +impl ByteRepr for S {} +#[derive(Clone, Copy, PartialEq, Debug, Default)] +enum TdEnum { + #[default] + TD_A = 0, + TD_B = 1, +} +#[derive(Clone, Copy, PartialEq, Debug, Default)] +enum anon_enum_24 { + #[default] + FIELD_A = 0, + FIELD_B = 1, +} +#[derive(Default)] +pub struct WithAnonField { + pub a: Value, + pub field: Value, +} +impl Clone for WithAnonField { + fn clone(&self) -> Self { + let mut this = Self { + a: Rc::new(RefCell::new((*self.a.borrow()))), + field: Rc::new(RefCell::new((*self.field.borrow()).clone())), + }; + this + } +} +impl ByteRepr for WithAnonField {} +pub fn main() { + std::process::exit(main_0()); +} +fn main_0() -> i32 { + #[derive(Clone, Copy, PartialEq, Debug, Default)] + enum anon_enum_31 { + #[default] + THIRD_A = 0, + THIRD_B = 1, + }; + assert!(((anon_enum_3::FIRST_A as i32) != (anon_enum_3::FIRST_B as i32))); + assert!(((anon_enum_11::SECOND_A as i32) != (anon_enum_11::SECOND_B as i32))); + assert!(((anon_enum_31::THIRD_A as i32) != (anon_enum_31::THIRD_B as i32))); + let td: Value = Rc::new(RefCell::new(TdEnum::TD_A)); + assert!((((*td.borrow()) as i32) == (TdEnum::TD_A as i32))); + (*td.borrow_mut()) = TdEnum::TD_B; + assert!((((*td.borrow()) as i32) == (TdEnum::TD_B as i32))); + let w: Value = Rc::new(RefCell::new(::default())); + (*(*w.borrow()).field.borrow_mut()) = anon_enum_24::FIELD_A; + assert!((((*(*w.borrow()).field.borrow()) as i32) == (anon_enum_24::FIELD_A as i32))); + (*(*w.borrow()).field.borrow_mut()) = anon_enum_24::FIELD_B; + assert!((((*(*w.borrow()).field.borrow()) as i32) == (anon_enum_24::FIELD_B as i32))); + return 0; +} diff --git a/tests/unit/out/refcount/anonymous_enum_c.rs b/tests/unit/out/refcount/anonymous_enum_c.rs new file mode 100644 index 00000000..0b0c762c --- /dev/null +++ b/tests/unit/out/refcount/anonymous_enum_c.rs @@ -0,0 +1,67 @@ +extern crate libcc2rs; +use libcc2rs::*; +use std::cell::RefCell; +use std::collections::BTreeMap; +use std::io::prelude::*; +use std::io::{Read, Seek, Write}; +use std::os::fd::AsFd; +use std::rc::{Rc, Weak}; +#[derive(Clone, Copy, PartialEq, Debug, Default)] +enum anon_enum_3 { + #[default] + FIRST_A = 0, + FIRST_B = 1, +} +#[derive(Clone, Copy, PartialEq, Debug, Default)] +enum anon_enum_11 { + #[default] + SECOND_A = 0, + SECOND_B = 1, +} +#[derive(Default)] +pub struct S { + pub a: Value, +} +impl ByteRepr for S {} +#[derive(Clone, Copy, PartialEq, Debug, Default)] +enum TdEnum { + #[default] + TD_A = 0, + TD_B = 1, +} +#[derive(Clone, Copy, PartialEq, Debug, Default)] +enum anon_enum_24 { + #[default] + FIELD_A = 0, + FIELD_B = 1, +} +#[derive(Default)] +pub struct WithAnonField { + pub a: Value, + pub field: Value, +} +impl ByteRepr for WithAnonField {} +pub fn main() { + std::process::exit(main_0()); +} +fn main_0() -> i32 { + #[derive(Clone, Copy, PartialEq, Debug, Default)] + enum anon_enum_31 { + #[default] + THIRD_A = 0, + THIRD_B = 1, + }; + assert!((anon_enum_3::FIRST_A != anon_enum_3::FIRST_B)); + assert!((anon_enum_11::SECOND_A != anon_enum_11::SECOND_B)); + assert!((anon_enum_31::THIRD_A != anon_enum_31::THIRD_B)); + let td: Value = Rc::new(RefCell::new((TdEnum::TD_A as TdEnum))); + assert!((((*td.borrow()) as u32) == (TdEnum::TD_A as u32))); + (*td.borrow_mut()) = (TdEnum::TD_B as TdEnum); + assert!((((*td.borrow()) as u32) == (TdEnum::TD_B as u32))); + let w: Value = >::default(); + (*(*w.borrow()).field.borrow_mut()) = (anon_enum_24::FIELD_A as anon_enum_24); + assert!((((*(*w.borrow()).field.borrow()) as u32) == (anon_enum_24::FIELD_A as u32))); + (*(*w.borrow()).field.borrow_mut()) = (anon_enum_24::FIELD_B as anon_enum_24); + assert!((((*(*w.borrow()).field.borrow()) as u32) == (anon_enum_24::FIELD_B as u32))); + return 0; +} diff --git a/tests/unit/out/unsafe/anonymous_enum.rs b/tests/unit/out/unsafe/anonymous_enum.rs new file mode 100644 index 00000000..a327b394 --- /dev/null +++ b/tests/unit/out/unsafe/anonymous_enum.rs @@ -0,0 +1,69 @@ +extern crate libc; +use libc::*; +extern crate libcc2rs; +use libcc2rs::*; +use std::collections::BTreeMap; +use std::io::{Read, Seek, Write}; +use std::os::fd::{AsFd, FromRawFd, IntoRawFd}; +use std::rc::Rc; +#[derive(Clone, Copy, PartialEq, Debug, Default)] +enum anon_enum_3 { + #[default] + FIRST_A = 0, + FIRST_B = 1, +} +#[derive(Clone, Copy, PartialEq, Debug, Default)] +enum anon_enum_11 { + #[default] + SECOND_A = 0, + SECOND_B = 1, +} +#[repr(C)] +#[derive(Copy, Clone, Default)] +pub struct S { + pub a: i32, +} +#[derive(Clone, Copy, PartialEq, Debug, Default)] +enum TdEnum { + #[default] + TD_A = 0, + TD_B = 1, +} +#[derive(Clone, Copy, PartialEq, Debug, Default)] +enum anon_enum_24 { + #[default] + FIELD_A = 0, + FIELD_B = 1, +} +#[repr(C)] +#[derive(Copy, Clone, Default)] +pub struct WithAnonField { + pub a: i32, + pub field: anon_enum_24, +} +pub fn main() { + unsafe { + std::process::exit(main_0() as i32); + } +} +unsafe fn main_0() -> i32 { + #[derive(Clone, Copy, PartialEq, Debug, Default)] + enum anon_enum_31 { + #[default] + THIRD_A = 0, + THIRD_B = 1, + }; + assert!(((anon_enum_3::FIRST_A as i32) != (anon_enum_3::FIRST_B as i32))); + assert!(((anon_enum_11::SECOND_A as i32) != (anon_enum_11::SECOND_B as i32))); + assert!(((anon_enum_31::THIRD_A as i32) != (anon_enum_31::THIRD_B as i32))); + let mut td: TdEnum = TdEnum::TD_A; + assert!(((td as i32) == (TdEnum::TD_A as i32))); + td = (TdEnum::TD_B).clone(); + assert!(((td as i32) == (TdEnum::TD_B as i32))); + let mut w: WithAnonField = ::default(); + w.field = anon_enum_24::FIELD_A; + assert!(((w.field as i32) == (anon_enum_24::FIELD_A as i32))); + w.field = (anon_enum_24::FIELD_B).clone(); + assert!(((w.field as i32) == (anon_enum_24::FIELD_B as i32))); + return 0; +} diff --git a/tests/unit/out/unsafe/anonymous_enum_c.rs b/tests/unit/out/unsafe/anonymous_enum_c.rs new file mode 100644 index 00000000..881be82d --- /dev/null +++ b/tests/unit/out/unsafe/anonymous_enum_c.rs @@ -0,0 +1,69 @@ +extern crate libc; +use libc::*; +extern crate libcc2rs; +use libcc2rs::*; +use std::collections::BTreeMap; +use std::io::{Read, Seek, Write}; +use std::os::fd::{AsFd, FromRawFd, IntoRawFd}; +use std::rc::Rc; +#[derive(Clone, Copy, PartialEq, Debug, Default)] +enum anon_enum_3 { + #[default] + FIRST_A = 0, + FIRST_B = 1, +} +#[derive(Clone, Copy, PartialEq, Debug, Default)] +enum anon_enum_11 { + #[default] + SECOND_A = 0, + SECOND_B = 1, +} +#[repr(C)] +#[derive(Copy, Clone, Default)] +pub struct S { + pub a: i32, +} +#[derive(Clone, Copy, PartialEq, Debug, Default)] +enum TdEnum { + #[default] + TD_A = 0, + TD_B = 1, +} +#[derive(Clone, Copy, PartialEq, Debug, Default)] +enum anon_enum_24 { + #[default] + FIELD_A = 0, + FIELD_B = 1, +} +#[repr(C)] +#[derive(Copy, Clone, Default)] +pub struct WithAnonField { + pub a: i32, + pub field: anon_enum_24, +} +pub fn main() { + unsafe { + std::process::exit(main_0() as i32); + } +} +unsafe fn main_0() -> i32 { + #[derive(Clone, Copy, PartialEq, Debug, Default)] + enum anon_enum_31 { + #[default] + THIRD_A = 0, + THIRD_B = 1, + }; + assert!(((anon_enum_3::FIRST_A) != (anon_enum_3::FIRST_B))); + assert!(((anon_enum_11::SECOND_A) != (anon_enum_11::SECOND_B))); + assert!(((anon_enum_31::THIRD_A) != (anon_enum_31::THIRD_B))); + let mut td: TdEnum = (TdEnum::TD_A as TdEnum); + assert!(((td as u32) == (TdEnum::TD_A as u32))); + td = (TdEnum::TD_B as TdEnum).clone(); + assert!(((td as u32) == (TdEnum::TD_B as u32))); + let mut w: WithAnonField = ::default(); + w.field = (anon_enum_24::FIELD_A as anon_enum_24); + assert!(((w.field as u32) == (anon_enum_24::FIELD_A as u32))); + w.field = (anon_enum_24::FIELD_B as anon_enum_24).clone(); + assert!(((w.field as u32) == (anon_enum_24::FIELD_B as u32))); + return 0; +}