diff --git a/libbindgen/src/codegen/mod.rs b/libbindgen/src/codegen/mod.rs index 9ab264c671..2f18036a92 100644 --- a/libbindgen/src/codegen/mod.rs +++ b/libbindgen/src/codegen/mod.rs @@ -1660,11 +1660,21 @@ impl CodeGenerator for Enum { match seen_values.entry(variant.val()) { Entry::Occupied(ref entry) => { if is_rust_enum { - let existing_variant_name = entry.get(); let variant_name = ctx.rust_mangle(variant.name()); + let mangled_name = if is_toplevel || enum_ty.name().is_some() { + variant_name + } else { + let parent_name = parent_canonical_name.as_ref() + .unwrap(); + + Cow::Owned( + format!("{}_{}", parent_name, variant_name)) + }; + + let existing_variant_name = entry.get(); add_constant(enum_ty, &name, - &*variant_name, + &*mangled_name, existing_variant_name, enum_rust_ty.clone(), result); @@ -1688,8 +1698,6 @@ impl CodeGenerator for Enum { // If it's an unnamed enum, we also generate a constant so // it can be properly accessed. if is_rust_enum && enum_ty.name().is_none() { - // NB: if we want to do this for other kind of nested - // enums we can probably mangle the name. let mangled_name = if is_toplevel { variant_name.clone() } else { diff --git a/libbindgen/src/ir/function.rs b/libbindgen/src/ir/function.rs index 76576dbdd0..516c486e86 100644 --- a/libbindgen/src/ir/function.rs +++ b/libbindgen/src/ir/function.rs @@ -186,8 +186,14 @@ impl FunctionSig { }; let is_method = cursor.kind() == CXCursor_CXXMethod; + let is_constructor = cursor.kind() == CXCursor_Constructor; + if (is_constructor || is_method) && + cursor.lexical_parent() != cursor.semantic_parent() { + // Only parse constructors once. + return Err(ParseError::Continue); + } - if is_method || cursor.kind() == CXCursor_Constructor { + if is_method || is_constructor { let is_const = is_method && cursor.method_is_const(); let is_virtual = is_method && cursor.method_is_virtual(); let is_static = is_method && cursor.method_is_static(); diff --git a/libbindgen/tests/expectations/tests/anon_enum_trait.rs b/libbindgen/tests/expectations/tests/anon_enum_trait.rs new file mode 100644 index 0000000000..8198bc15ce --- /dev/null +++ b/libbindgen/tests/expectations/tests/anon_enum_trait.rs @@ -0,0 +1,47 @@ +/* automatically generated by rust-bindgen */ + + +#![allow(non_snake_case)] + + +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct DataType<_Tp> { + pub _address: u8, + pub _phantom_0: ::std::marker::PhantomData<_Tp>, +} +pub type DataType_value_type<_Tp> = _Tp; +pub type DataType_work_type<_Tp> = DataType_value_type<_Tp>; +pub type DataType_channel_type<_Tp> = DataType_value_type<_Tp>; +pub type DataType_vec_type<_Tp> = DataType_value_type<_Tp>; +pub const DataType_generic_type: DataType__bindgen_ty_1 = + DataType__bindgen_ty_1::generic_type; +pub const DataType_depth: DataType__bindgen_ty_1 = + DataType__bindgen_ty_1::generic_type; +pub const DataType_channels: DataType__bindgen_ty_1 = + DataType__bindgen_ty_1::generic_type; +pub const DataType_fmt: DataType__bindgen_ty_1 = + DataType__bindgen_ty_1::generic_type; +pub const DataType_type_: DataType__bindgen_ty_1 = + DataType__bindgen_ty_1::generic_type; +#[repr(i32)] +#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)] +pub enum DataType__bindgen_ty_1 { generic_type = 0, } +#[repr(C)] +#[derive(Debug, Copy)] +pub struct Foo { + pub _address: u8, +} +pub const Foo_Bar: Foo__bindgen_ty_1 = Foo__bindgen_ty_1::Bar; +pub const Foo_Baz: Foo__bindgen_ty_1 = Foo__bindgen_ty_1::Bar; +#[repr(u32)] +#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)] +pub enum Foo__bindgen_ty_1 { Bar = 0, } +#[test] +fn bindgen_test_layout_Foo() { + assert_eq!(::std::mem::size_of::() , 1usize); + assert_eq!(::std::mem::align_of::() , 1usize); +} +impl Clone for Foo { + fn clone(&self) -> Self { *self } +} diff --git a/libbindgen/tests/expectations/tests/constructor-tp.rs b/libbindgen/tests/expectations/tests/constructor-tp.rs new file mode 100644 index 0000000000..5022048910 --- /dev/null +++ b/libbindgen/tests/expectations/tests/constructor-tp.rs @@ -0,0 +1,37 @@ +/* automatically generated by rust-bindgen */ + + +#![allow(non_snake_case)] + + +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct Foo { + pub _address: u8, + pub _phantom_0: ::std::marker::PhantomData, +} +#[repr(C)] +#[derive(Debug, Copy)] +pub struct Bar { + pub _address: u8, +} +#[test] +fn bindgen_test_layout_Bar() { + assert_eq!(::std::mem::size_of::() , 1usize); + assert_eq!(::std::mem::align_of::() , 1usize); +} +extern "C" { + #[link_name = "_ZN3BarC1Ev"] + pub fn Bar_Bar(this: *mut Bar); +} +impl Clone for Bar { + fn clone(&self) -> Self { *self } +} +impl Bar { + #[inline] + pub unsafe fn new() -> Self { + let mut __bindgen_tmp = ::std::mem::uninitialized(); + Bar_Bar(&mut __bindgen_tmp); + __bindgen_tmp + } +} diff --git a/libbindgen/tests/headers/anon_enum_trait.hpp b/libbindgen/tests/headers/anon_enum_trait.hpp new file mode 100644 index 0000000000..e1ec394c30 --- /dev/null +++ b/libbindgen/tests/headers/anon_enum_trait.hpp @@ -0,0 +1,22 @@ + +template +class DataType { +public: + typedef _Tp value_type; + typedef value_type work_type; + typedef value_type channel_type; + typedef value_type vec_type; + enum { generic_type = 1, + depth = -1, + channels = 1, + fmt = 0, + type = -1, + }; +}; + +struct Foo { + enum { + Bar = 0, + Baz = 0, + }; +}; diff --git a/libbindgen/tests/headers/constructor-tp.hpp b/libbindgen/tests/headers/constructor-tp.hpp new file mode 100644 index 0000000000..6e55ea7852 --- /dev/null +++ b/libbindgen/tests/headers/constructor-tp.hpp @@ -0,0 +1,26 @@ + +template +class Foo { +public: + Foo(); + + void doBaz(); +}; + +template +inline void +Foo::doBaz() { +} + +class Bar { +public: + Bar(); +}; + +template +Foo::Foo() { +} + +inline +Bar::Bar() { +}