Skip to content

Commit 15fbe1d

Browse files
lucic71nunoplopes
andcommitted
Avoid collision between tag and typedef identifier (#166)
C allows name collision between the following 2 declarations: ```c struct X {}; typedef enum {} X; ``` The 2 declarations live in different name spaces: 6.2.3 Name spaces of identifiers [...] there are separate namespaces for various categories of identifiers, as follows: 1. the tags of structures, unions, and enumerations (disambiguated by following any) of the keywords struct, union, or enum); 2. all other identifiers, called ordinary identifiers (declared in ordinary declarators or as enumeration constants). `struct X {}` lives in namespace 1 and `typedef enum {} X` lives in namespace 2. We cannot translate both to `X` in the Rust code. We need to disambiguate between the 2 names. I chose to translate them as: ``` struct X {} -> X typedef enum {} X -> X_enum ``` C++ does not have the name space rule for identifiers. I added the `tag->getASTContext().getLangOpts().CPlusPlus` check in DisambiguateAnonymousTag to avoid polluting the C++ generated files. --------- Co-authored-by: Nuno Lopes <nuno.lopes@tecnico.ulisboa.pt>
1 parent 42a07be commit 15fbe1d

5 files changed

Lines changed: 100 additions & 98 deletions

File tree

tests/unit/out/refcount/anonymous_enum_c.rs

Lines changed: 38 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -7,37 +7,37 @@ use std::io::{Read, Seek, Write};
77
use std::os::fd::AsFd;
88
use std::rc::{Rc, Weak};
99
#[derive(Clone, Copy, PartialEq, Debug, Default)]
10-
enum anon_0 {
10+
enum anon_enum_3 {
1111
#[default]
1212
FIRST_A = 0,
1313
FIRST_B = 1,
1414
}
15-
impl From<i32> for anon_0 {
16-
fn from(n: i32) -> anon_0 {
15+
impl From<i32> for anon_enum_3 {
16+
fn from(n: i32) -> anon_enum_3 {
1717
match n {
18-
0 => anon_0::FIRST_A,
19-
1 => anon_0::FIRST_B,
20-
_ => panic!("invalid anon_0 value: {}", n),
18+
0 => anon_enum_3::FIRST_A,
19+
1 => anon_enum_3::FIRST_B,
20+
_ => panic!("invalid anon_enum_3 value: {}", n),
2121
}
2222
}
2323
}
24-
libcc2rs::impl_enum_inc_dec!(anon_0);
24+
libcc2rs::impl_enum_inc_dec!(anon_enum_3);
2525
#[derive(Clone, Copy, PartialEq, Debug, Default)]
26-
enum anon_1 {
26+
enum anon_enum_11 {
2727
#[default]
2828
SECOND_A = 0,
2929
SECOND_B = 1,
3030
}
31-
impl From<i32> for anon_1 {
32-
fn from(n: i32) -> anon_1 {
31+
impl From<i32> for anon_enum_11 {
32+
fn from(n: i32) -> anon_enum_11 {
3333
match n {
34-
0 => anon_1::SECOND_A,
35-
1 => anon_1::SECOND_B,
36-
_ => panic!("invalid anon_1 value: {}", n),
34+
0 => anon_enum_11::SECOND_A,
35+
1 => anon_enum_11::SECOND_B,
36+
_ => panic!("invalid anon_enum_11 value: {}", n),
3737
}
3838
}
3939
}
40-
libcc2rs::impl_enum_inc_dec!(anon_1);
40+
libcc2rs::impl_enum_inc_dec!(anon_enum_11);
4141
#[derive(Default)]
4242
pub struct S {
4343
pub a: Value<i32>,
@@ -69,63 +69,65 @@ impl From<i32> for TdEnum_enum {
6969
}
7070
libcc2rs::impl_enum_inc_dec!(TdEnum_enum);
7171
#[derive(Clone, Copy, PartialEq, Debug, Default)]
72-
enum anon_2 {
72+
enum anon_enum_24 {
7373
#[default]
7474
FIELD_A = 0,
7575
FIELD_B = 1,
7676
}
77-
impl From<i32> for anon_2 {
78-
fn from(n: i32) -> anon_2 {
77+
impl From<i32> for anon_enum_24 {
78+
fn from(n: i32) -> anon_enum_24 {
7979
match n {
80-
0 => anon_2::FIELD_A,
81-
1 => anon_2::FIELD_B,
82-
_ => panic!("invalid anon_2 value: {}", n),
80+
0 => anon_enum_24::FIELD_A,
81+
1 => anon_enum_24::FIELD_B,
82+
_ => panic!("invalid anon_enum_24 value: {}", n),
8383
}
8484
}
8585
}
86-
libcc2rs::impl_enum_inc_dec!(anon_2);
86+
libcc2rs::impl_enum_inc_dec!(anon_enum_24);
8787
#[derive(Default)]
8888
pub struct WithAnonField {
8989
pub a: Value<i32>,
90-
pub field: Value<anon_2>,
90+
pub field: Value<anon_enum_24>,
9191
}
9292
impl ByteRepr for WithAnonField {}
9393
pub fn main() {
9494
std::process::exit(main_0());
9595
}
9696
fn main_0() -> i32 {
9797
#[derive(Clone, Copy, PartialEq, Debug, Default)]
98-
enum anon_3 {
98+
enum anon_enum_31 {
9999
#[default]
100100
THIRD_A = 0,
101101
THIRD_B = 1,
102102
}
103-
impl From<i32> for anon_3 {
104-
fn from(n: i32) -> anon_3 {
103+
impl From<i32> for anon_enum_31 {
104+
fn from(n: i32) -> anon_enum_31 {
105105
match n {
106-
0 => anon_3::THIRD_A,
107-
1 => anon_3::THIRD_B,
108-
_ => panic!("invalid anon_3 value: {}", n),
106+
0 => anon_enum_31::THIRD_A,
107+
1 => anon_enum_31::THIRD_B,
108+
_ => panic!("invalid anon_enum_31 value: {}", n),
109109
}
110110
}
111111
}
112-
libcc2rs::impl_enum_inc_dec!(anon_3);
113-
assert!(((((anon_0::FIRST_A as i32) != (anon_0::FIRST_B as i32)) as i32) != 0));
114-
assert!(((((anon_1::SECOND_A as i32) != (anon_1::SECOND_B as i32)) as i32) != 0));
115-
assert!(((((anon_3::THIRD_A as i32) != (anon_3::THIRD_B as i32)) as i32) != 0));
112+
libcc2rs::impl_enum_inc_dec!(anon_enum_31);
113+
assert!(((((anon_enum_3::FIRST_A as i32) != (anon_enum_3::FIRST_B as i32)) as i32) != 0));
114+
assert!(((((anon_enum_11::SECOND_A as i32) != (anon_enum_11::SECOND_B as i32)) as i32) != 0));
115+
assert!(((((anon_enum_31::THIRD_A as i32) != (anon_enum_31::THIRD_B as i32)) as i32) != 0));
116116
let td: Value<TdEnum_enum> = Rc::new(RefCell::new(TdEnum_enum::TD_A));
117117
assert!((((((*td.borrow()) as u32) == ((TdEnum_enum::TD_A as i32) as u32)) as i32) != 0));
118118
(*td.borrow_mut()) = TdEnum_enum::TD_B;
119119
assert!((((((*td.borrow()) as u32) == ((TdEnum_enum::TD_B as i32) as u32)) as i32) != 0));
120120
let w: Value<WithAnonField> = <Value<WithAnonField>>::default();
121-
(*(*w.borrow()).field.borrow_mut()) = anon_2::FIELD_A;
121+
(*(*w.borrow()).field.borrow_mut()) = anon_enum_24::FIELD_A;
122122
assert!(
123-
(((((*(*w.borrow()).field.borrow()) as u32) == ((anon_2::FIELD_A as i32) as u32)) as i32)
123+
(((((*(*w.borrow()).field.borrow()) as u32) == ((anon_enum_24::FIELD_A as i32) as u32))
124+
as i32)
124125
!= 0)
125126
);
126-
(*(*w.borrow()).field.borrow_mut()) = anon_2::FIELD_B;
127+
(*(*w.borrow()).field.borrow_mut()) = anon_enum_24::FIELD_B;
127128
assert!(
128-
(((((*(*w.borrow()).field.borrow()) as u32) == ((anon_2::FIELD_B as i32) as u32)) as i32)
129+
(((((*(*w.borrow()).field.borrow()) as u32) == ((anon_enum_24::FIELD_B as i32) as u32))
130+
as i32)
129131
!= 0)
130132
);
131133
return 0;

tests/unit/out/refcount/enum_int_interop_c.rs

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -81,17 +81,17 @@ thread_local!(
8181
thread_local!(
8282
pub static entries_3: Value<Box<[Entry]>> = Rc::new(RefCell::new(Box::new([
8383
Entry {
84-
name: Rc::new(RefCell::new(Ptr::from_string_literal(b"first"))),
84+
name: Rc::new(RefCell::new(Ptr::from_string_literal("first"))),
8585
color: Rc::new(RefCell::new(Color::RED)),
8686
opt: Rc::new(RefCell::new(Option::OPT_NONE)),
8787
},
8888
Entry {
89-
name: Rc::new(RefCell::new(Ptr::from_string_literal(b"second"))),
89+
name: Rc::new(RefCell::new(Ptr::from_string_literal("second"))),
9090
color: Rc::new(RefCell::new(Color::GREEN)),
9191
opt: Rc::new(RefCell::new(Option::OPT_A)),
9292
},
9393
Entry {
94-
name: Rc::new(RefCell::new(Ptr::from_string_literal(b"third"))),
94+
name: Rc::new(RefCell::new(Ptr::from_string_literal("third"))),
9595
color: Rc::new(RefCell::new(Color::BLUE)),
9696
opt: Rc::new(RefCell::new(Option::OPT_C)),
9797
},
@@ -106,16 +106,16 @@ pub fn classify_option_5(option: i32) -> i32 {
106106
'switch: {
107107
let __match_cond = (*option.borrow());
108108
match __match_cond {
109-
__v if __v == (Option::OPT_NONE as i32) => {
109+
v if v == (Option::OPT_NONE as i32) => {
110110
return -1_i32;
111111
}
112-
__v if __v == (Option::OPT_A as i32) => {
112+
v if v == (Option::OPT_A as i32) => {
113113
return 1;
114114
}
115-
__v if __v == (Option::OPT_B as i32) => {
115+
v if v == (Option::OPT_B as i32) => {
116116
return 2;
117117
}
118-
__v if __v == (Option::OPT_C as i32) => {
118+
v if v == (Option::OPT_C as i32) => {
119119
return 3;
120120
}
121121
_ => {
@@ -143,13 +143,13 @@ fn main_0() -> i32 {
143143
'switch: {
144144
let __match_cond = ((*c.borrow()) as u32);
145145
match __match_cond {
146-
__v if __v == (0 as u32) => {
146+
v if v == (0 as u32) => {
147147
break 'switch;
148148
}
149-
__v if __v == (1 as u32) => {
149+
v if v == (1 as u32) => {
150150
return 1;
151151
}
152-
__v if __v == (2 as u32) => {
152+
v if v == (2 as u32) => {
153153
return 2;
154154
}
155155
_ => {
@@ -209,13 +209,13 @@ fn main_0() -> i32 {
209209
'switch: {
210210
let __match_cond = ((*t.borrow()) as u32);
211211
match __match_cond {
212-
__v if __v == ((Tag_enum::TAG_ZERO as i32) as u32) => {
212+
v if v == ((Tag_enum::TAG_ZERO as i32) as u32) => {
213213
return 90;
214214
}
215-
__v if __v == (1 as u32) => {
215+
v if v == (1 as u32) => {
216216
return 91;
217217
}
218-
__v if __v == (2 as u32) => {
218+
v if v == (2 as u32) => {
219219
break 'switch;
220220
}
221221
_ => {}

tests/unit/out/unsafe/anonymous_enum_c.rs

Lines changed: 36 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -7,37 +7,37 @@ use std::io::{Read, Seek, Write};
77
use std::os::fd::{AsFd, FromRawFd, IntoRawFd};
88
use std::rc::Rc;
99
#[derive(Clone, Copy, PartialEq, Debug, Default)]
10-
enum anon_0 {
10+
enum anon_enum_3 {
1111
#[default]
1212
FIRST_A = 0,
1313
FIRST_B = 1,
1414
}
15-
impl From<i32> for anon_0 {
16-
fn from(n: i32) -> anon_0 {
15+
impl From<i32> for anon_enum_3 {
16+
fn from(n: i32) -> anon_enum_3 {
1717
match n {
18-
0 => anon_0::FIRST_A,
19-
1 => anon_0::FIRST_B,
20-
_ => panic!("invalid anon_0 value: {}", n),
18+
0 => anon_enum_3::FIRST_A,
19+
1 => anon_enum_3::FIRST_B,
20+
_ => panic!("invalid anon_enum_3 value: {}", n),
2121
}
2222
}
2323
}
24-
libcc2rs::impl_enum_inc_dec!(anon_0);
24+
libcc2rs::impl_enum_inc_dec!(anon_enum_3);
2525
#[derive(Clone, Copy, PartialEq, Debug, Default)]
26-
enum anon_1 {
26+
enum anon_enum_11 {
2727
#[default]
2828
SECOND_A = 0,
2929
SECOND_B = 1,
3030
}
31-
impl From<i32> for anon_1 {
32-
fn from(n: i32) -> anon_1 {
31+
impl From<i32> for anon_enum_11 {
32+
fn from(n: i32) -> anon_enum_11 {
3333
match n {
34-
0 => anon_1::SECOND_A,
35-
1 => anon_1::SECOND_B,
36-
_ => panic!("invalid anon_1 value: {}", n),
34+
0 => anon_enum_11::SECOND_A,
35+
1 => anon_enum_11::SECOND_B,
36+
_ => panic!("invalid anon_enum_11 value: {}", n),
3737
}
3838
}
3939
}
40-
libcc2rs::impl_enum_inc_dec!(anon_1);
40+
libcc2rs::impl_enum_inc_dec!(anon_enum_11);
4141
#[repr(C)]
4242
#[derive(Copy, Clone, Default)]
4343
pub struct S {
@@ -60,26 +60,26 @@ impl From<i32> for TdEnum_enum {
6060
}
6161
libcc2rs::impl_enum_inc_dec!(TdEnum_enum);
6262
#[derive(Clone, Copy, PartialEq, Debug, Default)]
63-
enum anon_2 {
63+
enum anon_enum_24 {
6464
#[default]
6565
FIELD_A = 0,
6666
FIELD_B = 1,
6767
}
68-
impl From<i32> for anon_2 {
69-
fn from(n: i32) -> anon_2 {
68+
impl From<i32> for anon_enum_24 {
69+
fn from(n: i32) -> anon_enum_24 {
7070
match n {
71-
0 => anon_2::FIELD_A,
72-
1 => anon_2::FIELD_B,
73-
_ => panic!("invalid anon_2 value: {}", n),
71+
0 => anon_enum_24::FIELD_A,
72+
1 => anon_enum_24::FIELD_B,
73+
_ => panic!("invalid anon_enum_24 value: {}", n),
7474
}
7575
}
7676
}
77-
libcc2rs::impl_enum_inc_dec!(anon_2);
77+
libcc2rs::impl_enum_inc_dec!(anon_enum_24);
7878
#[repr(C)]
7979
#[derive(Copy, Clone, Default)]
8080
pub struct WithAnonField {
8181
pub a: i32,
82-
pub field: anon_2,
82+
pub field: anon_enum_24,
8383
}
8484
pub fn main() {
8585
unsafe {
@@ -88,32 +88,32 @@ pub fn main() {
8888
}
8989
unsafe fn main_0() -> i32 {
9090
#[derive(Clone, Copy, PartialEq, Debug, Default)]
91-
enum anon_3 {
91+
enum anon_enum_31 {
9292
#[default]
9393
THIRD_A = 0,
9494
THIRD_B = 1,
9595
}
96-
impl From<i32> for anon_3 {
97-
fn from(n: i32) -> anon_3 {
96+
impl From<i32> for anon_enum_31 {
97+
fn from(n: i32) -> anon_enum_31 {
9898
match n {
99-
0 => anon_3::THIRD_A,
100-
1 => anon_3::THIRD_B,
101-
_ => panic!("invalid anon_3 value: {}", n),
99+
0 => anon_enum_31::THIRD_A,
100+
1 => anon_enum_31::THIRD_B,
101+
_ => panic!("invalid anon_enum_31 value: {}", n),
102102
}
103103
}
104104
}
105-
libcc2rs::impl_enum_inc_dec!(anon_3);
106-
assert!(((((anon_0::FIRST_A as i32) != (anon_0::FIRST_B as i32)) as i32) != 0));
107-
assert!(((((anon_1::SECOND_A as i32) != (anon_1::SECOND_B as i32)) as i32) != 0));
108-
assert!(((((anon_3::THIRD_A as i32) != (anon_3::THIRD_B as i32)) as i32) != 0));
105+
libcc2rs::impl_enum_inc_dec!(anon_enum_31);
106+
assert!(((((anon_enum_3::FIRST_A as i32) != (anon_enum_3::FIRST_B as i32)) as i32) != 0));
107+
assert!(((((anon_enum_11::SECOND_A as i32) != (anon_enum_11::SECOND_B as i32)) as i32) != 0));
108+
assert!(((((anon_enum_31::THIRD_A as i32) != (anon_enum_31::THIRD_B as i32)) as i32) != 0));
109109
let mut td: TdEnum_enum = TdEnum_enum::TD_A;
110110
assert!(((((td as u32) == ((TdEnum_enum::TD_A as i32) as u32)) as i32) != 0));
111111
td = (TdEnum_enum::TD_B).clone();
112112
assert!(((((td as u32) == ((TdEnum_enum::TD_B as i32) as u32)) as i32) != 0));
113113
let mut w: WithAnonField = <WithAnonField>::default();
114-
w.field = anon_2::FIELD_A;
115-
assert!(((((w.field as u32) == ((anon_2::FIELD_A as i32) as u32)) as i32) != 0));
116-
w.field = (anon_2::FIELD_B).clone();
117-
assert!(((((w.field as u32) == ((anon_2::FIELD_B as i32) as u32)) as i32) != 0));
114+
w.field = anon_enum_24::FIELD_A;
115+
assert!(((((w.field as u32) == ((anon_enum_24::FIELD_A as i32) as u32)) as i32) != 0));
116+
w.field = (anon_enum_24::FIELD_B).clone();
117+
assert!(((((w.field as u32) == ((anon_enum_24::FIELD_B as i32) as u32)) as i32) != 0));
118118
return 0;
119119
}

0 commit comments

Comments
 (0)