Auto merge of #518 - pornel:typedefstruct, r=emilio
typedef struct {} name
Fixes #427
It looks like clang is doing the hard work of getting the right name from the typedef, but it falls back to arbitrary pretty-printed descriptions if it can't find a typedef. I couldn't find an API to check whether the name comes from a typedef, so I just filter out non-ident-like spellings.
diff --git a/src/ir/ty.rs b/src/ir/ty.rs
index ec168f0..332ad23 100644
--- a/src/ir/ty.rs
+++ b/src/ir/ty.rs
@@ -311,19 +311,21 @@
match self.kind {
TypeKind::Named => {
let name = self.name().expect("Unnamed named type?");
- let mut chars = name.chars();
- let first = chars.next().unwrap();
- let mut remaining = chars;
-
- let valid = (first.is_alphabetic() || first == '_') &&
- remaining.all(|c| c.is_alphanumeric() || c == '_');
-
- !valid
+ !Self::is_valid_identifier(&name)
}
_ => false,
}
}
+ /// Checks whether the name looks like an identifier,
+ /// i.e. is alphanumeric (including '_') and does not start with a digit.
+ pub fn is_valid_identifier(name: &str) -> bool {
+ let mut chars = name.chars();
+ let first_valid = chars.next().map(|c| c.is_alphabetic() || c == '_').unwrap_or(false);
+
+ first_valid && chars.all(|c| c.is_alphanumeric() || c == '_')
+ }
+
/// See safe_canonical_type.
pub fn canonical_type<'tr>(&'tr self,
ctx: &'tr BindgenContext)
@@ -454,7 +456,6 @@
}
#[test]
-#[should_panic]
fn is_invalid_named_type_empty_name() {
let ty = Type::new(Some("".into()), None, TypeKind::Named, false);
assert!(ty.is_invalid_named_type())
@@ -1074,12 +1075,30 @@
}
CXType_Enum => {
let enum_ = Enum::from_ty(ty, ctx).expect("Not an enum?");
+
+ if name.is_empty() {
+ let pretty_name = ty.spelling();
+ if Self::is_valid_identifier(&pretty_name) {
+ name = pretty_name;
+ }
+ }
+
TypeKind::Enum(enum_)
}
CXType_Record => {
let complex =
CompInfo::from_ty(potential_id, ty, location, ctx)
.expect("Not a complex type?");
+
+ if name.is_empty() {
+ // The pretty-printed name may contain typedefed name,
+ // but may also be "struct (anonymous at .h:1)"
+ let pretty_name = ty.spelling();
+ if Self::is_valid_identifier(&pretty_name) {
+ name = pretty_name;
+ }
+ }
+
TypeKind::Comp(complex)
}
// FIXME: We stub vectors as arrays since in 99% of the cases the
diff --git a/tests/expectations/tests/anon_enum.rs b/tests/expectations/tests/anon_enum.rs
index 07ea481..71abc77 100644
--- a/tests/expectations/tests/anon_enum.rs
+++ b/tests/expectations/tests/anon_enum.rs
@@ -34,9 +34,6 @@
impl Clone for Test {
fn clone(&self) -> Self { *self }
}
-pub const Foo: _bindgen_ty_1 = _bindgen_ty_1::Foo;
-pub const Bar: _bindgen_ty_1 = _bindgen_ty_1::Bar;
#[repr(u32)]
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
-pub enum _bindgen_ty_1 { Foo = 0, Bar = 1, }
-pub use self::_bindgen_ty_1 as Baz;
+pub enum Baz { Foo = 0, Bar = 1, }
diff --git a/tests/expectations/tests/bitfield_method_mangling.rs b/tests/expectations/tests/bitfield_method_mangling.rs
index 0ab5fce..0a6c9fd 100644
--- a/tests/expectations/tests/bitfield_method_mangling.rs
+++ b/tests/expectations/tests/bitfield_method_mangling.rs
@@ -6,20 +6,23 @@
#[repr(C)]
#[derive(Debug, Default, Copy)]
-pub struct _bindgen_ty_1 {
+pub struct mach_msg_type_descriptor_t {
pub _bitfield_1: u32,
}
#[test]
-fn bindgen_test_layout__bindgen_ty_1() {
- assert_eq!(::std::mem::size_of::<_bindgen_ty_1>() , 4usize , concat ! (
- "Size of: " , stringify ! ( _bindgen_ty_1 ) ));
- assert_eq! (::std::mem::align_of::<_bindgen_ty_1>() , 4usize , concat ! (
- "Alignment of " , stringify ! ( _bindgen_ty_1 ) ));
+fn bindgen_test_layout_mach_msg_type_descriptor_t() {
+ assert_eq!(::std::mem::size_of::<mach_msg_type_descriptor_t>() , 4usize ,
+ concat ! (
+ "Size of: " , stringify ! ( mach_msg_type_descriptor_t ) ));
+ assert_eq! (::std::mem::align_of::<mach_msg_type_descriptor_t>() , 4usize
+ , concat ! (
+ "Alignment of " , stringify ! ( mach_msg_type_descriptor_t )
+ ));
}
-impl Clone for _bindgen_ty_1 {
+impl Clone for mach_msg_type_descriptor_t {
fn clone(&self) -> Self { *self }
}
-impl _bindgen_ty_1 {
+impl mach_msg_type_descriptor_t {
#[inline]
pub fn pad3(&self) -> ::std::os::raw::c_uint {
unsafe {
@@ -48,4 +51,3 @@
((val as u32 as u32) << 24u32) & (4278190080usize as u32);
}
}
-pub type mach_msg_type_descriptor_t = _bindgen_ty_1;
diff --git a/tests/expectations/tests/issue-410.rs b/tests/expectations/tests/issue-410.rs
index 2fe0f99..3c6cd28 100644
--- a/tests/expectations/tests/issue-410.rs
+++ b/tests/expectations/tests/issue-410.rs
@@ -38,6 +38,5 @@
}
}
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
- pub enum _bindgen_ty_1 { }
- pub use self::super::root::_bindgen_ty_1 as JSWhyMagic;
+ pub enum JSWhyMagic { }
}
diff --git a/tests/expectations/tests/layout_array.rs b/tests/expectations/tests/layout_array.rs
index c28d3ec..2cc8578 100644
--- a/tests/expectations/tests/layout_array.rs
+++ b/tests/expectations/tests/layout_array.rs
@@ -117,26 +117,25 @@
*/
#[repr(C)]
#[derive(Debug, Default, Copy)]
-pub struct _bindgen_ty_1 {
+pub struct rte_spinlock_t {
/**< lock status 0 = unlocked, 1 = locked */
pub locked: ::std::os::raw::c_int,
}
#[test]
-fn bindgen_test_layout__bindgen_ty_1() {
- assert_eq!(::std::mem::size_of::<_bindgen_ty_1>() , 4usize , concat ! (
- "Size of: " , stringify ! ( _bindgen_ty_1 ) ));
- assert_eq! (::std::mem::align_of::<_bindgen_ty_1>() , 4usize , concat ! (
- "Alignment of " , stringify ! ( _bindgen_ty_1 ) ));
+fn bindgen_test_layout_rte_spinlock_t() {
+ assert_eq!(::std::mem::size_of::<rte_spinlock_t>() , 4usize , concat ! (
+ "Size of: " , stringify ! ( rte_spinlock_t ) ));
+ assert_eq! (::std::mem::align_of::<rte_spinlock_t>() , 4usize , concat ! (
+ "Alignment of " , stringify ! ( rte_spinlock_t ) ));
assert_eq! (unsafe {
- & ( * ( 0 as * const _bindgen_ty_1 ) ) . locked as * const _
+ & ( * ( 0 as * const rte_spinlock_t ) ) . locked as * const _
as usize } , 0usize , concat ! (
- "Alignment of field: " , stringify ! ( _bindgen_ty_1 ) , "::"
+ "Alignment of field: " , stringify ! ( rte_spinlock_t ) , "::"
, stringify ! ( locked ) ));
}
-impl Clone for _bindgen_ty_1 {
+impl Clone for rte_spinlock_t {
fn clone(&self) -> Self { *self }
}
-pub type rte_spinlock_t = _bindgen_ty_1;
/**
* Structure storing the table of registered ops structs, each of which contain
* the function pointers for the mempool ops functions.
diff --git a/tests/expectations/tests/layout_mbuf.rs b/tests/expectations/tests/layout_mbuf.rs
index 189b50a..5732831 100644
--- a/tests/expectations/tests/layout_mbuf.rs
+++ b/tests/expectations/tests/layout_mbuf.rs
@@ -39,26 +39,25 @@
*/
#[repr(C)]
#[derive(Debug, Default, Copy)]
-pub struct _bindgen_ty_1 {
+pub struct rte_atomic16_t {
/**< An internal counter value. */
pub cnt: i16,
}
#[test]
-fn bindgen_test_layout__bindgen_ty_1() {
- assert_eq!(::std::mem::size_of::<_bindgen_ty_1>() , 2usize , concat ! (
- "Size of: " , stringify ! ( _bindgen_ty_1 ) ));
- assert_eq! (::std::mem::align_of::<_bindgen_ty_1>() , 2usize , concat ! (
- "Alignment of " , stringify ! ( _bindgen_ty_1 ) ));
+fn bindgen_test_layout_rte_atomic16_t() {
+ assert_eq!(::std::mem::size_of::<rte_atomic16_t>() , 2usize , concat ! (
+ "Size of: " , stringify ! ( rte_atomic16_t ) ));
+ assert_eq! (::std::mem::align_of::<rte_atomic16_t>() , 2usize , concat ! (
+ "Alignment of " , stringify ! ( rte_atomic16_t ) ));
assert_eq! (unsafe {
- & ( * ( 0 as * const _bindgen_ty_1 ) ) . cnt as * const _ as
+ & ( * ( 0 as * const rte_atomic16_t ) ) . cnt as * const _ as
usize } , 0usize , concat ! (
- "Alignment of field: " , stringify ! ( _bindgen_ty_1 ) , "::"
+ "Alignment of field: " , stringify ! ( rte_atomic16_t ) , "::"
, stringify ! ( cnt ) ));
}
-impl Clone for _bindgen_ty_1 {
+impl Clone for rte_atomic16_t {
fn clone(&self) -> Self { *self }
}
-pub type rte_atomic16_t = _bindgen_ty_1;
/**
* The generic rte_mbuf, containing a packet mbuf.
*/
diff --git a/tests/expectations/tests/struct_typedef.rs b/tests/expectations/tests/struct_typedef.rs
new file mode 100644
index 0000000..63811bd
--- /dev/null
+++ b/tests/expectations/tests/struct_typedef.rs
@@ -0,0 +1,61 @@
+/* automatically generated by rust-bindgen */
+
+
+#![allow(non_snake_case)]
+
+
+#[repr(C)]
+#[derive(Debug, Default, Copy)]
+pub struct typedef_named_struct {
+ pub has_name: bool,
+}
+#[test]
+fn bindgen_test_layout_typedef_named_struct() {
+ assert_eq!(::std::mem::size_of::<typedef_named_struct>() , 1usize , concat
+ ! ( "Size of: " , stringify ! ( typedef_named_struct ) ));
+ assert_eq! (::std::mem::align_of::<typedef_named_struct>() , 1usize ,
+ concat ! (
+ "Alignment of " , stringify ! ( typedef_named_struct ) ));
+ assert_eq! (unsafe {
+ & ( * ( 0 as * const typedef_named_struct ) ) . has_name as *
+ const _ as usize } , 0usize , concat ! (
+ "Alignment of field: " , stringify ! ( typedef_named_struct )
+ , "::" , stringify ! ( has_name ) ));
+}
+impl Clone for typedef_named_struct {
+ fn clone(&self) -> Self { *self }
+}
+#[repr(C)]
+#[derive(Debug, Copy)]
+pub struct _bindgen_ty_1 {
+ pub no_name: *mut ::std::os::raw::c_void,
+}
+#[test]
+fn bindgen_test_layout__bindgen_ty_1() {
+ assert_eq!(::std::mem::size_of::<_bindgen_ty_1>() , 8usize , concat ! (
+ "Size of: " , stringify ! ( _bindgen_ty_1 ) ));
+ assert_eq! (::std::mem::align_of::<_bindgen_ty_1>() , 8usize , concat ! (
+ "Alignment of " , stringify ! ( _bindgen_ty_1 ) ));
+ assert_eq! (unsafe {
+ & ( * ( 0 as * const _bindgen_ty_1 ) ) . no_name as * const _
+ as usize } , 0usize , concat ! (
+ "Alignment of field: " , stringify ! ( _bindgen_ty_1 ) , "::"
+ , stringify ! ( no_name ) ));
+}
+impl Clone for _bindgen_ty_1 {
+ fn clone(&self) -> Self { *self }
+}
+impl Default for _bindgen_ty_1 {
+ fn default() -> Self { unsafe { ::std::mem::zeroed() } }
+}
+pub type struct_ptr_t = *mut _bindgen_ty_1;
+pub type struct_ptr_ptr_t = *mut *mut _bindgen_ty_1;
+#[repr(u32)]
+#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
+pub enum typedef_named_enum { ENUM_HAS_NAME = 1, }
+pub const ENUM_IS_ANON: _bindgen_ty_2 = _bindgen_ty_2::ENUM_IS_ANON;
+#[repr(u32)]
+#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
+pub enum _bindgen_ty_2 { ENUM_IS_ANON = 0, }
+pub type enum_ptr_t = *mut _bindgen_ty_2;
+pub type enum_ptr_ptr_t = *mut *mut _bindgen_ty_2;
diff --git a/tests/expectations/tests/struct_typedef_ns.rs b/tests/expectations/tests/struct_typedef_ns.rs
new file mode 100644
index 0000000..d7ada7f
--- /dev/null
+++ b/tests/expectations/tests/struct_typedef_ns.rs
@@ -0,0 +1,79 @@
+/* automatically generated by rust-bindgen */
+
+
+#![allow(non_snake_case)]
+
+
+pub mod root {
+ #[allow(unused_imports)]
+ use self::super::root;
+ pub mod whatever {
+ #[allow(unused_imports)]
+ use self::super::super::root;
+ #[repr(C)]
+ #[derive(Debug, Default, Copy)]
+ pub struct _bindgen_ty_1 {
+ pub foo: ::std::os::raw::c_int,
+ }
+ #[test]
+ fn bindgen_test_layout__bindgen_ty_1() {
+ assert_eq!(::std::mem::size_of::<_bindgen_ty_1>() , 4usize ,
+ concat ! ( "Size of: " , stringify ! ( _bindgen_ty_1 )
+ ));
+ assert_eq! (::std::mem::align_of::<_bindgen_ty_1>() , 4usize ,
+ concat ! (
+ "Alignment of " , stringify ! ( _bindgen_ty_1 ) ));
+ assert_eq! (unsafe {
+ & ( * ( 0 as * const _bindgen_ty_1 ) ) . foo as *
+ const _ as usize } , 0usize , concat ! (
+ "Alignment of field: " , stringify ! ( _bindgen_ty_1 )
+ , "::" , stringify ! ( foo ) ));
+ }
+ impl Clone for _bindgen_ty_1 {
+ fn clone(&self) -> Self { *self }
+ }
+ pub type typedef_struct = root::whatever::_bindgen_ty_1;
+ pub const whatever_BAR: root::whatever::_bindgen_ty_2 =
+ _bindgen_ty_2::BAR;
+ #[repr(u32)]
+ #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
+ pub enum _bindgen_ty_2 { BAR = 1, }
+ pub use self::super::super::root::whatever::_bindgen_ty_2 as
+ typedef_enum;
+ }
+ pub mod _bindgen_mod_id_12 {
+ #[allow(unused_imports)]
+ use self::super::super::root;
+ #[repr(C)]
+ #[derive(Debug, Default, Copy)]
+ pub struct _bindgen_ty_1 {
+ pub foo: ::std::os::raw::c_int,
+ }
+ #[test]
+ fn bindgen_test_layout__bindgen_ty_1() {
+ assert_eq!(::std::mem::size_of::<_bindgen_ty_1>() , 4usize ,
+ concat ! ( "Size of: " , stringify ! ( _bindgen_ty_1 )
+ ));
+ assert_eq! (::std::mem::align_of::<_bindgen_ty_1>() , 4usize ,
+ concat ! (
+ "Alignment of " , stringify ! ( _bindgen_ty_1 ) ));
+ assert_eq! (unsafe {
+ & ( * ( 0 as * const _bindgen_ty_1 ) ) . foo as *
+ const _ as usize } , 0usize , concat ! (
+ "Alignment of field: " , stringify ! ( _bindgen_ty_1 )
+ , "::" , stringify ! ( foo ) ));
+ }
+ impl Clone for _bindgen_ty_1 {
+ fn clone(&self) -> Self { *self }
+ }
+ pub type typedef_struct = root::_bindgen_mod_id_12::_bindgen_ty_1;
+ pub const _bindgen_mod_id_12_BAR:
+ root::_bindgen_mod_id_12::_bindgen_ty_2 =
+ _bindgen_ty_2::BAR;
+ #[repr(u32)]
+ #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
+ pub enum _bindgen_ty_2 { BAR = 1, }
+ pub use self::super::super::root::_bindgen_mod_id_12::_bindgen_ty_2 as
+ typedef_enum;
+ }
+}
diff --git a/tests/expectations/tests/union_fields.rs b/tests/expectations/tests/union_fields.rs
index 823a0b8..8c8ef7d 100644
--- a/tests/expectations/tests/union_fields.rs
+++ b/tests/expectations/tests/union_fields.rs
@@ -30,35 +30,34 @@
}
#[repr(C)]
#[derive(Debug, Default, Copy)]
-pub struct _bindgen_ty_1 {
+pub struct nsStyleUnion {
pub mInt: __BindgenUnionField<::std::os::raw::c_int>,
pub mFloat: __BindgenUnionField<f32>,
pub mPointer: __BindgenUnionField<*mut ::std::os::raw::c_void>,
pub bindgen_union_field: u64,
}
#[test]
-fn bindgen_test_layout__bindgen_ty_1() {
- assert_eq!(::std::mem::size_of::<_bindgen_ty_1>() , 8usize , concat ! (
- "Size of: " , stringify ! ( _bindgen_ty_1 ) ));
- assert_eq! (::std::mem::align_of::<_bindgen_ty_1>() , 8usize , concat ! (
- "Alignment of " , stringify ! ( _bindgen_ty_1 ) ));
+fn bindgen_test_layout_nsStyleUnion() {
+ assert_eq!(::std::mem::size_of::<nsStyleUnion>() , 8usize , concat ! (
+ "Size of: " , stringify ! ( nsStyleUnion ) ));
+ assert_eq! (::std::mem::align_of::<nsStyleUnion>() , 8usize , concat ! (
+ "Alignment of " , stringify ! ( nsStyleUnion ) ));
assert_eq! (unsafe {
- & ( * ( 0 as * const _bindgen_ty_1 ) ) . mInt as * const _ as
+ & ( * ( 0 as * const nsStyleUnion ) ) . mInt as * const _ as
usize } , 0usize , concat ! (
- "Alignment of field: " , stringify ! ( _bindgen_ty_1 ) , "::"
- , stringify ! ( mInt ) ));
+ "Alignment of field: " , stringify ! ( nsStyleUnion ) , "::" ,
+ stringify ! ( mInt ) ));
assert_eq! (unsafe {
- & ( * ( 0 as * const _bindgen_ty_1 ) ) . mFloat as * const _
- as usize } , 0usize , concat ! (
- "Alignment of field: " , stringify ! ( _bindgen_ty_1 ) , "::"
- , stringify ! ( mFloat ) ));
+ & ( * ( 0 as * const nsStyleUnion ) ) . mFloat as * const _ as
+ usize } , 0usize , concat ! (
+ "Alignment of field: " , stringify ! ( nsStyleUnion ) , "::" ,
+ stringify ! ( mFloat ) ));
assert_eq! (unsafe {
- & ( * ( 0 as * const _bindgen_ty_1 ) ) . mPointer as * const _
+ & ( * ( 0 as * const nsStyleUnion ) ) . mPointer as * const _
as usize } , 0usize , concat ! (
- "Alignment of field: " , stringify ! ( _bindgen_ty_1 ) , "::"
- , stringify ! ( mPointer ) ));
+ "Alignment of field: " , stringify ! ( nsStyleUnion ) , "::" ,
+ stringify ! ( mPointer ) ));
}
-impl Clone for _bindgen_ty_1 {
+impl Clone for nsStyleUnion {
fn clone(&self) -> Self { *self }
}
-pub type nsStyleUnion = _bindgen_ty_1;
diff --git a/tests/expectations/tests/unknown_attr.rs b/tests/expectations/tests/unknown_attr.rs
index efb8610..2c50c36 100644
--- a/tests/expectations/tests/unknown_attr.rs
+++ b/tests/expectations/tests/unknown_attr.rs
@@ -6,30 +6,29 @@
#[repr(C)]
#[derive(Debug, Default, Copy)]
-pub struct _bindgen_ty_1 {
+pub struct max_align_t {
pub __clang_max_align_nonce1: ::std::os::raw::c_longlong,
pub __bindgen_padding_0: u64,
pub __clang_max_align_nonce2: f64,
pub __bindgen_padding_1: u64,
}
#[test]
-fn bindgen_test_layout__bindgen_ty_1() {
- assert_eq!(::std::mem::size_of::<_bindgen_ty_1>() , 32usize , concat ! (
- "Size of: " , stringify ! ( _bindgen_ty_1 ) ));
+fn bindgen_test_layout_max_align_t() {
+ assert_eq!(::std::mem::size_of::<max_align_t>() , 32usize , concat ! (
+ "Size of: " , stringify ! ( max_align_t ) ));
assert_eq! (unsafe {
- & ( * ( 0 as * const _bindgen_ty_1 ) ) .
+ & ( * ( 0 as * const max_align_t ) ) .
__clang_max_align_nonce1 as * const _ as usize } , 0usize ,
concat ! (
- "Alignment of field: " , stringify ! ( _bindgen_ty_1 ) , "::"
- , stringify ! ( __clang_max_align_nonce1 ) ));
+ "Alignment of field: " , stringify ! ( max_align_t ) , "::" ,
+ stringify ! ( __clang_max_align_nonce1 ) ));
assert_eq! (unsafe {
- & ( * ( 0 as * const _bindgen_ty_1 ) ) .
+ & ( * ( 0 as * const max_align_t ) ) .
__clang_max_align_nonce2 as * const _ as usize } , 16usize ,
concat ! (
- "Alignment of field: " , stringify ! ( _bindgen_ty_1 ) , "::"
- , stringify ! ( __clang_max_align_nonce2 ) ));
+ "Alignment of field: " , stringify ! ( max_align_t ) , "::" ,
+ stringify ! ( __clang_max_align_nonce2 ) ));
}
-impl Clone for _bindgen_ty_1 {
+impl Clone for max_align_t {
fn clone(&self) -> Self { *self }
}
-pub type max_align_t = _bindgen_ty_1;
diff --git a/tests/headers/struct_typedef.h b/tests/headers/struct_typedef.h
new file mode 100644
index 0000000..fdce9a7
--- /dev/null
+++ b/tests/headers/struct_typedef.h
@@ -0,0 +1,15 @@
+typedef struct {
+ _Bool has_name;
+} typedef_named_struct;
+
+typedef struct {
+ void *no_name;
+} *struct_ptr_t, **struct_ptr_ptr_t;
+
+typedef enum {
+ ENUM_HAS_NAME=1
+} typedef_named_enum;
+
+typedef enum {
+ ENUM_IS_ANON
+} *enum_ptr_t, **enum_ptr_ptr_t;
diff --git a/tests/headers/struct_typedef_ns.hpp b/tests/headers/struct_typedef_ns.hpp
new file mode 100644
index 0000000..bc89eb2
--- /dev/null
+++ b/tests/headers/struct_typedef_ns.hpp
@@ -0,0 +1,21 @@
+// bindgen-flags: --enable-cxx-namespaces
+
+namespace whatever {
+ typedef struct {
+ int foo;
+ } typedef_struct;
+
+ typedef enum {
+ BAR=1
+ } typedef_enum;
+}
+
+namespace {
+ typedef struct {
+ int foo;
+ } typedef_struct;
+
+ typedef enum {
+ BAR=1
+ } typedef_enum;
+}