Skip to content

Commit a56262e

Browse files
committed
Improve generation of typedef types.
Fixes rust-lang#169.
1 parent 8002891 commit a56262e

File tree

9 files changed

+226
-155
lines changed

9 files changed

+226
-155
lines changed

Changelog.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ This project adheres to [Semantic Versioning](http://semver.org/).
99
in the output of `--help`)
1010
- Map stdint.h + size_t types to Rust native ones (#256)
1111
- Default to fail on unknown type (see `-allow-unknown-types`)
12+
- Convert C `typedef struct {} Test` to rust `struct Test {}` (#169)
1213

1314
### Added
1415
- `-no-rust-enums` generate integer constants instead of enums

src/gen.rs

Lines changed: 60 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -55,10 +55,12 @@ fn rust_type_id(ctx: &mut GenCtx, name: &str) -> String {
5555
}
5656
}
5757

58+
const UNNAMED_PREFIX: &'static str = "Unnamed";
59+
5860
fn unnamed_name(ctx: &mut GenCtx, name: &str) -> String {
5961
if name.is_empty() {
6062
ctx.unnamed_ty += 1;
61-
format!("Unnamed{}", ctx.unnamed_ty)
63+
format!("{}{}", UNNAMED_PREFIX, ctx.unnamed_ty)
6264
} else {
6365
name.into()
6466
}
@@ -72,15 +74,27 @@ fn comp_name(kind: CompKind, name: &str) -> String {
7274
}
7375

7476
fn struct_name(name: &str) -> String {
75-
format!("Struct_{}", name)
77+
if name.starts_with(UNNAMED_PREFIX) {
78+
format!("Struct_{}", name)
79+
} else {
80+
name.into()
81+
}
7682
}
7783

7884
fn union_name(name: &str) -> String {
79-
format!("Union_{}", name)
85+
if name.starts_with(UNNAMED_PREFIX) {
86+
format!("Union_{}", name)
87+
} else {
88+
name.into()
89+
}
8090
}
8191

8292
fn enum_name(name: &str) -> String {
83-
format!("Enum_{}", name)
93+
if name.starts_with(UNNAMED_PREFIX) {
94+
format!("Enum_{}", name)
95+
} else {
96+
name.into()
97+
}
8498
}
8599

86100
fn extract_definitions(ctx: &mut GenCtx,
@@ -177,6 +191,47 @@ fn extract_functions(ctx: &mut GenCtx,
177191
map
178192
}
179193

194+
/// Converts `typedef struct {...} Test` to rust `struct Test {...}`
195+
fn remove_unnamed(globals: &mut Vec<Global>) {
196+
let mut i = 1;
197+
while i < globals.len() {
198+
let mut remove = false;
199+
match globals[i] {
200+
GType(ref t) => {
201+
let t = t.borrow();
202+
match t.ty {
203+
TComp(ref c) => {
204+
let mut c = c.borrow_mut();
205+
if c.name.is_empty() {
206+
c.name = t.name.clone();
207+
remove = true;
208+
} else if c.name == t.name {
209+
remove = true;
210+
}
211+
}
212+
TEnum(ref e) => {
213+
let mut e = e.borrow_mut();
214+
if e.name.is_empty() {
215+
e.name = t.name.clone();
216+
remove = true;
217+
} else if e.name == t.name {
218+
remove = true;
219+
}
220+
}
221+
_ => (),
222+
}
223+
}
224+
_ => (),
225+
}
226+
227+
if remove {
228+
globals.remove(i);
229+
} else {
230+
i += 1;
231+
}
232+
}
233+
}
234+
180235
pub fn gen_mod(
181236
options: &BindgenOptions,
182237
globs: Vec<Global>,
@@ -241,6 +296,7 @@ pub fn gen_mod(
241296
}
242297

243298
gs = remove_redundant_decl(gs);
299+
remove_unnamed(&mut gs);
244300
let mut defs = extract_definitions(&mut ctx, options, &gs);
245301

246302
let vars = vs.into_iter().map(|v| {

tests/headers/typedef_same_name.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
typedef struct SameS SameS;
2+
typedef enum SameE SameE;
3+
typedef union SameU SameU;

tests/test_enum.rs

Lines changed: 52 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -11,19 +11,19 @@ fn with_simple_enum() {
1111
#[derive(Copy, Clone)]
1212
#[repr(u32)]
1313
#[derive(Debug)]
14-
pub enum Enum_Foo { Bar = 0, Qux = 1, }
14+
pub enum Foo { Bar = 0, Qux = 1, }
1515
#[derive(Copy, Clone)]
1616
#[repr(i32)]
1717
#[derive(Debug)]
18-
pub enum Enum_Neg { MinusOne = -1, One = 1, }
18+
pub enum Neg { MinusOne = -1, One = 1, }
1919
");
2020
assert_bind_eq(default_without_rust_enums(), "headers/enum.h", "
21-
type Enum_Foo = u32;
22-
const Bar: Enum_Foo = 0;
23-
const Qux: Enum_Foo = 1;
24-
type Enum_Neg = i32;
25-
const MinusOne: Enum_Neg = -1;
26-
const One: Enum_Neg = 1;
21+
type Foo = u32;
22+
const Bar: Foo = 0;
23+
const Qux: Foo = 1;
24+
type Neg = i32;
25+
const MinusOne: Neg = -1;
26+
const One: Neg = 1;
2727
");
2828
}
2929

@@ -33,42 +33,42 @@ fn with_packed_enums() {
3333
#[derive(Copy, Clone)]
3434
#[repr(u8)]
3535
#[derive(Debug)]
36-
pub enum Enum_Foo { Bar = 0, Qux = 1, }
36+
pub enum Foo { Bar = 0, Qux = 1, }
3737
#[derive(Copy, Clone)]
3838
#[repr(i8)]
3939
#[derive(Debug)]
40-
pub enum Enum_Neg { MinusOne = -1, One = 1, }
40+
pub enum Neg { MinusOne = -1, One = 1, }
4141
#[derive(Copy, Clone)]
4242
#[repr(u16)]
4343
#[derive(Debug)]
44-
pub enum Enum_Bigger { Much = 255, Larger = 256, }
44+
pub enum Bigger { Much = 255, Larger = 256, }
4545
");
4646
assert_bind_eq(default_without_rust_enums(), "headers/enum_packed.h", "
47-
type Enum_Foo = u8;
48-
const Bar: Enum_Foo = 0;
49-
const Qux: Enum_Foo = 1;
50-
type Enum_Neg = i8;
51-
const MinusOne: Enum_Neg = -1;
52-
const One: Enum_Neg = 1;
53-
type Enum_Bigger = u16;
54-
const Much: Enum_Bigger = 255;
55-
const Larger: Enum_Bigger = 256;
47+
type Foo = u8;
48+
const Bar: Foo = 0;
49+
const Qux: Foo = 1;
50+
type Neg = i8;
51+
const MinusOne: Neg = -1;
52+
const One: Neg = 1;
53+
type Bigger = u16;
54+
const Much: Bigger = 255;
55+
const Larger: Bigger = 256;
5656
");
5757
}
5858

5959
#[test]
6060
fn with_duplicate_enum_value() {
6161
assert_bind_eq(Default::default(), "headers/enum_dupe.h", "
62-
pub const Dupe: Enum_Foo = Enum_Foo::Bar;
62+
pub const Dupe: Foo = Foo::Bar;
6363
#[derive(Copy, Clone)]
6464
#[repr(u32)]
6565
#[derive(Debug)]
66-
pub enum Enum_Foo { Bar = 1, }
66+
pub enum Foo { Bar = 1, }
6767
");
6868
assert_bind_eq(default_without_rust_enums(), "headers/enum_dupe.h", "
69-
type Enum_Foo = u32;
70-
const Bar: Enum_Foo = 1;
71-
const Dupe: Enum_Foo = 1;
69+
type Foo = u32;
70+
const Bar: Foo = 1;
71+
const Dupe: Foo = 1;
7272
");
7373
}
7474

@@ -78,38 +78,38 @@ fn with_explicitly_typed_cxx_enum() {
7878
#[derive(Copy, Clone)]
7979
#[repr(u8)]
8080
#[derive(Debug)]
81-
pub enum Enum_Foo { Bar = 0, Qux = 1, }
81+
pub enum Foo { Bar = 0, Qux = 1, }
8282
#[derive(Copy, Clone)]
8383
#[repr(i8)]
8484
#[derive(Debug)]
85-
pub enum Enum_Neg { MinusOne = -1, One = 1, }
85+
pub enum Neg { MinusOne = -1, One = 1, }
8686
#[derive(Copy, Clone)]
8787
#[repr(u16)]
8888
#[derive(Debug)]
89-
pub enum Enum_Bigger { Much = 255, Larger = 256, }
89+
pub enum Bigger { Much = 255, Larger = 256, }
9090
#[derive(Copy, Clone)]
9191
#[repr(i64)]
9292
#[derive(Debug)]
93-
pub enum Enum_MuchLong { MuchLow = -4294967296, }
93+
pub enum MuchLong { MuchLow = -4294967296, }
9494
#[derive(Copy, Clone)]
9595
#[repr(u64)]
9696
#[derive(Debug)]
97-
pub enum Enum_MuchLongLong { MuchHigh = 4294967296, }
97+
pub enum MuchLongLong { MuchHigh = 4294967296, }
9898
");
9999
assert_bind_eq(default_without_rust_enums(), "headers/enum_explicit_type.hpp", "
100-
type Enum_Foo = u8;
101-
const Bar: Enum_Foo = 0;
102-
const Qux: Enum_Foo = 1;
103-
type Enum_Neg = i8;
104-
const MinusOne: Enum_Neg = -1;
105-
const One: Enum_Neg = 1;
106-
type Enum_Bigger = u16;
107-
const Much: Enum_Bigger = 255;
108-
const Larger: Enum_Bigger = 256;
109-
type Enum_MuchLong = i64;
110-
const MuchLow: Enum_MuchLong = -4294967296;
111-
type Enum_MuchLongLong = u64;
112-
const MuchHigh: Enum_MuchLongLong = 4294967296;
100+
type Foo = u8;
101+
const Bar: Foo = 0;
102+
const Qux: Foo = 1;
103+
type Neg = i8;
104+
const MinusOne: Neg = -1;
105+
const One: Neg = 1;
106+
type Bigger = u16;
107+
const Much: Bigger = 255;
108+
const Larger: Bigger = 256;
109+
type MuchLong = i64;
110+
const MuchLow: MuchLong = -4294967296;
111+
type MuchLongLong = u64;
112+
const MuchHigh: MuchLongLong = 4294967296;
113113
");
114114
}
115115

@@ -119,23 +119,23 @@ fn with_overflowed_enum_value() {
119119
#[derive(Copy, Clone)]
120120
#[repr(u32)]
121121
#[derive(Debug)]
122-
pub enum Enum_Foo {
122+
pub enum Foo {
123123
BAP_ARM = 9698489,
124124
BAP_X86 = 11960045,
125125
BAP_X86_64 = 3128633167,
126126
}
127127
#[derive(Copy, Clone)]
128128
#[repr(u16)]
129129
#[derive(Debug)]
130-
pub enum Enum_Bar { One = 1, Big = 2, }
130+
pub enum Bar { One = 1, Big = 2, }
131131
");
132132
assert_bind_eq(default_without_rust_enums(), "headers/overflowed_enum.hpp", "
133-
type Enum_Foo = u32;
134-
const BAP_ARM: Enum_Foo = 9698489;
135-
const BAP_X86: Enum_Foo = 11960045;
136-
const BAP_X86_64: Enum_Foo = 3128633167;
137-
type Enum_Bar = u16;
138-
const One: Enum_Bar = 1;
139-
const Big: Enum_Bar = 2;
133+
type Foo = u32;
134+
const BAP_ARM: Foo = 9698489;
135+
const BAP_X86: Foo = 11960045;
136+
const BAP_X86_64: Foo = 3128633167;
137+
type Bar = u16;
138+
const One: Bar = 1;
139+
const Big: Bar = 2;
140140
");
141141
}

tests/test_func.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -17,16 +17,16 @@ fn func_ptr_in_struct() {
1717
#[derive(Copy, Clone)]
1818
#[repr(u32)]
1919
#[derive(Debug)]
20-
pub enum Enum_baz { TEST = 0, }
20+
pub enum baz { TEST = 0, }
2121
#[repr(C)]
2222
#[derive(Copy, Clone)]
2323
#[derive(Debug)]
24-
pub struct Struct_Foo {
24+
pub struct Foo {
2525
pub bar: ::std::option::Option<
2626
extern \"C\" fn(x: ::std::os::raw::c_int,
27-
y: ::std::os::raw::c_int) -> Enum_baz>,
27+
y: ::std::os::raw::c_int) -> baz>,
2828
}
29-
impl ::std::default::Default for Struct_Foo {
29+
impl ::std::default::Default for Foo {
3030
fn default() -> Self { unsafe { ::std::mem::zeroed() } }
3131
}
3232
");

0 commit comments

Comments
 (0)