summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEmilio Cobos Álvarez <emilio@crisal.io>2017-04-19 10:44:27 +0200
committerEmilio Cobos Álvarez <emilio@crisal.io>2017-04-19 11:40:44 +0200
commit469a428242560625f4dc09025a93aad4166bab01 (patch)
tree86501528d02223732e6c1789017c721451754c94
parent5b74655a00f4838e711aa02468e80ffa33765623 (diff)
ir: consider all nested definitions inside structs to be inner types.
Fixes #643
-rw-r--r--src/ir/comp.rs18
-rw-r--r--tests/expectations/tests/issue-643-inner-struct.rs108
-rw-r--r--tests/headers/issue-643-inner-struct.h13
3 files changed, 129 insertions, 10 deletions
diff --git a/src/ir/comp.rs b/src/ir/comp.rs
index 7a85794b..2711c3cf 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 00000000..5069905b
--- /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<T>(::std::marker::PhantomData<T>);
+impl <T> __IncompleteArrayField<T> {
+ #[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 <T> ::std::fmt::Debug for __IncompleteArrayField<T> {
+ fn fmt(&self, fmt: &mut ::std::fmt::Formatter) -> ::std::fmt::Result {
+ fmt.write_str("__IncompleteArrayField")
+ }
+}
+impl <T> ::std::clone::Clone for __IncompleteArrayField<T> {
+ #[inline]
+ fn clone(&self) -> Self { Self::new() }
+}
+impl <T> ::std::marker::Copy for __IncompleteArrayField<T> { }
+#[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::<rte_ring_prod>() , 4usize , concat ! (
+ "Size of: " , stringify ! ( rte_ring_prod ) ));
+ assert_eq! (::std::mem::align_of::<rte_ring_prod>() , 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::<rte_ring_cons>() , 4usize , concat ! (
+ "Size of: " , stringify ! ( rte_ring_cons ) ));
+ assert_eq! (::std::mem::align_of::<rte_ring_cons>() , 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::<rte_ring>() , 16usize , concat ! (
+ "Size of: " , stringify ! ( rte_ring ) ));
+ assert_eq! (::std::mem::align_of::<rte_ring>() , 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 00000000..25c525b3
--- /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[];
+};