diff options
-rw-r--r-- | bindgen-integration/cpp/Test.cc | 20 | ||||
-rw-r--r-- | bindgen-integration/cpp/Test.h | 31 | ||||
-rwxr-xr-x | bindgen-integration/src/lib.rs | 39 | ||||
-rw-r--r-- | src/ir/comp.rs | 68 | ||||
-rw-r--r-- | tests/expectations/tests/bitfield_align.rs | 192 | ||||
-rw-r--r-- | tests/expectations/tests/bitfield_align_2.rs | 72 | ||||
-rw-r--r-- | tests/expectations/tests/struct_with_bitfields.rs | 44 | ||||
-rw-r--r-- | tests/expectations/tests/weird_bitfields.rs | 110 | ||||
-rw-r--r-- | tests/headers/bitfield_align.h | 12 | ||||
-rw-r--r-- | tests/headers/bitfield_align_2.h | 12 |
10 files changed, 405 insertions, 195 deletions
diff --git a/bindgen-integration/cpp/Test.cc b/bindgen-integration/cpp/Test.cc index 7b0ec4ad..9d91250c 100644 --- a/bindgen-integration/cpp/Test.cc +++ b/bindgen-integration/cpp/Test.cc @@ -56,4 +56,24 @@ Third::assert(int first, bool second, ItemKind third) kind == third; } +bool +Fourth::assert(MyEnum tag, unsigned long ptr) +{ + return this->tag == tag && this->ptr == ptr; +} + +bool +Date2::assert(unsigned short nWeekDay, + unsigned short nMonthDay, + unsigned short nMonth, + unsigned short nYear, + unsigned short byte) +{ + return this->nWeekDay == nWeekDay && + this->nMonthDay == nMonthDay && + this->nMonth == nMonth && + this->nYear == nYear && + this->byte == byte; +} + } // namespace bitfields diff --git a/bindgen-integration/cpp/Test.h b/bindgen-integration/cpp/Test.h index 01c7aea1..4b8c1690 100644 --- a/bindgen-integration/cpp/Test.h +++ b/bindgen-integration/cpp/Test.h @@ -49,7 +49,7 @@ struct Second { }; enum ItemKind { - ITEM_KIND_UNO, + ITEM_KIND_UNO = 0, ITEM_KIND_DOS, ITEM_KIND_TRES, }; @@ -63,6 +63,35 @@ struct Third { bool assert(int first, bool second, ItemKind third); }; +enum MyEnum { + ONE = 0, + TWO, + THREE, + FOUR, +}; + +struct Fourth { + MyEnum tag: 2; + unsigned long ptr: 48; + + /// Returns true if the bitfields match the arguments, false otherwise. + bool assert(MyEnum tag, unsigned long ptr); +}; + +struct Date2 { + unsigned short nWeekDay : 3; // 0..7 (3 bits) + unsigned short nMonthDay : 6; // 0..31 (6 bits) + unsigned short nMonth : 5; // 0..12 (5 bits) + unsigned short nYear : 8; // 0..100 (8 bits) + unsigned char byte : 8; + + bool assert(unsigned short nWeekDay, + unsigned short nMonthDay, + unsigned short nMonth, + unsigned short nYear, + unsigned short byte); +}; + } // namespace bitfields struct AutoRestoreBool { diff --git a/bindgen-integration/src/lib.rs b/bindgen-integration/src/lib.rs index fe832464..ea2b77b2 100755 --- a/bindgen-integration/src/lib.rs +++ b/bindgen-integration/src/lib.rs @@ -103,10 +103,45 @@ fn test_bitfields_third() { } #[test] +fn test_bitfields_fourth() { + let mut fourth: bindings::bitfields::Fourth = unsafe { + mem::zeroed() + }; + assert!(unsafe { + fourth.assert(bindings::bitfields::MyEnum::ONE, 0) + }); + + fourth.set_tag(bindings::bitfields::MyEnum::THREE); + fourth.set_ptr(0xdeadbeef); + assert!(unsafe { + fourth.assert(bindings::bitfields::MyEnum::THREE, 0xdeadbeef) + }); +} + +#[test] +fn test_bitfields_date2() { + let mut date: bindings::bitfields::Date2 = unsafe { + mem::zeroed() + }; + assert!(unsafe { + date.assert(0, 0, 0, 0, 0) + }); + + date.set_nWeekDay(6); // saturdays are the best + date.set_nMonthDay(20); + date.set_nMonth(11); + date.set_nYear(95); + date.set_byte(255); + assert!(unsafe { + date.assert(6, 20, 11, 95, 255) + }); +} + +#[test] fn test_bitfield_constructors() { + use std::mem; let mut first = bindings::bitfields::First { - _bitfield_1: bindings::bitfields::First::new_bitfield_1(1), - _bitfield_2: bindings::bitfields::First::new_bitfield_2(2, 3), + _bitfield_1: unsafe { mem::transmute(bindings::bitfields::First::new_bitfield_1(1, 2, 3)) }, __bindgen_align: [], }; assert!(unsafe { diff --git a/src/ir/comp.rs b/src/ir/comp.rs index 9c7577c9..5be20416 100644 --- a/src/ir/comp.rs +++ b/src/ir/comp.rs @@ -490,30 +490,48 @@ fn bitfields_to_allocation_units<E, I>(ctx: &BindgenContext, let mut unit_align = 0; let mut bitfields_in_unit = vec![]; + // TODO(emilio): Determine this from attributes or pragma ms_struct + // directives. Also, perhaps we should check if the target is MSVC? + const is_ms_struct: bool = false; + for bitfield in raw_bitfields { let bitfield_width = bitfield.bitfield().unwrap() as usize; - let bitfield_align = ctx.resolve_type(bitfield.ty()) - .layout(ctx) - .expect("Bitfield without layout? Gah!") - .align; - - if unit_size_in_bits != 0 && - (bitfield_width == 0 || - bitfield_width > unfilled_bits_in_unit) { - // We've reached the end of this allocation unit, so flush it - // and its bitfields. - unit_size_in_bits = align_to(unit_size_in_bits, - bitfield_align); - flush_allocation_unit(fields, - bitfield_unit_count, - unit_size_in_bits, - unit_align, - mem::replace(&mut bitfields_in_unit, vec![])); - - // Now we're working on a fresh bitfield allocation unit, so reset - // the current unit size and alignment. - unit_size_in_bits = 0; - unit_align = 0; + let bitfield_layout = + ctx.resolve_type(bitfield.ty()) + .layout(ctx) + .expect("Bitfield without layout? Gah!"); + let bitfield_size = bitfield_layout.size; + let bitfield_align = bitfield_layout.align; + + let mut offset = unit_size_in_bits; + if is_ms_struct { + if unit_size_in_bits != 0 && + (bitfield_width == 0 || + bitfield_width > unfilled_bits_in_unit) { + // We've reached the end of this allocation unit, so flush it + // and its bitfields. + unit_size_in_bits = align_to(unit_size_in_bits, unit_align * 8); + flush_allocation_unit(fields, + bitfield_unit_count, + unit_size_in_bits, + unit_align, + mem::replace(&mut bitfields_in_unit, vec![])); + + // Now we're working on a fresh bitfield allocation unit, so reset + // the current unit size and alignment. + #[allow(unused_assignments)] + { + unit_size_in_bits = 0; + offset = 0; + unit_align = 0; + } + } + } else { + if offset != 0 && + (bitfield_width == 0 || + (offset & (bitfield_align * 8 - 1)) + bitfield_width > bitfield_size * 8) { + offset = align_to(offset, bitfield_align * 8); + } } // Only keep named bitfields around. Unnamed bitfields (with > 0 @@ -521,11 +539,9 @@ fn bitfields_to_allocation_units<E, I>(ctx: &BindgenContext, // the bit-offset into its allocation unit where its bits begin, we // don't need any padding bits hereafter. if bitfield.name().is_some() { - bitfields_in_unit.push(Bitfield::new(unit_size_in_bits, bitfield)); + bitfields_in_unit.push(Bitfield::new(offset, bitfield)); } - unit_size_in_bits += bitfield_width; - max_align = cmp::max(max_align, bitfield_align); // NB: The `bitfield_width` here is completely, absolutely intentional. @@ -533,6 +549,8 @@ fn bitfields_to_allocation_units<E, I>(ctx: &BindgenContext, // width, not (directly) on the bitfields' types' alignment. unit_align = cmp::max(unit_align, bitfield_width); + unit_size_in_bits = offset + bitfield_width; + // Compute what the physical unit's final size would be given what we // have seen so far, and use that to compute how many bits are still // available in the unit. diff --git a/tests/expectations/tests/bitfield_align.rs b/tests/expectations/tests/bitfield_align.rs index 7ebf1bbe..9b1fc603 100644 --- a/tests/expectations/tests/bitfield_align.rs +++ b/tests/expectations/tests/bitfield_align.rs @@ -392,9 +392,7 @@ impl C { #[repr(C)] #[derive(Debug, Default, Copy)] pub struct Date1 { - pub _bitfield_1: [u8; 2usize], - pub _bitfield_2: u8, - pub __bindgen_padding_0: u8, + pub _bitfield_1: [u8; 4usize], pub __bindgen_align: [u16; 0usize], } #[test] @@ -410,17 +408,17 @@ impl Clone for Date1 { impl Date1 { #[inline] pub fn nWeekDay(&self) -> ::std::os::raw::c_ushort { - let mask = 7usize as u16; - let unit_field_val: u16 = + let mask = 7usize as u32; + let unit_field_val: u32 = unsafe { ::std::mem::transmute(self._bitfield_1) }; let val = (unit_field_val & mask) >> 0usize; unsafe { ::std::mem::transmute(val as u16) } } #[inline] pub fn set_nWeekDay(&mut self, val: ::std::os::raw::c_ushort) { - let mask = 7usize as u16; - let val = val as u16 as u16; - let mut unit_field_val: u16 = + let mask = 7usize as u32; + let val = val as u16 as u32; + let mut unit_field_val: u32 = unsafe { ::std::mem::transmute(self._bitfield_1) }; unit_field_val &= !mask; unit_field_val |= (val << 0usize) & mask; @@ -428,17 +426,17 @@ impl Date1 { } #[inline] pub fn nMonthDay(&self) -> ::std::os::raw::c_ushort { - let mask = 504usize as u16; - let unit_field_val: u16 = + let mask = 504usize as u32; + let unit_field_val: u32 = unsafe { ::std::mem::transmute(self._bitfield_1) }; let val = (unit_field_val & mask) >> 3usize; unsafe { ::std::mem::transmute(val as u16) } } #[inline] pub fn set_nMonthDay(&mut self, val: ::std::os::raw::c_ushort) { - let mask = 504usize as u16; - let val = val as u16 as u16; - let mut unit_field_val: u16 = + let mask = 504usize as u32; + let val = val as u16 as u32; + let mut unit_field_val: u32 = unsafe { ::std::mem::transmute(self._bitfield_1) }; unit_field_val &= !mask; unit_field_val |= (val << 3usize) & mask; @@ -446,62 +444,62 @@ impl Date1 { } #[inline] pub fn nMonth(&self) -> ::std::os::raw::c_ushort { - let mask = 15872usize as u16; - let unit_field_val: u16 = + let mask = 15872usize as u32; + let unit_field_val: u32 = unsafe { ::std::mem::transmute(self._bitfield_1) }; let val = (unit_field_val & mask) >> 9usize; unsafe { ::std::mem::transmute(val as u16) } } #[inline] pub fn set_nMonth(&mut self, val: ::std::os::raw::c_ushort) { - let mask = 15872usize as u16; - let val = val as u16 as u16; - let mut unit_field_val: u16 = + let mask = 15872usize as u32; + let val = val as u16 as u32; + let mut unit_field_val: u32 = unsafe { ::std::mem::transmute(self._bitfield_1) }; unit_field_val &= !mask; unit_field_val |= (val << 9usize) & mask; self._bitfield_1 = unsafe { ::std::mem::transmute(unit_field_val) }; } #[inline] - pub fn new_bitfield_1(nWeekDay: ::std::os::raw::c_ushort, - nMonthDay: ::std::os::raw::c_ushort, - nMonth: ::std::os::raw::c_ushort) -> u16 { - ({ - ({ - ({ 0 } | - ((nWeekDay as u16 as u16) << 0usize) & (7usize as u16)) - } | ((nMonthDay as u16 as u16) << 3usize) & (504usize as u16)) - } | ((nMonth as u16 as u16) << 9usize) & (15872usize as u16)) - } - #[inline] pub fn nYear(&self) -> ::std::os::raw::c_ushort { - let mask = 255usize as u8; - let unit_field_val: u8 = - unsafe { ::std::mem::transmute(self._bitfield_2) }; - let val = (unit_field_val & mask) >> 0usize; + let mask = 16711680usize as u32; + let unit_field_val: u32 = + unsafe { ::std::mem::transmute(self._bitfield_1) }; + let val = (unit_field_val & mask) >> 16usize; unsafe { ::std::mem::transmute(val as u16) } } #[inline] pub fn set_nYear(&mut self, val: ::std::os::raw::c_ushort) { - let mask = 255usize as u8; - let val = val as u16 as u8; - let mut unit_field_val: u8 = - unsafe { ::std::mem::transmute(self._bitfield_2) }; + let mask = 16711680usize as u32; + let val = val as u16 as u32; + let mut unit_field_val: u32 = + unsafe { ::std::mem::transmute(self._bitfield_1) }; unit_field_val &= !mask; - unit_field_val |= (val << 0usize) & mask; - self._bitfield_2 = unsafe { ::std::mem::transmute(unit_field_val) }; + unit_field_val |= (val << 16usize) & mask; + self._bitfield_1 = unsafe { ::std::mem::transmute(unit_field_val) }; } #[inline] - pub fn new_bitfield_2(nYear: ::std::os::raw::c_ushort) -> u8 { - ({ 0 } | ((nYear as u16 as u8) << 0usize) & (255usize as u8)) + pub fn new_bitfield_1(nWeekDay: ::std::os::raw::c_ushort, + nMonthDay: ::std::os::raw::c_ushort, + nMonth: ::std::os::raw::c_ushort, + nYear: ::std::os::raw::c_ushort) -> u32 { + ({ + ({ + ({ + ({ 0 } | + ((nWeekDay as u16 as u32) << 0usize) & + (7usize as u32)) + } | + ((nMonthDay as u16 as u32) << 3usize) & + (504usize as u32)) + } | ((nMonth as u16 as u32) << 9usize) & (15872usize as u32)) + } | ((nYear as u16 as u32) << 16usize) & (16711680usize as u32)) } } #[repr(C)] #[derive(Debug, Default, Copy)] pub struct Date2 { - pub _bitfield_1: [u8; 2usize], - pub _bitfield_2: u8, - pub byte: ::std::os::raw::c_uchar, + pub _bitfield_1: [u8; 4usize], pub __bindgen_align: [u16; 0usize], } #[test] @@ -510,11 +508,6 @@ fn bindgen_test_layout_Date2() { "Size of: " , stringify ! ( Date2 ) )); assert_eq! (::std::mem::align_of::<Date2>() , 2usize , concat ! ( "Alignment of " , stringify ! ( Date2 ) )); - assert_eq! (unsafe { - & ( * ( 0 as * const Date2 ) ) . byte as * const _ as usize } - , 3usize , concat ! ( - "Alignment of field: " , stringify ! ( Date2 ) , "::" , - stringify ! ( byte ) )); } impl Clone for Date2 { fn clone(&self) -> Self { *self } @@ -522,17 +515,17 @@ impl Clone for Date2 { impl Date2 { #[inline] pub fn nWeekDay(&self) -> ::std::os::raw::c_ushort { - let mask = 7usize as u16; - let unit_field_val: u16 = + let mask = 7usize as u32; + let unit_field_val: u32 = unsafe { ::std::mem::transmute(self._bitfield_1) }; let val = (unit_field_val & mask) >> 0usize; unsafe { ::std::mem::transmute(val as u16) } } #[inline] pub fn set_nWeekDay(&mut self, val: ::std::os::raw::c_ushort) { - let mask = 7usize as u16; - let val = val as u16 as u16; - let mut unit_field_val: u16 = + let mask = 7usize as u32; + let val = val as u16 as u32; + let mut unit_field_val: u32 = unsafe { ::std::mem::transmute(self._bitfield_1) }; unit_field_val &= !mask; unit_field_val |= (val << 0usize) & mask; @@ -540,17 +533,17 @@ impl Date2 { } #[inline] pub fn nMonthDay(&self) -> ::std::os::raw::c_ushort { - let mask = 504usize as u16; - let unit_field_val: u16 = + let mask = 504usize as u32; + let unit_field_val: u32 = unsafe { ::std::mem::transmute(self._bitfield_1) }; let val = (unit_field_val & mask) >> 3usize; unsafe { ::std::mem::transmute(val as u16) } } #[inline] pub fn set_nMonthDay(&mut self, val: ::std::os::raw::c_ushort) { - let mask = 504usize as u16; - let val = val as u16 as u16; - let mut unit_field_val: u16 = + let mask = 504usize as u32; + let val = val as u16 as u32; + let mut unit_field_val: u32 = unsafe { ::std::mem::transmute(self._bitfield_1) }; unit_field_val &= !mask; unit_field_val |= (val << 3usize) & mask; @@ -558,53 +551,78 @@ impl Date2 { } #[inline] pub fn nMonth(&self) -> ::std::os::raw::c_ushort { - let mask = 15872usize as u16; - let unit_field_val: u16 = + let mask = 15872usize as u32; + let unit_field_val: u32 = unsafe { ::std::mem::transmute(self._bitfield_1) }; let val = (unit_field_val & mask) >> 9usize; unsafe { ::std::mem::transmute(val as u16) } } #[inline] pub fn set_nMonth(&mut self, val: ::std::os::raw::c_ushort) { - let mask = 15872usize as u16; - let val = val as u16 as u16; - let mut unit_field_val: u16 = + let mask = 15872usize as u32; + let val = val as u16 as u32; + let mut unit_field_val: u32 = unsafe { ::std::mem::transmute(self._bitfield_1) }; unit_field_val &= !mask; unit_field_val |= (val << 9usize) & mask; self._bitfield_1 = unsafe { ::std::mem::transmute(unit_field_val) }; } #[inline] - pub fn new_bitfield_1(nWeekDay: ::std::os::raw::c_ushort, - nMonthDay: ::std::os::raw::c_ushort, - nMonth: ::std::os::raw::c_ushort) -> u16 { - ({ - ({ - ({ 0 } | - ((nWeekDay as u16 as u16) << 0usize) & (7usize as u16)) - } | ((nMonthDay as u16 as u16) << 3usize) & (504usize as u16)) - } | ((nMonth as u16 as u16) << 9usize) & (15872usize as u16)) - } - #[inline] pub fn nYear(&self) -> ::std::os::raw::c_ushort { - let mask = 255usize as u8; - let unit_field_val: u8 = - unsafe { ::std::mem::transmute(self._bitfield_2) }; - let val = (unit_field_val & mask) >> 0usize; + let mask = 16711680usize as u32; + let unit_field_val: u32 = + unsafe { ::std::mem::transmute(self._bitfield_1) }; + let val = (unit_field_val & mask) >> 16usize; unsafe { ::std::mem::transmute(val as u16) } } #[inline] pub fn set_nYear(&mut self, val: ::std::os::raw::c_ushort) { - let mask = 255usize as u8; - let val = val as u16 as u8; - let mut unit_field_val: u8 = - unsafe { ::std::mem::transmute(self._bitfield_2) }; + let mask = 16711680usize as u32; + let val = val as u16 as u32; + let mut unit_field_val: u32 = + unsafe { ::std::mem::transmute(self._bitfield_1) }; unit_field_val &= !mask; - unit_field_val |= (val << 0usize) & mask; - self._bitfield_2 = unsafe { ::std::mem::transmute(unit_field_val) }; + unit_field_val |= (val << 16usize) & mask; + self._bitfield_1 = unsafe { ::std::mem::transmute(unit_field_val) }; + } + #[inline] + pub fn byte(&self) -> ::std::os::raw::c_uchar { + let mask = 4278190080usize as u32; + let unit_field_val: u32 = + unsafe { ::std::mem::transmute(self._bitfield_1) }; + let val = (unit_field_val & mask) >> 24usize; + unsafe { ::std::mem::transmute(val as u8) } + } + #[inline] + pub fn set_byte(&mut self, val: ::std::os::raw::c_uchar) { + let mask = 4278190080usize as u32; + let val = val as u8 as u32; + let mut unit_field_val: u32 = + unsafe { ::std::mem::transmute(self._bitfield_1) }; + unit_field_val &= !mask; + unit_field_val |= (val << 24usize) & mask; + self._bitfield_1 = unsafe { ::std::mem::transmute(unit_field_val) }; } #[inline] - pub fn new_bitfield_2(nYear: ::std::os::raw::c_ushort) -> u8 { - ({ 0 } | ((nYear as u16 as u8) << 0usize) & (255usize as u8)) + pub fn new_bitfield_1(nWeekDay: ::std::os::raw::c_ushort, + nMonthDay: ::std::os::raw::c_ushort, + nMonth: ::std::os::raw::c_ushort, + nYear: ::std::os::raw::c_ushort, + byte: ::std::os::raw::c_uchar) -> u32 { + ({ + ({ + ({ + ({ + ({ 0 } | + ((nWeekDay as u16 as u32) << 0usize) & + (7usize as u32)) + } | + ((nMonthDay as u16 as u32) << 3usize) & + (504usize as u32)) + } | + ((nMonth as u16 as u32) << 9usize) & + (15872usize as u32)) + } | ((nYear as u16 as u32) << 16usize) & (16711680usize as u32)) + } | ((byte as u8 as u32) << 24usize) & (4278190080usize as u32)) } } diff --git a/tests/expectations/tests/bitfield_align_2.rs b/tests/expectations/tests/bitfield_align_2.rs new file mode 100644 index 00000000..f406948c --- /dev/null +++ b/tests/expectations/tests/bitfield_align_2.rs @@ -0,0 +1,72 @@ +/* automatically generated by rust-bindgen */ + + +#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] + + +#[repr(u32)] +#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)] +pub enum MyEnum { ONE = 0, TWO = 1, THREE = 2, FOUR = 3, } +#[repr(C)] +#[derive(Debug, Copy)] +pub struct TaggedPtr { + pub _bitfield_1: u64, + pub __bindgen_align: [u64; 0usize], +} +#[test] +fn bindgen_test_layout_TaggedPtr() { + assert_eq!(::std::mem::size_of::<TaggedPtr>() , 8usize , concat ! ( + "Size of: " , stringify ! ( TaggedPtr ) )); + assert_eq! (::std::mem::align_of::<TaggedPtr>() , 8usize , concat ! ( + "Alignment of " , stringify ! ( TaggedPtr ) )); +} +impl Clone for TaggedPtr { + fn clone(&self) -> Self { *self } +} +impl Default for TaggedPtr { + fn default() -> Self { unsafe { ::std::mem::zeroed() } } +} +impl TaggedPtr { + #[inline] + pub fn tag(&self) -> MyEnum { + let mask = 3usize as u64; + let unit_field_val: u64 = + unsafe { ::std::mem::transmute(self._bitfield_1) }; + let val = (unit_field_val & mask) >> 0usize; + unsafe { ::std::mem::transmute(val as u32) } + } + #[inline] + pub fn set_tag(&mut self, val: MyEnum) { + let mask = 3usize as u64; + let val = val as u32 as u64; + let mut unit_field_val: u64 = + unsafe { ::std::mem::transmute(self._bitfield_1) }; + unit_field_val &= !mask; + unit_field_val |= (val << 0usize) & mask; + self._bitfield_1 = unsafe { ::std::mem::transmute(unit_field_val) }; + } + #[inline] + pub fn ptr(&self) -> ::std::os::raw::c_long { + let mask = 18446744073709551612usize as u64; + let unit_field_val: u64 = + unsafe { ::std::mem::transmute(self._bitfield_1) }; + let val = (unit_field_val & mask) >> 2usize; + unsafe { ::std::mem::transmute(val as u64) } + } + #[inline] + pub fn set_ptr(&mut self, val: ::std::os::raw::c_long) { + let mask = 18446744073709551612usize as u64; + let val = val as u64 as u64; + let mut unit_field_val: u64 = + unsafe { ::std::mem::transmute(self._bitfield_1) }; + unit_field_val &= !mask; + unit_field_val |= (val << 2usize) & mask; + self._bitfield_1 = unsafe { ::std::mem::transmute(unit_field_val) }; + } + #[inline] + pub fn new_bitfield_1(tag: MyEnum, ptr: ::std::os::raw::c_long) -> u64 { + ({ ({ 0 } | ((tag as u32 as u64) << 0usize) & (3usize as u64)) } | + ((ptr as u64 as u64) << 2usize) & + (18446744073709551612usize as u64)) + } +} diff --git a/tests/expectations/tests/struct_with_bitfields.rs b/tests/expectations/tests/struct_with_bitfields.rs index 135cf087..44681d2e 100644 --- a/tests/expectations/tests/struct_with_bitfields.rs +++ b/tests/expectations/tests/struct_with_bitfields.rs @@ -9,8 +9,7 @@ pub struct bitfield { pub _bitfield_1: u8, pub e: ::std::os::raw::c_int, - pub _bitfield_2: u8, - pub _bitfield_3: u32, + pub _bitfield_2: [u32; 2usize], } #[test] fn bindgen_test_layout_bitfield() { @@ -114,46 +113,45 @@ impl bitfield { } #[inline] pub fn f(&self) -> ::std::os::raw::c_uint { - let mask = 3usize as u8; - let unit_field_val: u8 = + let mask = 3usize as u64; + let unit_field_val: u64 = unsafe { ::std::mem::transmute(self._bitfield_2) }; let val = (unit_field_val & mask) >> 0usize; unsafe { ::std::mem::transmute(val as u32) } } #[inline] pub fn set_f(&mut self, val: ::std::os::raw::c_uint) { - let mask = 3usize as u8; - let val = val as u32 as u8; - let mut unit_field_val: u8 = + let mask = 3usize as u64; + let val = val as u32 as u64; + let mut unit_field_val: u64 = unsafe { ::std::mem::transmute(self._bitfield_2) }; unit_field_val &= !mask; unit_field_val |= (val << 0usize) & mask; self._bitfield_2 = unsafe { ::std::mem::transmute(unit_field_val) }; } #[inline] - pub fn new_bitfield_2(f: ::std::os::raw::c_uint) -> u8 { - ({ 0 } | ((f as u32 as u8) << 0usize) & (3usize as u8)) - } - #[inline] pub fn g(&self) -> ::std::os::raw::c_uint { - let mask = 4294967295usize as u32; - let unit_field_val: u32 = - unsafe { ::std::mem::transmute(self._bitfield_3) }; - let val = (unit_field_val & mask) >> 0usize; + let mask = 18446744069414584320usize as u64; + let unit_field_val: u64 = + unsafe { ::std::mem::transmute(self._bitfield_2) }; + let val = (unit_field_val & mask) >> 32usize; unsafe { ::std::mem::transmute(val as u32) } } #[inline] pub fn set_g(&mut self, val: ::std::os::raw::c_uint) { - let mask = 4294967295usize as u32; - let val = val as u32 as u32; - let mut unit_field_val: u32 = - unsafe { ::std::mem::transmute(self._bitfield_3) }; + let mask = 18446744069414584320usize as u64; + let val = val as u32 as u64; + let mut unit_field_val: u64 = + unsafe { ::std::mem::transmute(self._bitfield_2) }; unit_field_val &= !mask; - unit_field_val |= (val << 0usize) & mask; - self._bitfield_3 = unsafe { ::std::mem::transmute(unit_field_val) }; + unit_field_val |= (val << 32usize) & mask; + self._bitfield_2 = unsafe { ::std::mem::transmute(unit_field_val) }; } #[inline] - pub fn new_bitfield_3(g: ::std::os::raw::c_uint) -> u32 { - ({ 0 } | ((g as u32 as u32) << 0usize) & (4294967295usize as u32)) + pub fn new_bitfield_2(f: ::std::os::raw::c_uint, + g: ::std::os::raw::c_uint) -> u64 { + ({ ({ 0 } | ((f as u32 as u64) << 0usize) & (3usize as u64)) } | + ((g as u32 as u64) << 32usize) & + (18446744069414584320usize as u64)) } } diff --git a/tests/expectations/tests/weird_bitfields.rs b/tests/expectations/tests/weird_bitfields.rs index 413b7103..2fb9cbc5 100644 --- a/tests/expectations/tests/weird_bitfields.rs +++ b/tests/expectations/tests/weird_bitfields.rs @@ -27,8 +27,7 @@ pub struct Weird { pub mStrokeLinejoin: ::std::os::raw::c_uchar, pub mTextAnchor: ::std::os::raw::c_uchar, pub mTextRendering: ::std::os::raw::c_uchar, - pub _bitfield_2: u8, - pub _bitfield_3: u8, + pub _bitfield_2: [u8; 2usize], pub __bindgen_padding_0: [u8; 3usize], } #[test] @@ -151,17 +150,17 @@ impl Weird { } #[inline] pub fn mFillOpacitySource(&self) -> nsStyleSVGOpacitySource { - let mask = 7usize as u8; - let unit_field_val: u8 = + let mask = 7usize as u16; + let unit_field_val: u16 = unsafe { ::std::mem::transmute(self._bitfield_2) }; let val = (unit_field_val & mask) >> 0usize; unsafe { ::std::mem::transmute(val as u32) } } #[inline] pub fn set_mFillOpacitySource(&mut self, val: nsStyleSVGOpacitySource) { - let mask = 7usize as u8; - let val = val as u32 as u8; - let mut unit_field_val: u8 = + let mask = 7usize as u16; + let val = val as u32 as u16; + let mut unit_field_val: u16 = unsafe { ::std::mem::transmute(self._bitfield_2) }; unit_field_val &= !mask; unit_field_val |= (val << 0usize) & mask; @@ -169,17 +168,17 @@ impl Weird { } #[inline] pub fn mStrokeOpacitySource(&self) -> nsStyleSVGOpacitySource { - let mask = 56usize as u8; - let unit_field_val: u8 = + let mask = 56usize as u16; + let unit_field_val: u16 = unsafe { ::std::mem::transmute(self._bitfield_2) }; let val = (unit_field_val & mask) >> 3usize; unsafe { ::std::mem::transmute(val as u32) } } #[inline] pub fn set_mStrokeOpacitySource(&mut self, val: nsStyleSVGOpacitySource) { - let mask = 56usize as u8; - let val = val as u32 as u8; - let mut unit_field_val: u8 = + let mask = 56usize as u16; + let val = val as u32 as u16; + let mut unit_field_val: u16 = unsafe { ::std::mem::transmute(self._bitfield_2) }; unit_field_val &= !mask; unit_field_val |= (val << 3usize) & mask; @@ -187,17 +186,17 @@ impl Weird { } #[inline] pub fn mStrokeDasharrayFromObject(&self) -> bool { - let mask = 64usize as u8; - let unit_field_val: u8 = + let mask = 64usize as u16; + let unit_field_val: u16 = unsafe { ::std::mem::transmute(self._bitfield_2) }; let val = (unit_field_val & mask) >> 6usize; unsafe { ::std::mem::transmute(val as u8) } } #[inline] pub fn set_mStrokeDasharrayFromObject(&mut self, val: bool) { - let mask = 64usize as u8; - let val = val as u8 as u8; - let mut unit_field_val: u8 = + let mask = 64usize as u16; + let val = val as u8 as u16; + let mut unit_field_val: u16 = unsafe { ::std::mem::transmute(self._bitfield_2) }; unit_field_val &= !mask; unit_field_val |= (val << 6usize) & mask; @@ -205,65 +204,64 @@ impl Weird { } #[inline] pub fn mStrokeDashoffsetFromObject(&self) -> bool { - let mask = 128usize as u8; - let unit_field_val: u8 = + let mask = 128usize as u16; + let unit_field_val: u16 = unsafe { ::std::mem::transmute(self._bitfield_2) }; let val = (unit_field_val & mask) >> 7usize; unsafe { ::std::mem::transmute(val as u8) } } #[inline] pub fn set_mStrokeDashoffsetFromObject(&mut self, val: bool) { - let mask = 128usize as u8; - let val = val as u8 as u8; - let mut unit_field_val: u8 = + let mask = 128usize as u16; + let val = val as u8 as u16; + let mut unit_field_val: u16 = unsafe { ::std::mem::transmute(self._bitfield_2) }; unit_field_val &= !mask; unit_field_val |= (val << 7usize) & mask; self._bitfield_2 = unsafe { ::std::mem::transmute(unit_field_val) }; } #[inline] + pub fn mStrokeWidthFromObject(&self) -> bool { + let mask = 256usize as u16; + let unit_field_val: u16 = + unsafe { ::std::mem::transmute(self._bitfield_2) }; + let val = (unit_field_val & mask) >> 8usize; + unsafe { ::std::mem::transmute(val as u8) } + } + #[inline] + pub fn set_mStrokeWidthFromObject(&mut self, val: bool) { + let mask = 256usize as u16; + let val = val as u8 as u16; + let mut unit_field_val: u16 = + unsafe { ::std::mem::transmute(self._bitfield_2) }; + unit_field_val &= !mask; + unit_field_val |= (val << 8usize) & mask; + self._bitfield_2 = unsafe { ::std::mem::transmute(unit_field_val) }; + } + #[inline] pub fn new_bitfield_2(mFillOpacitySource: nsStyleSVGOpacitySource, mStrokeOpacitySource: nsStyleSVGOpacitySource, mStrokeDasharrayFromObject: bool, - mStrokeDashoffsetFromObject: bool) -> u8 { + mStrokeDashoffsetFromObject: bool, + mStrokeWidthFromObject: bool) -> u16 { ({ ({ ({ - ({ 0 } | - ((mFillOpacitySource as u32 as u8) << 0usize) & - (7usize as u8)) + ({ + ({ 0 } | + ((mFillOpacitySource as u32 as u16) << + 0usize) & (7usize as u16)) + } | + ((mStrokeOpacitySource as u32 as u16) << 3usize) & + (56usize as u16)) } | - ((mStrokeOpacitySource as u32 as u8) << 3usize) & - (56usize as u8)) + ((mStrokeDasharrayFromObject as u8 as u16) << 6usize) & + (64usize as u16)) } | - ((mStrokeDasharrayFromObject as u8 as u8) << 6usize) & - (64usize as u8)) + ((mStrokeDashoffsetFromObject as u8 as u16) << 7usize) & + (128usize as u16)) } | - ((mStrokeDashoffsetFromObject as u8 as u8) << 7usize) & - (128usize as u8)) - } - #[inline] - pub fn mStrokeWidthFromObject(&self) -> bool { - let mask = 1usize as u8; - let unit_field_val: u8 = - unsafe { ::std::mem::transmute(self._bitfield_3) }; - let val = (unit_field_val & mask) >> 0usize; - unsafe { ::std::mem::transmute(val as u8) } - } - #[inline] - pub fn set_mStrokeWidthFromObject(&mut self, val: bool) { - let mask = 1usize as u8; - let val = val as u8 as u8; - let mut unit_field_val: u8 = - unsafe { ::std::mem::transmute(self._bitfield_3) }; - unit_field_val &= !mask; - unit_field_val |= (val << 0usize) & mask; - self._bitfield_3 = unsafe { ::std::mem::transmute(unit_field_val) }; - } - #[inline] - pub fn new_bitfield_3(mStrokeWidthFromObject: bool) -> u8 { - ({ 0 } | - ((mStrokeWidthFromObject as u8 as u8) << 0usize) & - (1usize as u8)) + ((mStrokeWidthFromObject as u8 as u16) << 8usize) & + (256usize as u16)) } } diff --git a/tests/headers/bitfield_align.h b/tests/headers/bitfield_align.h index 82b53099..5316b697 100644 --- a/tests/headers/bitfield_align.h +++ b/tests/headers/bitfield_align.h @@ -37,5 +37,15 @@ struct Date2 { unsigned short nMonthDay : 6; // 0..31 (6 bits) unsigned short nMonth : 5; // 0..12 (5 bits) unsigned short nYear : 8; // 0..100 (8 bits) - unsigned char byte; + unsigned char byte : 8; }; + +// FIXME(#734) +// +// struct Date3 { +// unsigned short nWeekDay : 3; // 0..7 (3 bits) +// unsigned short nMonthDay : 6; // 0..31 (6 bits) +// unsigned short nMonth : 5; // 0..12 (5 bits) +// unsigned short nYear : 8; // 0..100 (8 bits) +// unsigned char byte; +// }; diff --git a/tests/headers/bitfield_align_2.h b/tests/headers/bitfield_align_2.h new file mode 100644 index 00000000..c6e5e5e7 --- /dev/null +++ b/tests/headers/bitfield_align_2.h @@ -0,0 +1,12 @@ + +enum MyEnum { + ONE, + TWO, + THREE, + FOUR +}; + +struct TaggedPtr { + enum MyEnum tag : 2; + long ptr : 62; +}; |