diff options
-rw-r--r-- | src/gen.rs | 30 | ||||
-rw-r--r-- | src/parser.rs | 9 | ||||
-rw-r--r-- | tests/expectations/jsval_layout_opaque.rs | 20 | ||||
-rw-r--r-- | tests/expectations/only_bitfields.rs | 14 | ||||
-rw-r--r-- | tests/expectations/struct_with_bitfields.rs | 97 | ||||
-rw-r--r-- | tests/expectations/template.rs | 5 | ||||
-rw-r--r-- | tests/expectations/union_with_anon_struct_bitfield.rs | 25 | ||||
-rw-r--r-- | tests/expectations/weird_bitfields.rs | 70 |
8 files changed, 201 insertions, 69 deletions
@@ -1017,7 +1017,7 @@ fn cstruct_to_rs(ctx: &mut GenCtx, name: &str, ci: CompInfo) -> Vec<P<ast::Item> let mut offset: u32 = 0; if let Some(ref bitfields) = f.bitfields { for &(ref bf_name, bf_size) in bitfields.iter() { - setters.push(gen_bitfield_method(ctx, &f_name, bf_name, &f_ty, offset as usize, bf_size)); + setters.extend(gen_bitfield_methods(ctx, &f_name, bf_name, &f_ty, offset as usize, bf_size).into_iter()); offset += bf_size; } setters.push(gen_fullbitfield_method(ctx, &f_name, &f_ty, bitfields)) @@ -1623,13 +1623,13 @@ fn type_for_bitfield_width(ctx: &mut GenCtx, width: u32, is_arg: bool) -> ast::T mk_ty(ctx, false, &[input_type.to_owned()]) } -fn gen_bitfield_method(ctx: &mut GenCtx, bindgen_name: &str, - field_name: &str, field_type: &Type, - offset: usize, width: u32) -> ast::ImplItem { +fn gen_bitfield_methods(ctx: &mut GenCtx, bindgen_name: &str, + field_name: &str, field_type: &Type, + offset: usize, width: u32) -> Vec<ast::ImplItem> { let input_type = type_for_bitfield_width(ctx, width, true); - let width = width % (field_type.layout().unwrap().size as u32 * 8); + let width = width as usize; - let field_type = cty_to_rs(ctx, &field_type, false, true); + let field_type = cty_to_rs(ctx, field_type, false, true); let real_field_name = if field_name.is_empty() { format!("at_offset_{}", offset) @@ -1638,20 +1638,28 @@ fn gen_bitfield_method(ctx: &mut GenCtx, bindgen_name: &str, }; - let setter_name = ctx.ext_cx.ident_of(&format!("set_{}", real_field_name)); let bindgen_ident = ctx.ext_cx.ident_of(bindgen_name); + let setter_name = ctx.ext_cx.ident_of(&format!("set_{}", real_field_name)); + let getter_name = ctx.ext_cx.ident_of(&real_field_name); + let mask = ((1usize << width) - 1) << offset; let item = quote_item!(&ctx.ext_cx, impl X { + #[inline] + pub fn $getter_name(&self) -> $field_type { + (self.$bindgen_ident & ($mask as $field_type)) >> $offset + } + + #[inline] pub fn $setter_name(&mut self, val: $input_type) { - self.$bindgen_ident &= !(((1 << $width as $field_type) - 1) << $offset); - self.$bindgen_ident |= (val as $field_type) << $offset; + self.$bindgen_ident &= !($mask as $field_type); + self.$bindgen_ident |= (val as $field_type << $offset) & ($mask as $field_type); } } ).unwrap(); - match &item.node { - &ast::ItemKind::Impl(_, _, _, _, _, ref items) => items[0].clone(), + match item.node { + ast::ItemKind::Impl(_, _, _, _, _, ref items) => items.clone(), _ => unreachable!() } } diff --git a/src/parser.rs b/src/parser.rs index b104c2a3..2d46d791 100644 --- a/src/parser.rs +++ b/src/parser.rs @@ -681,11 +681,12 @@ fn visit_composite(cursor: &Cursor, parent: &Cursor, (Some(width), _) => { // Bitfields containing enums are not supported by the c standard // https://stackoverflow.com/questions/11983231/is-it-safe-to-use-an-enum-in-a-bit-field + match ty { - il::TInt(_, _) => (), + il::TInt(..) => {}, _ => { - // NOTE: We rely on the name of the type converted to rust types, - // and on the alignment. + // NOTE: We rely on the name of the type converted + // to rust types, and on the alignment. let bits = cmp::max(width, ty.size() as u32 * 8); let layout_size = cmp::max(1, bits.next_power_of_two() / 8) as usize; @@ -710,7 +711,7 @@ fn visit_composite(cursor: &Cursor, parent: &Cursor, ty = TNamed(Rc::new(RefCell::new(ti))) } } - ("".to_owned(), Some(vec!((cursor.spelling(), width)))) + ("".to_owned(), Some(vec![(cursor.spelling(), width)])) }, // The field is not a bitfield (None, _) => (cursor.spelling(), None) diff --git a/tests/expectations/jsval_layout_opaque.rs b/tests/expectations/jsval_layout_opaque.rs index 07ad6789..760ac1f2 100644 --- a/tests/expectations/jsval_layout_opaque.rs +++ b/tests/expectations/jsval_layout_opaque.rs @@ -147,13 +147,25 @@ pub struct jsval_layout_jsval_layout_opaque_hpp_unnamed_1 { pub _bitfield_1: u64, } impl jsval_layout_jsval_layout_opaque_hpp_unnamed_1 { + #[inline] + pub fn payload47(&self) -> u64 { + (self._bitfield_1 & (140737488355327usize as u64)) >> 0usize + } + #[inline] pub fn set_payload47(&mut self, val: u32) { - self._bitfield_1 &= !(((1 << (47u32 as u64)) - 1) << 0usize); - self._bitfield_1 |= (val as u64) << 0usize; + self._bitfield_1 &= !(140737488355327usize as u64); + self._bitfield_1 |= + ((val as u64) << 0usize) & (140737488355327usize as u64); } + #[inline] + pub fn tag(&self) -> u64 { + (self._bitfield_1 & (18446603336221196288usize as u64)) >> 47usize + } + #[inline] pub fn set_tag(&mut self, val: u32) { - self._bitfield_1 &= !(((1 << (17u32 as u64)) - 1) << 47usize); - self._bitfield_1 |= (val as u64) << 47usize; + self._bitfield_1 &= !(18446603336221196288usize as u64); + self._bitfield_1 |= + ((val as u64) << 47usize) & (18446603336221196288usize as u64); } pub const fn new_bitfield_1(payload47: u32, tag: u32) -> u64 { 0 | ((payload47 as u64) << 0u32) | ((tag as u64) << 47u32) diff --git a/tests/expectations/only_bitfields.rs b/tests/expectations/only_bitfields.rs index 86ed8564..88345373 100644 --- a/tests/expectations/only_bitfields.rs +++ b/tests/expectations/only_bitfields.rs @@ -11,13 +11,19 @@ pub struct Struct_C { pub _bitfield_1: u8, } impl Struct_C { + #[inline] + pub fn a(&self) -> u8 { (self._bitfield_1 & (1usize as u8)) >> 0usize } + #[inline] pub fn set_a(&mut self, val: bool) { - self._bitfield_1 &= !(((1 << (1u32 as u8)) - 1) << 0usize); - self._bitfield_1 |= (val as u8) << 0usize; + self._bitfield_1 &= !(1usize as u8); + self._bitfield_1 |= ((val as u8) << 0usize) & (1usize as u8); } + #[inline] + pub fn b(&self) -> u8 { (self._bitfield_1 & (254usize as u8)) >> 1usize } + #[inline] pub fn set_b(&mut self, val: u8) { - self._bitfield_1 &= !(((1 << (7u32 as u8)) - 1) << 1usize); - self._bitfield_1 |= (val as u8) << 1usize; + self._bitfield_1 &= !(254usize as u8); + self._bitfield_1 |= ((val as u8) << 1usize) & (254usize as u8); } pub const fn new_bitfield_1(a: bool, b: u8) -> u8 { 0 | ((a as u8) << 0u32) | ((b as u8) << 1u32) diff --git a/tests/expectations/struct_with_bitfields.rs b/tests/expectations/struct_with_bitfields.rs index ab2acf2a..26003ebd 100644 --- a/tests/expectations/struct_with_bitfields.rs +++ b/tests/expectations/struct_with_bitfields.rs @@ -14,35 +14,71 @@ pub struct Struct_bitfield { pub _bitfield_3: ::std::os::raw::c_uint, } impl Struct_bitfield { + #[inline] + pub fn a(&self) -> ::std::os::raw::c_ushort { + (self._bitfield_1 & (1usize as ::std::os::raw::c_ushort)) >> 0usize + } + #[inline] pub fn set_a(&mut self, val: bool) { - self._bitfield_1 &= - !(((1 << (1u32 as ::std::os::raw::c_ushort)) - 1) << 0usize); - self._bitfield_1 |= (val as ::std::os::raw::c_ushort) << 0usize; + self._bitfield_1 &= !(1usize as ::std::os::raw::c_ushort); + self._bitfield_1 |= + ((val as ::std::os::raw::c_ushort) << 0usize) & + (1usize as ::std::os::raw::c_ushort); + } + #[inline] + pub fn b(&self) -> ::std::os::raw::c_ushort { + (self._bitfield_1 & (2usize as ::std::os::raw::c_ushort)) >> 1usize } + #[inline] pub fn set_b(&mut self, val: bool) { - self._bitfield_1 &= - !(((1 << (1u32 as ::std::os::raw::c_ushort)) - 1) << 1usize); - self._bitfield_1 |= (val as ::std::os::raw::c_ushort) << 1usize; + self._bitfield_1 &= !(2usize as ::std::os::raw::c_ushort); + self._bitfield_1 |= + ((val as ::std::os::raw::c_ushort) << 1usize) & + (2usize as ::std::os::raw::c_ushort); } + #[inline] + pub fn c(&self) -> ::std::os::raw::c_ushort { + (self._bitfield_1 & (4usize as ::std::os::raw::c_ushort)) >> 2usize + } + #[inline] pub fn set_c(&mut self, val: bool) { - self._bitfield_1 &= - !(((1 << (1u32 as ::std::os::raw::c_ushort)) - 1) << 2usize); - self._bitfield_1 |= (val as ::std::os::raw::c_ushort) << 2usize; + self._bitfield_1 &= !(4usize as ::std::os::raw::c_ushort); + self._bitfield_1 |= + ((val as ::std::os::raw::c_ushort) << 2usize) & + (4usize as ::std::os::raw::c_ushort); + } + #[inline] + pub fn at_offset_3(&self) -> ::std::os::raw::c_ushort { + (self._bitfield_1 & (8usize as ::std::os::raw::c_ushort)) >> 3usize } + #[inline] pub fn set_at_offset_3(&mut self, val: bool) { - self._bitfield_1 &= - !(((1 << (1u32 as ::std::os::raw::c_ushort)) - 1) << 3usize); - self._bitfield_1 |= (val as ::std::os::raw::c_ushort) << 3usize; + self._bitfield_1 &= !(8usize as ::std::os::raw::c_ushort); + self._bitfield_1 |= + ((val as ::std::os::raw::c_ushort) << 3usize) & + (8usize as ::std::os::raw::c_ushort); } + #[inline] + pub fn at_offset_4(&self) -> ::std::os::raw::c_ushort { + (self._bitfield_1 & (48usize as ::std::os::raw::c_ushort)) >> 4usize + } + #[inline] pub fn set_at_offset_4(&mut self, val: u8) { - self._bitfield_1 &= - !(((1 << (2u32 as ::std::os::raw::c_ushort)) - 1) << 4usize); - self._bitfield_1 |= (val as ::std::os::raw::c_ushort) << 4usize; + self._bitfield_1 &= !(48usize as ::std::os::raw::c_ushort); + self._bitfield_1 |= + ((val as ::std::os::raw::c_ushort) << 4usize) & + (48usize as ::std::os::raw::c_ushort); + } + #[inline] + pub fn d(&self) -> ::std::os::raw::c_ushort { + (self._bitfield_1 & (192usize as ::std::os::raw::c_ushort)) >> 6usize } + #[inline] pub fn set_d(&mut self, val: u8) { - self._bitfield_1 &= - !(((1 << (2u32 as ::std::os::raw::c_ushort)) - 1) << 6usize); - self._bitfield_1 |= (val as ::std::os::raw::c_ushort) << 6usize; + self._bitfield_1 &= !(192usize as ::std::os::raw::c_ushort); + self._bitfield_1 |= + ((val as ::std::os::raw::c_ushort) << 6usize) & + (192usize as ::std::os::raw::c_ushort); } pub const fn new_bitfield_1(a: bool, b: bool, c: bool, unnamed_bitfield1: bool, @@ -55,18 +91,31 @@ impl Struct_bitfield { ((unnamed_bitfield2 as ::std::os::raw::c_ushort) << 4u32) | ((d as ::std::os::raw::c_ushort) << 6u32) } + #[inline] + pub fn f(&self) -> ::std::os::raw::c_uint { + (self._bitfield_2 & (3usize as ::std::os::raw::c_uint)) >> 0usize + } + #[inline] pub fn set_f(&mut self, val: u8) { - self._bitfield_2 &= - !(((1 << (2u32 as ::std::os::raw::c_uint)) - 1) << 0usize); - self._bitfield_2 |= (val as ::std::os::raw::c_uint) << 0usize; + self._bitfield_2 &= !(3usize as ::std::os::raw::c_uint); + self._bitfield_2 |= + ((val as ::std::os::raw::c_uint) << 0usize) & + (3usize as ::std::os::raw::c_uint); } pub const fn new_bitfield_2(f: u8) -> ::std::os::raw::c_uint { 0 | ((f as ::std::os::raw::c_uint) << 0u32) } + #[inline] + pub fn g(&self) -> ::std::os::raw::c_uint { + (self._bitfield_3 & (4294967295usize as ::std::os::raw::c_uint)) >> + 0usize + } + #[inline] pub fn set_g(&mut self, val: u32) { - self._bitfield_3 &= - !(((1 << (0u32 as ::std::os::raw::c_uint)) - 1) << 0usize); - self._bitfield_3 |= (val as ::std::os::raw::c_uint) << 0usize; + self._bitfield_3 &= !(4294967295usize as ::std::os::raw::c_uint); + self._bitfield_3 |= + ((val as ::std::os::raw::c_uint) << 0usize) & + (4294967295usize as ::std::os::raw::c_uint); } pub const fn new_bitfield_3(g: u32) -> ::std::os::raw::c_uint { 0 | ((g as ::std::os::raw::c_uint) << 0u32) diff --git a/tests/expectations/template.rs b/tests/expectations/template.rs index fa67e09b..02e683a8 100644 --- a/tests/expectations/template.rs +++ b/tests/expectations/template.rs @@ -144,6 +144,11 @@ pub struct Struct_ShouldNotBeCopiable<T> { pub struct Struct_ShouldNotBeCopiableAsWell<U> { pub m_member: Struct_ReplacedWithoutDestructorFwd<U>, } +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct Struct_TemplateWithVar<T> { + pub _phantom0: ::std::marker::PhantomData<T>, +} extern "C" { #[link_name = "_Z3bar3FooIiiE"] pub fn bar(foo: Struct_Foo<::std::os::raw::c_int, ::std::os::raw::c_int>); diff --git a/tests/expectations/union_with_anon_struct_bitfield.rs b/tests/expectations/union_with_anon_struct_bitfield.rs index 3237ded7..26b428f5 100644 --- a/tests/expectations/union_with_anon_struct_bitfield.rs +++ b/tests/expectations/union_with_anon_struct_bitfield.rs @@ -56,15 +56,28 @@ pub struct Struct_foo_union_with_anon_struct_bitfield_h_unnamed_1 { pub _bitfield_1: ::std::os::raw::c_int, } impl Struct_foo_union_with_anon_struct_bitfield_h_unnamed_1 { + #[inline] + pub fn b(&self) -> ::std::os::raw::c_int { + (self._bitfield_1 & (127usize as ::std::os::raw::c_int)) >> 0usize + } + #[inline] pub fn set_b(&mut self, val: u8) { - self._bitfield_1 &= - !(((1 << (7u32 as ::std::os::raw::c_int)) - 1) << 0usize); - self._bitfield_1 |= (val as ::std::os::raw::c_int) << 0usize; + self._bitfield_1 &= !(127usize as ::std::os::raw::c_int); + self._bitfield_1 |= + ((val as ::std::os::raw::c_int) << 0usize) & + (127usize as ::std::os::raw::c_int); } + #[inline] + pub fn c(&self) -> ::std::os::raw::c_int { + (self._bitfield_1 & (4294967168usize as ::std::os::raw::c_int)) >> + 7usize + } + #[inline] pub fn set_c(&mut self, val: u32) { - self._bitfield_1 &= - !(((1 << (25u32 as ::std::os::raw::c_int)) - 1) << 7usize); - self._bitfield_1 |= (val as ::std::os::raw::c_int) << 7usize; + self._bitfield_1 &= !(4294967168usize as ::std::os::raw::c_int); + self._bitfield_1 |= + ((val as ::std::os::raw::c_int) << 7usize) & + (4294967168usize as ::std::os::raw::c_int); } pub const fn new_bitfield_1(b: u8, c: u32) -> ::std::os::raw::c_int { 0 | ((b as ::std::os::raw::c_int) << 0u32) | diff --git a/tests/expectations/weird_bitfields.rs b/tests/expectations/weird_bitfields.rs index c9b8daa4..d2ae1f96 100644 --- a/tests/expectations/weird_bitfields.rs +++ b/tests/expectations/weird_bitfields.rs @@ -31,40 +31,78 @@ pub struct Struct_Weird { pub _bitfield_2: u32, } impl Struct_Weird { + #[inline] + pub fn bitTest(&self) -> ::std::os::raw::c_uint { + (self._bitfield_1 & (65535usize as ::std::os::raw::c_uint)) >> 0usize + } + #[inline] pub fn set_bitTest(&mut self, val: u16) { - self._bitfield_1 &= - !(((1 << (16u32 as ::std::os::raw::c_uint)) - 1) << 0usize); - self._bitfield_1 |= (val as ::std::os::raw::c_uint) << 0usize; + self._bitfield_1 &= !(65535usize as ::std::os::raw::c_uint); + self._bitfield_1 |= + ((val as ::std::os::raw::c_uint) << 0usize) & + (65535usize as ::std::os::raw::c_uint); + } + #[inline] + pub fn bitTest2(&self) -> ::std::os::raw::c_uint { + (self._bitfield_1 & (2147418112usize as ::std::os::raw::c_uint)) >> + 16usize } + #[inline] pub fn set_bitTest2(&mut self, val: u16) { - self._bitfield_1 &= - !(((1 << (15u32 as ::std::os::raw::c_uint)) - 1) << 16usize); - self._bitfield_1 |= (val as ::std::os::raw::c_uint) << 16usize; + self._bitfield_1 &= !(2147418112usize as ::std::os::raw::c_uint); + self._bitfield_1 |= + ((val as ::std::os::raw::c_uint) << 16usize) & + (2147418112usize as ::std::os::raw::c_uint); } pub const fn new_bitfield_1(bitTest: u16, bitTest2: u16) -> ::std::os::raw::c_uint { 0 | ((bitTest as ::std::os::raw::c_uint) << 0u32) | ((bitTest2 as ::std::os::raw::c_uint) << 16u32) } + #[inline] + pub fn mFillOpacitySource(&self) -> u32 { + (self._bitfield_2 & (7usize as u32)) >> 0usize + } + #[inline] pub fn set_mFillOpacitySource(&mut self, val: u8) { - self._bitfield_2 &= !(((1 << (3u32 as u32)) - 1) << 0usize); - self._bitfield_2 |= (val as u32) << 0usize; + self._bitfield_2 &= !(7usize as u32); + self._bitfield_2 |= ((val as u32) << 0usize) & (7usize as u32); + } + #[inline] + pub fn mStrokeOpacitySource(&self) -> u32 { + (self._bitfield_2 & (56usize as u32)) >> 3usize } + #[inline] pub fn set_mStrokeOpacitySource(&mut self, val: u8) { - self._bitfield_2 &= !(((1 << (3u32 as u32)) - 1) << 3usize); - self._bitfield_2 |= (val as u32) << 3usize; + self._bitfield_2 &= !(56usize as u32); + self._bitfield_2 |= ((val as u32) << 3usize) & (56usize as u32); } + #[inline] + pub fn mStrokeDasharrayFromObject(&self) -> u32 { + (self._bitfield_2 & (64usize as u32)) >> 6usize + } + #[inline] pub fn set_mStrokeDasharrayFromObject(&mut self, val: bool) { - self._bitfield_2 &= !(((1 << (1u32 as u32)) - 1) << 6usize); - self._bitfield_2 |= (val as u32) << 6usize; + self._bitfield_2 &= !(64usize as u32); + self._bitfield_2 |= ((val as u32) << 6usize) & (64usize as u32); + } + #[inline] + pub fn mStrokeDashoffsetFromObject(&self) -> u32 { + (self._bitfield_2 & (128usize as u32)) >> 7usize } + #[inline] pub fn set_mStrokeDashoffsetFromObject(&mut self, val: bool) { - self._bitfield_2 &= !(((1 << (1u32 as u32)) - 1) << 7usize); - self._bitfield_2 |= (val as u32) << 7usize; + self._bitfield_2 &= !(128usize as u32); + self._bitfield_2 |= ((val as u32) << 7usize) & (128usize as u32); + } + #[inline] + pub fn mStrokeWidthFromObject(&self) -> u32 { + (self._bitfield_2 & (256usize as u32)) >> 8usize } + #[inline] pub fn set_mStrokeWidthFromObject(&mut self, val: bool) { - self._bitfield_2 &= !(((1 << (1u32 as u32)) - 1) << 8usize); - self._bitfield_2 |= (val as u32) << 8usize; + self._bitfield_2 &= !(256usize as u32); + self._bitfield_2 |= ((val as u32) << 8usize) & (256usize as u32); } pub const fn new_bitfield_2(mFillOpacitySource: u8, mStrokeOpacitySource: u8, |