Skip to content

Commit 673cb5f

Browse files
author
bors-servo
authored
Auto merge of #346 - emilio:fix-dtors, r=fitzgen
codegen: Properly mangle nested anonymous enums with duplicated variants. r? @fitzgen
2 parents 46b52e6 + ce0a254 commit 673cb5f

File tree

6 files changed

+151
-5
lines changed

6 files changed

+151
-5
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 {

libbindgen/src/ir/function.rs

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -186,8 +186,14 @@ impl FunctionSig {
186186
};
187187

188188
let is_method = cursor.kind() == CXCursor_CXXMethod;
189+
let is_constructor = cursor.kind() == CXCursor_Constructor;
190+
if (is_constructor || is_method) &&
191+
cursor.lexical_parent() != cursor.semantic_parent() {
192+
// Only parse constructors once.
193+
return Err(ParseError::Continue);
194+
}
189195

190-
if is_method || cursor.kind() == CXCursor_Constructor {
196+
if is_method || is_constructor {
191197
let is_const = is_method && cursor.method_is_const();
192198
let is_virtual = is_method && cursor.method_is_virtual();
193199
let is_static = is_method && cursor.method_is_static();
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: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
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 Foo<T> {
10+
pub _address: u8,
11+
pub _phantom_0: ::std::marker::PhantomData<T>,
12+
}
13+
#[repr(C)]
14+
#[derive(Debug, Copy)]
15+
pub struct Bar {
16+
pub _address: u8,
17+
}
18+
#[test]
19+
fn bindgen_test_layout_Bar() {
20+
assert_eq!(::std::mem::size_of::<Bar>() , 1usize);
21+
assert_eq!(::std::mem::align_of::<Bar>() , 1usize);
22+
}
23+
extern "C" {
24+
#[link_name = "_ZN3BarC1Ev"]
25+
pub fn Bar_Bar(this: *mut Bar);
26+
}
27+
impl Clone for Bar {
28+
fn clone(&self) -> Self { *self }
29+
}
30+
impl Bar {
31+
#[inline]
32+
pub unsafe fn new() -> Self {
33+
let mut __bindgen_tmp = ::std::mem::uninitialized();
34+
Bar_Bar(&mut __bindgen_tmp);
35+
__bindgen_tmp
36+
}
37+
}
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+
};
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
2+
template<typename T>
3+
class Foo {
4+
public:
5+
Foo();
6+
7+
void doBaz();
8+
};
9+
10+
template<typename T>
11+
inline void
12+
Foo<T>::doBaz() {
13+
}
14+
15+
class Bar {
16+
public:
17+
Bar();
18+
};
19+
20+
template<typename T>
21+
Foo<T>::Foo() {
22+
}
23+
24+
inline
25+
Bar::Bar() {
26+
}

0 commit comments

Comments
 (0)