Skip to content

Commit

Permalink
Ensure that every item is in some module's children list
Browse files Browse the repository at this point in the history
Previously, if an item's parent was not a module (eg a nested class definition
whose parent it the outer class definition) and the parent was not whitelisted
but the item was transitively whitelisted, then we could generate uses of the
item without emitting any definition for it. This could happen because we were
relying on the outer type calling for code generation on its inner types, but
that relies on us doing code generation for the outer type, which won't happen
if the outer type is not whitelisted.

This commit avoids this gotcha by ensuring that all items end up in a module's
children list, and so will be code generated even if their parent is not
whitelisted.

Fixes rust-lang#769
  • Loading branch information
fitzgen committed Jun 19, 2017
1 parent 77d6962 commit 5baaa4d
Show file tree
Hide file tree
Showing 110 changed files with 1,053 additions and 755 deletions.
10 changes: 10 additions & 0 deletions src/codegen/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -435,6 +435,16 @@ impl CodeGenerator for Var {
}
result.saw_var(&canonical_name);

// We can't generate bindings to static variables of templates. The
// number of actual variables for a single declaration are open ended
// and we don't know what instantiations do or don't exist.
let type_params = item.all_template_params(ctx);
if let Some(params) = type_params {
if !params.is_empty() {
return;
}
}

let ty = self.ty().to_rust_ty_or_opaque(ctx, &());

if let Some(val) = self.val() {
Expand Down
21 changes: 19 additions & 2 deletions src/ir/context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -348,14 +348,31 @@ impl<'ctx> BindgenContext<'ctx> {
let is_template_instantiation =
is_type && item.expect_type().is_template_instantiation();

// Be sure to track all the generated children under namespace, even
// those generated after resolving typerefs, etc.
// Ensure that every item (other than the root module) is in a module's
// children list.
if item.id() != item.parent_id() {
let mut added_as_child = false;

if let Some(mut parent) = self.items.get_mut(&item.parent_id()) {
if let Some(mut module) = parent.as_module_mut() {
module.children_mut().push(item.id());
added_as_child = true;
}
}

if !added_as_child {
if let Some(mut current_module) = self.items.get_mut(&self.current_module) {
current_module.as_module_mut()
.expect("self.current_module should always be a module")
.children_mut()
.push(item.id());
added_as_child = true;
}
}

assert!(added_as_child,
"We should have added the item as a child of its parent \
module or the current module");
}

if is_type && item.expect_type().is_comp() {
Expand Down
56 changes: 28 additions & 28 deletions tests/expectations/tests/16-byte-alignment.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,20 +30,6 @@ impl <T> ::std::fmt::Debug for __BindgenUnionField<T> {
}
#[repr(C)]
#[derive(Debug, Default, Copy)]
pub struct rte_ipv4_tuple {
pub src_addr: u32,
pub dst_addr: u32,
pub __bindgen_anon_1: rte_ipv4_tuple__bindgen_ty_1,
}
#[repr(C)]
#[derive(Debug, Default, Copy)]
pub struct rte_ipv4_tuple__bindgen_ty_1 {
pub __bindgen_anon_1: __BindgenUnionField<rte_ipv4_tuple__bindgen_ty_1__bindgen_ty_1>,
pub sctp_tag: __BindgenUnionField<u32>,
pub bindgen_union_field: u32,
}
#[repr(C)]
#[derive(Debug, Default, Copy)]
pub struct rte_ipv4_tuple__bindgen_ty_1__bindgen_ty_1 {
pub dport: u16,
pub sport: u16,
Expand Down Expand Up @@ -76,6 +62,13 @@ fn bindgen_test_layout_rte_ipv4_tuple__bindgen_ty_1__bindgen_ty_1() {
impl Clone for rte_ipv4_tuple__bindgen_ty_1__bindgen_ty_1 {
fn clone(&self) -> Self { *self }
}
#[repr(C)]
#[derive(Debug, Default, Copy)]
pub struct rte_ipv4_tuple__bindgen_ty_1 {
pub __bindgen_anon_1: __BindgenUnionField<rte_ipv4_tuple__bindgen_ty_1__bindgen_ty_1>,
pub sctp_tag: __BindgenUnionField<u32>,
pub bindgen_union_field: u32,
}
#[test]
fn bindgen_test_layout_rte_ipv4_tuple__bindgen_ty_1() {
assert_eq!(::std::mem::size_of::<rte_ipv4_tuple__bindgen_ty_1>() , 4usize
Expand All @@ -95,6 +88,13 @@ fn bindgen_test_layout_rte_ipv4_tuple__bindgen_ty_1() {
impl Clone for rte_ipv4_tuple__bindgen_ty_1 {
fn clone(&self) -> Self { *self }
}
#[repr(C)]
#[derive(Debug, Default, Copy)]
pub struct rte_ipv4_tuple {
pub src_addr: u32,
pub dst_addr: u32,
pub __bindgen_anon_1: rte_ipv4_tuple__bindgen_ty_1,
}
#[test]
fn bindgen_test_layout_rte_ipv4_tuple() {
assert_eq!(::std::mem::size_of::<rte_ipv4_tuple>() , 12usize , concat ! (
Expand All @@ -117,20 +117,6 @@ impl Clone for rte_ipv4_tuple {
}
#[repr(C)]
#[derive(Debug, Default, Copy)]
pub struct rte_ipv6_tuple {
pub src_addr: [u8; 16usize],
pub dst_addr: [u8; 16usize],
pub __bindgen_anon_1: rte_ipv6_tuple__bindgen_ty_1,
}
#[repr(C)]
#[derive(Debug, Default, Copy)]
pub struct rte_ipv6_tuple__bindgen_ty_1 {
pub __bindgen_anon_1: __BindgenUnionField<rte_ipv6_tuple__bindgen_ty_1__bindgen_ty_1>,
pub sctp_tag: __BindgenUnionField<u32>,
pub bindgen_union_field: u32,
}
#[repr(C)]
#[derive(Debug, Default, Copy)]
pub struct rte_ipv6_tuple__bindgen_ty_1__bindgen_ty_1 {
pub dport: u16,
pub sport: u16,
Expand Down Expand Up @@ -163,6 +149,13 @@ fn bindgen_test_layout_rte_ipv6_tuple__bindgen_ty_1__bindgen_ty_1() {
impl Clone for rte_ipv6_tuple__bindgen_ty_1__bindgen_ty_1 {
fn clone(&self) -> Self { *self }
}
#[repr(C)]
#[derive(Debug, Default, Copy)]
pub struct rte_ipv6_tuple__bindgen_ty_1 {
pub __bindgen_anon_1: __BindgenUnionField<rte_ipv6_tuple__bindgen_ty_1__bindgen_ty_1>,
pub sctp_tag: __BindgenUnionField<u32>,
pub bindgen_union_field: u32,
}
#[test]
fn bindgen_test_layout_rte_ipv6_tuple__bindgen_ty_1() {
assert_eq!(::std::mem::size_of::<rte_ipv6_tuple__bindgen_ty_1>() , 4usize
Expand All @@ -182,6 +175,13 @@ fn bindgen_test_layout_rte_ipv6_tuple__bindgen_ty_1() {
impl Clone for rte_ipv6_tuple__bindgen_ty_1 {
fn clone(&self) -> Self { *self }
}
#[repr(C)]
#[derive(Debug, Default, Copy)]
pub struct rte_ipv6_tuple {
pub src_addr: [u8; 16usize],
pub dst_addr: [u8; 16usize],
pub __bindgen_anon_1: rte_ipv6_tuple__bindgen_ty_1,
}
#[test]
fn bindgen_test_layout_rte_ipv6_tuple() {
assert_eq!(::std::mem::size_of::<rte_ipv6_tuple>() , 36usize , concat ! (
Expand Down
2 changes: 1 addition & 1 deletion tests/expectations/tests/381-decltype-alias.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,9 @@
#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)]


pub type std_allocator_traits___size_type<_Alloc> = _Alloc;
#[repr(C)]
#[derive(Debug, Default, Copy, Clone)]
pub struct std_allocator_traits {
pub _address: u8,
}
pub type std_allocator_traits___size_type<_Alloc> = _Alloc;
8 changes: 4 additions & 4 deletions tests/expectations/tests/anon_enum.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,16 +4,16 @@
#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)]


pub const Test_T_NONE: Test__bindgen_ty_1 = Test__bindgen_ty_1::T_NONE;
#[repr(u32)]
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
pub enum Test__bindgen_ty_1 { T_NONE = 0, }
#[repr(C)]
#[derive(Debug, Default, Copy)]
pub struct Test {
pub foo: ::std::os::raw::c_int,
pub bar: f32,
}
pub const Test_T_NONE: Test__bindgen_ty_1 = Test__bindgen_ty_1::T_NONE;
#[repr(u32)]
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
pub enum Test__bindgen_ty_1 { T_NONE = 0, }
#[test]
fn bindgen_test_layout_Test() {
assert_eq!(::std::mem::size_of::<Test>() , 8usize , concat ! (
Expand Down
14 changes: 7 additions & 7 deletions tests/expectations/tests/anon_enum_trait.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,6 @@
#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)]


#[repr(C)]
#[derive(Debug, Default, Copy, Clone)]
pub struct DataType {
pub _address: u8,
}
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>;
Expand All @@ -27,15 +22,20 @@ pub const DataType_type_: DataType__bindgen_ty_1 =
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
pub enum DataType__bindgen_ty_1 { generic_type = 0, }
#[repr(C)]
#[derive(Debug, Default, Copy)]
pub struct Foo {
#[derive(Debug, Default, Copy, Clone)]
pub struct DataType {
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, }
#[repr(C)]
#[derive(Debug, Default, Copy)]
pub struct Foo {
pub _address: u8,
}
#[test]
fn bindgen_test_layout_Foo() {
assert_eq!(::std::mem::size_of::<Foo>() , 1usize , concat ! (
Expand Down
22 changes: 11 additions & 11 deletions tests/expectations/tests/anon_struct_in_union.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,17 +30,6 @@ impl <T> ::std::fmt::Debug for __BindgenUnionField<T> {
}
#[repr(C)]
#[derive(Debug, Default, Copy)]
pub struct s {
pub u: s__bindgen_ty_1,
}
#[repr(C)]
#[derive(Debug, Default, Copy)]
pub struct s__bindgen_ty_1 {
pub field: __BindgenUnionField<s__bindgen_ty_1_inner>,
pub bindgen_union_field: u32,
}
#[repr(C)]
#[derive(Debug, Default, Copy)]
pub struct s__bindgen_ty_1_inner {
pub b: ::std::os::raw::c_int,
}
Expand All @@ -61,6 +50,12 @@ fn bindgen_test_layout_s__bindgen_ty_1_inner() {
impl Clone for s__bindgen_ty_1_inner {
fn clone(&self) -> Self { *self }
}
#[repr(C)]
#[derive(Debug, Default, Copy)]
pub struct s__bindgen_ty_1 {
pub field: __BindgenUnionField<s__bindgen_ty_1_inner>,
pub bindgen_union_field: u32,
}
#[test]
fn bindgen_test_layout_s__bindgen_ty_1() {
assert_eq!(::std::mem::size_of::<s__bindgen_ty_1>() , 4usize , concat ! (
Expand All @@ -76,6 +71,11 @@ fn bindgen_test_layout_s__bindgen_ty_1() {
impl Clone for s__bindgen_ty_1 {
fn clone(&self) -> Self { *self }
}
#[repr(C)]
#[derive(Debug, Default, Copy)]
pub struct s {
pub u: s__bindgen_ty_1,
}
#[test]
fn bindgen_test_layout_s() {
assert_eq!(::std::mem::size_of::<s>() , 4usize , concat ! (
Expand Down
16 changes: 8 additions & 8 deletions tests/expectations/tests/anon_union.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,14 +28,6 @@ impl <T> ::std::fmt::Debug for __BindgenUnionField<T> {
fmt.write_str("__BindgenUnionField")
}
}
#[repr(C)]
#[derive(Debug, Copy, Clone)]
pub struct TErrorResult {
pub mResult: ::std::os::raw::c_int,
pub __bindgen_anon_1: TErrorResult__bindgen_ty_1,
pub mMightHaveUnreported: bool,
pub mUnionState: TErrorResult_UnionState,
}
pub const TErrorResult_UnionState_HasException: TErrorResult_UnionState =
TErrorResult_UnionState::HasMessage;
#[repr(i32)]
Expand All @@ -58,6 +50,14 @@ pub struct TErrorResult__bindgen_ty_1 {
pub mDOMExceptionInfo: __BindgenUnionField<*mut TErrorResult_DOMExceptionInfo>,
pub bindgen_union_field: u64,
}
#[repr(C)]
#[derive(Debug, Copy, Clone)]
pub struct TErrorResult {
pub mResult: ::std::os::raw::c_int,
pub __bindgen_anon_1: TErrorResult__bindgen_ty_1,
pub mMightHaveUnreported: bool,
pub mUnionState: TErrorResult_UnionState,
}
impl Default for TErrorResult {
fn default() -> Self { unsafe { ::std::mem::zeroed() } }
}
Expand Down
10 changes: 5 additions & 5 deletions tests/expectations/tests/bitfield-enum-basic.rs
Original file line number Diff line number Diff line change
Expand Up @@ -95,11 +95,6 @@ impl ::std::ops::BitAndAssign for _bindgen_ty_1 {
#[repr(C)]
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
pub struct _bindgen_ty_1(pub ::std::os::raw::c_uint);
#[repr(C)]
#[derive(Debug, Default, Copy)]
pub struct Dummy {
pub _address: u8,
}
pub const Dummy_DUMMY_FOO: Dummy__bindgen_ty_1 = Dummy__bindgen_ty_1(1);
pub const Dummy_DUMMY_BAR: Dummy__bindgen_ty_1 = Dummy__bindgen_ty_1(2);
impl ::std::ops::BitOr<Dummy__bindgen_ty_1> for Dummy__bindgen_ty_1 {
Expand Down Expand Up @@ -133,6 +128,11 @@ impl ::std::ops::BitAndAssign for Dummy__bindgen_ty_1 {
#[repr(C)]
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
pub struct Dummy__bindgen_ty_1(pub ::std::os::raw::c_uint);
#[repr(C)]
#[derive(Debug, Default, Copy)]
pub struct Dummy {
pub _address: u8,
}
#[test]
fn bindgen_test_layout_Dummy() {
assert_eq!(::std::mem::size_of::<Dummy>() , 1usize , concat ! (
Expand Down
24 changes: 12 additions & 12 deletions tests/expectations/tests/bitfield-method-same-name.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,18 @@
#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)]


extern "C" {
#[link_name = "_ZN3Foo4typeEv"]
pub fn Foo_type(this: *mut Foo) -> ::std::os::raw::c_char;
}
extern "C" {
#[link_name = "_ZN3Foo9set_type_Ec"]
pub fn Foo_set_type_(this: *mut Foo, c: ::std::os::raw::c_char);
}
extern "C" {
#[link_name = "_ZN3Foo8set_typeEc"]
pub fn Foo_set_type(this: *mut Foo, c: ::std::os::raw::c_char);
}
#[repr(C)]
#[derive(Debug, Default, Copy)]
pub struct Foo {
Expand All @@ -17,18 +29,6 @@ fn bindgen_test_layout_Foo() {
assert_eq! (::std::mem::align_of::<Foo>() , 1usize , concat ! (
"Alignment of " , stringify ! ( Foo ) ));
}
extern "C" {
#[link_name = "_ZN3Foo4typeEv"]
pub fn Foo_type(this: *mut Foo) -> ::std::os::raw::c_char;
}
extern "C" {
#[link_name = "_ZN3Foo9set_type_Ec"]
pub fn Foo_set_type_(this: *mut Foo, c: ::std::os::raw::c_char);
}
extern "C" {
#[link_name = "_ZN3Foo8set_typeEc"]
pub fn Foo_set_type(this: *mut Foo, c: ::std::os::raw::c_char);
}
impl Clone for Foo {
fn clone(&self) -> Self { *self }
}
Expand Down
32 changes: 16 additions & 16 deletions tests/expectations/tests/class.rs
Original file line number Diff line number Diff line change
Expand Up @@ -242,22 +242,6 @@ fn bindgen_test_layout_WithUnion() {
impl Clone for WithUnion {
fn clone(&self) -> Self { *self }
}
#[repr(C)]
#[derive(Debug, Default, Copy)]
pub struct RealAbstractionWithTonsOfMethods {
pub _address: u8,
}
#[test]
fn bindgen_test_layout_RealAbstractionWithTonsOfMethods() {
assert_eq!(::std::mem::size_of::<RealAbstractionWithTonsOfMethods>() ,
1usize , concat ! (
"Size of: " , stringify ! ( RealAbstractionWithTonsOfMethods )
));
assert_eq! (::std::mem::align_of::<RealAbstractionWithTonsOfMethods>() ,
1usize , concat ! (
"Alignment of " , stringify ! (
RealAbstractionWithTonsOfMethods ) ));
}
extern "C" {
#[link_name = "_ZNK32RealAbstractionWithTonsOfMethods3barEv"]
pub fn RealAbstractionWithTonsOfMethods_bar(this:
Expand All @@ -278,6 +262,22 @@ extern "C" {
#[link_name = "_ZN32RealAbstractionWithTonsOfMethods3staEv"]
pub fn RealAbstractionWithTonsOfMethods_sta();
}
#[repr(C)]
#[derive(Debug, Default, Copy)]
pub struct RealAbstractionWithTonsOfMethods {
pub _address: u8,
}
#[test]
fn bindgen_test_layout_RealAbstractionWithTonsOfMethods() {
assert_eq!(::std::mem::size_of::<RealAbstractionWithTonsOfMethods>() ,
1usize , concat ! (
"Size of: " , stringify ! ( RealAbstractionWithTonsOfMethods )
));
assert_eq! (::std::mem::align_of::<RealAbstractionWithTonsOfMethods>() ,
1usize , concat ! (
"Alignment of " , stringify ! (
RealAbstractionWithTonsOfMethods ) ));
}
impl Clone for RealAbstractionWithTonsOfMethods {
fn clone(&self) -> Self { *self }
}
Expand Down
Loading

0 comments on commit 5baaa4d

Please sign in to comment.