summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--bindgen-integration/cpp/Test.cc20
-rw-r--r--bindgen-integration/cpp/Test.h31
-rwxr-xr-xbindgen-integration/src/lib.rs39
-rw-r--r--src/ir/comp.rs68
-rw-r--r--tests/expectations/tests/bitfield_align.rs192
-rw-r--r--tests/expectations/tests/bitfield_align_2.rs72
-rw-r--r--tests/expectations/tests/struct_with_bitfields.rs44
-rw-r--r--tests/expectations/tests/weird_bitfields.rs110
-rw-r--r--tests/headers/bitfield_align.h12
-rw-r--r--tests/headers/bitfield_align_2.h12
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;
+};