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
5 changes: 3 additions & 2 deletions cpp2rust/converter/converter_lib.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -408,9 +408,10 @@ std::string GetNamedDeclAsString(const clang::NamedDecl *decl) {
auto name = decl->getDeclName().isIdentifier() ? decl->getName().str()
: decl->getNameAsString();

// Anonymous record
// Anonymous record or enum
if (name.empty() && (clang::isa<clang::RecordDecl>(decl) ||
clang::isa<clang::FieldDecl>(decl))) {
clang::isa<clang::FieldDecl>(decl) ||
clang::isa<clang::EnumDecl>(decl))) {
const clang::NamedDecl *target = decl;
if (auto *field = clang::dyn_cast<clang::FieldDecl>(decl)) {
if (auto *record = field->getType()->getAsRecordDecl();
Expand Down
2 changes: 1 addition & 1 deletion cpp2rust/converter/mapper.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -765,7 +765,7 @@ std::string ToString(const clang::NamedDecl *decl) {
}
if (!enum_decl->getIdentifier() &&
!enum_decl->getTypedefNameForAnonDecl()) {
return std::format("anon_enum_{}", GetLineNumber(enum_decl));
return GetNamedDeclAsString(enum_decl);
}
}

Expand Down
3 changes: 3 additions & 0 deletions tests/multi-file/cross_tu_anon_enum_collision/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
cmake_minimum_required(VERSION 3.16)
project(cross_tu_anon_enum_collision LANGUAGES C)
add_executable(app a.c b.c)
17 changes: 17 additions & 0 deletions tests/multi-file/cross_tu_anon_enum_collision/a.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
#include <assert.h>
// anon enum below shares the same declaration line as b.c:enum { BETA = 9 }
enum { ALPHA = 7 };

int b_value(void);

int a_value(void) {
int x = 0;
x |= ALPHA;
return x;
}

int main(void) {
assert(a_value() == 7);
assert(b_value() == 9);
return 0;
}
9 changes: 9 additions & 0 deletions tests/multi-file/cross_tu_anon_enum_collision/b.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
// anon enum below shares the same declaration line as b.c:enum { ALPHA = 7 }

enum { BETA = 9 };

int b_value(void) {
int x = 0;
x |= BETA;
return x;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
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_0 {
#[default]
ALPHA = 7,
}
impl From<i32> for anon_0 {
fn from(n: i32) -> anon_0 {
match n {
7 => anon_0::ALPHA,
_ => panic!("invalid anon_0 value: {}", n),
}
}
}
libcc2rs::impl_enum_inc_dec!(anon_0);
pub fn a_value_1() -> i32 {
let x: Value<i32> = Rc::new(RefCell::new(0));
(*x.borrow_mut()) |= (anon_0::ALPHA as i32);
return (*x.borrow());
}
pub fn main() {
std::process::exit(main_0());
}
fn main_0() -> i32 {
assert!((((({ a_value_1() }) == 7) as i32) != 0));
assert!((((({ b_value_2() }) == 9) as i32) != 0));
return 0;
}
#[derive(Clone, Copy, PartialEq, Debug, Default)]
enum anon_3 {
#[default]
BETA = 9,
}
impl From<i32> for anon_3 {
fn from(n: i32) -> anon_3 {
match n {
9 => anon_3::BETA,
_ => panic!("invalid anon_3 value: {}", n),
}
}
}
libcc2rs::impl_enum_inc_dec!(anon_3);
pub fn b_value_2() -> i32 {
let x: Value<i32> = Rc::new(RefCell::new(0));
(*x.borrow_mut()) |= (anon_3::BETA as i32);
return (*x.borrow());
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
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_0 {
#[default]
ALPHA = 7,
}
impl From<i32> for anon_0 {
fn from(n: i32) -> anon_0 {
match n {
7 => anon_0::ALPHA,
_ => panic!("invalid anon_0 value: {}", n),
}
}
}
libcc2rs::impl_enum_inc_dec!(anon_0);
pub unsafe fn a_value_1() -> i32 {
let mut x: i32 = 0;
x |= (anon_0::ALPHA as i32);
return x;
}
pub fn main() {
unsafe {
std::process::exit(main_0() as i32);
}
}
unsafe fn main_0() -> i32 {
assert!(((((unsafe { a_value_1() }) == (7)) as i32) != 0));
assert!(((((unsafe { b_value_2() }) == (9)) as i32) != 0));
return 0;
}
#[derive(Clone, Copy, PartialEq, Debug, Default)]
enum anon_3 {
#[default]
BETA = 9,
}
impl From<i32> for anon_3 {
fn from(n: i32) -> anon_3 {
match n {
9 => anon_3::BETA,
_ => panic!("invalid anon_3 value: {}", n),
}
}
}
libcc2rs::impl_enum_inc_dec!(anon_3);
pub unsafe fn b_value_2() -> i32 {
let mut x: i32 = 0;
x |= (anon_3::BETA as i32);
return x;
}
72 changes: 36 additions & 36 deletions tests/unit/out/refcount/anonymous_enum.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,37 +7,37 @@ 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 {
enum anon_0 {
#[default]
FIRST_A = 0,
FIRST_B = 1,
}
impl From<i32> for anon_enum_3 {
fn from(n: i32) -> anon_enum_3 {
impl From<i32> for anon_0 {
fn from(n: i32) -> anon_0 {
match n {
0 => anon_enum_3::FIRST_A,
1 => anon_enum_3::FIRST_B,
_ => panic!("invalid anon_enum_3 value: {}", n),
0 => anon_0::FIRST_A,
1 => anon_0::FIRST_B,
_ => panic!("invalid anon_0 value: {}", n),
}
}
}
libcc2rs::impl_enum_inc_dec!(anon_enum_3);
libcc2rs::impl_enum_inc_dec!(anon_0);
#[derive(Clone, Copy, PartialEq, Debug, Default)]
enum anon_enum_11 {
enum anon_1 {
#[default]
SECOND_A = 0,
SECOND_B = 1,
}
impl From<i32> for anon_enum_11 {
fn from(n: i32) -> anon_enum_11 {
impl From<i32> for anon_1 {
fn from(n: i32) -> anon_1 {
match n {
0 => anon_enum_11::SECOND_A,
1 => anon_enum_11::SECOND_B,
_ => panic!("invalid anon_enum_11 value: {}", n),
0 => anon_1::SECOND_A,
1 => anon_1::SECOND_B,
_ => panic!("invalid anon_1 value: {}", n),
}
}
}
libcc2rs::impl_enum_inc_dec!(anon_enum_11);
libcc2rs::impl_enum_inc_dec!(anon_1);
#[derive(Default)]
pub struct S {
pub a: Value<i32>,
Expand Down Expand Up @@ -77,25 +77,25 @@ impl From<i32> for TdEnum {
}
libcc2rs::impl_enum_inc_dec!(TdEnum);
#[derive(Clone, Copy, PartialEq, Debug, Default)]
enum anon_enum_24 {
enum anon_2 {
#[default]
FIELD_A = 0,
FIELD_B = 1,
}
impl From<i32> for anon_enum_24 {
fn from(n: i32) -> anon_enum_24 {
impl From<i32> for anon_2 {
fn from(n: i32) -> anon_2 {
match n {
0 => anon_enum_24::FIELD_A,
1 => anon_enum_24::FIELD_B,
_ => panic!("invalid anon_enum_24 value: {}", n),
0 => anon_2::FIELD_A,
1 => anon_2::FIELD_B,
_ => panic!("invalid anon_2 value: {}", n),
}
}
}
libcc2rs::impl_enum_inc_dec!(anon_enum_24);
libcc2rs::impl_enum_inc_dec!(anon_2);
#[derive(Default)]
pub struct WithAnonField {
pub a: Value<i32>,
pub field: Value<anon_enum_24>,
pub field: Value<anon_2>,
}
impl Clone for WithAnonField {
fn clone(&self) -> Self {
Expand All @@ -112,32 +112,32 @@ pub fn main() {
}
fn main_0() -> i32 {
#[derive(Clone, Copy, PartialEq, Debug, Default)]
enum anon_enum_31 {
enum anon_3 {
#[default]
THIRD_A = 0,
THIRD_B = 1,
}
impl From<i32> for anon_enum_31 {
fn from(n: i32) -> anon_enum_31 {
impl From<i32> for anon_3 {
fn from(n: i32) -> anon_3 {
match n {
0 => anon_enum_31::THIRD_A,
1 => anon_enum_31::THIRD_B,
_ => panic!("invalid anon_enum_31 value: {}", n),
0 => anon_3::THIRD_A,
1 => anon_3::THIRD_B,
_ => panic!("invalid anon_3 value: {}", n),
}
}
}
libcc2rs::impl_enum_inc_dec!(anon_enum_31);
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)));
libcc2rs::impl_enum_inc_dec!(anon_3);
assert!(((anon_0::FIRST_A as i32) != (anon_0::FIRST_B as i32)));
assert!(((anon_1::SECOND_A as i32) != (anon_1::SECOND_B as i32)));
assert!(((anon_3::THIRD_A as i32) != (anon_3::THIRD_B as i32)));
let td: Value<TdEnum> = 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<WithAnonField> = Rc::new(RefCell::new(<WithAnonField>::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)));
(*(*w.borrow()).field.borrow_mut()) = anon_2::FIELD_A;
assert!((((*(*w.borrow()).field.borrow()) as i32) == (anon_2::FIELD_A as i32)));
(*(*w.borrow()).field.borrow_mut()) = anon_2::FIELD_B;
assert!((((*(*w.borrow()).field.borrow()) as i32) == (anon_2::FIELD_B as i32)));
return 0;
}
Loading
Loading