diff --git a/src/ir/comp.rs b/src/ir/comp.rs index 7a85794b41..2711c3cf97 100644 --- a/src/ir/comp.rs +++ b/src/ir/comp.rs @@ -588,21 +588,19 @@ impl CompInfo { CXCursor_ClassTemplate | CXCursor_ClassDecl => { // We can find non-semantic children here, clang uses a - // StructDecl to note incomplete structs that hasn't been - // forward-declared before, see: + // StructDecl to note incomplete structs that haven't been + // forward-declared before, see [1]. // // Also, clang seems to scope struct definitions inside - // unions to the whole translation unit. Since those are - // anonymous, let's just assume that if the cursor we've - // found is a definition it's a valid inner type. + // unions, and other named struct definitions inside other + // structs to the whole translation unit. // - // Note that doing this could be always ok, but let's just - // keep the union check for now. + // Let's just assume that if the cursor we've found is a + // definition, it's a valid inner type. // - // https://github.com/servo/rust-bindgen/issues/482 + // [1]: https://github.com/servo/rust-bindgen/issues/482 let is_inner_struct = cur.semantic_parent() == cursor || - (kind == CompKind::Union && - cur.is_definition()); + cur.is_definition(); if !is_inner_struct { return CXChildVisit_Continue; } diff --git a/tests/expectations/tests/issue-643-inner-struct.rs b/tests/expectations/tests/issue-643-inner-struct.rs new file mode 100644 index 0000000000..5069905b3d --- /dev/null +++ b/tests/expectations/tests/issue-643-inner-struct.rs @@ -0,0 +1,108 @@ +/* automatically generated by rust-bindgen */ + + +#![allow(non_snake_case)] + + +#[repr(C)] +#[derive(Default)] +pub struct __IncompleteArrayField(::std::marker::PhantomData); +impl __IncompleteArrayField { + #[inline] + pub fn new() -> Self { + __IncompleteArrayField(::std::marker::PhantomData) + } + #[inline] + pub unsafe fn as_ptr(&self) -> *const T { ::std::mem::transmute(self) } + #[inline] + pub unsafe fn as_mut_ptr(&mut self) -> *mut T { + ::std::mem::transmute(self) + } + #[inline] + pub unsafe fn as_slice(&self, len: usize) -> &[T] { + ::std::slice::from_raw_parts(self.as_ptr(), len) + } + #[inline] + pub unsafe fn as_mut_slice(&mut self, len: usize) -> &mut [T] { + ::std::slice::from_raw_parts_mut(self.as_mut_ptr(), len) + } +} +impl ::std::fmt::Debug for __IncompleteArrayField { + fn fmt(&self, fmt: &mut ::std::fmt::Formatter) -> ::std::fmt::Result { + fmt.write_str("__IncompleteArrayField") + } +} +impl ::std::clone::Clone for __IncompleteArrayField { + #[inline] + fn clone(&self) -> Self { Self::new() } +} +impl ::std::marker::Copy for __IncompleteArrayField { } +#[repr(C)] +#[derive(Debug, Copy)] +pub struct rte_ring { + pub memzone: *mut rte_memzone, + pub prod: rte_ring_prod, + pub cons: rte_ring_cons, + pub ring: __IncompleteArrayField<*mut ::std::os::raw::c_void>, +} +#[repr(C)] +#[derive(Debug, Default, Copy)] +pub struct rte_ring_prod { + pub watermark: ::std::os::raw::c_uint, +} +#[test] +fn bindgen_test_layout_rte_ring_prod() { + assert_eq!(::std::mem::size_of::() , 4usize , concat ! ( + "Size of: " , stringify ! ( rte_ring_prod ) )); + assert_eq! (::std::mem::align_of::() , 4usize , concat ! ( + "Alignment of " , stringify ! ( rte_ring_prod ) )); + assert_eq! (unsafe { + & ( * ( 0 as * const rte_ring_prod ) ) . watermark as * const + _ as usize } , 0usize , concat ! ( + "Alignment of field: " , stringify ! ( rte_ring_prod ) , "::" + , stringify ! ( watermark ) )); +} +impl Clone for rte_ring_prod { + fn clone(&self) -> Self { *self } +} +#[repr(C)] +#[derive(Debug, Default, Copy)] +pub struct rte_ring_cons { + pub sc_dequeue: ::std::os::raw::c_uint, +} +#[test] +fn bindgen_test_layout_rte_ring_cons() { + assert_eq!(::std::mem::size_of::() , 4usize , concat ! ( + "Size of: " , stringify ! ( rte_ring_cons ) )); + assert_eq! (::std::mem::align_of::() , 4usize , concat ! ( + "Alignment of " , stringify ! ( rte_ring_cons ) )); + assert_eq! (unsafe { + & ( * ( 0 as * const rte_ring_cons ) ) . sc_dequeue as * const + _ as usize } , 0usize , concat ! ( + "Alignment of field: " , stringify ! ( rte_ring_cons ) , "::" + , stringify ! ( sc_dequeue ) )); +} +impl Clone for rte_ring_cons { + fn clone(&self) -> Self { *self } +} +#[test] +fn bindgen_test_layout_rte_ring() { + assert_eq!(::std::mem::size_of::() , 16usize , concat ! ( + "Size of: " , stringify ! ( rte_ring ) )); + assert_eq! (::std::mem::align_of::() , 8usize , concat ! ( + "Alignment of " , stringify ! ( rte_ring ) )); +} +impl Clone for rte_ring { + fn clone(&self) -> Self { *self } +} +impl Default for rte_ring { + fn default() -> Self { unsafe { ::std::mem::zeroed() } } +} +#[repr(C)] +#[derive(Debug, Default, Copy)] +pub struct rte_memzone { + pub _address: u8, +} +impl Clone for rte_memzone { + fn clone(&self) -> Self { *self } +} diff --git a/tests/headers/issue-643-inner-struct.h b/tests/headers/issue-643-inner-struct.h new file mode 100644 index 0000000000..25c525b357 --- /dev/null +++ b/tests/headers/issue-643-inner-struct.h @@ -0,0 +1,13 @@ +struct rte_ring { + struct rte_memzone *memzone; + + struct prod { + unsigned watermark; + } prod; + + struct cons { + unsigned sc_dequeue; + } cons; + + void *ring[]; +};