diff options
-rw-r--r-- | src/gen.rs | 26 | ||||
-rw-r--r-- | src/types.rs | 17 | ||||
-rw-r--r-- | tests/headers/struct_with_derive_debug.h | 15 | ||||
-rw-r--r-- | tests/test_func.rs | 1 | ||||
-rw-r--r-- | tests/test_struct.rs | 68 | ||||
-rw-r--r-- | tests/test_union.rs | 1 |
6 files changed, 127 insertions, 1 deletions
@@ -505,6 +505,9 @@ fn cstruct_to_rs(ctx: &mut GenCtx, name: String, let mut unnamed: u32 = 0; let mut bitfields: u32 = 0; + // Debug is only defined on little arrays + let mut can_derive_debug = true; + for m in &members { let (opt_rc_c, opt_f) = match *m { CompMember::Field(ref f) => { (None, Some(f)) } @@ -521,6 +524,10 @@ fn cstruct_to_rs(ctx: &mut GenCtx, name: String, None => rust_type_id(ctx, f.name.clone()) }; + if !f.ty.can_derive_debug() { + can_derive_debug = false; + } + let f_ty = P(cty_to_rs(ctx, &f.ty)); fields.push(respan(ctx.span, ast::StructField_ { @@ -554,8 +561,12 @@ fn cstruct_to_rs(ctx: &mut GenCtx, name: String, ); let id = rust_type_id(ctx, name.clone()); + let mut attrs = vec!(mk_repr_attr(ctx, layout), mk_deriving_copy_attr(ctx, false)); + if can_derive_debug { + attrs.push(mk_deriving_debug_attr(ctx)); + } let struct_def = P(ast::Item { ident: ctx.ext_cx.ident_of(&id[..]), - attrs: vec!(mk_repr_attr(ctx, layout), mk_deriving_copy_attr(ctx, false)), + attrs: attrs, id: ast::DUMMY_NODE_ID, node: def, vis: ast::Visibility::Public, @@ -947,6 +958,19 @@ fn mk_deriving_copy_attr(ctx: &mut GenCtx, clone: bool) -> ast::Attribute { }) } +fn mk_deriving_debug_attr(ctx: &mut GenCtx) -> ast::Attribute { + let words = vec!(ctx.ext_cx.meta_word(ctx.span, InternedString::new("Debug"))); + + let attr_val = ctx.ext_cx.meta_list(ctx.span, InternedString::new("derive"), words); + + respan(ctx.span, ast::Attribute_ { + id: mk_attr_id(), + style: ast::AttrStyle::Outer, + value: attr_val, + is_sugared_doc: false + }) +} + fn cvar_to_rs(ctx: &mut GenCtx, name: String, ty: &Type, is_const: bool) -> ast::ForeignItem { diff --git a/src/types.rs b/src/types.rs index 2e4dd09c..3673df36 100644 --- a/src/types.rs +++ b/src/types.rs @@ -123,6 +123,23 @@ impl Type { TFuncPtr(..) => 0, } } + + pub fn can_derive_debug(&self) -> bool { + match self { + &TArray(_, size, _) => size <= 32, + &TComp(ref comp) => { + comp.borrow() + .members + .iter() + .all(|member| match member { + &CompMember::Field(ref f) | + &CompMember::CompField(_, ref f) => f.ty.can_derive_debug(), + _ => true, + }) + } + _ => true, + } + } } #[derive(Copy, Clone, PartialEq)] diff --git a/tests/headers/struct_with_derive_debug.h b/tests/headers/struct_with_derive_debug.h new file mode 100644 index 00000000..98ba1b3d --- /dev/null +++ b/tests/headers/struct_with_derive_debug.h @@ -0,0 +1,15 @@ +struct LittleArray { + int a[32]; +}; + +struct BigArray{ + int a[33]; +}; + +struct WithLittleArray { + struct LittleArray a; +}; + +struct WithBigArray { + struct BigArray a; +}; diff --git a/tests/test_func.rs b/tests/test_func.rs index e9364987..4260ad16 100644 --- a/tests/test_func.rs +++ b/tests/test_func.rs @@ -16,6 +16,7 @@ fn func_ptr_in_struct() { assert_bind_eq("headers/func_ptr_in_struct.h", " #[repr(C)] #[derive(Copy)] + #[derive(Debug)] pub struct Struct_Foo { pub bar: ::std::option::Option< extern \"C\" fn(x: ::std::os::raw::c_int, diff --git a/tests/test_struct.rs b/tests/test_struct.rs index a6ef32f2..7c24f94d 100644 --- a/tests/test_struct.rs +++ b/tests/test_struct.rs @@ -5,6 +5,7 @@ fn with_anon_struct() { assert_bind_eq("headers/struct_with_anon_struct.h", " #[repr(C)] #[derive(Copy)] + #[derive(Debug)] pub struct Struct_foo { pub bar: Struct_Unnamed1, } @@ -16,6 +17,7 @@ fn with_anon_struct() { } #[repr(C)] #[derive(Copy)] + #[derive(Debug)] pub struct Struct_Unnamed1 { pub a: ::std::os::raw::c_int, pub b: ::std::os::raw::c_int, @@ -34,6 +36,7 @@ fn with_anon_struct_array() { assert_bind_eq("headers/struct_with_anon_struct_array.h", " #[repr(C)] #[derive(Copy)] + #[derive(Debug)] pub struct Struct_foo { pub bar: [Struct_Unnamed1; 2usize], pub baz: [[[Struct_Unnamed2; 4usize]; 3usize]; 2usize], @@ -49,6 +52,7 @@ fn with_anon_struct_array() { #[repr(C)] #[derive(Copy)] + #[derive(Debug)] pub struct Struct_Unnamed1 { pub a: ::std::os::raw::c_int, pub b: ::std::os::raw::c_int, @@ -64,6 +68,7 @@ fn with_anon_struct_array() { #[repr(C)] #[derive(Copy)] + #[derive(Debug)] pub struct Struct_Unnamed2 { pub a: ::std::os::raw::c_int, pub b: ::std::os::raw::c_int, @@ -84,6 +89,7 @@ fn with_anon_struct_pointer() { assert_bind_eq("headers/struct_with_anon_struct_pointer.h", " #[repr(C)] #[derive(Copy)] + #[derive(Debug)] pub struct Struct_foo { pub bar: *mut Struct_Unnamed1, } @@ -95,6 +101,7 @@ fn with_anon_struct_pointer() { } #[repr(C)] #[derive(Copy)] + #[derive(Debug)] pub struct Struct_Unnamed1 { pub a: ::std::os::raw::c_int, pub b: ::std::os::raw::c_int, @@ -113,6 +120,7 @@ fn with_anon_union() { assert_bind_eq("headers/struct_with_anon_union.h", " #[repr(C)] #[derive(Copy)] + #[derive(Debug)] pub struct Struct_foo { pub bar: Union_Unnamed1, } @@ -151,6 +159,7 @@ fn with_anon_unnamed_struct() { assert_bind_eq("headers/struct_with_anon_unnamed_struct.h", " #[repr(C)] #[derive(Copy)] + #[derive(Debug)] pub struct Struct_foo { pub _bindgen_data_1_: [u32; 2usize], } @@ -178,6 +187,7 @@ fn with_anon_unnamed_union() { assert_bind_eq("headers/struct_with_anon_unnamed_union.h", " #[repr(C)] #[derive(Copy)] + #[derive(Debug)] pub struct Struct_foo { pub _bindgen_data_1_: [u32; 1usize], } @@ -205,6 +215,7 @@ fn with_nesting() { assert_bind_eq("headers/struct_with_nesting.h", " #[repr(C)] #[derive(Copy)] + #[derive(Debug)] pub struct Struct_foo { pub a: ::std::os::raw::c_uint, pub _bindgen_data_1_: [u32; 1usize], @@ -253,6 +264,7 @@ fn containing_fwd_decl_struct() { assert_bind_eq("headers/struct_containing_forward_declared_struct.h", " #[repr(C)] #[derive(Copy)] + #[derive(Debug)] pub struct Struct_a { pub val_a: *mut Struct_b, } @@ -267,6 +279,7 @@ fn containing_fwd_decl_struct() { #[repr(C)] #[derive(Copy)] + #[derive(Debug)] pub struct Struct_b { pub val_b: ::std::os::raw::c_int, } @@ -286,6 +299,7 @@ fn with_bitfields() { assert_bind_eq("headers/struct_with_bitfields.h", " #[repr(C)] #[derive(Copy)] + #[derive(Debug)] pub struct Struct_bitfield { pub _bindgen_bitfield_1_: ::std::os::raw::c_ushort, pub e: ::std::os::raw::c_int, @@ -308,6 +322,7 @@ fn with_fwd_decl_struct() { assert_bind_eq("headers/forward_declared_struct.h", " #[repr(C)] #[derive(Copy)] + #[derive(Debug)] pub struct Struct_a { pub b: ::std::os::raw::c_int, } @@ -319,6 +334,7 @@ fn with_fwd_decl_struct() { } #[repr(C)] #[derive(Copy)] + #[derive(Debug)] pub struct Struct_c { pub d: ::std::os::raw::c_int, } @@ -337,6 +353,7 @@ fn packed_struct() { assert_bind_eq("headers/struct_with_packing.h", " #[repr(C, packed)] #[derive(Copy)] + #[derive(Debug)] pub struct Struct_a { pub b: ::std::os::raw::c_char, pub c: ::std::os::raw::c_short, @@ -350,3 +367,54 @@ fn packed_struct() { "); } +#[test] +fn derive_debug_big_array() { + assert_bind_eq("headers/struct_with_derive_debug.h", " + #[repr(C)] + #[derive(Copy)] + #[derive(Debug)] + pub struct Struct_LittleArray { + pub a: [::std::os::raw::c_int; 32usize], + } + impl ::std::clone::Clone for Struct_LittleArray { + fn clone(&self) -> Self { *self } + } + impl ::std::default::Default for Struct_LittleArray { + fn default() -> Self { unsafe { ::std::mem::zeroed() } } + } + #[repr(C)] + #[derive(Copy)] + pub struct Struct_BigArray { + pub a: [::std::os::raw::c_int; 33usize], + } + impl ::std::clone::Clone for Struct_BigArray { + fn clone(&self) -> Self { *self } + } + impl ::std::default::Default for Struct_BigArray { + fn default() -> Self { unsafe { ::std::mem::zeroed() } } + } + #[repr(C)] + #[derive(Copy)] + #[derive(Debug)] + pub struct Struct_WithLittleArray { + pub a: Struct_LittleArray, + } + impl ::std::clone::Clone for Struct_WithLittleArray { + fn clone(&self) -> Self { *self } + } + impl ::std::default::Default for Struct_WithLittleArray { + fn default() -> Self { unsafe { ::std::mem::zeroed() } } + } + #[repr(C)] + #[derive(Copy)] + pub struct Struct_WithBigArray { + pub a: Struct_BigArray, + } + impl ::std::clone::Clone for Struct_WithBigArray { + fn clone(&self) -> Self { *self } + } + impl ::std::default::Default for Struct_WithBigArray { + fn default() -> Self { unsafe { ::std::mem::zeroed() } } + } + "); +} diff --git a/tests/test_union.rs b/tests/test_union.rs index 9ea68c0e..011440a7 100644 --- a/tests/test_union.rs +++ b/tests/test_union.rs @@ -22,6 +22,7 @@ fn with_anon_struct() { } #[repr(C)] #[derive(Copy)] + #[derive(Debug)] pub struct Struct_Unnamed1 { pub a: ::std::os::raw::c_uint, pub b: ::std::os::raw::c_uint, |