Skip to content

Commit 59987f1

Browse files
committed
codegen: Properly mangle nested anonymous enums with duplicated variants.
1 parent 31bd2d3 commit 59987f1

File tree

3 files changed

+81
-4
lines changed

3 files changed

+81
-4
lines changed

libbindgen/src/codegen/mod.rs

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1660,11 +1660,21 @@ impl CodeGenerator for Enum {
16601660
match seen_values.entry(variant.val()) {
16611661
Entry::Occupied(ref entry) => {
16621662
if is_rust_enum {
1663-
let existing_variant_name = entry.get();
16641663
let variant_name = ctx.rust_mangle(variant.name());
1664+
let mangled_name = if is_toplevel || enum_ty.name().is_some() {
1665+
variant_name
1666+
} else {
1667+
let parent_name = parent_canonical_name.as_ref()
1668+
.unwrap();
1669+
1670+
Cow::Owned(
1671+
format!("{}_{}", parent_name, variant_name))
1672+
};
1673+
1674+
let existing_variant_name = entry.get();
16651675
add_constant(enum_ty,
16661676
&name,
1667-
&*variant_name,
1677+
&*mangled_name,
16681678
existing_variant_name,
16691679
enum_rust_ty.clone(),
16701680
result);
@@ -1688,8 +1698,6 @@ impl CodeGenerator for Enum {
16881698
// If it's an unnamed enum, we also generate a constant so
16891699
// it can be properly accessed.
16901700
if is_rust_enum && enum_ty.name().is_none() {
1691-
// NB: if we want to do this for other kind of nested
1692-
// enums we can probably mangle the name.
16931701
let mangled_name = if is_toplevel {
16941702
variant_name.clone()
16951703
} else {
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
/* automatically generated by rust-bindgen */
2+
3+
4+
#![allow(non_snake_case)]
5+
6+
7+
#[repr(C)]
8+
#[derive(Debug, Copy, Clone)]
9+
pub struct DataType<_Tp> {
10+
pub _address: u8,
11+
pub _phantom_0: ::std::marker::PhantomData<_Tp>,
12+
}
13+
pub type DataType_value_type<_Tp> = _Tp;
14+
pub type DataType_work_type<_Tp> = DataType_value_type<_Tp>;
15+
pub type DataType_channel_type<_Tp> = DataType_value_type<_Tp>;
16+
pub type DataType_vec_type<_Tp> = DataType_value_type<_Tp>;
17+
pub const DataType_generic_type: DataType__bindgen_ty_1 =
18+
DataType__bindgen_ty_1::generic_type;
19+
pub const DataType_depth: DataType__bindgen_ty_1 =
20+
DataType__bindgen_ty_1::generic_type;
21+
pub const DataType_channels: DataType__bindgen_ty_1 =
22+
DataType__bindgen_ty_1::generic_type;
23+
pub const DataType_fmt: DataType__bindgen_ty_1 =
24+
DataType__bindgen_ty_1::generic_type;
25+
pub const DataType_type_: DataType__bindgen_ty_1 =
26+
DataType__bindgen_ty_1::generic_type;
27+
#[repr(i32)]
28+
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
29+
pub enum DataType__bindgen_ty_1 { generic_type = 0, }
30+
#[repr(C)]
31+
#[derive(Debug, Copy)]
32+
pub struct Foo {
33+
pub _address: u8,
34+
}
35+
pub const Foo_Bar: Foo__bindgen_ty_1 = Foo__bindgen_ty_1::Bar;
36+
pub const Foo_Baz: Foo__bindgen_ty_1 = Foo__bindgen_ty_1::Bar;
37+
#[repr(u32)]
38+
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
39+
pub enum Foo__bindgen_ty_1 { Bar = 0, }
40+
#[test]
41+
fn bindgen_test_layout_Foo() {
42+
assert_eq!(::std::mem::size_of::<Foo>() , 1usize);
43+
assert_eq!(::std::mem::align_of::<Foo>() , 1usize);
44+
}
45+
impl Clone for Foo {
46+
fn clone(&self) -> Self { *self }
47+
}
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
2+
template<typename _Tp>
3+
class DataType {
4+
public:
5+
typedef _Tp value_type;
6+
typedef value_type work_type;
7+
typedef value_type channel_type;
8+
typedef value_type vec_type;
9+
enum { generic_type = 1,
10+
depth = -1,
11+
channels = 1,
12+
fmt = 0,
13+
type = -1,
14+
};
15+
};
16+
17+
struct Foo {
18+
enum {
19+
Bar = 0,
20+
Baz = 0,
21+
};
22+
};

0 commit comments

Comments
 (0)