diff options
author | Emilio Cobos Álvarez <emilio@crisal.io> | 2017-02-07 13:35:34 +0100 |
---|---|---|
committer | Emilio Cobos Álvarez <emilio@crisal.io> | 2017-02-10 14:03:04 +0100 |
commit | 7e1b7d98d1da5a449ae18f6f60bac29b9079b9ab (patch) | |
tree | c210115eb181cbf45adc553f8aaaec557644db65 | |
parent | 0ae42f2c55305aab12b2f55346001b7d5539cb6f (diff) |
ir: Don't parse non-semantic-children cursor as inner structs.
Fixes: https://github.com/servo/rust-bindgen/issues/482
-rw-r--r-- | src/codegen/mod.rs | 2 | ||||
-rw-r--r-- | src/ir/comp.rs | 15 | ||||
-rw-r--r-- | tests/expectations/tests/class_nested.rs | 43 | ||||
-rw-r--r-- | tests/expectations/tests/layout_array.rs | 3 | ||||
-rw-r--r-- | tests/expectations/tests/layout_cmdline_token.rs | 107 | ||||
-rw-r--r-- | tests/expectations/tests/layout_mbuf.rs | 3 | ||||
-rw-r--r-- | tests/expectations/tests/struct_containing_forward_declared_struct.rs | 42 | ||||
-rw-r--r-- | tests/headers/class_nested.hpp | 12 |
8 files changed, 138 insertions, 89 deletions
diff --git a/src/codegen/mod.rs b/src/codegen/mod.rs index 7469abb9..99400f7a 100644 --- a/src/codegen/mod.rs +++ b/src/codegen/mod.rs @@ -2190,7 +2190,7 @@ impl ToRustTy for Type { .map(|arg| arg.to_rust_ty(ctx)) .collect::<Vec<_>>(); - path.segments.last_mut().unwrap().parameters = if + path.segments.last_mut().unwrap().parameters = if template_args.is_empty() { None } else { diff --git a/src/ir/comp.rs b/src/ir/comp.rs index b02cd342..7c58e233 100644 --- a/src/ir/comp.rs +++ b/src/ir/comp.rs @@ -669,11 +669,20 @@ impl CompInfo { CXCursor_UnionDecl | 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: + // + // https://github.com/servo/rust-bindgen/issues/482 + if cur.semantic_parent() != cursor { + return CXChildVisit_Continue; + } + let inner = Item::parse(cur, Some(potential_id), ctx) .expect("Inner ClassDecl"); - if !ci.inner_types.contains(&inner) { - ci.inner_types.push(inner); - } + + ci.inner_types.push(inner); + // A declaration of an union or a struct without name could // also be an unnamed field, unfortunately. if cur.spelling().is_empty() && diff --git a/tests/expectations/tests/class_nested.rs b/tests/expectations/tests/class_nested.rs index 19d70e50..6ddcf91b 100644 --- a/tests/expectations/tests/class_nested.rs +++ b/tests/expectations/tests/class_nested.rs @@ -29,6 +29,34 @@ fn bindgen_test_layout_A_B() { impl Clone for A_B { fn clone(&self) -> Self { *self } } +#[repr(C)] +#[derive(Debug, Default, Copy)] +pub struct A_C { + pub baz: ::std::os::raw::c_int, +} +#[test] +fn bindgen_test_layout_A_C() { + assert_eq!(::std::mem::size_of::<A_C>() , 4usize , concat ! ( + "Size of: " , stringify ! ( A_C ) )); + assert_eq! (::std::mem::align_of::<A_C>() , 4usize , concat ! ( + "Alignment of " , stringify ! ( A_C ) )); + assert_eq! (unsafe { + & ( * ( 0 as * const A_C ) ) . baz as * const _ as usize } , + 0usize , concat ! ( + "Alignment of field: " , stringify ! ( A_C ) , "::" , + stringify ! ( baz ) )); +} +impl Clone for A_C { + fn clone(&self) -> Self { *self } +} +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct A_D<T> { + pub foo: T, +} +impl <T> Default for A_D<T> { + fn default() -> Self { unsafe { ::std::mem::zeroed() } } +} #[test] fn bindgen_test_layout_A() { assert_eq!(::std::mem::size_of::<A>() , 4usize , concat ! ( @@ -48,6 +76,21 @@ extern "C" { #[link_name = "var"] pub static mut var: A_B; } +#[test] +fn __bindgen_test_layout_template_1() { + assert_eq!(::std::mem::size_of::<A_D<::std::os::raw::c_int>>() , 4usize , + concat ! ( + "Size of template specialization: " , stringify ! ( + A_D<::std::os::raw::c_int> ) )); + assert_eq!(::std::mem::align_of::<A_D<::std::os::raw::c_int>>() , 4usize , + concat ! ( + "Alignment of template specialization: " , stringify ! ( + A_D<::std::os::raw::c_int> ) )); +} +extern "C" { + #[link_name = "baz"] + pub static mut baz: A_D<::std::os::raw::c_int>; +} #[repr(C)] #[derive(Debug, Default, Copy)] pub struct D { diff --git a/tests/expectations/tests/layout_array.rs b/tests/expectations/tests/layout_array.rs index 3f86cda9..facf9462 100644 --- a/tests/expectations/tests/layout_array.rs +++ b/tests/expectations/tests/layout_array.rs @@ -202,9 +202,6 @@ pub struct malloc_heap { pub struct malloc_heap__bindgen_ty_1 { pub lh_first: *mut malloc_heap__bindgen_ty_1_malloc_elem, } -#[repr(C)] -#[derive(Debug, Copy, Clone)] -pub struct malloc_heap__bindgen_ty_1_malloc_elem([u8; 0]); #[test] fn bindgen_test_layout_malloc_heap__bindgen_ty_1() { assert_eq!(::std::mem::size_of::<malloc_heap__bindgen_ty_1>() , 8usize , diff --git a/tests/expectations/tests/layout_cmdline_token.rs b/tests/expectations/tests/layout_cmdline_token.rs index 35127399..791ea9b3 100644 --- a/tests/expectations/tests/layout_cmdline_token.rs +++ b/tests/expectations/tests/layout_cmdline_token.rs @@ -11,9 +11,33 @@ #[repr(C)] #[derive(Debug, Copy)] pub struct cmdline_token_hdr { - pub ops: *mut cmdline_token_hdr_cmdline_token_ops, + pub ops: *mut cmdline_token_ops, pub offset: ::std::os::raw::c_uint, } +#[test] +fn bindgen_test_layout_cmdline_token_hdr() { + assert_eq!(::std::mem::size_of::<cmdline_token_hdr>() , 16usize , concat ! + ( "Size of: " , stringify ! ( cmdline_token_hdr ) )); + assert_eq! (::std::mem::align_of::<cmdline_token_hdr>() , 8usize , concat + ! ( "Alignment of " , stringify ! ( cmdline_token_hdr ) )); + assert_eq! (unsafe { + & ( * ( 0 as * const cmdline_token_hdr ) ) . ops as * const _ + as usize } , 0usize , concat ! ( + "Alignment of field: " , stringify ! ( cmdline_token_hdr ) , + "::" , stringify ! ( ops ) )); + assert_eq! (unsafe { + & ( * ( 0 as * const cmdline_token_hdr ) ) . offset as * const + _ as usize } , 8usize , concat ! ( + "Alignment of field: " , stringify ! ( cmdline_token_hdr ) , + "::" , stringify ! ( offset ) )); +} +impl Clone for cmdline_token_hdr { + fn clone(&self) -> Self { *self } +} +impl Default for cmdline_token_hdr { + fn default() -> Self { unsafe { ::std::mem::zeroed() } } +} +pub type cmdline_parse_token_hdr_t = cmdline_token_hdr; /** * A token is defined by this structure. * @@ -35,7 +59,7 @@ pub struct cmdline_token_hdr { */ #[repr(C)] #[derive(Debug, Copy)] -pub struct cmdline_token_hdr_cmdline_token_ops { +pub struct cmdline_token_ops { /** parse(token ptr, buf, res pts, buf len) */ pub parse: ::std::option::Option<unsafe extern "C" fn(arg1: *mut cmdline_parse_token_hdr_t, @@ -70,71 +94,38 @@ pub struct cmdline_token_hdr_cmdline_token_ops { -> ::std::os::raw::c_int>, } #[test] -fn bindgen_test_layout_cmdline_token_hdr_cmdline_token_ops() { - assert_eq!(::std::mem::size_of::<cmdline_token_hdr_cmdline_token_ops>() , - 32usize , concat ! ( - "Size of: " , stringify ! ( cmdline_token_hdr_cmdline_token_ops - ) )); - assert_eq! (::std::mem::align_of::<cmdline_token_hdr_cmdline_token_ops>() - , 8usize , concat ! ( - "Alignment of " , stringify ! ( - cmdline_token_hdr_cmdline_token_ops ) )); +fn bindgen_test_layout_cmdline_token_ops() { + assert_eq!(::std::mem::size_of::<cmdline_token_ops>() , 32usize , concat ! + ( "Size of: " , stringify ! ( cmdline_token_ops ) )); + assert_eq! (::std::mem::align_of::<cmdline_token_ops>() , 8usize , concat + ! ( "Alignment of " , stringify ! ( cmdline_token_ops ) )); assert_eq! (unsafe { - & ( * ( 0 as * const cmdline_token_hdr_cmdline_token_ops ) ) . - parse as * const _ as usize } , 0usize , concat ! ( - "Alignment of field: " , stringify ! ( - cmdline_token_hdr_cmdline_token_ops ) , "::" , stringify ! ( - parse ) )); + & ( * ( 0 as * const cmdline_token_ops ) ) . parse as * const + _ as usize } , 0usize , concat ! ( + "Alignment of field: " , stringify ! ( cmdline_token_ops ) , + "::" , stringify ! ( parse ) )); assert_eq! (unsafe { - & ( * ( 0 as * const cmdline_token_hdr_cmdline_token_ops ) ) . - complete_get_nb as * const _ as usize } , 8usize , concat ! ( - "Alignment of field: " , stringify ! ( - cmdline_token_hdr_cmdline_token_ops ) , "::" , stringify ! ( - complete_get_nb ) )); + & ( * ( 0 as * const cmdline_token_ops ) ) . complete_get_nb + as * const _ as usize } , 8usize , concat ! ( + "Alignment of field: " , stringify ! ( cmdline_token_ops ) , + "::" , stringify ! ( complete_get_nb ) )); assert_eq! (unsafe { - & ( * ( 0 as * const cmdline_token_hdr_cmdline_token_ops ) ) . - complete_get_elt as * const _ as usize } , 16usize , concat ! - ( - "Alignment of field: " , stringify ! ( - cmdline_token_hdr_cmdline_token_ops ) , "::" , stringify ! ( - complete_get_elt ) )); + & ( * ( 0 as * const cmdline_token_ops ) ) . complete_get_elt + as * const _ as usize } , 16usize , concat ! ( + "Alignment of field: " , stringify ! ( cmdline_token_ops ) , + "::" , stringify ! ( complete_get_elt ) )); assert_eq! (unsafe { - & ( * ( 0 as * const cmdline_token_hdr_cmdline_token_ops ) ) . - get_help as * const _ as usize } , 24usize , concat ! ( - "Alignment of field: " , stringify ! ( - cmdline_token_hdr_cmdline_token_ops ) , "::" , stringify ! ( - get_help ) )); + & ( * ( 0 as * const cmdline_token_ops ) ) . get_help as * + const _ as usize } , 24usize , concat ! ( + "Alignment of field: " , stringify ! ( cmdline_token_ops ) , + "::" , stringify ! ( get_help ) )); } -impl Clone for cmdline_token_hdr_cmdline_token_ops { +impl Clone for cmdline_token_ops { fn clone(&self) -> Self { *self } } -impl Default for cmdline_token_hdr_cmdline_token_ops { +impl Default for cmdline_token_ops { fn default() -> Self { unsafe { ::std::mem::zeroed() } } } -#[test] -fn bindgen_test_layout_cmdline_token_hdr() { - assert_eq!(::std::mem::size_of::<cmdline_token_hdr>() , 16usize , concat ! - ( "Size of: " , stringify ! ( cmdline_token_hdr ) )); - assert_eq! (::std::mem::align_of::<cmdline_token_hdr>() , 8usize , concat - ! ( "Alignment of " , stringify ! ( cmdline_token_hdr ) )); - assert_eq! (unsafe { - & ( * ( 0 as * const cmdline_token_hdr ) ) . ops as * const _ - as usize } , 0usize , concat ! ( - "Alignment of field: " , stringify ! ( cmdline_token_hdr ) , - "::" , stringify ! ( ops ) )); - assert_eq! (unsafe { - & ( * ( 0 as * const cmdline_token_hdr ) ) . offset as * const - _ as usize } , 8usize , concat ! ( - "Alignment of field: " , stringify ! ( cmdline_token_hdr ) , - "::" , stringify ! ( offset ) )); -} -impl Clone for cmdline_token_hdr { - fn clone(&self) -> Self { *self } -} -impl Default for cmdline_token_hdr { - fn default() -> Self { unsafe { ::std::mem::zeroed() } } -} -pub type cmdline_parse_token_hdr_t = cmdline_token_hdr; #[repr(u32)] #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)] pub enum cmdline_numtype { diff --git a/tests/expectations/tests/layout_mbuf.rs b/tests/expectations/tests/layout_mbuf.rs index c0c2cce2..7bd3bf1a 100644 --- a/tests/expectations/tests/layout_mbuf.rs +++ b/tests/expectations/tests/layout_mbuf.rs @@ -490,9 +490,6 @@ impl Clone for rte_mbuf__bindgen_ty_4 { fn clone(&self) -> Self { *self } } #[repr(C)] -#[derive(Debug, Copy, Clone)] -pub struct rte_mbuf_rte_mempool([u8; 0]); -#[repr(C)] #[derive(Debug, Default, Copy)] pub struct rte_mbuf__bindgen_ty_5 { /**< combined for easy fetch */ diff --git a/tests/expectations/tests/struct_containing_forward_declared_struct.rs b/tests/expectations/tests/struct_containing_forward_declared_struct.rs index ff16490a..58ab04c9 100644 --- a/tests/expectations/tests/struct_containing_forward_declared_struct.rs +++ b/tests/expectations/tests/struct_containing_forward_declared_struct.rs @@ -7,27 +7,7 @@ #[repr(C)] #[derive(Debug, Copy)] pub struct a { - pub val_a: *mut a_b, -} -#[repr(C)] -#[derive(Debug, Default, Copy)] -pub struct a_b { - pub val_b: ::std::os::raw::c_int, -} -#[test] -fn bindgen_test_layout_a_b() { - assert_eq!(::std::mem::size_of::<a_b>() , 4usize , concat ! ( - "Size of: " , stringify ! ( a_b ) )); - assert_eq! (::std::mem::align_of::<a_b>() , 4usize , concat ! ( - "Alignment of " , stringify ! ( a_b ) )); - assert_eq! (unsafe { - & ( * ( 0 as * const a_b ) ) . val_b as * const _ as usize } , - 0usize , concat ! ( - "Alignment of field: " , stringify ! ( a_b ) , "::" , - stringify ! ( val_b ) )); -} -impl Clone for a_b { - fn clone(&self) -> Self { *self } + pub val_a: *mut b, } #[test] fn bindgen_test_layout_a() { @@ -47,3 +27,23 @@ impl Clone for a { impl Default for a { fn default() -> Self { unsafe { ::std::mem::zeroed() } } } +#[repr(C)] +#[derive(Debug, Default, Copy)] +pub struct b { + pub val_b: ::std::os::raw::c_int, +} +#[test] +fn bindgen_test_layout_b() { + assert_eq!(::std::mem::size_of::<b>() , 4usize , concat ! ( + "Size of: " , stringify ! ( b ) )); + assert_eq! (::std::mem::align_of::<b>() , 4usize , concat ! ( + "Alignment of " , stringify ! ( b ) )); + assert_eq! (unsafe { + & ( * ( 0 as * const b ) ) . val_b as * const _ as usize } , + 0usize , concat ! ( + "Alignment of field: " , stringify ! ( b ) , "::" , stringify + ! ( val_b ) )); +} +impl Clone for b { + fn clone(&self) -> Self { *self } +} diff --git a/tests/headers/class_nested.hpp b/tests/headers/class_nested.hpp index ab38d500..ccf2f895 100644 --- a/tests/headers/class_nested.hpp +++ b/tests/headers/class_nested.hpp @@ -4,9 +4,21 @@ public: class B { int member_b; }; + + class C; + + template<typename T> + class D { + T foo; + }; +}; + +class A::C { + int baz; }; A::B var; +A::D<int> baz; class D { A::B member; |