diff --git a/bindgen-integration/build.rs b/bindgen-integration/build.rs index 071d72b5ab..a9970135cd 100644 --- a/bindgen-integration/build.rs +++ b/bindgen-integration/build.rs @@ -20,7 +20,7 @@ impl ParseCallbacks for MacroCallback { } fn main() { - gcc::Config::new() + gcc::Build::new() .cpp(true) .file("cpp/Test.cc") .compile("libtest.a"); diff --git a/bindgen-integration/cpp/Test.cc b/bindgen-integration/cpp/Test.cc index f125109a7a..57c2186b2e 100644 --- a/bindgen-integration/cpp/Test.cc +++ b/bindgen-integration/cpp/Test.cc @@ -69,11 +69,11 @@ Date2::assert(unsigned short nWeekDay, unsigned short nYear, unsigned short byte) { - return this->nWeekDay == nWeekDay && - this->nMonthDay == nMonthDay && - this->nMonth == nMonth && - this->nYear == nYear && - this->byte == byte; + return this->nWeekDay == nWeekDay && + this->nMonthDay == nMonthDay && + this->nMonth == nMonth && + this->nYear == nYear && + this->byte == byte; } bool @@ -83,11 +83,11 @@ Fifth::assert(unsigned short nWeekDay, unsigned short nYear, unsigned char byte) { - return this->nWeekDay == nWeekDay && - this->nMonthDay == nMonthDay && - this->nMonth == nMonth && - this->nYear == nYear && - this->byte == byte; + return this->nWeekDay == nWeekDay && + this->nMonthDay == nMonthDay && + this->nMonth == nMonth && + this->nYear == nYear && + this->byte == byte; } bool @@ -95,10 +95,27 @@ Sixth::assert(unsigned char byte, unsigned char nWeekDay, unsigned char nMonth, unsigned char nMonthDay) { - return this->nWeekDay == nWeekDay && - this->nMonthDay == nMonthDay && - this->nMonth == nMonth && - this->byte == byte; + return this->nWeekDay == nWeekDay && + this->nMonthDay == nMonthDay && + this->nMonth == nMonth && + this->byte == byte; +}; + +bool +Seventh::assert(bool first, + int second, + unsigned short third, + unsigned int fourth, + unsigned short fifth, + bool sixth, + int seventh) { + return this->first_one_bit == first && + this->second_thirty_bits == second && + this->third_two_bits == third && + this->fourth_thirty_bits == fourth && + this->fifth_two_bits == fifth && + this->sixth_one_bit == sixth && + this->seventh_thirty_bits == seventh; }; } // namespace bitfields diff --git a/bindgen-integration/cpp/Test.h b/bindgen-integration/cpp/Test.h index e23a32e6cd..7ddb98bd7d 100644 --- a/bindgen-integration/cpp/Test.h +++ b/bindgen-integration/cpp/Test.h @@ -121,6 +121,24 @@ struct Sixth { unsigned char nMonthDay); }; +struct Seventh { + bool first_one_bit : 1; + unsigned int second_thirty_bits : 30; + unsigned short third_two_bits : 2; + unsigned int fourth_thirty_bits : 30; + unsigned short fifth_two_bits : 2; + bool sixth_one_bit : 1; + unsigned int seventh_thirty_bits : 30; + + /// Returns true if the bitfields match the arguments, false otherwise. + bool assert(bool first, + int second, + unsigned short third, + unsigned int fourth, + unsigned short fifth, + bool sixth, + int seventh); +}; } // namespace bitfields diff --git a/bindgen-integration/src/lib.rs b/bindgen-integration/src/lib.rs index b09b289d99..3c3652d9aa 100755 --- a/bindgen-integration/src/lib.rs +++ b/bindgen-integration/src/lib.rs @@ -179,11 +179,42 @@ fn test_bitfields_sixth() { }); } +#[test] +fn test_bitfields_seventh() { + let mut large: bindings::bitfields::Seventh = unsafe { + mem::zeroed() + }; + + assert!(unsafe { + large.assert(false, 0, 0, 0, 0, false, 0) + }); + + large.set_first_one_bit(true); + large.set_second_thirty_bits(375028802); + large.set_third_two_bits(2); + large.set_fourth_thirty_bits(643472885); + large.set_fifth_two_bits(3); + large.set_sixth_one_bit(true); + large.set_seventh_thirty_bits(1061657575); + + assert!(unsafe { + large.assert(true, 375028802, 2, 643472885, 3, true, 1061657575) + }); + + assert_eq!(large.first_one_bit(), true); + assert_eq!(large.second_thirty_bits(), 375028802); + assert_eq!(large.third_two_bits(), 2); + assert_eq!(large.fourth_thirty_bits(), 643472885); + assert_eq!(large.fifth_two_bits(), 3); + assert_eq!(large.sixth_one_bit(), true); + assert_eq!(large.seventh_thirty_bits(), 1061657575); +} + #[test] fn test_bitfield_constructors() { use std::mem; let mut first = bindings::bitfields::First { - _bitfield_1: unsafe { mem::transmute(bindings::bitfields::First::new_bitfield_1(1, 2, 3)) } + _bitfield_1: bindings::bitfields::First::new_bitfield_1(1, 2, 3) }; assert!(unsafe { first.assert(1, 2, 3) diff --git a/src/codegen/bitfield_unit.rs b/src/codegen/bitfield_unit.rs new file mode 100755 index 0000000000..3c7c9b7b8b --- /dev/null +++ b/src/codegen/bitfield_unit.rs @@ -0,0 +1,82 @@ +#[repr(C)] +#[derive(Copy, Clone, Debug, Default, Eq, Hash, Ord, PartialEq, PartialOrd)] +pub struct __BindgenBitfieldUnit +where + Storage: AsRef<[u8]> + AsMut<[u8]>, +{ + storage: Storage, + align: [Align; 0], +} + +impl __BindgenBitfieldUnit +where + Storage: AsRef<[u8]> + AsMut<[u8]>, +{ + #[inline] + pub fn new(storage: Storage) -> Self { + Self { + storage, + align: [], + } + } + + #[inline] + pub fn get_bit(&self, index: usize) -> bool { + debug_assert!(index / 8 < self.storage.as_ref().len()); + + let byte_index = index / 8; + let byte = self.storage.as_ref()[byte_index]; + + let bit_index = index % 8; + let mask = 1 << bit_index; + + byte & mask == mask + } + + #[inline] + pub fn set_bit(&mut self, index: usize, val: bool) { + debug_assert!(index / 8 < self.storage.as_ref().len()); + + let byte_index = index / 8; + let byte = &mut self.storage.as_mut()[byte_index]; + + let bit_index = index % 8; + let mask = 1 << bit_index; + + if val { + *byte |= mask; + } else { + *byte &= !mask; + } + } + + #[inline] + pub fn get(&self, bit_offset: usize, bit_width: u8) -> u64 { + debug_assert!(bit_width <= 64); + debug_assert!(bit_offset / 8 < self.storage.as_ref().len()); + debug_assert!((bit_offset + (bit_width as usize)) / 8 <= self.storage.as_ref().len()); + + let mut val = 0; + + for i in 0..(bit_width as usize) { + if self.get_bit(i + bit_offset) { + val |= 1 << i; + } + } + + val + } + + #[inline] + pub fn set(&mut self, bit_offset: usize, bit_width: u8, val: u64) { + debug_assert!(bit_width <= 64); + debug_assert!(bit_offset / 8 < self.storage.as_ref().len()); + debug_assert!((bit_offset + (bit_width as usize)) / 8 <= self.storage.as_ref().len()); + + for i in 0..(bit_width as usize) { + let mask = 1 << i; + let val_bit_is_set = val & mask == mask; + self.set_bit(i + bit_offset, val_bit_is_set); + } + } +} diff --git a/src/codegen/bitfield_unit_tests.rs b/src/codegen/bitfield_unit_tests.rs new file mode 100644 index 0000000000..d39878ccd9 --- /dev/null +++ b/src/codegen/bitfield_unit_tests.rs @@ -0,0 +1,284 @@ +//! Tests for `__BindgenBitfieldUnit`. +//! +//! Note that bit-fields are allocated right to left (least to most significant +//! bits). +//! +//! From the x86 PS ABI: +//! +//! ```c +//! struct { +//! int j : 5; +//! int k : 6; +//! int m : 7; +//! }; +//! ``` +//! +//! ```ignore +//! +------------------------------------------------------------+ +//! | | | | | +//! | padding | m | k | j | +//! |31 18|17 11|10 5|4 0| +//! +------------------------------------------------------------+ +//! ``` + +use super::bitfield_unit::__BindgenBitfieldUnit; +use std::mem; + +#[test] +fn bitfield_unit_get_bit() { + let unit = __BindgenBitfieldUnit::<[u8; 2], u64>::new([0b10011101, 0b00011101]); + + let mut bits = vec![]; + for i in 0..16 { + bits.push(unit.get_bit(i)); + } + + println!(); + println!("bits = {:?}", bits); + assert_eq!(bits, &[ + // 0b10011101 + true, + false, + true, + true, + true, + false, + false, + true , + + // 0b00011101 + true, + false, + true, + true, + true, + false, + false, + false + ]); +} + +#[test] +fn bitfield_unit_set_bit() { + let mut unit = __BindgenBitfieldUnit::<[u8; 2], u64>::new([0b00000000, 0b00000000]); + + for i in 0..16 { + if i % 3 == 0 { + unit.set_bit(i, true); + } + } + + for i in 0..16 { + assert_eq!(unit.get_bit(i), i % 3 == 0); + } + + let mut unit = __BindgenBitfieldUnit::<[u8; 2], u64>::new([0b11111111, 0b11111111]); + + for i in 0..16 { + if i % 3 == 0 { + unit.set_bit(i, false); + } + } + + for i in 0..16 { + assert_eq!(unit.get_bit(i), i % 3 != 0); + } +} + +#[test] +fn bitfield_unit_align() { + assert_eq!(mem::align_of::<__BindgenBitfieldUnit<[u8; 1], u8>>(), mem::align_of::()); + assert_eq!(mem::align_of::<__BindgenBitfieldUnit<[u8; 1], u16>>(), mem::align_of::()); + assert_eq!(mem::align_of::<__BindgenBitfieldUnit<[u8; 1], u32>>(), mem::align_of::()); + assert_eq!(mem::align_of::<__BindgenBitfieldUnit<[u8; 1], u64>>(), mem::align_of::()); + + assert_eq!(mem::align_of::<__BindgenBitfieldUnit<[u8; 8], u8>>(), mem::align_of::()); + assert_eq!(mem::align_of::<__BindgenBitfieldUnit<[u8; 8], u16>>(), mem::align_of::()); + assert_eq!(mem::align_of::<__BindgenBitfieldUnit<[u8; 8], u32>>(), mem::align_of::()); + assert_eq!(mem::align_of::<__BindgenBitfieldUnit<[u8; 8], u64>>(), mem::align_of::()); +} + +macro_rules! bitfield_unit_get { + ( + $( + With $storage:expr , then get($start:expr, $len:expr) is $expected:expr; + )* + ) => { + #[test] + fn bitfield_unit_get() { + $({ + let expected = $expected; + let unit = __BindgenBitfieldUnit::<_, u64>::new($storage); + let actual = unit.get($start, $len); + + println!(); + println!("expected = {:064b}", expected); + println!("actual = {:064b}", actual); + + assert_eq!(expected, actual); + })* + } + } +} + +bitfield_unit_get! { + // Let's just exhaustively test getting the bits from a single byte, since + // there are few enough combinations... + + With [0b11100010], then get(0, 1) is 0; + With [0b11100010], then get(1, 1) is 1; + With [0b11100010], then get(2, 1) is 0; + With [0b11100010], then get(3, 1) is 0; + With [0b11100010], then get(4, 1) is 0; + With [0b11100010], then get(5, 1) is 1; + With [0b11100010], then get(6, 1) is 1; + With [0b11100010], then get(7, 1) is 1; + + With [0b11100010], then get(0, 2) is 0b10; + With [0b11100010], then get(1, 2) is 0b01; + With [0b11100010], then get(2, 2) is 0b00; + With [0b11100010], then get(3, 2) is 0b00; + With [0b11100010], then get(4, 2) is 0b10; + With [0b11100010], then get(5, 2) is 0b11; + With [0b11100010], then get(6, 2) is 0b11; + + With [0b11100010], then get(0, 3) is 0b010; + With [0b11100010], then get(1, 3) is 0b001; + With [0b11100010], then get(2, 3) is 0b000; + With [0b11100010], then get(3, 3) is 0b100; + With [0b11100010], then get(4, 3) is 0b110; + With [0b11100010], then get(5, 3) is 0b111; + + With [0b11100010], then get(0, 4) is 0b0010; + With [0b11100010], then get(1, 4) is 0b0001; + With [0b11100010], then get(2, 4) is 0b1000; + With [0b11100010], then get(3, 4) is 0b1100; + With [0b11100010], then get(4, 4) is 0b1110; + + With [0b11100010], then get(0, 5) is 0b00010; + With [0b11100010], then get(1, 5) is 0b10001; + With [0b11100010], then get(2, 5) is 0b11000; + With [0b11100010], then get(3, 5) is 0b11100; + + With [0b11100010], then get(0, 6) is 0b100010; + With [0b11100010], then get(1, 6) is 0b110001; + With [0b11100010], then get(2, 6) is 0b111000; + + With [0b11100010], then get(0, 7) is 0b1100010; + With [0b11100010], then get(1, 7) is 0b1110001; + + With [0b11100010], then get(0, 8) is 0b11100010; + + // OK. Now let's test getting bits from across byte boundaries. + + With [0b01010101, 0b11111111, 0b00000000, 0b11111111], + then get(0, 16) is 0b1111111101010101; + + With [0b01010101, 0b11111111, 0b00000000, 0b11111111], + then get(1, 16) is 0b0111111110101010; + + With [0b01010101, 0b11111111, 0b00000000, 0b11111111], + then get(2, 16) is 0b0011111111010101; + + With [0b01010101, 0b11111111, 0b00000000, 0b11111111], + then get(3, 16) is 0b0001111111101010; + + With [0b01010101, 0b11111111, 0b00000000, 0b11111111], + then get(4, 16) is 0b0000111111110101; + + With [0b01010101, 0b11111111, 0b00000000, 0b11111111], + then get(5, 16) is 0b0000011111111010; + + With [0b01010101, 0b11111111, 0b00000000, 0b11111111], + then get(6, 16) is 0b0000001111111101; + + With [0b01010101, 0b11111111, 0b00000000, 0b11111111], + then get(7, 16) is 0b0000000111111110; + + With [0b01010101, 0b11111111, 0b00000000, 0b11111111], + then get(8, 16) is 0b0000000011111111; +} + +macro_rules! bitfield_unit_set { + ( + $( + set($start:expr, $len:expr, $val:expr) is $expected:expr; + )* + ) => { + #[test] + fn bitfield_unit_set() { + $( + let mut unit = __BindgenBitfieldUnit::<[u8; 4], u64>::new([0, 0, 0, 0]); + unit.set($start, $len, $val); + let actual = unit.get(0, 32); + + println!(); + println!("set({}, {}, {:032b}", $start, $len, $val); + println!("expected = {:064b}", $expected); + println!("actual = {:064b}", actual); + + assert_eq!($expected, actual); + )* + } + } +} + +bitfield_unit_set! { + // Once again, let's exhaustively test single byte combinations. + + set(0, 1, 0b11111111) is 0b00000001; + set(1, 1, 0b11111111) is 0b00000010; + set(2, 1, 0b11111111) is 0b00000100; + set(3, 1, 0b11111111) is 0b00001000; + set(4, 1, 0b11111111) is 0b00010000; + set(5, 1, 0b11111111) is 0b00100000; + set(6, 1, 0b11111111) is 0b01000000; + set(7, 1, 0b11111111) is 0b10000000; + + set(0, 2, 0b11111111) is 0b00000011; + set(1, 2, 0b11111111) is 0b00000110; + set(2, 2, 0b11111111) is 0b00001100; + set(3, 2, 0b11111111) is 0b00011000; + set(4, 2, 0b11111111) is 0b00110000; + set(5, 2, 0b11111111) is 0b01100000; + set(6, 2, 0b11111111) is 0b11000000; + + set(0, 3, 0b11111111) is 0b00000111; + set(1, 3, 0b11111111) is 0b00001110; + set(2, 3, 0b11111111) is 0b00011100; + set(3, 3, 0b11111111) is 0b00111000; + set(4, 3, 0b11111111) is 0b01110000; + set(5, 3, 0b11111111) is 0b11100000; + + set(0, 4, 0b11111111) is 0b00001111; + set(1, 4, 0b11111111) is 0b00011110; + set(2, 4, 0b11111111) is 0b00111100; + set(3, 4, 0b11111111) is 0b01111000; + set(4, 4, 0b11111111) is 0b11110000; + + set(0, 5, 0b11111111) is 0b00011111; + set(1, 5, 0b11111111) is 0b00111110; + set(2, 5, 0b11111111) is 0b01111100; + set(3, 5, 0b11111111) is 0b11111000; + + set(0, 6, 0b11111111) is 0b00111111; + set(1, 6, 0b11111111) is 0b01111110; + set(2, 6, 0b11111111) is 0b11111100; + + set(0, 7, 0b11111111) is 0b01111111; + set(1, 7, 0b11111111) is 0b11111110; + + set(0, 8, 0b11111111) is 0b11111111; + + // And, now let's cross byte boundaries. + + set(0, 16, 0b1111111111111111) is 0b00000000000000001111111111111111; + set(1, 16, 0b1111111111111111) is 0b00000000000000011111111111111110; + set(2, 16, 0b1111111111111111) is 0b00000000000000111111111111111100; + set(3, 16, 0b1111111111111111) is 0b00000000000001111111111111111000; + set(4, 16, 0b1111111111111111) is 0b00000000000011111111111111110000; + set(5, 16, 0b1111111111111111) is 0b00000000000111111111111111100000; + set(6, 16, 0b1111111111111111) is 0b00000000001111111111111111000000; + set(7, 16, 0b1111111111111111) is 0b00000000011111111111111110000000; + set(8, 16, 0b1111111111111111) is 0b00000000111111111111111100000000; +} diff --git a/src/codegen/helpers.rs b/src/codegen/helpers.rs index 4ff398c409..9905430572 100644 --- a/src/codegen/helpers.rs +++ b/src/codegen/helpers.rs @@ -1,7 +1,9 @@ //! Helpers for code generation that don't need macro expansion. +use ir::context::BindgenContext; use ir::layout::Layout; use quote; +use std::mem; pub mod attributes { use quote; @@ -86,6 +88,39 @@ pub fn blob(layout: Layout) -> quote::Tokens { } } +/// Integer type of the same size as the given `Layout`. +pub fn integer_type(layout: Layout) -> Option { + // This guard can be weakened when Rust implements u128. + if layout.size > mem::size_of::() { + None + } else { + Some(blob(layout)) + } +} + +/// Generates a bitfield allocation unit type for a type with the given `Layout`. +pub fn bitfield_unit(ctx: &BindgenContext, layout: Layout) -> quote::Tokens { + let mut tokens = quote! {}; + + if ctx.options().enable_cxx_namespaces { + tokens.append(quote! { root:: }); + } + + let align = match layout.align { + n if n >= 8 => quote! { u64 }, + 4 => quote! { u32 }, + 2 => quote! { u16 }, + _ => quote! { u8 }, + }; + + let size = layout.size; + tokens.append(quote! { + __BindgenBitfieldUnit<[u8; #size], #align> + }); + + tokens +} + pub mod ast_ty { use ir::context::BindgenContext; use ir::function::FunctionSig; @@ -143,13 +178,6 @@ pub mod ast_ty { tokens } - /// Returns hex representation of the given value. - pub fn hex_expr(val: u64) -> quote::Tokens { - let mut tokens = quote! {}; - tokens.append(format!("{:#x}", val)); - tokens - } - pub fn byte_array_expr(bytes: &[u8]) -> quote::Tokens { let mut bytes: Vec<_> = bytes.iter().cloned().collect(); bytes.push(0); diff --git a/src/codegen/mod.rs b/src/codegen/mod.rs index f0a7e0be28..bfc32129cc 100644 --- a/src/codegen/mod.rs +++ b/src/codegen/mod.rs @@ -4,6 +4,12 @@ mod error; mod helpers; pub mod struct_layout; +#[cfg(test)] +#[allow(warnings)] +pub(crate) mod bitfield_unit; +#[cfg(test)] +mod bitfield_unit_tests; + use self::helpers::attributes; use self::struct_layout::StructLayoutTracker; @@ -96,6 +102,9 @@ struct CodegenResult<'a> { /// Whether Objective C types have been seen at least once. saw_objc: bool, + /// Whether a bitfield allocation unit has been seen at least once. + saw_bitfield_unit: bool, + items_seen: HashSet, /// The set of generated function/var names, needed because in C/C++ is /// legal to do something like: @@ -130,6 +139,7 @@ impl<'a> CodegenResult<'a> { saw_bindgen_union: false, saw_incomplete_array: false, saw_objc: false, + saw_bitfield_unit: false, codegen_id: codegen_id, items_seen: Default::default(), functions_seen: Default::default(), @@ -155,6 +165,10 @@ impl<'a> CodegenResult<'a> { self.saw_objc = true; } + fn saw_bitfield_unit(&mut self) { + self.saw_bitfield_unit = true; + } + fn seen>(&self, item: Id) -> bool { self.items_seen.contains(&item.into()) } @@ -200,6 +214,7 @@ impl<'a> CodegenResult<'a> { self.saw_union |= new.saw_union; self.saw_incomplete_array |= new.saw_incomplete_array; self.saw_objc |= new.saw_objc; + self.saw_bitfield_unit |= new.saw_bitfield_unit; new.items } @@ -395,6 +410,9 @@ impl CodeGenerator for Module { if result.saw_objc { utils::prepend_objc_header(ctx, &mut *result); } + if result.saw_bitfield_unit { + utils::prepend_bitfield_unit_type(&mut *result); + } } }; @@ -1119,14 +1137,13 @@ impl Bitfield { /// /// 1. Adding a parameter with this bitfield's name and its type. /// - /// 2. Bitwise or'ing the parameter into the final value of the constructed - /// bitfield unit. + /// 2. Setting the relevant bits on the `__bindgen_bitfield_unit` variable + /// that's being constructed. fn extend_ctor_impl( &self, ctx: &BindgenContext, param_name: quote::Tokens, - ctor_impl: quote::Tokens, - unit_field_int_ty: "e::Tokens, + mut ctor_impl: quote::Tokens, ) -> quote::Tokens { let bitfield_ty = ctx.resolve_type(self.ty()); let bitfield_ty_layout = bitfield_ty.layout(ctx).expect( @@ -1135,15 +1152,23 @@ impl Bitfield { let bitfield_int_ty = helpers::blob(bitfield_ty_layout); let offset = self.offset_into_unit(); - let mask = helpers::ast_ty::hex_expr(self.mask()); + let width = self.width() as u8; + let prefix = ctx.trait_prefix(); - // Don't use variables or blocks because const functions do not allow - // them. - quote! { - (#ctor_impl | - ((#param_name as #bitfield_int_ty as #unit_field_int_ty) << #offset) & - (#mask as #unit_field_int_ty)) - } + ctor_impl.append(quote! { + __bindgen_bitfield_unit.set( + #offset, + #width, + { + let #param_name: #bitfield_int_ty = unsafe { + ::#prefix::mem::transmute(#param_name) + }; + #param_name as u64 + } + ); + }); + + ctor_impl } } @@ -1166,19 +1191,23 @@ impl<'a> FieldCodegen<'a> for BitfieldUnit { F: Extend, M: Extend, { - let field_ty = if parent.is_union() && !parent.can_be_rust_union(ctx) { - let ty = helpers::blob(self.layout()); - if ctx.options().enable_cxx_namespaces { - quote! { - root::__BindgenUnionField<#ty> + result.saw_bitfield_unit(); + + let field_ty = { + let ty = helpers::bitfield_unit(ctx, self.layout()); + if parent.is_union() && !parent.can_be_rust_union(ctx) { + if ctx.options().enable_cxx_namespaces { + quote! { + root::__BindgenUnionField<#ty> + } + } else { + quote! { + __BindgenUnionField<#ty> + } } } else { - quote! { - __BindgenUnionField<#ty> - } + ty } - } else { - helpers::blob(self.layout()) }; let unit_field_name = format!("_bitfield_{}", self.nth()); @@ -1189,34 +1218,21 @@ impl<'a> FieldCodegen<'a> for BitfieldUnit { }; fields.extend(Some(field)); - let mut field_int_size = self.layout().size; - if !field_int_size.is_power_of_two() { - field_int_size = field_int_size.next_power_of_two(); - } - - let unit_field_int_ty = match field_int_size { - 8 => quote! { u64 }, - 4 => quote! { u32 }, - 2 => quote! { u16 }, - 1 => quote! { u8 }, - size => { - debug_assert!(size > 8); - // Can't generate bitfield accessors for unit sizes larger than - // 64 bits at the moment. - struct_layout.saw_bitfield_unit(self.layout()); - return; - } - }; + let unit_field_ty = helpers::bitfield_unit(ctx, self.layout()); let ctor_name = self.ctor_name(); let mut ctor_params = vec![]; - let mut ctor_impl = quote! { 0 }; + let mut ctor_impl = quote! {}; + let mut generate_ctor = true; for bf in self.bitfields() { // Codegen not allowed for anonymous bitfields if bf.name().is_none() { continue; } + + let mut bitfield_representable_as_int = true; + bf.codegen( ctx, fields_should_be_private, @@ -1227,9 +1243,15 @@ impl<'a> FieldCodegen<'a> for BitfieldUnit { struct_layout, fields, methods, - (&unit_field_name, unit_field_int_ty.clone(), self.layout().size), + (&unit_field_name, &mut bitfield_representable_as_int), ); + // Generating a constructor requires the bitfield to be representable as an integer. + if !bitfield_representable_as_int { + generate_ctor = false; + continue; + } + let param_name = bitfield_getter_name(ctx, bf); let bitfield_ty_item = ctx.resolve_item(bf.ty()); let bitfield_ty = bitfield_ty_item.expect_type(); @@ -1243,22 +1265,19 @@ impl<'a> FieldCodegen<'a> for BitfieldUnit { ctx, param_name, ctor_impl, - &unit_field_int_ty, ); } - let const_ = if ctx.options().rust_features().const_fn() { - quote! { const } - } else { - quote! { } - }; - - methods.extend(Some(quote! { - #[inline] - pub #const_ fn #ctor_name ( #( #ctor_params ),* ) -> #unit_field_int_ty { - #ctor_impl - } - })); + if generate_ctor { + methods.extend(Some(quote! { + #[inline] + pub fn #ctor_name ( #( #ctor_params ),* ) -> #unit_field_ty { + let mut __bindgen_bitfield_unit: #unit_field_ty = Default::default(); + #ctor_impl + __bindgen_bitfield_unit + } + })); + } struct_layout.saw_bitfield_unit(self.layout()); } @@ -1283,7 +1302,7 @@ fn bitfield_setter_name( } impl<'a> FieldCodegen<'a> for Bitfield { - type Extra = (&'a str, quote::Tokens, usize); + type Extra = (&'a str, &'a mut bool); fn codegen( &self, @@ -1291,12 +1310,12 @@ impl<'a> FieldCodegen<'a> for Bitfield { _fields_should_be_private: bool, _codegen_depth: usize, _accessor_kind: FieldAccessorKind, - _parent: &CompInfo, + parent: &CompInfo, _result: &mut CodegenResult, _struct_layout: &mut StructLayoutTracker, _fields: &mut F, methods: &mut M, - (unit_field_name, unit_field_int_ty, unit_field_size): (&'a str, quote::Tokens, usize), + (unit_field_name, bitfield_representable_as_int): (&'a str, &mut bool), ) where F: Extend, M: Extend, @@ -1312,65 +1331,73 @@ impl<'a> FieldCodegen<'a> for Bitfield { let bitfield_ty_layout = bitfield_ty.layout(ctx).expect( "Bitfield without layout? Gah!", ); - let bitfield_int_ty = helpers::blob(bitfield_ty_layout); + let bitfield_int_ty = match helpers::integer_type(bitfield_ty_layout) { + Some(int_ty) => { + *bitfield_representable_as_int = true; + int_ty + } + None => { + *bitfield_representable_as_int = false; + return; + } + }; let bitfield_ty = bitfield_ty.to_rust_ty_or_opaque(ctx, bitfield_ty_item); let offset = self.offset_into_unit(); - let mask = helpers::ast_ty::hex_expr(self.mask()); - methods.extend(Some(quote! { - #[inline] - pub fn #getter_name(&self) -> #bitfield_ty { - let mut unit_field_val: #unit_field_int_ty = unsafe { - ::#prefix::mem::uninitialized() - }; + let width = self.width() as u8; - unsafe { - ::#prefix::ptr::copy_nonoverlapping( - &self.#unit_field_ident as *const _ as *const u8, - &mut unit_field_val as *mut #unit_field_int_ty as *mut u8, - #unit_field_size, - ) - }; - - let mask = #mask as #unit_field_int_ty; - let val = (unit_field_val & mask) >> #offset; - unsafe { - ::#prefix::mem::transmute(val as #bitfield_int_ty) + if parent.is_union() && !parent.can_be_rust_union(ctx) { + methods.extend(Some(quote! { + #[inline] + pub fn #getter_name(&self) -> #bitfield_ty { + unsafe { + ::#prefix::mem::transmute( + self.#unit_field_ident.as_ref().get(#offset, #width) + as #bitfield_int_ty + ) + } } - } - #[inline] - pub fn #setter_name(&mut self, val: #bitfield_ty) { - let mask = #mask as #unit_field_int_ty; - let val = val as #bitfield_int_ty as #unit_field_int_ty; - - let mut unit_field_val: #unit_field_int_ty = unsafe { - ::#prefix::mem::uninitialized() - }; - - unsafe { - ::#prefix::ptr::copy_nonoverlapping( - &self.#unit_field_ident as *const _ as *const u8, - &mut unit_field_val as *mut #unit_field_int_ty as *mut u8, - #unit_field_size, - ) - }; - - unit_field_val &= !mask; - unit_field_val |= (val << #offset) & mask; + #[inline] + pub fn #setter_name(&mut self, val: #bitfield_ty) { + unsafe { + let val: #bitfield_int_ty = ::#prefix::mem::transmute(val); + self.#unit_field_ident.as_mut().set( + #offset, + #width, + val as u64 + ) + } + } + })); + } else { + methods.extend(Some(quote! { + #[inline] + pub fn #getter_name(&self) -> #bitfield_ty { + unsafe { + ::#prefix::mem::transmute( + self.#unit_field_ident.get(#offset, #width) + as #bitfield_int_ty + ) + } + } - unsafe { - ::#prefix::ptr::copy_nonoverlapping( - &unit_field_val as *const _ as *const u8, - &mut self.#unit_field_ident as *mut _ as *mut u8, - #unit_field_size, - ); + #[inline] + pub fn #setter_name(&mut self, val: #bitfield_ty) { + unsafe { + let val: #bitfield_int_ty = ::#prefix::mem::transmute(val); + self.#unit_field_ident.set( + #offset, + #width, + val as u64 + ) + } } - } - })); + })); + } } } @@ -3393,6 +3420,15 @@ mod utils { use quote; use std::mem; + pub fn prepend_bitfield_unit_type(result: &mut Vec) { + let mut bitfield_unit_type = quote! {}; + bitfield_unit_type.append(include_str!("./bitfield_unit.rs")); + + let items = vec![bitfield_unit_type]; + let old_items = mem::replace(result, items); + result.extend(old_items); + } + pub fn prepend_objc_header( ctx: &BindgenContext, result: &mut Vec, diff --git a/src/features.rs b/src/features.rs index 0954d87b84..d4fbd92821 100644 --- a/src/features.rs +++ b/src/features.rs @@ -140,8 +140,6 @@ macro_rules! rust_feature_def { rust_feature_def!( /// Untagged unions ([RFC 1444](https://github.com/rust-lang/rfcs/blob/master/text/1444-union.md)) => untagged_union; - /// Constant function ([RFC 911](https://github.com/rust-lang/rfcs/blob/master/text/0911-const-fn.md)) - => const_fn; /// `thiscall` calling convention ([Tracking issue](https://github.com/rust-lang/rust/issues/42202)) => thiscall_abi; /// builtin impls for `Clone` ([PR](https://github.com/rust-lang/rust/pull/43690)) @@ -161,7 +159,6 @@ impl From for RustFeatures { } if rust_target >= RustTarget::Nightly { - features.const_fn = true; features.thiscall_abi = true; } diff --git a/tests/expectations/tests/bitfield-32bit-overflow.rs b/tests/expectations/tests/bitfield-32bit-overflow.rs index 4da37a1ac6..f64299a6ab 100644 --- a/tests/expectations/tests/bitfield-32bit-overflow.rs +++ b/tests/expectations/tests/bitfield-32bit-overflow.rs @@ -4,10 +4,89 @@ #![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] +#[repr(C)] +#[derive(Copy, Clone, Debug, Default, Eq, Hash, Ord, PartialEq, PartialOrd)] +pub struct __BindgenBitfieldUnit +where + Storage: AsRef<[u8]> + AsMut<[u8]>, +{ + storage: Storage, + align: [Align; 0], +} + +impl __BindgenBitfieldUnit +where + Storage: AsRef<[u8]> + AsMut<[u8]>, +{ + #[inline] + pub fn new(storage: Storage) -> Self { + Self { storage, align: [] } + } + + #[inline] + pub fn get_bit(&self, index: usize) -> bool { + debug_assert!(index / 8 < self.storage.as_ref().len()); + + let byte_index = index / 8; + let byte = self.storage.as_ref()[byte_index]; + + let bit_index = index % 8; + let mask = 1 << bit_index; + + byte & mask == mask + } + + #[inline] + pub fn set_bit(&mut self, index: usize, val: bool) { + debug_assert!(index / 8 < self.storage.as_ref().len()); + + let byte_index = index / 8; + let byte = &mut self.storage.as_mut()[byte_index]; + + let bit_index = index % 8; + let mask = 1 << bit_index; + + if val { + *byte |= mask; + } else { + *byte &= !mask; + } + } + + #[inline] + pub fn get(&self, bit_offset: usize, bit_width: u8) -> u64 { + debug_assert!(bit_width <= 64); + debug_assert!(bit_offset / 8 < self.storage.as_ref().len()); + debug_assert!((bit_offset + (bit_width as usize)) / 8 <= self.storage.as_ref().len()); + + let mut val = 0; + + for i in 0..(bit_width as usize) { + if self.get_bit(i + bit_offset) { + val |= 1 << i; + } + } + + val + } + + #[inline] + pub fn set(&mut self, bit_offset: usize, bit_width: u8, val: u64) { + debug_assert!(bit_width <= 64); + debug_assert!(bit_offset / 8 < self.storage.as_ref().len()); + debug_assert!((bit_offset + (bit_width as usize)) / 8 <= self.storage.as_ref().len()); + + for i in 0..(bit_width as usize) { + let mask = 1 << i; + let val_bit_is_set = val & mask == mask; + self.set_bit(i + bit_offset, val_bit_is_set); + } + } +} #[repr(C, packed)] #[derive(Debug, Default, Copy, Clone)] pub struct MuchBitfield { - pub _bitfield_1: [u8; 5usize], + pub _bitfield_1: __BindgenBitfieldUnit<[u8; 5usize], u8>, } #[test] fn bindgen_test_layout_MuchBitfield() { @@ -25,1190 +104,365 @@ fn bindgen_test_layout_MuchBitfield() { impl MuchBitfield { #[inline] pub fn m0(&self) -> ::std::os::raw::c_char { - let mut unit_field_val: u64 = unsafe { ::std::mem::uninitialized() }; - unsafe { - ::std::ptr::copy_nonoverlapping( - &self._bitfield_1 as *const _ as *const u8, - &mut unit_field_val as *mut u64 as *mut u8, - 5usize, - ) - }; - let mask = 0x1 as u64; - let val = (unit_field_val & mask) >> 0usize; - unsafe { ::std::mem::transmute(val as u8) } + unsafe { ::std::mem::transmute(self._bitfield_1.get(0usize, 1u8) as u8) } } #[inline] pub fn set_m0(&mut self, val: ::std::os::raw::c_char) { - let mask = 0x1 as u64; - let val = val as u8 as u64; - let mut unit_field_val: u64 = unsafe { ::std::mem::uninitialized() }; - unsafe { - ::std::ptr::copy_nonoverlapping( - &self._bitfield_1 as *const _ as *const u8, - &mut unit_field_val as *mut u64 as *mut u8, - 5usize, - ) - }; - unit_field_val &= !mask; - unit_field_val |= (val << 0usize) & mask; unsafe { - ::std::ptr::copy_nonoverlapping( - &unit_field_val as *const _ as *const u8, - &mut self._bitfield_1 as *mut _ as *mut u8, - 5usize, - ); + let val: u8 = ::std::mem::transmute(val); + self._bitfield_1.set(0usize, 1u8, val as u64) } } #[inline] pub fn m1(&self) -> ::std::os::raw::c_char { - let mut unit_field_val: u64 = unsafe { ::std::mem::uninitialized() }; - unsafe { - ::std::ptr::copy_nonoverlapping( - &self._bitfield_1 as *const _ as *const u8, - &mut unit_field_val as *mut u64 as *mut u8, - 5usize, - ) - }; - let mask = 0x2 as u64; - let val = (unit_field_val & mask) >> 1usize; - unsafe { ::std::mem::transmute(val as u8) } + unsafe { ::std::mem::transmute(self._bitfield_1.get(1usize, 1u8) as u8) } } #[inline] pub fn set_m1(&mut self, val: ::std::os::raw::c_char) { - let mask = 0x2 as u64; - let val = val as u8 as u64; - let mut unit_field_val: u64 = unsafe { ::std::mem::uninitialized() }; unsafe { - ::std::ptr::copy_nonoverlapping( - &self._bitfield_1 as *const _ as *const u8, - &mut unit_field_val as *mut u64 as *mut u8, - 5usize, - ) - }; - unit_field_val &= !mask; - unit_field_val |= (val << 1usize) & mask; - unsafe { - ::std::ptr::copy_nonoverlapping( - &unit_field_val as *const _ as *const u8, - &mut self._bitfield_1 as *mut _ as *mut u8, - 5usize, - ); + let val: u8 = ::std::mem::transmute(val); + self._bitfield_1.set(1usize, 1u8, val as u64) } } #[inline] pub fn m2(&self) -> ::std::os::raw::c_char { - let mut unit_field_val: u64 = unsafe { ::std::mem::uninitialized() }; - unsafe { - ::std::ptr::copy_nonoverlapping( - &self._bitfield_1 as *const _ as *const u8, - &mut unit_field_val as *mut u64 as *mut u8, - 5usize, - ) - }; - let mask = 0x4 as u64; - let val = (unit_field_val & mask) >> 2usize; - unsafe { ::std::mem::transmute(val as u8) } + unsafe { ::std::mem::transmute(self._bitfield_1.get(2usize, 1u8) as u8) } } #[inline] pub fn set_m2(&mut self, val: ::std::os::raw::c_char) { - let mask = 0x4 as u64; - let val = val as u8 as u64; - let mut unit_field_val: u64 = unsafe { ::std::mem::uninitialized() }; - unsafe { - ::std::ptr::copy_nonoverlapping( - &self._bitfield_1 as *const _ as *const u8, - &mut unit_field_val as *mut u64 as *mut u8, - 5usize, - ) - }; - unit_field_val &= !mask; - unit_field_val |= (val << 2usize) & mask; unsafe { - ::std::ptr::copy_nonoverlapping( - &unit_field_val as *const _ as *const u8, - &mut self._bitfield_1 as *mut _ as *mut u8, - 5usize, - ); + let val: u8 = ::std::mem::transmute(val); + self._bitfield_1.set(2usize, 1u8, val as u64) } } #[inline] pub fn m3(&self) -> ::std::os::raw::c_char { - let mut unit_field_val: u64 = unsafe { ::std::mem::uninitialized() }; - unsafe { - ::std::ptr::copy_nonoverlapping( - &self._bitfield_1 as *const _ as *const u8, - &mut unit_field_val as *mut u64 as *mut u8, - 5usize, - ) - }; - let mask = 0x8 as u64; - let val = (unit_field_val & mask) >> 3usize; - unsafe { ::std::mem::transmute(val as u8) } + unsafe { ::std::mem::transmute(self._bitfield_1.get(3usize, 1u8) as u8) } } #[inline] pub fn set_m3(&mut self, val: ::std::os::raw::c_char) { - let mask = 0x8 as u64; - let val = val as u8 as u64; - let mut unit_field_val: u64 = unsafe { ::std::mem::uninitialized() }; - unsafe { - ::std::ptr::copy_nonoverlapping( - &self._bitfield_1 as *const _ as *const u8, - &mut unit_field_val as *mut u64 as *mut u8, - 5usize, - ) - }; - unit_field_val &= !mask; - unit_field_val |= (val << 3usize) & mask; unsafe { - ::std::ptr::copy_nonoverlapping( - &unit_field_val as *const _ as *const u8, - &mut self._bitfield_1 as *mut _ as *mut u8, - 5usize, - ); + let val: u8 = ::std::mem::transmute(val); + self._bitfield_1.set(3usize, 1u8, val as u64) } } #[inline] pub fn m4(&self) -> ::std::os::raw::c_char { - let mut unit_field_val: u64 = unsafe { ::std::mem::uninitialized() }; - unsafe { - ::std::ptr::copy_nonoverlapping( - &self._bitfield_1 as *const _ as *const u8, - &mut unit_field_val as *mut u64 as *mut u8, - 5usize, - ) - }; - let mask = 0x10 as u64; - let val = (unit_field_val & mask) >> 4usize; - unsafe { ::std::mem::transmute(val as u8) } + unsafe { ::std::mem::transmute(self._bitfield_1.get(4usize, 1u8) as u8) } } #[inline] pub fn set_m4(&mut self, val: ::std::os::raw::c_char) { - let mask = 0x10 as u64; - let val = val as u8 as u64; - let mut unit_field_val: u64 = unsafe { ::std::mem::uninitialized() }; unsafe { - ::std::ptr::copy_nonoverlapping( - &self._bitfield_1 as *const _ as *const u8, - &mut unit_field_val as *mut u64 as *mut u8, - 5usize, - ) - }; - unit_field_val &= !mask; - unit_field_val |= (val << 4usize) & mask; - unsafe { - ::std::ptr::copy_nonoverlapping( - &unit_field_val as *const _ as *const u8, - &mut self._bitfield_1 as *mut _ as *mut u8, - 5usize, - ); + let val: u8 = ::std::mem::transmute(val); + self._bitfield_1.set(4usize, 1u8, val as u64) } } #[inline] pub fn m5(&self) -> ::std::os::raw::c_char { - let mut unit_field_val: u64 = unsafe { ::std::mem::uninitialized() }; - unsafe { - ::std::ptr::copy_nonoverlapping( - &self._bitfield_1 as *const _ as *const u8, - &mut unit_field_val as *mut u64 as *mut u8, - 5usize, - ) - }; - let mask = 0x20 as u64; - let val = (unit_field_val & mask) >> 5usize; - unsafe { ::std::mem::transmute(val as u8) } + unsafe { ::std::mem::transmute(self._bitfield_1.get(5usize, 1u8) as u8) } } #[inline] pub fn set_m5(&mut self, val: ::std::os::raw::c_char) { - let mask = 0x20 as u64; - let val = val as u8 as u64; - let mut unit_field_val: u64 = unsafe { ::std::mem::uninitialized() }; - unsafe { - ::std::ptr::copy_nonoverlapping( - &self._bitfield_1 as *const _ as *const u8, - &mut unit_field_val as *mut u64 as *mut u8, - 5usize, - ) - }; - unit_field_val &= !mask; - unit_field_val |= (val << 5usize) & mask; unsafe { - ::std::ptr::copy_nonoverlapping( - &unit_field_val as *const _ as *const u8, - &mut self._bitfield_1 as *mut _ as *mut u8, - 5usize, - ); + let val: u8 = ::std::mem::transmute(val); + self._bitfield_1.set(5usize, 1u8, val as u64) } } #[inline] pub fn m6(&self) -> ::std::os::raw::c_char { - let mut unit_field_val: u64 = unsafe { ::std::mem::uninitialized() }; - unsafe { - ::std::ptr::copy_nonoverlapping( - &self._bitfield_1 as *const _ as *const u8, - &mut unit_field_val as *mut u64 as *mut u8, - 5usize, - ) - }; - let mask = 0x40 as u64; - let val = (unit_field_val & mask) >> 6usize; - unsafe { ::std::mem::transmute(val as u8) } + unsafe { ::std::mem::transmute(self._bitfield_1.get(6usize, 1u8) as u8) } } #[inline] pub fn set_m6(&mut self, val: ::std::os::raw::c_char) { - let mask = 0x40 as u64; - let val = val as u8 as u64; - let mut unit_field_val: u64 = unsafe { ::std::mem::uninitialized() }; - unsafe { - ::std::ptr::copy_nonoverlapping( - &self._bitfield_1 as *const _ as *const u8, - &mut unit_field_val as *mut u64 as *mut u8, - 5usize, - ) - }; - unit_field_val &= !mask; - unit_field_val |= (val << 6usize) & mask; unsafe { - ::std::ptr::copy_nonoverlapping( - &unit_field_val as *const _ as *const u8, - &mut self._bitfield_1 as *mut _ as *mut u8, - 5usize, - ); + let val: u8 = ::std::mem::transmute(val); + self._bitfield_1.set(6usize, 1u8, val as u64) } } #[inline] pub fn m7(&self) -> ::std::os::raw::c_char { - let mut unit_field_val: u64 = unsafe { ::std::mem::uninitialized() }; - unsafe { - ::std::ptr::copy_nonoverlapping( - &self._bitfield_1 as *const _ as *const u8, - &mut unit_field_val as *mut u64 as *mut u8, - 5usize, - ) - }; - let mask = 0x80 as u64; - let val = (unit_field_val & mask) >> 7usize; - unsafe { ::std::mem::transmute(val as u8) } + unsafe { ::std::mem::transmute(self._bitfield_1.get(7usize, 1u8) as u8) } } #[inline] pub fn set_m7(&mut self, val: ::std::os::raw::c_char) { - let mask = 0x80 as u64; - let val = val as u8 as u64; - let mut unit_field_val: u64 = unsafe { ::std::mem::uninitialized() }; unsafe { - ::std::ptr::copy_nonoverlapping( - &self._bitfield_1 as *const _ as *const u8, - &mut unit_field_val as *mut u64 as *mut u8, - 5usize, - ) - }; - unit_field_val &= !mask; - unit_field_val |= (val << 7usize) & mask; - unsafe { - ::std::ptr::copy_nonoverlapping( - &unit_field_val as *const _ as *const u8, - &mut self._bitfield_1 as *mut _ as *mut u8, - 5usize, - ); + let val: u8 = ::std::mem::transmute(val); + self._bitfield_1.set(7usize, 1u8, val as u64) } } #[inline] pub fn m8(&self) -> ::std::os::raw::c_char { - let mut unit_field_val: u64 = unsafe { ::std::mem::uninitialized() }; - unsafe { - ::std::ptr::copy_nonoverlapping( - &self._bitfield_1 as *const _ as *const u8, - &mut unit_field_val as *mut u64 as *mut u8, - 5usize, - ) - }; - let mask = 0x100 as u64; - let val = (unit_field_val & mask) >> 8usize; - unsafe { ::std::mem::transmute(val as u8) } + unsafe { ::std::mem::transmute(self._bitfield_1.get(8usize, 1u8) as u8) } } #[inline] pub fn set_m8(&mut self, val: ::std::os::raw::c_char) { - let mask = 0x100 as u64; - let val = val as u8 as u64; - let mut unit_field_val: u64 = unsafe { ::std::mem::uninitialized() }; - unsafe { - ::std::ptr::copy_nonoverlapping( - &self._bitfield_1 as *const _ as *const u8, - &mut unit_field_val as *mut u64 as *mut u8, - 5usize, - ) - }; - unit_field_val &= !mask; - unit_field_val |= (val << 8usize) & mask; unsafe { - ::std::ptr::copy_nonoverlapping( - &unit_field_val as *const _ as *const u8, - &mut self._bitfield_1 as *mut _ as *mut u8, - 5usize, - ); + let val: u8 = ::std::mem::transmute(val); + self._bitfield_1.set(8usize, 1u8, val as u64) } } #[inline] pub fn m9(&self) -> ::std::os::raw::c_char { - let mut unit_field_val: u64 = unsafe { ::std::mem::uninitialized() }; - unsafe { - ::std::ptr::copy_nonoverlapping( - &self._bitfield_1 as *const _ as *const u8, - &mut unit_field_val as *mut u64 as *mut u8, - 5usize, - ) - }; - let mask = 0x200 as u64; - let val = (unit_field_val & mask) >> 9usize; - unsafe { ::std::mem::transmute(val as u8) } + unsafe { ::std::mem::transmute(self._bitfield_1.get(9usize, 1u8) as u8) } } #[inline] pub fn set_m9(&mut self, val: ::std::os::raw::c_char) { - let mask = 0x200 as u64; - let val = val as u8 as u64; - let mut unit_field_val: u64 = unsafe { ::std::mem::uninitialized() }; - unsafe { - ::std::ptr::copy_nonoverlapping( - &self._bitfield_1 as *const _ as *const u8, - &mut unit_field_val as *mut u64 as *mut u8, - 5usize, - ) - }; - unit_field_val &= !mask; - unit_field_val |= (val << 9usize) & mask; unsafe { - ::std::ptr::copy_nonoverlapping( - &unit_field_val as *const _ as *const u8, - &mut self._bitfield_1 as *mut _ as *mut u8, - 5usize, - ); + let val: u8 = ::std::mem::transmute(val); + self._bitfield_1.set(9usize, 1u8, val as u64) } } #[inline] pub fn m10(&self) -> ::std::os::raw::c_char { - let mut unit_field_val: u64 = unsafe { ::std::mem::uninitialized() }; - unsafe { - ::std::ptr::copy_nonoverlapping( - &self._bitfield_1 as *const _ as *const u8, - &mut unit_field_val as *mut u64 as *mut u8, - 5usize, - ) - }; - let mask = 0x400 as u64; - let val = (unit_field_val & mask) >> 10usize; - unsafe { ::std::mem::transmute(val as u8) } + unsafe { ::std::mem::transmute(self._bitfield_1.get(10usize, 1u8) as u8) } } #[inline] pub fn set_m10(&mut self, val: ::std::os::raw::c_char) { - let mask = 0x400 as u64; - let val = val as u8 as u64; - let mut unit_field_val: u64 = unsafe { ::std::mem::uninitialized() }; unsafe { - ::std::ptr::copy_nonoverlapping( - &self._bitfield_1 as *const _ as *const u8, - &mut unit_field_val as *mut u64 as *mut u8, - 5usize, - ) - }; - unit_field_val &= !mask; - unit_field_val |= (val << 10usize) & mask; - unsafe { - ::std::ptr::copy_nonoverlapping( - &unit_field_val as *const _ as *const u8, - &mut self._bitfield_1 as *mut _ as *mut u8, - 5usize, - ); + let val: u8 = ::std::mem::transmute(val); + self._bitfield_1.set(10usize, 1u8, val as u64) } } #[inline] pub fn m11(&self) -> ::std::os::raw::c_char { - let mut unit_field_val: u64 = unsafe { ::std::mem::uninitialized() }; - unsafe { - ::std::ptr::copy_nonoverlapping( - &self._bitfield_1 as *const _ as *const u8, - &mut unit_field_val as *mut u64 as *mut u8, - 5usize, - ) - }; - let mask = 0x800 as u64; - let val = (unit_field_val & mask) >> 11usize; - unsafe { ::std::mem::transmute(val as u8) } + unsafe { ::std::mem::transmute(self._bitfield_1.get(11usize, 1u8) as u8) } } #[inline] pub fn set_m11(&mut self, val: ::std::os::raw::c_char) { - let mask = 0x800 as u64; - let val = val as u8 as u64; - let mut unit_field_val: u64 = unsafe { ::std::mem::uninitialized() }; - unsafe { - ::std::ptr::copy_nonoverlapping( - &self._bitfield_1 as *const _ as *const u8, - &mut unit_field_val as *mut u64 as *mut u8, - 5usize, - ) - }; - unit_field_val &= !mask; - unit_field_val |= (val << 11usize) & mask; unsafe { - ::std::ptr::copy_nonoverlapping( - &unit_field_val as *const _ as *const u8, - &mut self._bitfield_1 as *mut _ as *mut u8, - 5usize, - ); + let val: u8 = ::std::mem::transmute(val); + self._bitfield_1.set(11usize, 1u8, val as u64) } } #[inline] pub fn m12(&self) -> ::std::os::raw::c_char { - let mut unit_field_val: u64 = unsafe { ::std::mem::uninitialized() }; - unsafe { - ::std::ptr::copy_nonoverlapping( - &self._bitfield_1 as *const _ as *const u8, - &mut unit_field_val as *mut u64 as *mut u8, - 5usize, - ) - }; - let mask = 0x1000 as u64; - let val = (unit_field_val & mask) >> 12usize; - unsafe { ::std::mem::transmute(val as u8) } + unsafe { ::std::mem::transmute(self._bitfield_1.get(12usize, 1u8) as u8) } } #[inline] pub fn set_m12(&mut self, val: ::std::os::raw::c_char) { - let mask = 0x1000 as u64; - let val = val as u8 as u64; - let mut unit_field_val: u64 = unsafe { ::std::mem::uninitialized() }; - unsafe { - ::std::ptr::copy_nonoverlapping( - &self._bitfield_1 as *const _ as *const u8, - &mut unit_field_val as *mut u64 as *mut u8, - 5usize, - ) - }; - unit_field_val &= !mask; - unit_field_val |= (val << 12usize) & mask; unsafe { - ::std::ptr::copy_nonoverlapping( - &unit_field_val as *const _ as *const u8, - &mut self._bitfield_1 as *mut _ as *mut u8, - 5usize, - ); + let val: u8 = ::std::mem::transmute(val); + self._bitfield_1.set(12usize, 1u8, val as u64) } } #[inline] pub fn m13(&self) -> ::std::os::raw::c_char { - let mut unit_field_val: u64 = unsafe { ::std::mem::uninitialized() }; - unsafe { - ::std::ptr::copy_nonoverlapping( - &self._bitfield_1 as *const _ as *const u8, - &mut unit_field_val as *mut u64 as *mut u8, - 5usize, - ) - }; - let mask = 0x2000 as u64; - let val = (unit_field_val & mask) >> 13usize; - unsafe { ::std::mem::transmute(val as u8) } + unsafe { ::std::mem::transmute(self._bitfield_1.get(13usize, 1u8) as u8) } } #[inline] pub fn set_m13(&mut self, val: ::std::os::raw::c_char) { - let mask = 0x2000 as u64; - let val = val as u8 as u64; - let mut unit_field_val: u64 = unsafe { ::std::mem::uninitialized() }; unsafe { - ::std::ptr::copy_nonoverlapping( - &self._bitfield_1 as *const _ as *const u8, - &mut unit_field_val as *mut u64 as *mut u8, - 5usize, - ) - }; - unit_field_val &= !mask; - unit_field_val |= (val << 13usize) & mask; - unsafe { - ::std::ptr::copy_nonoverlapping( - &unit_field_val as *const _ as *const u8, - &mut self._bitfield_1 as *mut _ as *mut u8, - 5usize, - ); + let val: u8 = ::std::mem::transmute(val); + self._bitfield_1.set(13usize, 1u8, val as u64) } } #[inline] pub fn m14(&self) -> ::std::os::raw::c_char { - let mut unit_field_val: u64 = unsafe { ::std::mem::uninitialized() }; - unsafe { - ::std::ptr::copy_nonoverlapping( - &self._bitfield_1 as *const _ as *const u8, - &mut unit_field_val as *mut u64 as *mut u8, - 5usize, - ) - }; - let mask = 0x4000 as u64; - let val = (unit_field_val & mask) >> 14usize; - unsafe { ::std::mem::transmute(val as u8) } + unsafe { ::std::mem::transmute(self._bitfield_1.get(14usize, 1u8) as u8) } } #[inline] pub fn set_m14(&mut self, val: ::std::os::raw::c_char) { - let mask = 0x4000 as u64; - let val = val as u8 as u64; - let mut unit_field_val: u64 = unsafe { ::std::mem::uninitialized() }; - unsafe { - ::std::ptr::copy_nonoverlapping( - &self._bitfield_1 as *const _ as *const u8, - &mut unit_field_val as *mut u64 as *mut u8, - 5usize, - ) - }; - unit_field_val &= !mask; - unit_field_val |= (val << 14usize) & mask; unsafe { - ::std::ptr::copy_nonoverlapping( - &unit_field_val as *const _ as *const u8, - &mut self._bitfield_1 as *mut _ as *mut u8, - 5usize, - ); + let val: u8 = ::std::mem::transmute(val); + self._bitfield_1.set(14usize, 1u8, val as u64) } } #[inline] pub fn m15(&self) -> ::std::os::raw::c_char { - let mut unit_field_val: u64 = unsafe { ::std::mem::uninitialized() }; - unsafe { - ::std::ptr::copy_nonoverlapping( - &self._bitfield_1 as *const _ as *const u8, - &mut unit_field_val as *mut u64 as *mut u8, - 5usize, - ) - }; - let mask = 0x8000 as u64; - let val = (unit_field_val & mask) >> 15usize; - unsafe { ::std::mem::transmute(val as u8) } + unsafe { ::std::mem::transmute(self._bitfield_1.get(15usize, 1u8) as u8) } } #[inline] pub fn set_m15(&mut self, val: ::std::os::raw::c_char) { - let mask = 0x8000 as u64; - let val = val as u8 as u64; - let mut unit_field_val: u64 = unsafe { ::std::mem::uninitialized() }; - unsafe { - ::std::ptr::copy_nonoverlapping( - &self._bitfield_1 as *const _ as *const u8, - &mut unit_field_val as *mut u64 as *mut u8, - 5usize, - ) - }; - unit_field_val &= !mask; - unit_field_val |= (val << 15usize) & mask; unsafe { - ::std::ptr::copy_nonoverlapping( - &unit_field_val as *const _ as *const u8, - &mut self._bitfield_1 as *mut _ as *mut u8, - 5usize, - ); + let val: u8 = ::std::mem::transmute(val); + self._bitfield_1.set(15usize, 1u8, val as u64) } } #[inline] pub fn m16(&self) -> ::std::os::raw::c_char { - let mut unit_field_val: u64 = unsafe { ::std::mem::uninitialized() }; - unsafe { - ::std::ptr::copy_nonoverlapping( - &self._bitfield_1 as *const _ as *const u8, - &mut unit_field_val as *mut u64 as *mut u8, - 5usize, - ) - }; - let mask = 0x10000 as u64; - let val = (unit_field_val & mask) >> 16usize; - unsafe { ::std::mem::transmute(val as u8) } + unsafe { ::std::mem::transmute(self._bitfield_1.get(16usize, 1u8) as u8) } } #[inline] pub fn set_m16(&mut self, val: ::std::os::raw::c_char) { - let mask = 0x10000 as u64; - let val = val as u8 as u64; - let mut unit_field_val: u64 = unsafe { ::std::mem::uninitialized() }; unsafe { - ::std::ptr::copy_nonoverlapping( - &self._bitfield_1 as *const _ as *const u8, - &mut unit_field_val as *mut u64 as *mut u8, - 5usize, - ) - }; - unit_field_val &= !mask; - unit_field_val |= (val << 16usize) & mask; - unsafe { - ::std::ptr::copy_nonoverlapping( - &unit_field_val as *const _ as *const u8, - &mut self._bitfield_1 as *mut _ as *mut u8, - 5usize, - ); + let val: u8 = ::std::mem::transmute(val); + self._bitfield_1.set(16usize, 1u8, val as u64) } } #[inline] pub fn m17(&self) -> ::std::os::raw::c_char { - let mut unit_field_val: u64 = unsafe { ::std::mem::uninitialized() }; - unsafe { - ::std::ptr::copy_nonoverlapping( - &self._bitfield_1 as *const _ as *const u8, - &mut unit_field_val as *mut u64 as *mut u8, - 5usize, - ) - }; - let mask = 0x20000 as u64; - let val = (unit_field_val & mask) >> 17usize; - unsafe { ::std::mem::transmute(val as u8) } + unsafe { ::std::mem::transmute(self._bitfield_1.get(17usize, 1u8) as u8) } } #[inline] pub fn set_m17(&mut self, val: ::std::os::raw::c_char) { - let mask = 0x20000 as u64; - let val = val as u8 as u64; - let mut unit_field_val: u64 = unsafe { ::std::mem::uninitialized() }; - unsafe { - ::std::ptr::copy_nonoverlapping( - &self._bitfield_1 as *const _ as *const u8, - &mut unit_field_val as *mut u64 as *mut u8, - 5usize, - ) - }; - unit_field_val &= !mask; - unit_field_val |= (val << 17usize) & mask; unsafe { - ::std::ptr::copy_nonoverlapping( - &unit_field_val as *const _ as *const u8, - &mut self._bitfield_1 as *mut _ as *mut u8, - 5usize, - ); + let val: u8 = ::std::mem::transmute(val); + self._bitfield_1.set(17usize, 1u8, val as u64) } } #[inline] pub fn m18(&self) -> ::std::os::raw::c_char { - let mut unit_field_val: u64 = unsafe { ::std::mem::uninitialized() }; - unsafe { - ::std::ptr::copy_nonoverlapping( - &self._bitfield_1 as *const _ as *const u8, - &mut unit_field_val as *mut u64 as *mut u8, - 5usize, - ) - }; - let mask = 0x40000 as u64; - let val = (unit_field_val & mask) >> 18usize; - unsafe { ::std::mem::transmute(val as u8) } + unsafe { ::std::mem::transmute(self._bitfield_1.get(18usize, 1u8) as u8) } } #[inline] pub fn set_m18(&mut self, val: ::std::os::raw::c_char) { - let mask = 0x40000 as u64; - let val = val as u8 as u64; - let mut unit_field_val: u64 = unsafe { ::std::mem::uninitialized() }; - unsafe { - ::std::ptr::copy_nonoverlapping( - &self._bitfield_1 as *const _ as *const u8, - &mut unit_field_val as *mut u64 as *mut u8, - 5usize, - ) - }; - unit_field_val &= !mask; - unit_field_val |= (val << 18usize) & mask; unsafe { - ::std::ptr::copy_nonoverlapping( - &unit_field_val as *const _ as *const u8, - &mut self._bitfield_1 as *mut _ as *mut u8, - 5usize, - ); + let val: u8 = ::std::mem::transmute(val); + self._bitfield_1.set(18usize, 1u8, val as u64) } } #[inline] pub fn m19(&self) -> ::std::os::raw::c_char { - let mut unit_field_val: u64 = unsafe { ::std::mem::uninitialized() }; - unsafe { - ::std::ptr::copy_nonoverlapping( - &self._bitfield_1 as *const _ as *const u8, - &mut unit_field_val as *mut u64 as *mut u8, - 5usize, - ) - }; - let mask = 0x80000 as u64; - let val = (unit_field_val & mask) >> 19usize; - unsafe { ::std::mem::transmute(val as u8) } + unsafe { ::std::mem::transmute(self._bitfield_1.get(19usize, 1u8) as u8) } } #[inline] pub fn set_m19(&mut self, val: ::std::os::raw::c_char) { - let mask = 0x80000 as u64; - let val = val as u8 as u64; - let mut unit_field_val: u64 = unsafe { ::std::mem::uninitialized() }; unsafe { - ::std::ptr::copy_nonoverlapping( - &self._bitfield_1 as *const _ as *const u8, - &mut unit_field_val as *mut u64 as *mut u8, - 5usize, - ) - }; - unit_field_val &= !mask; - unit_field_val |= (val << 19usize) & mask; - unsafe { - ::std::ptr::copy_nonoverlapping( - &unit_field_val as *const _ as *const u8, - &mut self._bitfield_1 as *mut _ as *mut u8, - 5usize, - ); + let val: u8 = ::std::mem::transmute(val); + self._bitfield_1.set(19usize, 1u8, val as u64) } } #[inline] pub fn m20(&self) -> ::std::os::raw::c_char { - let mut unit_field_val: u64 = unsafe { ::std::mem::uninitialized() }; - unsafe { - ::std::ptr::copy_nonoverlapping( - &self._bitfield_1 as *const _ as *const u8, - &mut unit_field_val as *mut u64 as *mut u8, - 5usize, - ) - }; - let mask = 0x100000 as u64; - let val = (unit_field_val & mask) >> 20usize; - unsafe { ::std::mem::transmute(val as u8) } + unsafe { ::std::mem::transmute(self._bitfield_1.get(20usize, 1u8) as u8) } } #[inline] pub fn set_m20(&mut self, val: ::std::os::raw::c_char) { - let mask = 0x100000 as u64; - let val = val as u8 as u64; - let mut unit_field_val: u64 = unsafe { ::std::mem::uninitialized() }; - unsafe { - ::std::ptr::copy_nonoverlapping( - &self._bitfield_1 as *const _ as *const u8, - &mut unit_field_val as *mut u64 as *mut u8, - 5usize, - ) - }; - unit_field_val &= !mask; - unit_field_val |= (val << 20usize) & mask; unsafe { - ::std::ptr::copy_nonoverlapping( - &unit_field_val as *const _ as *const u8, - &mut self._bitfield_1 as *mut _ as *mut u8, - 5usize, - ); + let val: u8 = ::std::mem::transmute(val); + self._bitfield_1.set(20usize, 1u8, val as u64) } } #[inline] pub fn m21(&self) -> ::std::os::raw::c_char { - let mut unit_field_val: u64 = unsafe { ::std::mem::uninitialized() }; - unsafe { - ::std::ptr::copy_nonoverlapping( - &self._bitfield_1 as *const _ as *const u8, - &mut unit_field_val as *mut u64 as *mut u8, - 5usize, - ) - }; - let mask = 0x200000 as u64; - let val = (unit_field_val & mask) >> 21usize; - unsafe { ::std::mem::transmute(val as u8) } + unsafe { ::std::mem::transmute(self._bitfield_1.get(21usize, 1u8) as u8) } } #[inline] pub fn set_m21(&mut self, val: ::std::os::raw::c_char) { - let mask = 0x200000 as u64; - let val = val as u8 as u64; - let mut unit_field_val: u64 = unsafe { ::std::mem::uninitialized() }; - unsafe { - ::std::ptr::copy_nonoverlapping( - &self._bitfield_1 as *const _ as *const u8, - &mut unit_field_val as *mut u64 as *mut u8, - 5usize, - ) - }; - unit_field_val &= !mask; - unit_field_val |= (val << 21usize) & mask; unsafe { - ::std::ptr::copy_nonoverlapping( - &unit_field_val as *const _ as *const u8, - &mut self._bitfield_1 as *mut _ as *mut u8, - 5usize, - ); + let val: u8 = ::std::mem::transmute(val); + self._bitfield_1.set(21usize, 1u8, val as u64) } } #[inline] pub fn m22(&self) -> ::std::os::raw::c_char { - let mut unit_field_val: u64 = unsafe { ::std::mem::uninitialized() }; - unsafe { - ::std::ptr::copy_nonoverlapping( - &self._bitfield_1 as *const _ as *const u8, - &mut unit_field_val as *mut u64 as *mut u8, - 5usize, - ) - }; - let mask = 0x400000 as u64; - let val = (unit_field_val & mask) >> 22usize; - unsafe { ::std::mem::transmute(val as u8) } + unsafe { ::std::mem::transmute(self._bitfield_1.get(22usize, 1u8) as u8) } } #[inline] pub fn set_m22(&mut self, val: ::std::os::raw::c_char) { - let mask = 0x400000 as u64; - let val = val as u8 as u64; - let mut unit_field_val: u64 = unsafe { ::std::mem::uninitialized() }; unsafe { - ::std::ptr::copy_nonoverlapping( - &self._bitfield_1 as *const _ as *const u8, - &mut unit_field_val as *mut u64 as *mut u8, - 5usize, - ) - }; - unit_field_val &= !mask; - unit_field_val |= (val << 22usize) & mask; - unsafe { - ::std::ptr::copy_nonoverlapping( - &unit_field_val as *const _ as *const u8, - &mut self._bitfield_1 as *mut _ as *mut u8, - 5usize, - ); + let val: u8 = ::std::mem::transmute(val); + self._bitfield_1.set(22usize, 1u8, val as u64) } } #[inline] pub fn m23(&self) -> ::std::os::raw::c_char { - let mut unit_field_val: u64 = unsafe { ::std::mem::uninitialized() }; - unsafe { - ::std::ptr::copy_nonoverlapping( - &self._bitfield_1 as *const _ as *const u8, - &mut unit_field_val as *mut u64 as *mut u8, - 5usize, - ) - }; - let mask = 0x800000 as u64; - let val = (unit_field_val & mask) >> 23usize; - unsafe { ::std::mem::transmute(val as u8) } + unsafe { ::std::mem::transmute(self._bitfield_1.get(23usize, 1u8) as u8) } } #[inline] pub fn set_m23(&mut self, val: ::std::os::raw::c_char) { - let mask = 0x800000 as u64; - let val = val as u8 as u64; - let mut unit_field_val: u64 = unsafe { ::std::mem::uninitialized() }; - unsafe { - ::std::ptr::copy_nonoverlapping( - &self._bitfield_1 as *const _ as *const u8, - &mut unit_field_val as *mut u64 as *mut u8, - 5usize, - ) - }; - unit_field_val &= !mask; - unit_field_val |= (val << 23usize) & mask; unsafe { - ::std::ptr::copy_nonoverlapping( - &unit_field_val as *const _ as *const u8, - &mut self._bitfield_1 as *mut _ as *mut u8, - 5usize, - ); + let val: u8 = ::std::mem::transmute(val); + self._bitfield_1.set(23usize, 1u8, val as u64) } } #[inline] pub fn m24(&self) -> ::std::os::raw::c_char { - let mut unit_field_val: u64 = unsafe { ::std::mem::uninitialized() }; - unsafe { - ::std::ptr::copy_nonoverlapping( - &self._bitfield_1 as *const _ as *const u8, - &mut unit_field_val as *mut u64 as *mut u8, - 5usize, - ) - }; - let mask = 0x1000000 as u64; - let val = (unit_field_val & mask) >> 24usize; - unsafe { ::std::mem::transmute(val as u8) } + unsafe { ::std::mem::transmute(self._bitfield_1.get(24usize, 1u8) as u8) } } #[inline] pub fn set_m24(&mut self, val: ::std::os::raw::c_char) { - let mask = 0x1000000 as u64; - let val = val as u8 as u64; - let mut unit_field_val: u64 = unsafe { ::std::mem::uninitialized() }; - unsafe { - ::std::ptr::copy_nonoverlapping( - &self._bitfield_1 as *const _ as *const u8, - &mut unit_field_val as *mut u64 as *mut u8, - 5usize, - ) - }; - unit_field_val &= !mask; - unit_field_val |= (val << 24usize) & mask; unsafe { - ::std::ptr::copy_nonoverlapping( - &unit_field_val as *const _ as *const u8, - &mut self._bitfield_1 as *mut _ as *mut u8, - 5usize, - ); + let val: u8 = ::std::mem::transmute(val); + self._bitfield_1.set(24usize, 1u8, val as u64) } } #[inline] pub fn m25(&self) -> ::std::os::raw::c_char { - let mut unit_field_val: u64 = unsafe { ::std::mem::uninitialized() }; - unsafe { - ::std::ptr::copy_nonoverlapping( - &self._bitfield_1 as *const _ as *const u8, - &mut unit_field_val as *mut u64 as *mut u8, - 5usize, - ) - }; - let mask = 0x2000000 as u64; - let val = (unit_field_val & mask) >> 25usize; - unsafe { ::std::mem::transmute(val as u8) } + unsafe { ::std::mem::transmute(self._bitfield_1.get(25usize, 1u8) as u8) } } #[inline] pub fn set_m25(&mut self, val: ::std::os::raw::c_char) { - let mask = 0x2000000 as u64; - let val = val as u8 as u64; - let mut unit_field_val: u64 = unsafe { ::std::mem::uninitialized() }; unsafe { - ::std::ptr::copy_nonoverlapping( - &self._bitfield_1 as *const _ as *const u8, - &mut unit_field_val as *mut u64 as *mut u8, - 5usize, - ) - }; - unit_field_val &= !mask; - unit_field_val |= (val << 25usize) & mask; - unsafe { - ::std::ptr::copy_nonoverlapping( - &unit_field_val as *const _ as *const u8, - &mut self._bitfield_1 as *mut _ as *mut u8, - 5usize, - ); + let val: u8 = ::std::mem::transmute(val); + self._bitfield_1.set(25usize, 1u8, val as u64) } } #[inline] pub fn m26(&self) -> ::std::os::raw::c_char { - let mut unit_field_val: u64 = unsafe { ::std::mem::uninitialized() }; - unsafe { - ::std::ptr::copy_nonoverlapping( - &self._bitfield_1 as *const _ as *const u8, - &mut unit_field_val as *mut u64 as *mut u8, - 5usize, - ) - }; - let mask = 0x4000000 as u64; - let val = (unit_field_val & mask) >> 26usize; - unsafe { ::std::mem::transmute(val as u8) } + unsafe { ::std::mem::transmute(self._bitfield_1.get(26usize, 1u8) as u8) } } #[inline] pub fn set_m26(&mut self, val: ::std::os::raw::c_char) { - let mask = 0x4000000 as u64; - let val = val as u8 as u64; - let mut unit_field_val: u64 = unsafe { ::std::mem::uninitialized() }; - unsafe { - ::std::ptr::copy_nonoverlapping( - &self._bitfield_1 as *const _ as *const u8, - &mut unit_field_val as *mut u64 as *mut u8, - 5usize, - ) - }; - unit_field_val &= !mask; - unit_field_val |= (val << 26usize) & mask; unsafe { - ::std::ptr::copy_nonoverlapping( - &unit_field_val as *const _ as *const u8, - &mut self._bitfield_1 as *mut _ as *mut u8, - 5usize, - ); + let val: u8 = ::std::mem::transmute(val); + self._bitfield_1.set(26usize, 1u8, val as u64) } } #[inline] pub fn m27(&self) -> ::std::os::raw::c_char { - let mut unit_field_val: u64 = unsafe { ::std::mem::uninitialized() }; - unsafe { - ::std::ptr::copy_nonoverlapping( - &self._bitfield_1 as *const _ as *const u8, - &mut unit_field_val as *mut u64 as *mut u8, - 5usize, - ) - }; - let mask = 0x8000000 as u64; - let val = (unit_field_val & mask) >> 27usize; - unsafe { ::std::mem::transmute(val as u8) } + unsafe { ::std::mem::transmute(self._bitfield_1.get(27usize, 1u8) as u8) } } #[inline] pub fn set_m27(&mut self, val: ::std::os::raw::c_char) { - let mask = 0x8000000 as u64; - let val = val as u8 as u64; - let mut unit_field_val: u64 = unsafe { ::std::mem::uninitialized() }; - unsafe { - ::std::ptr::copy_nonoverlapping( - &self._bitfield_1 as *const _ as *const u8, - &mut unit_field_val as *mut u64 as *mut u8, - 5usize, - ) - }; - unit_field_val &= !mask; - unit_field_val |= (val << 27usize) & mask; unsafe { - ::std::ptr::copy_nonoverlapping( - &unit_field_val as *const _ as *const u8, - &mut self._bitfield_1 as *mut _ as *mut u8, - 5usize, - ); + let val: u8 = ::std::mem::transmute(val); + self._bitfield_1.set(27usize, 1u8, val as u64) } } #[inline] pub fn m28(&self) -> ::std::os::raw::c_char { - let mut unit_field_val: u64 = unsafe { ::std::mem::uninitialized() }; - unsafe { - ::std::ptr::copy_nonoverlapping( - &self._bitfield_1 as *const _ as *const u8, - &mut unit_field_val as *mut u64 as *mut u8, - 5usize, - ) - }; - let mask = 0x10000000 as u64; - let val = (unit_field_val & mask) >> 28usize; - unsafe { ::std::mem::transmute(val as u8) } + unsafe { ::std::mem::transmute(self._bitfield_1.get(28usize, 1u8) as u8) } } #[inline] pub fn set_m28(&mut self, val: ::std::os::raw::c_char) { - let mask = 0x10000000 as u64; - let val = val as u8 as u64; - let mut unit_field_val: u64 = unsafe { ::std::mem::uninitialized() }; unsafe { - ::std::ptr::copy_nonoverlapping( - &self._bitfield_1 as *const _ as *const u8, - &mut unit_field_val as *mut u64 as *mut u8, - 5usize, - ) - }; - unit_field_val &= !mask; - unit_field_val |= (val << 28usize) & mask; - unsafe { - ::std::ptr::copy_nonoverlapping( - &unit_field_val as *const _ as *const u8, - &mut self._bitfield_1 as *mut _ as *mut u8, - 5usize, - ); + let val: u8 = ::std::mem::transmute(val); + self._bitfield_1.set(28usize, 1u8, val as u64) } } #[inline] pub fn m29(&self) -> ::std::os::raw::c_char { - let mut unit_field_val: u64 = unsafe { ::std::mem::uninitialized() }; - unsafe { - ::std::ptr::copy_nonoverlapping( - &self._bitfield_1 as *const _ as *const u8, - &mut unit_field_val as *mut u64 as *mut u8, - 5usize, - ) - }; - let mask = 0x20000000 as u64; - let val = (unit_field_val & mask) >> 29usize; - unsafe { ::std::mem::transmute(val as u8) } + unsafe { ::std::mem::transmute(self._bitfield_1.get(29usize, 1u8) as u8) } } #[inline] pub fn set_m29(&mut self, val: ::std::os::raw::c_char) { - let mask = 0x20000000 as u64; - let val = val as u8 as u64; - let mut unit_field_val: u64 = unsafe { ::std::mem::uninitialized() }; - unsafe { - ::std::ptr::copy_nonoverlapping( - &self._bitfield_1 as *const _ as *const u8, - &mut unit_field_val as *mut u64 as *mut u8, - 5usize, - ) - }; - unit_field_val &= !mask; - unit_field_val |= (val << 29usize) & mask; unsafe { - ::std::ptr::copy_nonoverlapping( - &unit_field_val as *const _ as *const u8, - &mut self._bitfield_1 as *mut _ as *mut u8, - 5usize, - ); + let val: u8 = ::std::mem::transmute(val); + self._bitfield_1.set(29usize, 1u8, val as u64) } } #[inline] pub fn m30(&self) -> ::std::os::raw::c_char { - let mut unit_field_val: u64 = unsafe { ::std::mem::uninitialized() }; - unsafe { - ::std::ptr::copy_nonoverlapping( - &self._bitfield_1 as *const _ as *const u8, - &mut unit_field_val as *mut u64 as *mut u8, - 5usize, - ) - }; - let mask = 0x40000000 as u64; - let val = (unit_field_val & mask) >> 30usize; - unsafe { ::std::mem::transmute(val as u8) } + unsafe { ::std::mem::transmute(self._bitfield_1.get(30usize, 1u8) as u8) } } #[inline] pub fn set_m30(&mut self, val: ::std::os::raw::c_char) { - let mask = 0x40000000 as u64; - let val = val as u8 as u64; - let mut unit_field_val: u64 = unsafe { ::std::mem::uninitialized() }; - unsafe { - ::std::ptr::copy_nonoverlapping( - &self._bitfield_1 as *const _ as *const u8, - &mut unit_field_val as *mut u64 as *mut u8, - 5usize, - ) - }; - unit_field_val &= !mask; - unit_field_val |= (val << 30usize) & mask; unsafe { - ::std::ptr::copy_nonoverlapping( - &unit_field_val as *const _ as *const u8, - &mut self._bitfield_1 as *mut _ as *mut u8, - 5usize, - ); + let val: u8 = ::std::mem::transmute(val); + self._bitfield_1.set(30usize, 1u8, val as u64) } } #[inline] pub fn m31(&self) -> ::std::os::raw::c_char { - let mut unit_field_val: u64 = unsafe { ::std::mem::uninitialized() }; - unsafe { - ::std::ptr::copy_nonoverlapping( - &self._bitfield_1 as *const _ as *const u8, - &mut unit_field_val as *mut u64 as *mut u8, - 5usize, - ) - }; - let mask = 0x80000000 as u64; - let val = (unit_field_val & mask) >> 31usize; - unsafe { ::std::mem::transmute(val as u8) } + unsafe { ::std::mem::transmute(self._bitfield_1.get(31usize, 1u8) as u8) } } #[inline] pub fn set_m31(&mut self, val: ::std::os::raw::c_char) { - let mask = 0x80000000 as u64; - let val = val as u8 as u64; - let mut unit_field_val: u64 = unsafe { ::std::mem::uninitialized() }; unsafe { - ::std::ptr::copy_nonoverlapping( - &self._bitfield_1 as *const _ as *const u8, - &mut unit_field_val as *mut u64 as *mut u8, - 5usize, - ) - }; - unit_field_val &= !mask; - unit_field_val |= (val << 31usize) & mask; - unsafe { - ::std::ptr::copy_nonoverlapping( - &unit_field_val as *const _ as *const u8, - &mut self._bitfield_1 as *mut _ as *mut u8, - 5usize, - ); + let val: u8 = ::std::mem::transmute(val); + self._bitfield_1.set(31usize, 1u8, val as u64) } } #[inline] pub fn m32(&self) -> ::std::os::raw::c_char { - let mut unit_field_val: u64 = unsafe { ::std::mem::uninitialized() }; - unsafe { - ::std::ptr::copy_nonoverlapping( - &self._bitfield_1 as *const _ as *const u8, - &mut unit_field_val as *mut u64 as *mut u8, - 5usize, - ) - }; - let mask = 0x100000000 as u64; - let val = (unit_field_val & mask) >> 32usize; - unsafe { ::std::mem::transmute(val as u8) } + unsafe { ::std::mem::transmute(self._bitfield_1.get(32usize, 1u8) as u8) } } #[inline] pub fn set_m32(&mut self, val: ::std::os::raw::c_char) { - let mask = 0x100000000 as u64; - let val = val as u8 as u64; - let mut unit_field_val: u64 = unsafe { ::std::mem::uninitialized() }; - unsafe { - ::std::ptr::copy_nonoverlapping( - &self._bitfield_1 as *const _ as *const u8, - &mut unit_field_val as *mut u64 as *mut u8, - 5usize, - ) - }; - unit_field_val &= !mask; - unit_field_val |= (val << 32usize) & mask; unsafe { - ::std::ptr::copy_nonoverlapping( - &unit_field_val as *const _ as *const u8, - &mut self._bitfield_1 as *mut _ as *mut u8, - 5usize, - ); + let val: u8 = ::std::mem::transmute(val); + self._bitfield_1.set(32usize, 1u8, val as u64) } } #[inline] @@ -1246,39 +500,141 @@ impl MuchBitfield { m30: ::std::os::raw::c_char, m31: ::std::os::raw::c_char, m32: ::std::os::raw::c_char, - ) -> u64 { - (((((((((((((((((((((((((((((((((0 | ((m0 as u8 as u64) << 0usize) & (0x1 as u64)) - | ((m1 as u8 as u64) << 1usize) & (0x2 as u64)) - | ((m2 as u8 as u64) << 2usize) & (0x4 as u64)) - | ((m3 as u8 as u64) << 3usize) & (0x8 as u64)) - | ((m4 as u8 as u64) << 4usize) & (0x10 as u64)) - | ((m5 as u8 as u64) << 5usize) & (0x20 as u64)) - | ((m6 as u8 as u64) << 6usize) & (0x40 as u64)) - | ((m7 as u8 as u64) << 7usize) & (0x80 as u64)) - | ((m8 as u8 as u64) << 8usize) & (0x100 as u64)) - | ((m9 as u8 as u64) << 9usize) & (0x200 as u64)) - | ((m10 as u8 as u64) << 10usize) & (0x400 as u64)) - | ((m11 as u8 as u64) << 11usize) & (0x800 as u64)) - | ((m12 as u8 as u64) << 12usize) & (0x1000 as u64)) - | ((m13 as u8 as u64) << 13usize) & (0x2000 as u64)) - | ((m14 as u8 as u64) << 14usize) & (0x4000 as u64)) - | ((m15 as u8 as u64) << 15usize) & (0x8000 as u64)) - | ((m16 as u8 as u64) << 16usize) & (0x10000 as u64)) - | ((m17 as u8 as u64) << 17usize) & (0x20000 as u64)) - | ((m18 as u8 as u64) << 18usize) & (0x40000 as u64)) - | ((m19 as u8 as u64) << 19usize) & (0x80000 as u64)) - | ((m20 as u8 as u64) << 20usize) & (0x100000 as u64)) - | ((m21 as u8 as u64) << 21usize) & (0x200000 as u64)) - | ((m22 as u8 as u64) << 22usize) & (0x400000 as u64)) - | ((m23 as u8 as u64) << 23usize) & (0x800000 as u64)) - | ((m24 as u8 as u64) << 24usize) & (0x1000000 as u64)) - | ((m25 as u8 as u64) << 25usize) & (0x2000000 as u64)) - | ((m26 as u8 as u64) << 26usize) & (0x4000000 as u64)) - | ((m27 as u8 as u64) << 27usize) & (0x8000000 as u64)) - | ((m28 as u8 as u64) << 28usize) & (0x10000000 as u64)) - | ((m29 as u8 as u64) << 29usize) & (0x20000000 as u64)) - | ((m30 as u8 as u64) << 30usize) & (0x40000000 as u64)) - | ((m31 as u8 as u64) << 31usize) & (0x80000000 as u64)) - | ((m32 as u8 as u64) << 32usize) & (0x100000000 as u64)) + ) -> __BindgenBitfieldUnit<[u8; 5usize], u8> { + let mut __bindgen_bitfield_unit: __BindgenBitfieldUnit<[u8; 5usize], u8> = + Default::default(); + __bindgen_bitfield_unit.set(0usize, 1u8, { + let m0: u8 = unsafe { ::std::mem::transmute(m0) }; + m0 as u64 + }); + __bindgen_bitfield_unit.set(1usize, 1u8, { + let m1: u8 = unsafe { ::std::mem::transmute(m1) }; + m1 as u64 + }); + __bindgen_bitfield_unit.set(2usize, 1u8, { + let m2: u8 = unsafe { ::std::mem::transmute(m2) }; + m2 as u64 + }); + __bindgen_bitfield_unit.set(3usize, 1u8, { + let m3: u8 = unsafe { ::std::mem::transmute(m3) }; + m3 as u64 + }); + __bindgen_bitfield_unit.set(4usize, 1u8, { + let m4: u8 = unsafe { ::std::mem::transmute(m4) }; + m4 as u64 + }); + __bindgen_bitfield_unit.set(5usize, 1u8, { + let m5: u8 = unsafe { ::std::mem::transmute(m5) }; + m5 as u64 + }); + __bindgen_bitfield_unit.set(6usize, 1u8, { + let m6: u8 = unsafe { ::std::mem::transmute(m6) }; + m6 as u64 + }); + __bindgen_bitfield_unit.set(7usize, 1u8, { + let m7: u8 = unsafe { ::std::mem::transmute(m7) }; + m7 as u64 + }); + __bindgen_bitfield_unit.set(8usize, 1u8, { + let m8: u8 = unsafe { ::std::mem::transmute(m8) }; + m8 as u64 + }); + __bindgen_bitfield_unit.set(9usize, 1u8, { + let m9: u8 = unsafe { ::std::mem::transmute(m9) }; + m9 as u64 + }); + __bindgen_bitfield_unit.set(10usize, 1u8, { + let m10: u8 = unsafe { ::std::mem::transmute(m10) }; + m10 as u64 + }); + __bindgen_bitfield_unit.set(11usize, 1u8, { + let m11: u8 = unsafe { ::std::mem::transmute(m11) }; + m11 as u64 + }); + __bindgen_bitfield_unit.set(12usize, 1u8, { + let m12: u8 = unsafe { ::std::mem::transmute(m12) }; + m12 as u64 + }); + __bindgen_bitfield_unit.set(13usize, 1u8, { + let m13: u8 = unsafe { ::std::mem::transmute(m13) }; + m13 as u64 + }); + __bindgen_bitfield_unit.set(14usize, 1u8, { + let m14: u8 = unsafe { ::std::mem::transmute(m14) }; + m14 as u64 + }); + __bindgen_bitfield_unit.set(15usize, 1u8, { + let m15: u8 = unsafe { ::std::mem::transmute(m15) }; + m15 as u64 + }); + __bindgen_bitfield_unit.set(16usize, 1u8, { + let m16: u8 = unsafe { ::std::mem::transmute(m16) }; + m16 as u64 + }); + __bindgen_bitfield_unit.set(17usize, 1u8, { + let m17: u8 = unsafe { ::std::mem::transmute(m17) }; + m17 as u64 + }); + __bindgen_bitfield_unit.set(18usize, 1u8, { + let m18: u8 = unsafe { ::std::mem::transmute(m18) }; + m18 as u64 + }); + __bindgen_bitfield_unit.set(19usize, 1u8, { + let m19: u8 = unsafe { ::std::mem::transmute(m19) }; + m19 as u64 + }); + __bindgen_bitfield_unit.set(20usize, 1u8, { + let m20: u8 = unsafe { ::std::mem::transmute(m20) }; + m20 as u64 + }); + __bindgen_bitfield_unit.set(21usize, 1u8, { + let m21: u8 = unsafe { ::std::mem::transmute(m21) }; + m21 as u64 + }); + __bindgen_bitfield_unit.set(22usize, 1u8, { + let m22: u8 = unsafe { ::std::mem::transmute(m22) }; + m22 as u64 + }); + __bindgen_bitfield_unit.set(23usize, 1u8, { + let m23: u8 = unsafe { ::std::mem::transmute(m23) }; + m23 as u64 + }); + __bindgen_bitfield_unit.set(24usize, 1u8, { + let m24: u8 = unsafe { ::std::mem::transmute(m24) }; + m24 as u64 + }); + __bindgen_bitfield_unit.set(25usize, 1u8, { + let m25: u8 = unsafe { ::std::mem::transmute(m25) }; + m25 as u64 + }); + __bindgen_bitfield_unit.set(26usize, 1u8, { + let m26: u8 = unsafe { ::std::mem::transmute(m26) }; + m26 as u64 + }); + __bindgen_bitfield_unit.set(27usize, 1u8, { + let m27: u8 = unsafe { ::std::mem::transmute(m27) }; + m27 as u64 + }); + __bindgen_bitfield_unit.set(28usize, 1u8, { + let m28: u8 = unsafe { ::std::mem::transmute(m28) }; + m28 as u64 + }); + __bindgen_bitfield_unit.set(29usize, 1u8, { + let m29: u8 = unsafe { ::std::mem::transmute(m29) }; + m29 as u64 + }); + __bindgen_bitfield_unit.set(30usize, 1u8, { + let m30: u8 = unsafe { ::std::mem::transmute(m30) }; + m30 as u64 + }); + __bindgen_bitfield_unit.set(31usize, 1u8, { + let m31: u8 = unsafe { ::std::mem::transmute(m31) }; + m31 as u64 + }); + __bindgen_bitfield_unit.set(32usize, 1u8, { + let m32: u8 = unsafe { ::std::mem::transmute(m32) }; + m32 as u64 + }); + __bindgen_bitfield_unit } } diff --git a/tests/expectations/tests/bitfield-large.rs b/tests/expectations/tests/bitfield-large.rs index c3209ea5e4..7b93f1190b 100644 --- a/tests/expectations/tests/bitfield-large.rs +++ b/tests/expectations/tests/bitfield-large.rs @@ -4,10 +4,89 @@ #![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] +#[repr(C)] +#[derive(Copy, Clone, Debug, Default, Eq, Hash, Ord, PartialEq, PartialOrd)] +pub struct __BindgenBitfieldUnit +where + Storage: AsRef<[u8]> + AsMut<[u8]>, +{ + storage: Storage, + align: [Align; 0], +} + +impl __BindgenBitfieldUnit +where + Storage: AsRef<[u8]> + AsMut<[u8]>, +{ + #[inline] + pub fn new(storage: Storage) -> Self { + Self { storage, align: [] } + } + + #[inline] + pub fn get_bit(&self, index: usize) -> bool { + debug_assert!(index / 8 < self.storage.as_ref().len()); + + let byte_index = index / 8; + let byte = self.storage.as_ref()[byte_index]; + + let bit_index = index % 8; + let mask = 1 << bit_index; + + byte & mask == mask + } + + #[inline] + pub fn set_bit(&mut self, index: usize, val: bool) { + debug_assert!(index / 8 < self.storage.as_ref().len()); + + let byte_index = index / 8; + let byte = &mut self.storage.as_mut()[byte_index]; + + let bit_index = index % 8; + let mask = 1 << bit_index; + + if val { + *byte |= mask; + } else { + *byte &= !mask; + } + } + + #[inline] + pub fn get(&self, bit_offset: usize, bit_width: u8) -> u64 { + debug_assert!(bit_width <= 64); + debug_assert!(bit_offset / 8 < self.storage.as_ref().len()); + debug_assert!((bit_offset + (bit_width as usize)) / 8 <= self.storage.as_ref().len()); + + let mut val = 0; + + for i in 0..(bit_width as usize) { + if self.get_bit(i + bit_offset) { + val |= 1 << i; + } + } + + val + } + + #[inline] + pub fn set(&mut self, bit_offset: usize, bit_width: u8, val: u64) { + debug_assert!(bit_width <= 64); + debug_assert!(bit_offset / 8 < self.storage.as_ref().len()); + debug_assert!((bit_offset + (bit_width as usize)) / 8 <= self.storage.as_ref().len()); + + for i in 0..(bit_width as usize) { + let mask = 1 << i; + let val_bit_is_set = val & mask == mask; + self.set_bit(i + bit_offset, val_bit_is_set); + } + } +} #[repr(C)] #[derive(Debug, Default, Copy, Clone)] pub struct HasBigBitfield { - pub _bitfield_1: [u8; 16usize], + pub _bitfield_1: __BindgenBitfieldUnit<[u8; 16usize], u64>, } #[test] fn bindgen_test_layout_HasBigBitfield() { @@ -20,7 +99,7 @@ fn bindgen_test_layout_HasBigBitfield() { #[repr(C)] #[derive(Debug, Default, Copy, Clone)] pub struct HasTwoBigBitfields { - pub _bitfield_1: [u8; 16usize], + pub _bitfield_1: __BindgenBitfieldUnit<[u8; 16usize], u64>, } #[test] fn bindgen_test_layout_HasTwoBigBitfields() { diff --git a/tests/expectations/tests/bitfield-method-same-name.rs b/tests/expectations/tests/bitfield-method-same-name.rs index a737e7b111..b8700605a4 100644 --- a/tests/expectations/tests/bitfield-method-same-name.rs +++ b/tests/expectations/tests/bitfield-method-same-name.rs @@ -4,10 +4,89 @@ #![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] +#[repr(C)] +#[derive(Copy, Clone, Debug, Default, Eq, Hash, Ord, PartialEq, PartialOrd)] +pub struct __BindgenBitfieldUnit +where + Storage: AsRef<[u8]> + AsMut<[u8]>, +{ + storage: Storage, + align: [Align; 0], +} + +impl __BindgenBitfieldUnit +where + Storage: AsRef<[u8]> + AsMut<[u8]>, +{ + #[inline] + pub fn new(storage: Storage) -> Self { + Self { storage, align: [] } + } + + #[inline] + pub fn get_bit(&self, index: usize) -> bool { + debug_assert!(index / 8 < self.storage.as_ref().len()); + + let byte_index = index / 8; + let byte = self.storage.as_ref()[byte_index]; + + let bit_index = index % 8; + let mask = 1 << bit_index; + + byte & mask == mask + } + + #[inline] + pub fn set_bit(&mut self, index: usize, val: bool) { + debug_assert!(index / 8 < self.storage.as_ref().len()); + + let byte_index = index / 8; + let byte = &mut self.storage.as_mut()[byte_index]; + + let bit_index = index % 8; + let mask = 1 << bit_index; + + if val { + *byte |= mask; + } else { + *byte &= !mask; + } + } + + #[inline] + pub fn get(&self, bit_offset: usize, bit_width: u8) -> u64 { + debug_assert!(bit_width <= 64); + debug_assert!(bit_offset / 8 < self.storage.as_ref().len()); + debug_assert!((bit_offset + (bit_width as usize)) / 8 <= self.storage.as_ref().len()); + + let mut val = 0; + + for i in 0..(bit_width as usize) { + if self.get_bit(i + bit_offset) { + val |= 1 << i; + } + } + + val + } + + #[inline] + pub fn set(&mut self, bit_offset: usize, bit_width: u8, val: u64) { + debug_assert!(bit_width <= 64); + debug_assert!(bit_offset / 8 < self.storage.as_ref().len()); + debug_assert!((bit_offset + (bit_width as usize)) / 8 <= self.storage.as_ref().len()); + + for i in 0..(bit_width as usize) { + let mask = 1 << i; + let val_bit_is_set = val & mask == mask; + self.set_bit(i + bit_offset, val_bit_is_set); + } + } +} #[repr(C, packed)] #[derive(Debug, Default, Copy, Clone)] pub struct Foo { - pub _bitfield_1: u8, + pub _bitfield_1: __BindgenBitfieldUnit<[u8; 1usize], u8>, } #[test] fn bindgen_test_layout_Foo() { @@ -37,43 +116,27 @@ extern "C" { impl Foo { #[inline] pub fn type__bindgen_bitfield(&self) -> ::std::os::raw::c_char { - let mut unit_field_val: u8 = unsafe { ::std::mem::uninitialized() }; - unsafe { - ::std::ptr::copy_nonoverlapping( - &self._bitfield_1 as *const _ as *const u8, - &mut unit_field_val as *mut u8 as *mut u8, - 1usize, - ) - }; - let mask = 0x7 as u8; - let val = (unit_field_val & mask) >> 0usize; - unsafe { ::std::mem::transmute(val as u8) } + unsafe { ::std::mem::transmute(self._bitfield_1.get(0usize, 3u8) as u8) } } #[inline] pub fn set_type__bindgen_bitfield(&mut self, val: ::std::os::raw::c_char) { - let mask = 0x7 as u8; - let val = val as u8 as u8; - let mut unit_field_val: u8 = unsafe { ::std::mem::uninitialized() }; - unsafe { - ::std::ptr::copy_nonoverlapping( - &self._bitfield_1 as *const _ as *const u8, - &mut unit_field_val as *mut u8 as *mut u8, - 1usize, - ) - }; - unit_field_val &= !mask; - unit_field_val |= (val << 0usize) & mask; unsafe { - ::std::ptr::copy_nonoverlapping( - &unit_field_val as *const _ as *const u8, - &mut self._bitfield_1 as *mut _ as *mut u8, - 1usize, - ); + let val: u8 = ::std::mem::transmute(val); + self._bitfield_1.set(0usize, 3u8, val as u64) } } #[inline] - pub fn new_bitfield_1(type__bindgen_bitfield: ::std::os::raw::c_char) -> u8 { - (0 | ((type__bindgen_bitfield as u8 as u8) << 0usize) & (0x7 as u8)) + pub fn new_bitfield_1( + type__bindgen_bitfield: ::std::os::raw::c_char, + ) -> __BindgenBitfieldUnit<[u8; 1usize], u8> { + let mut __bindgen_bitfield_unit: __BindgenBitfieldUnit<[u8; 1usize], u8> = + Default::default(); + __bindgen_bitfield_unit.set(0usize, 3u8, { + let type__bindgen_bitfield: u8 = + unsafe { ::std::mem::transmute(type__bindgen_bitfield) }; + type__bindgen_bitfield as u64 + }); + __bindgen_bitfield_unit } #[inline] pub unsafe fn type_(&mut self) -> ::std::os::raw::c_char { diff --git a/tests/expectations/tests/bitfield_align.rs b/tests/expectations/tests/bitfield_align.rs index cc433aa91d..fc4b033b71 100644 --- a/tests/expectations/tests/bitfield_align.rs +++ b/tests/expectations/tests/bitfield_align.rs @@ -4,11 +4,90 @@ #![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] +#[repr(C)] +#[derive(Copy, Clone, Debug, Default, Eq, Hash, Ord, PartialEq, PartialOrd)] +pub struct __BindgenBitfieldUnit +where + Storage: AsRef<[u8]> + AsMut<[u8]>, +{ + storage: Storage, + align: [Align; 0], +} + +impl __BindgenBitfieldUnit +where + Storage: AsRef<[u8]> + AsMut<[u8]>, +{ + #[inline] + pub fn new(storage: Storage) -> Self { + Self { storage, align: [] } + } + + #[inline] + pub fn get_bit(&self, index: usize) -> bool { + debug_assert!(index / 8 < self.storage.as_ref().len()); + + let byte_index = index / 8; + let byte = self.storage.as_ref()[byte_index]; + + let bit_index = index % 8; + let mask = 1 << bit_index; + + byte & mask == mask + } + + #[inline] + pub fn set_bit(&mut self, index: usize, val: bool) { + debug_assert!(index / 8 < self.storage.as_ref().len()); + + let byte_index = index / 8; + let byte = &mut self.storage.as_mut()[byte_index]; + + let bit_index = index % 8; + let mask = 1 << bit_index; + + if val { + *byte |= mask; + } else { + *byte &= !mask; + } + } + + #[inline] + pub fn get(&self, bit_offset: usize, bit_width: u8) -> u64 { + debug_assert!(bit_width <= 64); + debug_assert!(bit_offset / 8 < self.storage.as_ref().len()); + debug_assert!((bit_offset + (bit_width as usize)) / 8 <= self.storage.as_ref().len()); + + let mut val = 0; + + for i in 0..(bit_width as usize) { + if self.get_bit(i + bit_offset) { + val |= 1 << i; + } + } + + val + } + + #[inline] + pub fn set(&mut self, bit_offset: usize, bit_width: u8, val: u64) { + debug_assert!(bit_width <= 64); + debug_assert!(bit_offset / 8 < self.storage.as_ref().len()); + debug_assert!((bit_offset + (bit_width as usize)) / 8 <= self.storage.as_ref().len()); + + for i in 0..(bit_width as usize) { + let mask = 1 << i; + let val_bit_is_set = val & mask == mask; + self.set_bit(i + bit_offset, val_bit_is_set); + } + } +} #[repr(C)] #[derive(Debug, Default, Copy, Clone)] pub struct A { pub x: ::std::os::raw::c_uchar, - pub _bitfield_1: [u8; 2usize], + pub _bitfield_1: __BindgenBitfieldUnit<[u8; 2usize], u8>, pub y: ::std::os::raw::c_uchar, pub __bindgen_align: [u32; 0usize], } @@ -38,362 +117,112 @@ fn bindgen_test_layout_A() { impl A { #[inline] pub fn b1(&self) -> ::std::os::raw::c_uint { - let mut unit_field_val: u16 = unsafe { ::std::mem::uninitialized() }; - unsafe { - ::std::ptr::copy_nonoverlapping( - &self._bitfield_1 as *const _ as *const u8, - &mut unit_field_val as *mut u16 as *mut u8, - 2usize, - ) - }; - let mask = 0x1 as u16; - let val = (unit_field_val & mask) >> 0usize; - unsafe { ::std::mem::transmute(val as u32) } + unsafe { ::std::mem::transmute(self._bitfield_1.get(0usize, 1u8) as u32) } } #[inline] pub fn set_b1(&mut self, val: ::std::os::raw::c_uint) { - let mask = 0x1 as u16; - let val = val as u32 as u16; - let mut unit_field_val: u16 = unsafe { ::std::mem::uninitialized() }; unsafe { - ::std::ptr::copy_nonoverlapping( - &self._bitfield_1 as *const _ as *const u8, - &mut unit_field_val as *mut u16 as *mut u8, - 2usize, - ) - }; - unit_field_val &= !mask; - unit_field_val |= (val << 0usize) & mask; - unsafe { - ::std::ptr::copy_nonoverlapping( - &unit_field_val as *const _ as *const u8, - &mut self._bitfield_1 as *mut _ as *mut u8, - 2usize, - ); + let val: u32 = ::std::mem::transmute(val); + self._bitfield_1.set(0usize, 1u8, val as u64) } } #[inline] pub fn b2(&self) -> ::std::os::raw::c_uint { - let mut unit_field_val: u16 = unsafe { ::std::mem::uninitialized() }; - unsafe { - ::std::ptr::copy_nonoverlapping( - &self._bitfield_1 as *const _ as *const u8, - &mut unit_field_val as *mut u16 as *mut u8, - 2usize, - ) - }; - let mask = 0x2 as u16; - let val = (unit_field_val & mask) >> 1usize; - unsafe { ::std::mem::transmute(val as u32) } + unsafe { ::std::mem::transmute(self._bitfield_1.get(1usize, 1u8) as u32) } } #[inline] pub fn set_b2(&mut self, val: ::std::os::raw::c_uint) { - let mask = 0x2 as u16; - let val = val as u32 as u16; - let mut unit_field_val: u16 = unsafe { ::std::mem::uninitialized() }; unsafe { - ::std::ptr::copy_nonoverlapping( - &self._bitfield_1 as *const _ as *const u8, - &mut unit_field_val as *mut u16 as *mut u8, - 2usize, - ) - }; - unit_field_val &= !mask; - unit_field_val |= (val << 1usize) & mask; - unsafe { - ::std::ptr::copy_nonoverlapping( - &unit_field_val as *const _ as *const u8, - &mut self._bitfield_1 as *mut _ as *mut u8, - 2usize, - ); + let val: u32 = ::std::mem::transmute(val); + self._bitfield_1.set(1usize, 1u8, val as u64) } } #[inline] pub fn b3(&self) -> ::std::os::raw::c_uint { - let mut unit_field_val: u16 = unsafe { ::std::mem::uninitialized() }; - unsafe { - ::std::ptr::copy_nonoverlapping( - &self._bitfield_1 as *const _ as *const u8, - &mut unit_field_val as *mut u16 as *mut u8, - 2usize, - ) - }; - let mask = 0x4 as u16; - let val = (unit_field_val & mask) >> 2usize; - unsafe { ::std::mem::transmute(val as u32) } + unsafe { ::std::mem::transmute(self._bitfield_1.get(2usize, 1u8) as u32) } } #[inline] pub fn set_b3(&mut self, val: ::std::os::raw::c_uint) { - let mask = 0x4 as u16; - let val = val as u32 as u16; - let mut unit_field_val: u16 = unsafe { ::std::mem::uninitialized() }; - unsafe { - ::std::ptr::copy_nonoverlapping( - &self._bitfield_1 as *const _ as *const u8, - &mut unit_field_val as *mut u16 as *mut u8, - 2usize, - ) - }; - unit_field_val &= !mask; - unit_field_val |= (val << 2usize) & mask; unsafe { - ::std::ptr::copy_nonoverlapping( - &unit_field_val as *const _ as *const u8, - &mut self._bitfield_1 as *mut _ as *mut u8, - 2usize, - ); + let val: u32 = ::std::mem::transmute(val); + self._bitfield_1.set(2usize, 1u8, val as u64) } } #[inline] pub fn b4(&self) -> ::std::os::raw::c_uint { - let mut unit_field_val: u16 = unsafe { ::std::mem::uninitialized() }; - unsafe { - ::std::ptr::copy_nonoverlapping( - &self._bitfield_1 as *const _ as *const u8, - &mut unit_field_val as *mut u16 as *mut u8, - 2usize, - ) - }; - let mask = 0x8 as u16; - let val = (unit_field_val & mask) >> 3usize; - unsafe { ::std::mem::transmute(val as u32) } + unsafe { ::std::mem::transmute(self._bitfield_1.get(3usize, 1u8) as u32) } } #[inline] pub fn set_b4(&mut self, val: ::std::os::raw::c_uint) { - let mask = 0x8 as u16; - let val = val as u32 as u16; - let mut unit_field_val: u16 = unsafe { ::std::mem::uninitialized() }; - unsafe { - ::std::ptr::copy_nonoverlapping( - &self._bitfield_1 as *const _ as *const u8, - &mut unit_field_val as *mut u16 as *mut u8, - 2usize, - ) - }; - unit_field_val &= !mask; - unit_field_val |= (val << 3usize) & mask; unsafe { - ::std::ptr::copy_nonoverlapping( - &unit_field_val as *const _ as *const u8, - &mut self._bitfield_1 as *mut _ as *mut u8, - 2usize, - ); + let val: u32 = ::std::mem::transmute(val); + self._bitfield_1.set(3usize, 1u8, val as u64) } } #[inline] pub fn b5(&self) -> ::std::os::raw::c_uint { - let mut unit_field_val: u16 = unsafe { ::std::mem::uninitialized() }; - unsafe { - ::std::ptr::copy_nonoverlapping( - &self._bitfield_1 as *const _ as *const u8, - &mut unit_field_val as *mut u16 as *mut u8, - 2usize, - ) - }; - let mask = 0x10 as u16; - let val = (unit_field_val & mask) >> 4usize; - unsafe { ::std::mem::transmute(val as u32) } + unsafe { ::std::mem::transmute(self._bitfield_1.get(4usize, 1u8) as u32) } } #[inline] pub fn set_b5(&mut self, val: ::std::os::raw::c_uint) { - let mask = 0x10 as u16; - let val = val as u32 as u16; - let mut unit_field_val: u16 = unsafe { ::std::mem::uninitialized() }; unsafe { - ::std::ptr::copy_nonoverlapping( - &self._bitfield_1 as *const _ as *const u8, - &mut unit_field_val as *mut u16 as *mut u8, - 2usize, - ) - }; - unit_field_val &= !mask; - unit_field_val |= (val << 4usize) & mask; - unsafe { - ::std::ptr::copy_nonoverlapping( - &unit_field_val as *const _ as *const u8, - &mut self._bitfield_1 as *mut _ as *mut u8, - 2usize, - ); + let val: u32 = ::std::mem::transmute(val); + self._bitfield_1.set(4usize, 1u8, val as u64) } } #[inline] pub fn b6(&self) -> ::std::os::raw::c_uint { - let mut unit_field_val: u16 = unsafe { ::std::mem::uninitialized() }; - unsafe { - ::std::ptr::copy_nonoverlapping( - &self._bitfield_1 as *const _ as *const u8, - &mut unit_field_val as *mut u16 as *mut u8, - 2usize, - ) - }; - let mask = 0x20 as u16; - let val = (unit_field_val & mask) >> 5usize; - unsafe { ::std::mem::transmute(val as u32) } + unsafe { ::std::mem::transmute(self._bitfield_1.get(5usize, 1u8) as u32) } } #[inline] pub fn set_b6(&mut self, val: ::std::os::raw::c_uint) { - let mask = 0x20 as u16; - let val = val as u32 as u16; - let mut unit_field_val: u16 = unsafe { ::std::mem::uninitialized() }; - unsafe { - ::std::ptr::copy_nonoverlapping( - &self._bitfield_1 as *const _ as *const u8, - &mut unit_field_val as *mut u16 as *mut u8, - 2usize, - ) - }; - unit_field_val &= !mask; - unit_field_val |= (val << 5usize) & mask; unsafe { - ::std::ptr::copy_nonoverlapping( - &unit_field_val as *const _ as *const u8, - &mut self._bitfield_1 as *mut _ as *mut u8, - 2usize, - ); + let val: u32 = ::std::mem::transmute(val); + self._bitfield_1.set(5usize, 1u8, val as u64) } } #[inline] pub fn b7(&self) -> ::std::os::raw::c_uint { - let mut unit_field_val: u16 = unsafe { ::std::mem::uninitialized() }; - unsafe { - ::std::ptr::copy_nonoverlapping( - &self._bitfield_1 as *const _ as *const u8, - &mut unit_field_val as *mut u16 as *mut u8, - 2usize, - ) - }; - let mask = 0x40 as u16; - let val = (unit_field_val & mask) >> 6usize; - unsafe { ::std::mem::transmute(val as u32) } + unsafe { ::std::mem::transmute(self._bitfield_1.get(6usize, 1u8) as u32) } } #[inline] pub fn set_b7(&mut self, val: ::std::os::raw::c_uint) { - let mask = 0x40 as u16; - let val = val as u32 as u16; - let mut unit_field_val: u16 = unsafe { ::std::mem::uninitialized() }; - unsafe { - ::std::ptr::copy_nonoverlapping( - &self._bitfield_1 as *const _ as *const u8, - &mut unit_field_val as *mut u16 as *mut u8, - 2usize, - ) - }; - unit_field_val &= !mask; - unit_field_val |= (val << 6usize) & mask; unsafe { - ::std::ptr::copy_nonoverlapping( - &unit_field_val as *const _ as *const u8, - &mut self._bitfield_1 as *mut _ as *mut u8, - 2usize, - ); + let val: u32 = ::std::mem::transmute(val); + self._bitfield_1.set(6usize, 1u8, val as u64) } } #[inline] pub fn b8(&self) -> ::std::os::raw::c_uint { - let mut unit_field_val: u16 = unsafe { ::std::mem::uninitialized() }; - unsafe { - ::std::ptr::copy_nonoverlapping( - &self._bitfield_1 as *const _ as *const u8, - &mut unit_field_val as *mut u16 as *mut u8, - 2usize, - ) - }; - let mask = 0x80 as u16; - let val = (unit_field_val & mask) >> 7usize; - unsafe { ::std::mem::transmute(val as u32) } + unsafe { ::std::mem::transmute(self._bitfield_1.get(7usize, 1u8) as u32) } } #[inline] pub fn set_b8(&mut self, val: ::std::os::raw::c_uint) { - let mask = 0x80 as u16; - let val = val as u32 as u16; - let mut unit_field_val: u16 = unsafe { ::std::mem::uninitialized() }; - unsafe { - ::std::ptr::copy_nonoverlapping( - &self._bitfield_1 as *const _ as *const u8, - &mut unit_field_val as *mut u16 as *mut u8, - 2usize, - ) - }; - unit_field_val &= !mask; - unit_field_val |= (val << 7usize) & mask; unsafe { - ::std::ptr::copy_nonoverlapping( - &unit_field_val as *const _ as *const u8, - &mut self._bitfield_1 as *mut _ as *mut u8, - 2usize, - ); + let val: u32 = ::std::mem::transmute(val); + self._bitfield_1.set(7usize, 1u8, val as u64) } } #[inline] pub fn b9(&self) -> ::std::os::raw::c_uint { - let mut unit_field_val: u16 = unsafe { ::std::mem::uninitialized() }; - unsafe { - ::std::ptr::copy_nonoverlapping( - &self._bitfield_1 as *const _ as *const u8, - &mut unit_field_val as *mut u16 as *mut u8, - 2usize, - ) - }; - let mask = 0x100 as u16; - let val = (unit_field_val & mask) >> 8usize; - unsafe { ::std::mem::transmute(val as u32) } + unsafe { ::std::mem::transmute(self._bitfield_1.get(8usize, 1u8) as u32) } } #[inline] pub fn set_b9(&mut self, val: ::std::os::raw::c_uint) { - let mask = 0x100 as u16; - let val = val as u32 as u16; - let mut unit_field_val: u16 = unsafe { ::std::mem::uninitialized() }; unsafe { - ::std::ptr::copy_nonoverlapping( - &self._bitfield_1 as *const _ as *const u8, - &mut unit_field_val as *mut u16 as *mut u8, - 2usize, - ) - }; - unit_field_val &= !mask; - unit_field_val |= (val << 8usize) & mask; - unsafe { - ::std::ptr::copy_nonoverlapping( - &unit_field_val as *const _ as *const u8, - &mut self._bitfield_1 as *mut _ as *mut u8, - 2usize, - ); + let val: u32 = ::std::mem::transmute(val); + self._bitfield_1.set(8usize, 1u8, val as u64) } } #[inline] pub fn b10(&self) -> ::std::os::raw::c_uint { - let mut unit_field_val: u16 = unsafe { ::std::mem::uninitialized() }; - unsafe { - ::std::ptr::copy_nonoverlapping( - &self._bitfield_1 as *const _ as *const u8, - &mut unit_field_val as *mut u16 as *mut u8, - 2usize, - ) - }; - let mask = 0x200 as u16; - let val = (unit_field_val & mask) >> 9usize; - unsafe { ::std::mem::transmute(val as u32) } + unsafe { ::std::mem::transmute(self._bitfield_1.get(9usize, 1u8) as u32) } } #[inline] pub fn set_b10(&mut self, val: ::std::os::raw::c_uint) { - let mask = 0x200 as u16; - let val = val as u32 as u16; - let mut unit_field_val: u16 = unsafe { ::std::mem::uninitialized() }; - unsafe { - ::std::ptr::copy_nonoverlapping( - &self._bitfield_1 as *const _ as *const u8, - &mut unit_field_val as *mut u16 as *mut u8, - 2usize, - ) - }; - unit_field_val &= !mask; - unit_field_val |= (val << 9usize) & mask; unsafe { - ::std::ptr::copy_nonoverlapping( - &unit_field_val as *const _ as *const u8, - &mut self._bitfield_1 as *mut _ as *mut u8, - 2usize, - ); + let val: u32 = ::std::mem::transmute(val); + self._bitfield_1.set(9usize, 1u8, val as u64) } } #[inline] @@ -408,23 +237,56 @@ impl A { b8: ::std::os::raw::c_uint, b9: ::std::os::raw::c_uint, b10: ::std::os::raw::c_uint, - ) -> u16 { - ((((((((((0 | ((b1 as u32 as u16) << 0usize) & (0x1 as u16)) - | ((b2 as u32 as u16) << 1usize) & (0x2 as u16)) - | ((b3 as u32 as u16) << 2usize) & (0x4 as u16)) - | ((b4 as u32 as u16) << 3usize) & (0x8 as u16)) - | ((b5 as u32 as u16) << 4usize) & (0x10 as u16)) - | ((b6 as u32 as u16) << 5usize) & (0x20 as u16)) - | ((b7 as u32 as u16) << 6usize) & (0x40 as u16)) - | ((b8 as u32 as u16) << 7usize) & (0x80 as u16)) - | ((b9 as u32 as u16) << 8usize) & (0x100 as u16)) - | ((b10 as u32 as u16) << 9usize) & (0x200 as u16)) + ) -> __BindgenBitfieldUnit<[u8; 2usize], u8> { + let mut __bindgen_bitfield_unit: __BindgenBitfieldUnit<[u8; 2usize], u8> = + Default::default(); + __bindgen_bitfield_unit.set(0usize, 1u8, { + let b1: u32 = unsafe { ::std::mem::transmute(b1) }; + b1 as u64 + }); + __bindgen_bitfield_unit.set(1usize, 1u8, { + let b2: u32 = unsafe { ::std::mem::transmute(b2) }; + b2 as u64 + }); + __bindgen_bitfield_unit.set(2usize, 1u8, { + let b3: u32 = unsafe { ::std::mem::transmute(b3) }; + b3 as u64 + }); + __bindgen_bitfield_unit.set(3usize, 1u8, { + let b4: u32 = unsafe { ::std::mem::transmute(b4) }; + b4 as u64 + }); + __bindgen_bitfield_unit.set(4usize, 1u8, { + let b5: u32 = unsafe { ::std::mem::transmute(b5) }; + b5 as u64 + }); + __bindgen_bitfield_unit.set(5usize, 1u8, { + let b6: u32 = unsafe { ::std::mem::transmute(b6) }; + b6 as u64 + }); + __bindgen_bitfield_unit.set(6usize, 1u8, { + let b7: u32 = unsafe { ::std::mem::transmute(b7) }; + b7 as u64 + }); + __bindgen_bitfield_unit.set(7usize, 1u8, { + let b8: u32 = unsafe { ::std::mem::transmute(b8) }; + b8 as u64 + }); + __bindgen_bitfield_unit.set(8usize, 1u8, { + let b9: u32 = unsafe { ::std::mem::transmute(b9) }; + b9 as u64 + }); + __bindgen_bitfield_unit.set(9usize, 1u8, { + let b10: u32 = unsafe { ::std::mem::transmute(b10) }; + b10 as u64 + }); + __bindgen_bitfield_unit } } #[repr(C)] #[derive(Debug, Default, Copy, Clone)] pub struct B { - pub _bitfield_1: u32, + pub _bitfield_1: __BindgenBitfieldUnit<[u8; 4usize], u32>, pub __bindgen_align: [u32; 0usize], } #[test] @@ -443,87 +305,49 @@ fn bindgen_test_layout_B() { impl B { #[inline] pub fn foo(&self) -> ::std::os::raw::c_uint { - let mut unit_field_val: u32 = unsafe { ::std::mem::uninitialized() }; - unsafe { - ::std::ptr::copy_nonoverlapping( - &self._bitfield_1 as *const _ as *const u8, - &mut unit_field_val as *mut u32 as *mut u8, - 4usize, - ) - }; - let mask = 0x7fffffff as u32; - let val = (unit_field_val & mask) >> 0usize; - unsafe { ::std::mem::transmute(val as u32) } + unsafe { ::std::mem::transmute(self._bitfield_1.get(0usize, 31u8) as u32) } } #[inline] pub fn set_foo(&mut self, val: ::std::os::raw::c_uint) { - let mask = 0x7fffffff as u32; - let val = val as u32 as u32; - let mut unit_field_val: u32 = unsafe { ::std::mem::uninitialized() }; - unsafe { - ::std::ptr::copy_nonoverlapping( - &self._bitfield_1 as *const _ as *const u8, - &mut unit_field_val as *mut u32 as *mut u8, - 4usize, - ) - }; - unit_field_val &= !mask; - unit_field_val |= (val << 0usize) & mask; unsafe { - ::std::ptr::copy_nonoverlapping( - &unit_field_val as *const _ as *const u8, - &mut self._bitfield_1 as *mut _ as *mut u8, - 4usize, - ); + let val: u32 = ::std::mem::transmute(val); + self._bitfield_1.set(0usize, 31u8, val as u64) } } #[inline] pub fn bar(&self) -> ::std::os::raw::c_uchar { - let mut unit_field_val: u32 = unsafe { ::std::mem::uninitialized() }; - unsafe { - ::std::ptr::copy_nonoverlapping( - &self._bitfield_1 as *const _ as *const u8, - &mut unit_field_val as *mut u32 as *mut u8, - 4usize, - ) - }; - let mask = 0x80000000 as u32; - let val = (unit_field_val & mask) >> 31usize; - unsafe { ::std::mem::transmute(val as u8) } + unsafe { ::std::mem::transmute(self._bitfield_1.get(31usize, 1u8) as u8) } } #[inline] pub fn set_bar(&mut self, val: ::std::os::raw::c_uchar) { - let mask = 0x80000000 as u32; - let val = val as u8 as u32; - let mut unit_field_val: u32 = unsafe { ::std::mem::uninitialized() }; unsafe { - ::std::ptr::copy_nonoverlapping( - &self._bitfield_1 as *const _ as *const u8, - &mut unit_field_val as *mut u32 as *mut u8, - 4usize, - ) - }; - unit_field_val &= !mask; - unit_field_val |= (val << 31usize) & mask; - unsafe { - ::std::ptr::copy_nonoverlapping( - &unit_field_val as *const _ as *const u8, - &mut self._bitfield_1 as *mut _ as *mut u8, - 4usize, - ); + let val: u8 = ::std::mem::transmute(val); + self._bitfield_1.set(31usize, 1u8, val as u64) } } #[inline] - pub fn new_bitfield_1(foo: ::std::os::raw::c_uint, bar: ::std::os::raw::c_uchar) -> u32 { - ((0 | ((foo as u32 as u32) << 0usize) & (0x7fffffff as u32)) - | ((bar as u8 as u32) << 31usize) & (0x80000000 as u32)) + pub fn new_bitfield_1( + foo: ::std::os::raw::c_uint, + bar: ::std::os::raw::c_uchar, + ) -> __BindgenBitfieldUnit<[u8; 4usize], u32> { + let mut __bindgen_bitfield_unit: __BindgenBitfieldUnit<[u8; 4usize], u32> = + Default::default(); + __bindgen_bitfield_unit.set(0usize, 31u8, { + let foo: u32 = unsafe { ::std::mem::transmute(foo) }; + foo as u64 + }); + __bindgen_bitfield_unit.set(31usize, 1u8, { + let bar: u8 = unsafe { ::std::mem::transmute(bar) }; + bar as u64 + }); + __bindgen_bitfield_unit } } #[repr(C)] #[derive(Debug, Default, Copy, Clone)] pub struct C { pub x: ::std::os::raw::c_uchar, - pub _bitfield_1: u8, + pub _bitfield_1: __BindgenBitfieldUnit<[u8; 1usize], u8>, pub baz: ::std::os::raw::c_uint, } #[test] @@ -552,86 +376,48 @@ fn bindgen_test_layout_C() { impl C { #[inline] pub fn b1(&self) -> ::std::os::raw::c_uint { - let mut unit_field_val: u8 = unsafe { ::std::mem::uninitialized() }; - unsafe { - ::std::ptr::copy_nonoverlapping( - &self._bitfield_1 as *const _ as *const u8, - &mut unit_field_val as *mut u8 as *mut u8, - 1usize, - ) - }; - let mask = 0x1 as u8; - let val = (unit_field_val & mask) >> 0usize; - unsafe { ::std::mem::transmute(val as u32) } + unsafe { ::std::mem::transmute(self._bitfield_1.get(0usize, 1u8) as u32) } } #[inline] pub fn set_b1(&mut self, val: ::std::os::raw::c_uint) { - let mask = 0x1 as u8; - let val = val as u32 as u8; - let mut unit_field_val: u8 = unsafe { ::std::mem::uninitialized() }; - unsafe { - ::std::ptr::copy_nonoverlapping( - &self._bitfield_1 as *const _ as *const u8, - &mut unit_field_val as *mut u8 as *mut u8, - 1usize, - ) - }; - unit_field_val &= !mask; - unit_field_val |= (val << 0usize) & mask; unsafe { - ::std::ptr::copy_nonoverlapping( - &unit_field_val as *const _ as *const u8, - &mut self._bitfield_1 as *mut _ as *mut u8, - 1usize, - ); + let val: u32 = ::std::mem::transmute(val); + self._bitfield_1.set(0usize, 1u8, val as u64) } } #[inline] pub fn b2(&self) -> ::std::os::raw::c_uint { - let mut unit_field_val: u8 = unsafe { ::std::mem::uninitialized() }; - unsafe { - ::std::ptr::copy_nonoverlapping( - &self._bitfield_1 as *const _ as *const u8, - &mut unit_field_val as *mut u8 as *mut u8, - 1usize, - ) - }; - let mask = 0x2 as u8; - let val = (unit_field_val & mask) >> 1usize; - unsafe { ::std::mem::transmute(val as u32) } + unsafe { ::std::mem::transmute(self._bitfield_1.get(1usize, 1u8) as u32) } } #[inline] pub fn set_b2(&mut self, val: ::std::os::raw::c_uint) { - let mask = 0x2 as u8; - let val = val as u32 as u8; - let mut unit_field_val: u8 = unsafe { ::std::mem::uninitialized() }; unsafe { - ::std::ptr::copy_nonoverlapping( - &self._bitfield_1 as *const _ as *const u8, - &mut unit_field_val as *mut u8 as *mut u8, - 1usize, - ) - }; - unit_field_val &= !mask; - unit_field_val |= (val << 1usize) & mask; - unsafe { - ::std::ptr::copy_nonoverlapping( - &unit_field_val as *const _ as *const u8, - &mut self._bitfield_1 as *mut _ as *mut u8, - 1usize, - ); + let val: u32 = ::std::mem::transmute(val); + self._bitfield_1.set(1usize, 1u8, val as u64) } } #[inline] - pub fn new_bitfield_1(b1: ::std::os::raw::c_uint, b2: ::std::os::raw::c_uint) -> u8 { - ((0 | ((b1 as u32 as u8) << 0usize) & (0x1 as u8)) - | ((b2 as u32 as u8) << 1usize) & (0x2 as u8)) + pub fn new_bitfield_1( + b1: ::std::os::raw::c_uint, + b2: ::std::os::raw::c_uint, + ) -> __BindgenBitfieldUnit<[u8; 1usize], u8> { + let mut __bindgen_bitfield_unit: __BindgenBitfieldUnit<[u8; 1usize], u8> = + Default::default(); + __bindgen_bitfield_unit.set(0usize, 1u8, { + let b1: u32 = unsafe { ::std::mem::transmute(b1) }; + b1 as u64 + }); + __bindgen_bitfield_unit.set(1usize, 1u8, { + let b2: u32 = unsafe { ::std::mem::transmute(b2) }; + b2 as u64 + }); + __bindgen_bitfield_unit } } #[repr(C)] #[derive(Debug, Default, Copy, Clone)] pub struct Date1 { - pub _bitfield_1: [u8; 3usize], + pub _bitfield_1: __BindgenBitfieldUnit<[u8; 3usize], u8>, pub __bindgen_padding_0: u8, pub __bindgen_align: [u16; 0usize], } @@ -651,146 +437,46 @@ fn bindgen_test_layout_Date1() { impl Date1 { #[inline] pub fn nWeekDay(&self) -> ::std::os::raw::c_ushort { - let mut unit_field_val: u32 = unsafe { ::std::mem::uninitialized() }; - unsafe { - ::std::ptr::copy_nonoverlapping( - &self._bitfield_1 as *const _ as *const u8, - &mut unit_field_val as *mut u32 as *mut u8, - 3usize, - ) - }; - let mask = 0x7 as u32; - let val = (unit_field_val & mask) >> 0usize; - unsafe { ::std::mem::transmute(val as u16) } + unsafe { ::std::mem::transmute(self._bitfield_1.get(0usize, 3u8) as u16) } } #[inline] pub fn set_nWeekDay(&mut self, val: ::std::os::raw::c_ushort) { - let mask = 0x7 as u32; - let val = val as u16 as u32; - let mut unit_field_val: u32 = unsafe { ::std::mem::uninitialized() }; - unsafe { - ::std::ptr::copy_nonoverlapping( - &self._bitfield_1 as *const _ as *const u8, - &mut unit_field_val as *mut u32 as *mut u8, - 3usize, - ) - }; - unit_field_val &= !mask; - unit_field_val |= (val << 0usize) & mask; unsafe { - ::std::ptr::copy_nonoverlapping( - &unit_field_val as *const _ as *const u8, - &mut self._bitfield_1 as *mut _ as *mut u8, - 3usize, - ); + let val: u16 = ::std::mem::transmute(val); + self._bitfield_1.set(0usize, 3u8, val as u64) } } #[inline] pub fn nMonthDay(&self) -> ::std::os::raw::c_ushort { - let mut unit_field_val: u32 = unsafe { ::std::mem::uninitialized() }; - unsafe { - ::std::ptr::copy_nonoverlapping( - &self._bitfield_1 as *const _ as *const u8, - &mut unit_field_val as *mut u32 as *mut u8, - 3usize, - ) - }; - let mask = 0x1f8 as u32; - let val = (unit_field_val & mask) >> 3usize; - unsafe { ::std::mem::transmute(val as u16) } + unsafe { ::std::mem::transmute(self._bitfield_1.get(3usize, 6u8) as u16) } } #[inline] pub fn set_nMonthDay(&mut self, val: ::std::os::raw::c_ushort) { - let mask = 0x1f8 as u32; - let val = val as u16 as u32; - let mut unit_field_val: u32 = unsafe { ::std::mem::uninitialized() }; - unsafe { - ::std::ptr::copy_nonoverlapping( - &self._bitfield_1 as *const _ as *const u8, - &mut unit_field_val as *mut u32 as *mut u8, - 3usize, - ) - }; - unit_field_val &= !mask; - unit_field_val |= (val << 3usize) & mask; unsafe { - ::std::ptr::copy_nonoverlapping( - &unit_field_val as *const _ as *const u8, - &mut self._bitfield_1 as *mut _ as *mut u8, - 3usize, - ); + let val: u16 = ::std::mem::transmute(val); + self._bitfield_1.set(3usize, 6u8, val as u64) } } #[inline] pub fn nMonth(&self) -> ::std::os::raw::c_ushort { - let mut unit_field_val: u32 = unsafe { ::std::mem::uninitialized() }; - unsafe { - ::std::ptr::copy_nonoverlapping( - &self._bitfield_1 as *const _ as *const u8, - &mut unit_field_val as *mut u32 as *mut u8, - 3usize, - ) - }; - let mask = 0x3e00 as u32; - let val = (unit_field_val & mask) >> 9usize; - unsafe { ::std::mem::transmute(val as u16) } + unsafe { ::std::mem::transmute(self._bitfield_1.get(9usize, 5u8) as u16) } } #[inline] pub fn set_nMonth(&mut self, val: ::std::os::raw::c_ushort) { - let mask = 0x3e00 as u32; - let val = val as u16 as u32; - let mut unit_field_val: u32 = unsafe { ::std::mem::uninitialized() }; - unsafe { - ::std::ptr::copy_nonoverlapping( - &self._bitfield_1 as *const _ as *const u8, - &mut unit_field_val as *mut u32 as *mut u8, - 3usize, - ) - }; - unit_field_val &= !mask; - unit_field_val |= (val << 9usize) & mask; unsafe { - ::std::ptr::copy_nonoverlapping( - &unit_field_val as *const _ as *const u8, - &mut self._bitfield_1 as *mut _ as *mut u8, - 3usize, - ); + let val: u16 = ::std::mem::transmute(val); + self._bitfield_1.set(9usize, 5u8, val as u64) } } #[inline] pub fn nYear(&self) -> ::std::os::raw::c_ushort { - let mut unit_field_val: u32 = unsafe { ::std::mem::uninitialized() }; - unsafe { - ::std::ptr::copy_nonoverlapping( - &self._bitfield_1 as *const _ as *const u8, - &mut unit_field_val as *mut u32 as *mut u8, - 3usize, - ) - }; - let mask = 0xff0000 as u32; - let val = (unit_field_val & mask) >> 16usize; - unsafe { ::std::mem::transmute(val as u16) } + unsafe { ::std::mem::transmute(self._bitfield_1.get(16usize, 8u8) as u16) } } #[inline] pub fn set_nYear(&mut self, val: ::std::os::raw::c_ushort) { - let mask = 0xff0000 as u32; - let val = val as u16 as u32; - let mut unit_field_val: u32 = unsafe { ::std::mem::uninitialized() }; unsafe { - ::std::ptr::copy_nonoverlapping( - &self._bitfield_1 as *const _ as *const u8, - &mut unit_field_val as *mut u32 as *mut u8, - 3usize, - ) - }; - unit_field_val &= !mask; - unit_field_val |= (val << 16usize) & mask; - unsafe { - ::std::ptr::copy_nonoverlapping( - &unit_field_val as *const _ as *const u8, - &mut self._bitfield_1 as *mut _ as *mut u8, - 3usize, - ); + let val: u16 = ::std::mem::transmute(val); + self._bitfield_1.set(16usize, 8u8, val as u64) } } #[inline] @@ -799,17 +485,32 @@ impl Date1 { 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) & (0x7 as u32)) - | ((nMonthDay as u16 as u32) << 3usize) & (0x1f8 as u32)) - | ((nMonth as u16 as u32) << 9usize) & (0x3e00 as u32)) - | ((nYear as u16 as u32) << 16usize) & (0xff0000 as u32)) + ) -> __BindgenBitfieldUnit<[u8; 3usize], u8> { + let mut __bindgen_bitfield_unit: __BindgenBitfieldUnit<[u8; 3usize], u8> = + Default::default(); + __bindgen_bitfield_unit.set(0usize, 3u8, { + let nWeekDay: u16 = unsafe { ::std::mem::transmute(nWeekDay) }; + nWeekDay as u64 + }); + __bindgen_bitfield_unit.set(3usize, 6u8, { + let nMonthDay: u16 = unsafe { ::std::mem::transmute(nMonthDay) }; + nMonthDay as u64 + }); + __bindgen_bitfield_unit.set(9usize, 5u8, { + let nMonth: u16 = unsafe { ::std::mem::transmute(nMonth) }; + nMonth as u64 + }); + __bindgen_bitfield_unit.set(16usize, 8u8, { + let nYear: u16 = unsafe { ::std::mem::transmute(nYear) }; + nYear as u64 + }); + __bindgen_bitfield_unit } } #[repr(C)] #[derive(Debug, Default, Copy, Clone)] pub struct Date2 { - pub _bitfield_1: [u8; 4usize], + pub _bitfield_1: __BindgenBitfieldUnit<[u8; 4usize], u8>, pub __bindgen_align: [u16; 0usize], } #[test] @@ -828,182 +529,57 @@ fn bindgen_test_layout_Date2() { impl Date2 { #[inline] pub fn nWeekDay(&self) -> ::std::os::raw::c_ushort { - let mut unit_field_val: u32 = unsafe { ::std::mem::uninitialized() }; - unsafe { - ::std::ptr::copy_nonoverlapping( - &self._bitfield_1 as *const _ as *const u8, - &mut unit_field_val as *mut u32 as *mut u8, - 4usize, - ) - }; - let mask = 0x7 as u32; - let val = (unit_field_val & mask) >> 0usize; - unsafe { ::std::mem::transmute(val as u16) } + unsafe { ::std::mem::transmute(self._bitfield_1.get(0usize, 3u8) as u16) } } #[inline] pub fn set_nWeekDay(&mut self, val: ::std::os::raw::c_ushort) { - let mask = 0x7 as u32; - let val = val as u16 as u32; - let mut unit_field_val: u32 = unsafe { ::std::mem::uninitialized() }; - unsafe { - ::std::ptr::copy_nonoverlapping( - &self._bitfield_1 as *const _ as *const u8, - &mut unit_field_val as *mut u32 as *mut u8, - 4usize, - ) - }; - unit_field_val &= !mask; - unit_field_val |= (val << 0usize) & mask; unsafe { - ::std::ptr::copy_nonoverlapping( - &unit_field_val as *const _ as *const u8, - &mut self._bitfield_1 as *mut _ as *mut u8, - 4usize, - ); + let val: u16 = ::std::mem::transmute(val); + self._bitfield_1.set(0usize, 3u8, val as u64) } } #[inline] pub fn nMonthDay(&self) -> ::std::os::raw::c_ushort { - let mut unit_field_val: u32 = unsafe { ::std::mem::uninitialized() }; - unsafe { - ::std::ptr::copy_nonoverlapping( - &self._bitfield_1 as *const _ as *const u8, - &mut unit_field_val as *mut u32 as *mut u8, - 4usize, - ) - }; - let mask = 0x1f8 as u32; - let val = (unit_field_val & mask) >> 3usize; - unsafe { ::std::mem::transmute(val as u16) } + unsafe { ::std::mem::transmute(self._bitfield_1.get(3usize, 6u8) as u16) } } #[inline] pub fn set_nMonthDay(&mut self, val: ::std::os::raw::c_ushort) { - let mask = 0x1f8 as u32; - let val = val as u16 as u32; - let mut unit_field_val: u32 = unsafe { ::std::mem::uninitialized() }; - unsafe { - ::std::ptr::copy_nonoverlapping( - &self._bitfield_1 as *const _ as *const u8, - &mut unit_field_val as *mut u32 as *mut u8, - 4usize, - ) - }; - unit_field_val &= !mask; - unit_field_val |= (val << 3usize) & mask; unsafe { - ::std::ptr::copy_nonoverlapping( - &unit_field_val as *const _ as *const u8, - &mut self._bitfield_1 as *mut _ as *mut u8, - 4usize, - ); + let val: u16 = ::std::mem::transmute(val); + self._bitfield_1.set(3usize, 6u8, val as u64) } } #[inline] pub fn nMonth(&self) -> ::std::os::raw::c_ushort { - let mut unit_field_val: u32 = unsafe { ::std::mem::uninitialized() }; - unsafe { - ::std::ptr::copy_nonoverlapping( - &self._bitfield_1 as *const _ as *const u8, - &mut unit_field_val as *mut u32 as *mut u8, - 4usize, - ) - }; - let mask = 0x3e00 as u32; - let val = (unit_field_val & mask) >> 9usize; - unsafe { ::std::mem::transmute(val as u16) } + unsafe { ::std::mem::transmute(self._bitfield_1.get(9usize, 5u8) as u16) } } #[inline] pub fn set_nMonth(&mut self, val: ::std::os::raw::c_ushort) { - let mask = 0x3e00 as u32; - let val = val as u16 as u32; - let mut unit_field_val: u32 = unsafe { ::std::mem::uninitialized() }; unsafe { - ::std::ptr::copy_nonoverlapping( - &self._bitfield_1 as *const _ as *const u8, - &mut unit_field_val as *mut u32 as *mut u8, - 4usize, - ) - }; - unit_field_val &= !mask; - unit_field_val |= (val << 9usize) & mask; - unsafe { - ::std::ptr::copy_nonoverlapping( - &unit_field_val as *const _ as *const u8, - &mut self._bitfield_1 as *mut _ as *mut u8, - 4usize, - ); + let val: u16 = ::std::mem::transmute(val); + self._bitfield_1.set(9usize, 5u8, val as u64) } } #[inline] pub fn nYear(&self) -> ::std::os::raw::c_ushort { - let mut unit_field_val: u32 = unsafe { ::std::mem::uninitialized() }; - unsafe { - ::std::ptr::copy_nonoverlapping( - &self._bitfield_1 as *const _ as *const u8, - &mut unit_field_val as *mut u32 as *mut u8, - 4usize, - ) - }; - let mask = 0xff0000 as u32; - let val = (unit_field_val & mask) >> 16usize; - unsafe { ::std::mem::transmute(val as u16) } + unsafe { ::std::mem::transmute(self._bitfield_1.get(16usize, 8u8) as u16) } } #[inline] pub fn set_nYear(&mut self, val: ::std::os::raw::c_ushort) { - let mask = 0xff0000 as u32; - let val = val as u16 as u32; - let mut unit_field_val: u32 = unsafe { ::std::mem::uninitialized() }; unsafe { - ::std::ptr::copy_nonoverlapping( - &self._bitfield_1 as *const _ as *const u8, - &mut unit_field_val as *mut u32 as *mut u8, - 4usize, - ) - }; - unit_field_val &= !mask; - unit_field_val |= (val << 16usize) & mask; - unsafe { - ::std::ptr::copy_nonoverlapping( - &unit_field_val as *const _ as *const u8, - &mut self._bitfield_1 as *mut _ as *mut u8, - 4usize, - ); + let val: u16 = ::std::mem::transmute(val); + self._bitfield_1.set(16usize, 8u8, val as u64) } } #[inline] pub fn byte(&self) -> ::std::os::raw::c_uchar { - let mut unit_field_val: u32 = unsafe { ::std::mem::uninitialized() }; - unsafe { - ::std::ptr::copy_nonoverlapping( - &self._bitfield_1 as *const _ as *const u8, - &mut unit_field_val as *mut u32 as *mut u8, - 4usize, - ) - }; - let mask = 0xff000000 as u32; - let val = (unit_field_val & mask) >> 24usize; - unsafe { ::std::mem::transmute(val as u8) } + unsafe { ::std::mem::transmute(self._bitfield_1.get(24usize, 8u8) as u8) } } #[inline] pub fn set_byte(&mut self, val: ::std::os::raw::c_uchar) { - let mask = 0xff000000 as u32; - let val = val as u8 as u32; - let mut unit_field_val: u32 = unsafe { ::std::mem::uninitialized() }; - unsafe { - ::std::ptr::copy_nonoverlapping( - &self._bitfield_1 as *const _ as *const u8, - &mut unit_field_val as *mut u32 as *mut u8, - 4usize, - ) - }; - unit_field_val &= !mask; - unit_field_val |= (val << 24usize) & mask; unsafe { - ::std::ptr::copy_nonoverlapping( - &unit_field_val as *const _ as *const u8, - &mut self._bitfield_1 as *mut _ as *mut u8, - 4usize, - ); + let val: u8 = ::std::mem::transmute(val); + self._bitfield_1.set(24usize, 8u8, val as u64) } } #[inline] @@ -1013,18 +589,36 @@ impl Date2 { 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) & (0x7 as u32)) - | ((nMonthDay as u16 as u32) << 3usize) & (0x1f8 as u32)) - | ((nMonth as u16 as u32) << 9usize) & (0x3e00 as u32)) - | ((nYear as u16 as u32) << 16usize) & (0xff0000 as u32)) - | ((byte as u8 as u32) << 24usize) & (0xff000000 as u32)) + ) -> __BindgenBitfieldUnit<[u8; 4usize], u8> { + let mut __bindgen_bitfield_unit: __BindgenBitfieldUnit<[u8; 4usize], u8> = + Default::default(); + __bindgen_bitfield_unit.set(0usize, 3u8, { + let nWeekDay: u16 = unsafe { ::std::mem::transmute(nWeekDay) }; + nWeekDay as u64 + }); + __bindgen_bitfield_unit.set(3usize, 6u8, { + let nMonthDay: u16 = unsafe { ::std::mem::transmute(nMonthDay) }; + nMonthDay as u64 + }); + __bindgen_bitfield_unit.set(9usize, 5u8, { + let nMonth: u16 = unsafe { ::std::mem::transmute(nMonth) }; + nMonth as u64 + }); + __bindgen_bitfield_unit.set(16usize, 8u8, { + let nYear: u16 = unsafe { ::std::mem::transmute(nYear) }; + nYear as u64 + }); + __bindgen_bitfield_unit.set(24usize, 8u8, { + let byte: u8 = unsafe { ::std::mem::transmute(byte) }; + byte as u64 + }); + __bindgen_bitfield_unit } } #[repr(C)] #[derive(Debug, Default, Copy, Clone)] pub struct Date3 { - pub _bitfield_1: [u8; 3usize], + pub _bitfield_1: __BindgenBitfieldUnit<[u8; 3usize], u8>, pub byte: ::std::os::raw::c_uchar, pub __bindgen_align: [u16; 0usize], } @@ -1054,146 +648,46 @@ fn bindgen_test_layout_Date3() { impl Date3 { #[inline] pub fn nWeekDay(&self) -> ::std::os::raw::c_ushort { - let mut unit_field_val: u32 = unsafe { ::std::mem::uninitialized() }; - unsafe { - ::std::ptr::copy_nonoverlapping( - &self._bitfield_1 as *const _ as *const u8, - &mut unit_field_val as *mut u32 as *mut u8, - 3usize, - ) - }; - let mask = 0x7 as u32; - let val = (unit_field_val & mask) >> 0usize; - unsafe { ::std::mem::transmute(val as u16) } + unsafe { ::std::mem::transmute(self._bitfield_1.get(0usize, 3u8) as u16) } } #[inline] pub fn set_nWeekDay(&mut self, val: ::std::os::raw::c_ushort) { - let mask = 0x7 as u32; - let val = val as u16 as u32; - let mut unit_field_val: u32 = unsafe { ::std::mem::uninitialized() }; - unsafe { - ::std::ptr::copy_nonoverlapping( - &self._bitfield_1 as *const _ as *const u8, - &mut unit_field_val as *mut u32 as *mut u8, - 3usize, - ) - }; - unit_field_val &= !mask; - unit_field_val |= (val << 0usize) & mask; unsafe { - ::std::ptr::copy_nonoverlapping( - &unit_field_val as *const _ as *const u8, - &mut self._bitfield_1 as *mut _ as *mut u8, - 3usize, - ); + let val: u16 = ::std::mem::transmute(val); + self._bitfield_1.set(0usize, 3u8, val as u64) } } #[inline] pub fn nMonthDay(&self) -> ::std::os::raw::c_ushort { - let mut unit_field_val: u32 = unsafe { ::std::mem::uninitialized() }; - unsafe { - ::std::ptr::copy_nonoverlapping( - &self._bitfield_1 as *const _ as *const u8, - &mut unit_field_val as *mut u32 as *mut u8, - 3usize, - ) - }; - let mask = 0x1f8 as u32; - let val = (unit_field_val & mask) >> 3usize; - unsafe { ::std::mem::transmute(val as u16) } + unsafe { ::std::mem::transmute(self._bitfield_1.get(3usize, 6u8) as u16) } } #[inline] pub fn set_nMonthDay(&mut self, val: ::std::os::raw::c_ushort) { - let mask = 0x1f8 as u32; - let val = val as u16 as u32; - let mut unit_field_val: u32 = unsafe { ::std::mem::uninitialized() }; unsafe { - ::std::ptr::copy_nonoverlapping( - &self._bitfield_1 as *const _ as *const u8, - &mut unit_field_val as *mut u32 as *mut u8, - 3usize, - ) - }; - unit_field_val &= !mask; - unit_field_val |= (val << 3usize) & mask; - unsafe { - ::std::ptr::copy_nonoverlapping( - &unit_field_val as *const _ as *const u8, - &mut self._bitfield_1 as *mut _ as *mut u8, - 3usize, - ); + let val: u16 = ::std::mem::transmute(val); + self._bitfield_1.set(3usize, 6u8, val as u64) } } #[inline] pub fn nMonth(&self) -> ::std::os::raw::c_ushort { - let mut unit_field_val: u32 = unsafe { ::std::mem::uninitialized() }; - unsafe { - ::std::ptr::copy_nonoverlapping( - &self._bitfield_1 as *const _ as *const u8, - &mut unit_field_val as *mut u32 as *mut u8, - 3usize, - ) - }; - let mask = 0x3e00 as u32; - let val = (unit_field_val & mask) >> 9usize; - unsafe { ::std::mem::transmute(val as u16) } + unsafe { ::std::mem::transmute(self._bitfield_1.get(9usize, 5u8) as u16) } } #[inline] pub fn set_nMonth(&mut self, val: ::std::os::raw::c_ushort) { - let mask = 0x3e00 as u32; - let val = val as u16 as u32; - let mut unit_field_val: u32 = unsafe { ::std::mem::uninitialized() }; - unsafe { - ::std::ptr::copy_nonoverlapping( - &self._bitfield_1 as *const _ as *const u8, - &mut unit_field_val as *mut u32 as *mut u8, - 3usize, - ) - }; - unit_field_val &= !mask; - unit_field_val |= (val << 9usize) & mask; unsafe { - ::std::ptr::copy_nonoverlapping( - &unit_field_val as *const _ as *const u8, - &mut self._bitfield_1 as *mut _ as *mut u8, - 3usize, - ); + let val: u16 = ::std::mem::transmute(val); + self._bitfield_1.set(9usize, 5u8, val as u64) } } #[inline] pub fn nYear(&self) -> ::std::os::raw::c_ushort { - let mut unit_field_val: u32 = unsafe { ::std::mem::uninitialized() }; - unsafe { - ::std::ptr::copy_nonoverlapping( - &self._bitfield_1 as *const _ as *const u8, - &mut unit_field_val as *mut u32 as *mut u8, - 3usize, - ) - }; - let mask = 0xff0000 as u32; - let val = (unit_field_val & mask) >> 16usize; - unsafe { ::std::mem::transmute(val as u16) } + unsafe { ::std::mem::transmute(self._bitfield_1.get(16usize, 8u8) as u16) } } #[inline] pub fn set_nYear(&mut self, val: ::std::os::raw::c_ushort) { - let mask = 0xff0000 as u32; - let val = val as u16 as u32; - let mut unit_field_val: u32 = unsafe { ::std::mem::uninitialized() }; - unsafe { - ::std::ptr::copy_nonoverlapping( - &self._bitfield_1 as *const _ as *const u8, - &mut unit_field_val as *mut u32 as *mut u8, - 3usize, - ) - }; - unit_field_val &= !mask; - unit_field_val |= (val << 16usize) & mask; unsafe { - ::std::ptr::copy_nonoverlapping( - &unit_field_val as *const _ as *const u8, - &mut self._bitfield_1 as *mut _ as *mut u8, - 3usize, - ); + let val: u16 = ::std::mem::transmute(val); + self._bitfield_1.set(16usize, 8u8, val as u64) } } #[inline] @@ -1202,10 +696,25 @@ impl Date3 { 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) & (0x7 as u32)) - | ((nMonthDay as u16 as u32) << 3usize) & (0x1f8 as u32)) - | ((nMonth as u16 as u32) << 9usize) & (0x3e00 as u32)) - | ((nYear as u16 as u32) << 16usize) & (0xff0000 as u32)) + ) -> __BindgenBitfieldUnit<[u8; 3usize], u8> { + let mut __bindgen_bitfield_unit: __BindgenBitfieldUnit<[u8; 3usize], u8> = + Default::default(); + __bindgen_bitfield_unit.set(0usize, 3u8, { + let nWeekDay: u16 = unsafe { ::std::mem::transmute(nWeekDay) }; + nWeekDay as u64 + }); + __bindgen_bitfield_unit.set(3usize, 6u8, { + let nMonthDay: u16 = unsafe { ::std::mem::transmute(nMonthDay) }; + nMonthDay as u64 + }); + __bindgen_bitfield_unit.set(9usize, 5u8, { + let nMonth: u16 = unsafe { ::std::mem::transmute(nMonth) }; + nMonth as u64 + }); + __bindgen_bitfield_unit.set(16usize, 8u8, { + let nYear: u16 = unsafe { ::std::mem::transmute(nYear) }; + nYear as u64 + }); + __bindgen_bitfield_unit } } diff --git a/tests/expectations/tests/bitfield_align_2.rs b/tests/expectations/tests/bitfield_align_2.rs index f1f21fa03d..6f4a0f693e 100644 --- a/tests/expectations/tests/bitfield_align_2.rs +++ b/tests/expectations/tests/bitfield_align_2.rs @@ -4,6 +4,85 @@ #![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] +#[repr(C)] +#[derive(Copy, Clone, Debug, Default, Eq, Hash, Ord, PartialEq, PartialOrd)] +pub struct __BindgenBitfieldUnit +where + Storage: AsRef<[u8]> + AsMut<[u8]>, +{ + storage: Storage, + align: [Align; 0], +} + +impl __BindgenBitfieldUnit +where + Storage: AsRef<[u8]> + AsMut<[u8]>, +{ + #[inline] + pub fn new(storage: Storage) -> Self { + Self { storage, align: [] } + } + + #[inline] + pub fn get_bit(&self, index: usize) -> bool { + debug_assert!(index / 8 < self.storage.as_ref().len()); + + let byte_index = index / 8; + let byte = self.storage.as_ref()[byte_index]; + + let bit_index = index % 8; + let mask = 1 << bit_index; + + byte & mask == mask + } + + #[inline] + pub fn set_bit(&mut self, index: usize, val: bool) { + debug_assert!(index / 8 < self.storage.as_ref().len()); + + let byte_index = index / 8; + let byte = &mut self.storage.as_mut()[byte_index]; + + let bit_index = index % 8; + let mask = 1 << bit_index; + + if val { + *byte |= mask; + } else { + *byte &= !mask; + } + } + + #[inline] + pub fn get(&self, bit_offset: usize, bit_width: u8) -> u64 { + debug_assert!(bit_width <= 64); + debug_assert!(bit_offset / 8 < self.storage.as_ref().len()); + debug_assert!((bit_offset + (bit_width as usize)) / 8 <= self.storage.as_ref().len()); + + let mut val = 0; + + for i in 0..(bit_width as usize) { + if self.get_bit(i + bit_offset) { + val |= 1 << i; + } + } + + val + } + + #[inline] + pub fn set(&mut self, bit_offset: usize, bit_width: u8, val: u64) { + debug_assert!(bit_width <= 64); + debug_assert!(bit_offset / 8 < self.storage.as_ref().len()); + debug_assert!((bit_offset + (bit_width as usize)) / 8 <= self.storage.as_ref().len()); + + for i in 0..(bit_width as usize) { + let mask = 1 << i; + let val_bit_is_set = val & mask == mask; + self.set_bit(i + bit_offset, val_bit_is_set); + } + } +} #[repr(u32)] #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)] pub enum MyEnum { @@ -15,7 +94,7 @@ pub enum MyEnum { #[repr(C)] #[derive(Debug, Copy, Clone)] pub struct TaggedPtr { - pub _bitfield_1: u64, + pub _bitfield_1: __BindgenBitfieldUnit<[u8; 8usize], u64>, pub __bindgen_align: [u64; 0usize], } #[test] @@ -39,79 +118,41 @@ impl Default for TaggedPtr { impl TaggedPtr { #[inline] pub fn tag(&self) -> MyEnum { - let mut unit_field_val: u64 = unsafe { ::std::mem::uninitialized() }; - unsafe { - ::std::ptr::copy_nonoverlapping( - &self._bitfield_1 as *const _ as *const u8, - &mut unit_field_val as *mut u64 as *mut u8, - 8usize, - ) - }; - let mask = 0x3 as u64; - let val = (unit_field_val & mask) >> 0usize; - unsafe { ::std::mem::transmute(val as u32) } + unsafe { ::std::mem::transmute(self._bitfield_1.get(0usize, 2u8) as u32) } } #[inline] pub fn set_tag(&mut self, val: MyEnum) { - let mask = 0x3 as u64; - let val = val as u32 as u64; - let mut unit_field_val: u64 = unsafe { ::std::mem::uninitialized() }; - unsafe { - ::std::ptr::copy_nonoverlapping( - &self._bitfield_1 as *const _ as *const u8, - &mut unit_field_val as *mut u64 as *mut u8, - 8usize, - ) - }; - unit_field_val &= !mask; - unit_field_val |= (val << 0usize) & mask; unsafe { - ::std::ptr::copy_nonoverlapping( - &unit_field_val as *const _ as *const u8, - &mut self._bitfield_1 as *mut _ as *mut u8, - 8usize, - ); + let val: u32 = ::std::mem::transmute(val); + self._bitfield_1.set(0usize, 2u8, val as u64) } } #[inline] pub fn ptr(&self) -> ::std::os::raw::c_long { - let mut unit_field_val: u64 = unsafe { ::std::mem::uninitialized() }; - unsafe { - ::std::ptr::copy_nonoverlapping( - &self._bitfield_1 as *const _ as *const u8, - &mut unit_field_val as *mut u64 as *mut u8, - 8usize, - ) - }; - let mask = 0xfffffffffffffffc as u64; - let val = (unit_field_val & mask) >> 2usize; - unsafe { ::std::mem::transmute(val as u64) } + unsafe { ::std::mem::transmute(self._bitfield_1.get(2usize, 62u8) as u64) } } #[inline] pub fn set_ptr(&mut self, val: ::std::os::raw::c_long) { - let mask = 0xfffffffffffffffc as u64; - let val = val as u64 as u64; - let mut unit_field_val: u64 = unsafe { ::std::mem::uninitialized() }; - unsafe { - ::std::ptr::copy_nonoverlapping( - &self._bitfield_1 as *const _ as *const u8, - &mut unit_field_val as *mut u64 as *mut u8, - 8usize, - ) - }; - unit_field_val &= !mask; - unit_field_val |= (val << 2usize) & mask; unsafe { - ::std::ptr::copy_nonoverlapping( - &unit_field_val as *const _ as *const u8, - &mut self._bitfield_1 as *mut _ as *mut u8, - 8usize, - ); + let val: u64 = ::std::mem::transmute(val); + self._bitfield_1.set(2usize, 62u8, val as u64) } } #[inline] - pub fn new_bitfield_1(tag: MyEnum, ptr: ::std::os::raw::c_long) -> u64 { - ((0 | ((tag as u32 as u64) << 0usize) & (0x3 as u64)) - | ((ptr as u64 as u64) << 2usize) & (0xfffffffffffffffc as u64)) + pub fn new_bitfield_1( + tag: MyEnum, + ptr: ::std::os::raw::c_long, + ) -> __BindgenBitfieldUnit<[u8; 8usize], u64> { + let mut __bindgen_bitfield_unit: __BindgenBitfieldUnit<[u8; 8usize], u64> = + Default::default(); + __bindgen_bitfield_unit.set(0usize, 2u8, { + let tag: u32 = unsafe { ::std::mem::transmute(tag) }; + tag as u64 + }); + __bindgen_bitfield_unit.set(2usize, 62u8, { + let ptr: u64 = unsafe { ::std::mem::transmute(ptr) }; + ptr as u64 + }); + __bindgen_bitfield_unit } } diff --git a/tests/expectations/tests/bitfield_method_mangling.rs b/tests/expectations/tests/bitfield_method_mangling.rs index e64a166a57..e557f92b2d 100644 --- a/tests/expectations/tests/bitfield_method_mangling.rs +++ b/tests/expectations/tests/bitfield_method_mangling.rs @@ -4,10 +4,89 @@ #![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] +#[repr(C)] +#[derive(Copy, Clone, Debug, Default, Eq, Hash, Ord, PartialEq, PartialOrd)] +pub struct __BindgenBitfieldUnit +where + Storage: AsRef<[u8]> + AsMut<[u8]>, +{ + storage: Storage, + align: [Align; 0], +} + +impl __BindgenBitfieldUnit +where + Storage: AsRef<[u8]> + AsMut<[u8]>, +{ + #[inline] + pub fn new(storage: Storage) -> Self { + Self { storage, align: [] } + } + + #[inline] + pub fn get_bit(&self, index: usize) -> bool { + debug_assert!(index / 8 < self.storage.as_ref().len()); + + let byte_index = index / 8; + let byte = self.storage.as_ref()[byte_index]; + + let bit_index = index % 8; + let mask = 1 << bit_index; + + byte & mask == mask + } + + #[inline] + pub fn set_bit(&mut self, index: usize, val: bool) { + debug_assert!(index / 8 < self.storage.as_ref().len()); + + let byte_index = index / 8; + let byte = &mut self.storage.as_mut()[byte_index]; + + let bit_index = index % 8; + let mask = 1 << bit_index; + + if val { + *byte |= mask; + } else { + *byte &= !mask; + } + } + + #[inline] + pub fn get(&self, bit_offset: usize, bit_width: u8) -> u64 { + debug_assert!(bit_width <= 64); + debug_assert!(bit_offset / 8 < self.storage.as_ref().len()); + debug_assert!((bit_offset + (bit_width as usize)) / 8 <= self.storage.as_ref().len()); + + let mut val = 0; + + for i in 0..(bit_width as usize) { + if self.get_bit(i + bit_offset) { + val |= 1 << i; + } + } + + val + } + + #[inline] + pub fn set(&mut self, bit_offset: usize, bit_width: u8, val: u64) { + debug_assert!(bit_width <= 64); + debug_assert!(bit_offset / 8 < self.storage.as_ref().len()); + debug_assert!((bit_offset + (bit_width as usize)) / 8 <= self.storage.as_ref().len()); + + for i in 0..(bit_width as usize) { + let mask = 1 << i; + let val_bit_is_set = val & mask == mask; + self.set_bit(i + bit_offset, val_bit_is_set); + } + } +} #[repr(C)] #[derive(Debug, Default, Copy, Clone)] pub struct mach_msg_type_descriptor_t { - pub _bitfield_1: u32, + pub _bitfield_1: __BindgenBitfieldUnit<[u8; 4usize], u32>, pub __bindgen_align: [u32; 0usize], } #[test] @@ -26,79 +105,41 @@ fn bindgen_test_layout_mach_msg_type_descriptor_t() { impl mach_msg_type_descriptor_t { #[inline] pub fn pad3(&self) -> ::std::os::raw::c_uint { - let mut unit_field_val: u32 = unsafe { ::std::mem::uninitialized() }; - unsafe { - ::std::ptr::copy_nonoverlapping( - &self._bitfield_1 as *const _ as *const u8, - &mut unit_field_val as *mut u32 as *mut u8, - 4usize, - ) - }; - let mask = 0xffffff as u32; - let val = (unit_field_val & mask) >> 0usize; - unsafe { ::std::mem::transmute(val as u32) } + unsafe { ::std::mem::transmute(self._bitfield_1.get(0usize, 24u8) as u32) } } #[inline] pub fn set_pad3(&mut self, val: ::std::os::raw::c_uint) { - let mask = 0xffffff as u32; - let val = val as u32 as u32; - let mut unit_field_val: u32 = unsafe { ::std::mem::uninitialized() }; - unsafe { - ::std::ptr::copy_nonoverlapping( - &self._bitfield_1 as *const _ as *const u8, - &mut unit_field_val as *mut u32 as *mut u8, - 4usize, - ) - }; - unit_field_val &= !mask; - unit_field_val |= (val << 0usize) & mask; unsafe { - ::std::ptr::copy_nonoverlapping( - &unit_field_val as *const _ as *const u8, - &mut self._bitfield_1 as *mut _ as *mut u8, - 4usize, - ); + let val: u32 = ::std::mem::transmute(val); + self._bitfield_1.set(0usize, 24u8, val as u64) } } #[inline] pub fn type_(&self) -> ::std::os::raw::c_uint { - let mut unit_field_val: u32 = unsafe { ::std::mem::uninitialized() }; - unsafe { - ::std::ptr::copy_nonoverlapping( - &self._bitfield_1 as *const _ as *const u8, - &mut unit_field_val as *mut u32 as *mut u8, - 4usize, - ) - }; - let mask = 0xff000000 as u32; - let val = (unit_field_val & mask) >> 24usize; - unsafe { ::std::mem::transmute(val as u32) } + unsafe { ::std::mem::transmute(self._bitfield_1.get(24usize, 8u8) as u32) } } #[inline] pub fn set_type(&mut self, val: ::std::os::raw::c_uint) { - let mask = 0xff000000 as u32; - let val = val as u32 as u32; - let mut unit_field_val: u32 = unsafe { ::std::mem::uninitialized() }; - unsafe { - ::std::ptr::copy_nonoverlapping( - &self._bitfield_1 as *const _ as *const u8, - &mut unit_field_val as *mut u32 as *mut u8, - 4usize, - ) - }; - unit_field_val &= !mask; - unit_field_val |= (val << 24usize) & mask; unsafe { - ::std::ptr::copy_nonoverlapping( - &unit_field_val as *const _ as *const u8, - &mut self._bitfield_1 as *mut _ as *mut u8, - 4usize, - ); + let val: u32 = ::std::mem::transmute(val); + self._bitfield_1.set(24usize, 8u8, val as u64) } } #[inline] - pub fn new_bitfield_1(pad3: ::std::os::raw::c_uint, type_: ::std::os::raw::c_uint) -> u32 { - ((0 | ((pad3 as u32 as u32) << 0usize) & (0xffffff as u32)) - | ((type_ as u32 as u32) << 24usize) & (0xff000000 as u32)) + pub fn new_bitfield_1( + pad3: ::std::os::raw::c_uint, + type_: ::std::os::raw::c_uint, + ) -> __BindgenBitfieldUnit<[u8; 4usize], u32> { + let mut __bindgen_bitfield_unit: __BindgenBitfieldUnit<[u8; 4usize], u32> = + Default::default(); + __bindgen_bitfield_unit.set(0usize, 24u8, { + let pad3: u32 = unsafe { ::std::mem::transmute(pad3) }; + pad3 as u64 + }); + __bindgen_bitfield_unit.set(24usize, 8u8, { + let type_: u32 = unsafe { ::std::mem::transmute(type_) }; + type_ as u64 + }); + __bindgen_bitfield_unit } } diff --git a/tests/expectations/tests/derive-bitfield-method-same-name.rs b/tests/expectations/tests/derive-bitfield-method-same-name.rs index a3d9870d3a..f9d9d64bba 100644 --- a/tests/expectations/tests/derive-bitfield-method-same-name.rs +++ b/tests/expectations/tests/derive-bitfield-method-same-name.rs @@ -4,6 +4,85 @@ #![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] +#[repr(C)] +#[derive(Copy, Clone, Debug, Default, Eq, Hash, Ord, PartialEq, PartialOrd)] +pub struct __BindgenBitfieldUnit +where + Storage: AsRef<[u8]> + AsMut<[u8]>, +{ + storage: Storage, + align: [Align; 0], +} + +impl __BindgenBitfieldUnit +where + Storage: AsRef<[u8]> + AsMut<[u8]>, +{ + #[inline] + pub fn new(storage: Storage) -> Self { + Self { storage, align: [] } + } + + #[inline] + pub fn get_bit(&self, index: usize) -> bool { + debug_assert!(index / 8 < self.storage.as_ref().len()); + + let byte_index = index / 8; + let byte = self.storage.as_ref()[byte_index]; + + let bit_index = index % 8; + let mask = 1 << bit_index; + + byte & mask == mask + } + + #[inline] + pub fn set_bit(&mut self, index: usize, val: bool) { + debug_assert!(index / 8 < self.storage.as_ref().len()); + + let byte_index = index / 8; + let byte = &mut self.storage.as_mut()[byte_index]; + + let bit_index = index % 8; + let mask = 1 << bit_index; + + if val { + *byte |= mask; + } else { + *byte &= !mask; + } + } + + #[inline] + pub fn get(&self, bit_offset: usize, bit_width: u8) -> u64 { + debug_assert!(bit_width <= 64); + debug_assert!(bit_offset / 8 < self.storage.as_ref().len()); + debug_assert!((bit_offset + (bit_width as usize)) / 8 <= self.storage.as_ref().len()); + + let mut val = 0; + + for i in 0..(bit_width as usize) { + if self.get_bit(i + bit_offset) { + val |= 1 << i; + } + } + + val + } + + #[inline] + pub fn set(&mut self, bit_offset: usize, bit_width: u8, val: u64) { + debug_assert!(bit_width <= 64); + debug_assert!(bit_offset / 8 < self.storage.as_ref().len()); + debug_assert!((bit_offset + (bit_width as usize)) / 8 <= self.storage.as_ref().len()); + + for i in 0..(bit_width as usize) { + let mask = 1 << i; + let val_bit_is_set = val & mask == mask; + self.set_bit(i + bit_offset, val_bit_is_set); + } + } +} /// Because this struct have array larger than 32 items /// and --with-derive-partialeq --impl-partialeq --impl-debug is provided, @@ -12,7 +91,7 @@ #[derive(Copy, Clone)] pub struct Foo { pub large: [::std::os::raw::c_int; 33usize], - pub _bitfield_1: [u8; 2usize], + pub _bitfield_1: __BindgenBitfieldUnit<[u8; 2usize], u8>, pub __bindgen_padding_0: u16, } #[test] @@ -78,43 +157,27 @@ impl ::std::cmp::PartialEq for Foo { impl Foo { #[inline] pub fn type__bindgen_bitfield(&self) -> ::std::os::raw::c_char { - let mut unit_field_val: u16 = unsafe { ::std::mem::uninitialized() }; - unsafe { - ::std::ptr::copy_nonoverlapping( - &self._bitfield_1 as *const _ as *const u8, - &mut unit_field_val as *mut u16 as *mut u8, - 2usize, - ) - }; - let mask = 0x7 as u16; - let val = (unit_field_val & mask) >> 0usize; - unsafe { ::std::mem::transmute(val as u8) } + unsafe { ::std::mem::transmute(self._bitfield_1.get(0usize, 3u8) as u8) } } #[inline] pub fn set_type__bindgen_bitfield(&mut self, val: ::std::os::raw::c_char) { - let mask = 0x7 as u16; - let val = val as u8 as u16; - let mut unit_field_val: u16 = unsafe { ::std::mem::uninitialized() }; - unsafe { - ::std::ptr::copy_nonoverlapping( - &self._bitfield_1 as *const _ as *const u8, - &mut unit_field_val as *mut u16 as *mut u8, - 2usize, - ) - }; - unit_field_val &= !mask; - unit_field_val |= (val << 0usize) & mask; unsafe { - ::std::ptr::copy_nonoverlapping( - &unit_field_val as *const _ as *const u8, - &mut self._bitfield_1 as *mut _ as *mut u8, - 2usize, - ); + let val: u8 = ::std::mem::transmute(val); + self._bitfield_1.set(0usize, 3u8, val as u64) } } #[inline] - pub fn new_bitfield_1(type__bindgen_bitfield: ::std::os::raw::c_char) -> u16 { - (0 | ((type__bindgen_bitfield as u8 as u16) << 0usize) & (0x7 as u16)) + pub fn new_bitfield_1( + type__bindgen_bitfield: ::std::os::raw::c_char, + ) -> __BindgenBitfieldUnit<[u8; 2usize], u8> { + let mut __bindgen_bitfield_unit: __BindgenBitfieldUnit<[u8; 2usize], u8> = + Default::default(); + __bindgen_bitfield_unit.set(0usize, 3u8, { + let type__bindgen_bitfield: u8 = + unsafe { ::std::mem::transmute(type__bindgen_bitfield) }; + type__bindgen_bitfield as u64 + }); + __bindgen_bitfield_unit } #[inline] pub unsafe fn type_(&mut self) -> ::std::os::raw::c_char { diff --git a/tests/expectations/tests/derive-debug-bitfield.rs b/tests/expectations/tests/derive-debug-bitfield.rs index 33800ab269..3cabb58676 100644 --- a/tests/expectations/tests/derive-debug-bitfield.rs +++ b/tests/expectations/tests/derive-debug-bitfield.rs @@ -4,10 +4,89 @@ #![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] +#[repr(C)] +#[derive(Copy, Clone, Debug, Default, Eq, Hash, Ord, PartialEq, PartialOrd)] +pub struct __BindgenBitfieldUnit +where + Storage: AsRef<[u8]> + AsMut<[u8]>, +{ + storage: Storage, + align: [Align; 0], +} + +impl __BindgenBitfieldUnit +where + Storage: AsRef<[u8]> + AsMut<[u8]>, +{ + #[inline] + pub fn new(storage: Storage) -> Self { + Self { storage, align: [] } + } + + #[inline] + pub fn get_bit(&self, index: usize) -> bool { + debug_assert!(index / 8 < self.storage.as_ref().len()); + + let byte_index = index / 8; + let byte = self.storage.as_ref()[byte_index]; + + let bit_index = index % 8; + let mask = 1 << bit_index; + + byte & mask == mask + } + + #[inline] + pub fn set_bit(&mut self, index: usize, val: bool) { + debug_assert!(index / 8 < self.storage.as_ref().len()); + + let byte_index = index / 8; + let byte = &mut self.storage.as_mut()[byte_index]; + + let bit_index = index % 8; + let mask = 1 << bit_index; + + if val { + *byte |= mask; + } else { + *byte &= !mask; + } + } + + #[inline] + pub fn get(&self, bit_offset: usize, bit_width: u8) -> u64 { + debug_assert!(bit_width <= 64); + debug_assert!(bit_offset / 8 < self.storage.as_ref().len()); + debug_assert!((bit_offset + (bit_width as usize)) / 8 <= self.storage.as_ref().len()); + + let mut val = 0; + + for i in 0..(bit_width as usize) { + if self.get_bit(i + bit_offset) { + val |= 1 << i; + } + } + + val + } + + #[inline] + pub fn set(&mut self, bit_offset: usize, bit_width: u8, val: u64) { + debug_assert!(bit_width <= 64); + debug_assert!(bit_offset / 8 < self.storage.as_ref().len()); + debug_assert!((bit_offset + (bit_width as usize)) / 8 <= self.storage.as_ref().len()); + + for i in 0..(bit_width as usize) { + let mask = 1 << i; + let val_bit_is_set = val & mask == mask; + self.set_bit(i + bit_offset, val_bit_is_set); + } + } +} #[repr(C)] #[derive(Copy, Clone)] pub struct C { - pub _bitfield_1: u8, + pub _bitfield_1: __BindgenBitfieldUnit<[u8; 1usize], u8>, pub large_array: [::std::os::raw::c_int; 50usize], } #[test] @@ -56,79 +135,38 @@ impl ::std::fmt::Debug for C { impl C { #[inline] pub fn a(&self) -> bool { - let mut unit_field_val: u8 = unsafe { ::std::mem::uninitialized() }; - unsafe { - ::std::ptr::copy_nonoverlapping( - &self._bitfield_1 as *const _ as *const u8, - &mut unit_field_val as *mut u8 as *mut u8, - 1usize, - ) - }; - let mask = 0x1 as u8; - let val = (unit_field_val & mask) >> 0usize; - unsafe { ::std::mem::transmute(val as u8) } + unsafe { ::std::mem::transmute(self._bitfield_1.get(0usize, 1u8) as u8) } } #[inline] pub fn set_a(&mut self, val: bool) { - let mask = 0x1 as u8; - let val = val as u8 as u8; - let mut unit_field_val: u8 = unsafe { ::std::mem::uninitialized() }; - unsafe { - ::std::ptr::copy_nonoverlapping( - &self._bitfield_1 as *const _ as *const u8, - &mut unit_field_val as *mut u8 as *mut u8, - 1usize, - ) - }; - unit_field_val &= !mask; - unit_field_val |= (val << 0usize) & mask; unsafe { - ::std::ptr::copy_nonoverlapping( - &unit_field_val as *const _ as *const u8, - &mut self._bitfield_1 as *mut _ as *mut u8, - 1usize, - ); + let val: u8 = ::std::mem::transmute(val); + self._bitfield_1.set(0usize, 1u8, val as u64) } } #[inline] pub fn b(&self) -> bool { - let mut unit_field_val: u8 = unsafe { ::std::mem::uninitialized() }; - unsafe { - ::std::ptr::copy_nonoverlapping( - &self._bitfield_1 as *const _ as *const u8, - &mut unit_field_val as *mut u8 as *mut u8, - 1usize, - ) - }; - let mask = 0xfe as u8; - let val = (unit_field_val & mask) >> 1usize; - unsafe { ::std::mem::transmute(val as u8) } + unsafe { ::std::mem::transmute(self._bitfield_1.get(1usize, 7u8) as u8) } } #[inline] pub fn set_b(&mut self, val: bool) { - let mask = 0xfe as u8; - let val = val as u8 as u8; - let mut unit_field_val: u8 = unsafe { ::std::mem::uninitialized() }; - unsafe { - ::std::ptr::copy_nonoverlapping( - &self._bitfield_1 as *const _ as *const u8, - &mut unit_field_val as *mut u8 as *mut u8, - 1usize, - ) - }; - unit_field_val &= !mask; - unit_field_val |= (val << 1usize) & mask; unsafe { - ::std::ptr::copy_nonoverlapping( - &unit_field_val as *const _ as *const u8, - &mut self._bitfield_1 as *mut _ as *mut u8, - 1usize, - ); + let val: u8 = ::std::mem::transmute(val); + self._bitfield_1.set(1usize, 7u8, val as u64) } } #[inline] - pub fn new_bitfield_1(a: bool, b: bool) -> u8 { - ((0 | ((a as u8 as u8) << 0usize) & (0x1 as u8)) - | ((b as u8 as u8) << 1usize) & (0xfe as u8)) + pub fn new_bitfield_1(a: bool, b: bool) -> __BindgenBitfieldUnit<[u8; 1usize], u8> { + let mut __bindgen_bitfield_unit: __BindgenBitfieldUnit<[u8; 1usize], u8> = + Default::default(); + __bindgen_bitfield_unit.set(0usize, 1u8, { + let a: u8 = unsafe { ::std::mem::transmute(a) }; + a as u64 + }); + __bindgen_bitfield_unit.set(1usize, 7u8, { + let b: u8 = unsafe { ::std::mem::transmute(b) }; + b as u64 + }); + __bindgen_bitfield_unit } } diff --git a/tests/expectations/tests/derive-partialeq-bitfield.rs b/tests/expectations/tests/derive-partialeq-bitfield.rs index 4efb5981eb..98d3ee4405 100644 --- a/tests/expectations/tests/derive-partialeq-bitfield.rs +++ b/tests/expectations/tests/derive-partialeq-bitfield.rs @@ -4,10 +4,89 @@ #![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] +#[repr(C)] +#[derive(Copy, Clone, Debug, Default, Eq, Hash, Ord, PartialEq, PartialOrd)] +pub struct __BindgenBitfieldUnit +where + Storage: AsRef<[u8]> + AsMut<[u8]>, +{ + storage: Storage, + align: [Align; 0], +} + +impl __BindgenBitfieldUnit +where + Storage: AsRef<[u8]> + AsMut<[u8]>, +{ + #[inline] + pub fn new(storage: Storage) -> Self { + Self { storage, align: [] } + } + + #[inline] + pub fn get_bit(&self, index: usize) -> bool { + debug_assert!(index / 8 < self.storage.as_ref().len()); + + let byte_index = index / 8; + let byte = self.storage.as_ref()[byte_index]; + + let bit_index = index % 8; + let mask = 1 << bit_index; + + byte & mask == mask + } + + #[inline] + pub fn set_bit(&mut self, index: usize, val: bool) { + debug_assert!(index / 8 < self.storage.as_ref().len()); + + let byte_index = index / 8; + let byte = &mut self.storage.as_mut()[byte_index]; + + let bit_index = index % 8; + let mask = 1 << bit_index; + + if val { + *byte |= mask; + } else { + *byte &= !mask; + } + } + + #[inline] + pub fn get(&self, bit_offset: usize, bit_width: u8) -> u64 { + debug_assert!(bit_width <= 64); + debug_assert!(bit_offset / 8 < self.storage.as_ref().len()); + debug_assert!((bit_offset + (bit_width as usize)) / 8 <= self.storage.as_ref().len()); + + let mut val = 0; + + for i in 0..(bit_width as usize) { + if self.get_bit(i + bit_offset) { + val |= 1 << i; + } + } + + val + } + + #[inline] + pub fn set(&mut self, bit_offset: usize, bit_width: u8, val: u64) { + debug_assert!(bit_width <= 64); + debug_assert!(bit_offset / 8 < self.storage.as_ref().len()); + debug_assert!((bit_offset + (bit_width as usize)) / 8 <= self.storage.as_ref().len()); + + for i in 0..(bit_width as usize) { + let mask = 1 << i; + let val_bit_is_set = val & mask == mask; + self.set_bit(i + bit_offset, val_bit_is_set); + } + } +} #[repr(C)] #[derive(Copy, Clone)] pub struct C { - pub _bitfield_1: u8, + pub _bitfield_1: __BindgenBitfieldUnit<[u8; 1usize], u8>, pub large_array: [::std::os::raw::c_int; 50usize], } #[test] @@ -47,79 +126,38 @@ impl ::std::cmp::PartialEq for C { impl C { #[inline] pub fn a(&self) -> bool { - let mut unit_field_val: u8 = unsafe { ::std::mem::uninitialized() }; - unsafe { - ::std::ptr::copy_nonoverlapping( - &self._bitfield_1 as *const _ as *const u8, - &mut unit_field_val as *mut u8 as *mut u8, - 1usize, - ) - }; - let mask = 0x1 as u8; - let val = (unit_field_val & mask) >> 0usize; - unsafe { ::std::mem::transmute(val as u8) } + unsafe { ::std::mem::transmute(self._bitfield_1.get(0usize, 1u8) as u8) } } #[inline] pub fn set_a(&mut self, val: bool) { - let mask = 0x1 as u8; - let val = val as u8 as u8; - let mut unit_field_val: u8 = unsafe { ::std::mem::uninitialized() }; - unsafe { - ::std::ptr::copy_nonoverlapping( - &self._bitfield_1 as *const _ as *const u8, - &mut unit_field_val as *mut u8 as *mut u8, - 1usize, - ) - }; - unit_field_val &= !mask; - unit_field_val |= (val << 0usize) & mask; unsafe { - ::std::ptr::copy_nonoverlapping( - &unit_field_val as *const _ as *const u8, - &mut self._bitfield_1 as *mut _ as *mut u8, - 1usize, - ); + let val: u8 = ::std::mem::transmute(val); + self._bitfield_1.set(0usize, 1u8, val as u64) } } #[inline] pub fn b(&self) -> bool { - let mut unit_field_val: u8 = unsafe { ::std::mem::uninitialized() }; - unsafe { - ::std::ptr::copy_nonoverlapping( - &self._bitfield_1 as *const _ as *const u8, - &mut unit_field_val as *mut u8 as *mut u8, - 1usize, - ) - }; - let mask = 0xfe as u8; - let val = (unit_field_val & mask) >> 1usize; - unsafe { ::std::mem::transmute(val as u8) } + unsafe { ::std::mem::transmute(self._bitfield_1.get(1usize, 7u8) as u8) } } #[inline] pub fn set_b(&mut self, val: bool) { - let mask = 0xfe as u8; - let val = val as u8 as u8; - let mut unit_field_val: u8 = unsafe { ::std::mem::uninitialized() }; - unsafe { - ::std::ptr::copy_nonoverlapping( - &self._bitfield_1 as *const _ as *const u8, - &mut unit_field_val as *mut u8 as *mut u8, - 1usize, - ) - }; - unit_field_val &= !mask; - unit_field_val |= (val << 1usize) & mask; unsafe { - ::std::ptr::copy_nonoverlapping( - &unit_field_val as *const _ as *const u8, - &mut self._bitfield_1 as *mut _ as *mut u8, - 1usize, - ); + let val: u8 = ::std::mem::transmute(val); + self._bitfield_1.set(1usize, 7u8, val as u64) } } #[inline] - pub fn new_bitfield_1(a: bool, b: bool) -> u8 { - ((0 | ((a as u8 as u8) << 0usize) & (0x1 as u8)) - | ((b as u8 as u8) << 1usize) & (0xfe as u8)) + pub fn new_bitfield_1(a: bool, b: bool) -> __BindgenBitfieldUnit<[u8; 1usize], u8> { + let mut __bindgen_bitfield_unit: __BindgenBitfieldUnit<[u8; 1usize], u8> = + Default::default(); + __bindgen_bitfield_unit.set(0usize, 1u8, { + let a: u8 = unsafe { ::std::mem::transmute(a) }; + a as u64 + }); + __bindgen_bitfield_unit.set(1usize, 7u8, { + let b: u8 = unsafe { ::std::mem::transmute(b) }; + b as u64 + }); + __bindgen_bitfield_unit } } diff --git a/tests/expectations/tests/divide-by-zero-in-struct-layout.rs b/tests/expectations/tests/divide-by-zero-in-struct-layout.rs index 9fb429af12..9709332180 100644 --- a/tests/expectations/tests/divide-by-zero-in-struct-layout.rs +++ b/tests/expectations/tests/divide-by-zero-in-struct-layout.rs @@ -4,42 +4,127 @@ #![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] +#[repr(C)] +#[derive(Copy, Clone, Debug, Default, Eq, Hash, Ord, PartialEq, PartialOrd)] +pub struct __BindgenBitfieldUnit +where + Storage: AsRef<[u8]> + AsMut<[u8]>, +{ + storage: Storage, + align: [Align; 0], +} + +impl __BindgenBitfieldUnit +where + Storage: AsRef<[u8]> + AsMut<[u8]>, +{ + #[inline] + pub fn new(storage: Storage) -> Self { + Self { storage, align: [] } + } + + #[inline] + pub fn get_bit(&self, index: usize) -> bool { + debug_assert!(index / 8 < self.storage.as_ref().len()); + + let byte_index = index / 8; + let byte = self.storage.as_ref()[byte_index]; + + let bit_index = index % 8; + let mask = 1 << bit_index; + + byte & mask == mask + } + + #[inline] + pub fn set_bit(&mut self, index: usize, val: bool) { + debug_assert!(index / 8 < self.storage.as_ref().len()); + + let byte_index = index / 8; + let byte = &mut self.storage.as_mut()[byte_index]; + + let bit_index = index % 8; + let mask = 1 << bit_index; + + if val { + *byte |= mask; + } else { + *byte &= !mask; + } + } + + #[inline] + pub fn get(&self, bit_offset: usize, bit_width: u8) -> u64 { + debug_assert!(bit_width <= 64); + debug_assert!(bit_offset / 8 < self.storage.as_ref().len()); + debug_assert!((bit_offset + (bit_width as usize)) / 8 <= self.storage.as_ref().len()); + + let mut val = 0; + + for i in 0..(bit_width as usize) { + if self.get_bit(i + bit_offset) { + val |= 1 << i; + } + } + + val + } + + #[inline] + pub fn set(&mut self, bit_offset: usize, bit_width: u8, val: u64) { + debug_assert!(bit_width <= 64); + debug_assert!(bit_offset / 8 < self.storage.as_ref().len()); + debug_assert!((bit_offset + (bit_width as usize)) / 8 <= self.storage.as_ref().len()); + + for i in 0..(bit_width as usize) { + let mask = 1 << i; + let val_bit_is_set = val & mask == mask; + self.set_bit(i + bit_offset, val_bit_is_set); + } + } +} #[repr(C)] #[derive(Debug, Default, Copy, Clone)] pub struct WithBitfield { - pub _bitfield_1: [u8; 0usize], + pub _bitfield_1: __BindgenBitfieldUnit<[u8; 0usize], u8>, pub __bindgen_padding_0: u32, pub a: ::std::os::raw::c_uint, } impl WithBitfield { #[inline] - pub fn new_bitfield_1() -> u8 { - 0 + pub fn new_bitfield_1() -> __BindgenBitfieldUnit<[u8; 0usize], u8> { + let mut __bindgen_bitfield_unit: __BindgenBitfieldUnit<[u8; 0usize], u8> = + Default::default(); + __bindgen_bitfield_unit } } #[repr(C, packed)] #[derive(Debug, Default, Copy, Clone)] pub struct WithBitfieldAndAttrPacked { - pub _bitfield_1: [u8; 0usize], + pub _bitfield_1: __BindgenBitfieldUnit<[u8; 0usize], u8>, pub a: ::std::os::raw::c_uint, pub __bindgen_padding_0: u8, } impl WithBitfieldAndAttrPacked { #[inline] - pub fn new_bitfield_1() -> u8 { - 0 + pub fn new_bitfield_1() -> __BindgenBitfieldUnit<[u8; 0usize], u8> { + let mut __bindgen_bitfield_unit: __BindgenBitfieldUnit<[u8; 0usize], u8> = + Default::default(); + __bindgen_bitfield_unit } } #[repr(C, packed)] #[derive(Debug, Default, Copy, Clone)] pub struct WithBitfieldAndPacked { - pub _bitfield_1: [u8; 0usize], + pub _bitfield_1: __BindgenBitfieldUnit<[u8; 0usize], u8>, pub a: ::std::os::raw::c_uint, pub __bindgen_padding_0: u8, } impl WithBitfieldAndPacked { #[inline] - pub fn new_bitfield_1() -> u8 { - 0 + pub fn new_bitfield_1() -> __BindgenBitfieldUnit<[u8; 0usize], u8> { + let mut __bindgen_bitfield_unit: __BindgenBitfieldUnit<[u8; 0usize], u8> = + Default::default(); + __bindgen_bitfield_unit } } diff --git a/tests/expectations/tests/issue-1034.rs b/tests/expectations/tests/issue-1034.rs index b5c7d6bb16..687c430593 100644 --- a/tests/expectations/tests/issue-1034.rs +++ b/tests/expectations/tests/issue-1034.rs @@ -4,10 +4,89 @@ #![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] +#[repr(C)] +#[derive(Copy, Clone, Debug, Default, Eq, Hash, Ord, PartialEq, PartialOrd)] +pub struct __BindgenBitfieldUnit +where + Storage: AsRef<[u8]> + AsMut<[u8]>, +{ + storage: Storage, + align: [Align; 0], +} + +impl __BindgenBitfieldUnit +where + Storage: AsRef<[u8]> + AsMut<[u8]>, +{ + #[inline] + pub fn new(storage: Storage) -> Self { + Self { storage, align: [] } + } + + #[inline] + pub fn get_bit(&self, index: usize) -> bool { + debug_assert!(index / 8 < self.storage.as_ref().len()); + + let byte_index = index / 8; + let byte = self.storage.as_ref()[byte_index]; + + let bit_index = index % 8; + let mask = 1 << bit_index; + + byte & mask == mask + } + + #[inline] + pub fn set_bit(&mut self, index: usize, val: bool) { + debug_assert!(index / 8 < self.storage.as_ref().len()); + + let byte_index = index / 8; + let byte = &mut self.storage.as_mut()[byte_index]; + + let bit_index = index % 8; + let mask = 1 << bit_index; + + if val { + *byte |= mask; + } else { + *byte &= !mask; + } + } + + #[inline] + pub fn get(&self, bit_offset: usize, bit_width: u8) -> u64 { + debug_assert!(bit_width <= 64); + debug_assert!(bit_offset / 8 < self.storage.as_ref().len()); + debug_assert!((bit_offset + (bit_width as usize)) / 8 <= self.storage.as_ref().len()); + + let mut val = 0; + + for i in 0..(bit_width as usize) { + if self.get_bit(i + bit_offset) { + val |= 1 << i; + } + } + + val + } + + #[inline] + pub fn set(&mut self, bit_offset: usize, bit_width: u8, val: u64) { + debug_assert!(bit_width <= 64); + debug_assert!(bit_offset / 8 < self.storage.as_ref().len()); + debug_assert!((bit_offset + (bit_width as usize)) / 8 <= self.storage.as_ref().len()); + + for i in 0..(bit_width as usize) { + let mask = 1 << i; + let val_bit_is_set = val & mask == mask; + self.set_bit(i + bit_offset, val_bit_is_set); + } + } +} #[repr(C)] #[derive(Debug, Default, Copy, Clone)] pub struct S2 { - pub _bitfield_1: u8, + pub _bitfield_1: __BindgenBitfieldUnit<[u8; 1usize], u8>, pub __bindgen_padding_0: u8, } #[test] @@ -25,7 +104,9 @@ fn bindgen_test_layout_S2() { } impl S2 { #[inline] - pub fn new_bitfield_1() -> u8 { - 0 + pub fn new_bitfield_1() -> __BindgenBitfieldUnit<[u8; 1usize], u8> { + let mut __bindgen_bitfield_unit: __BindgenBitfieldUnit<[u8; 1usize], u8> = + Default::default(); + __bindgen_bitfield_unit } } diff --git a/tests/expectations/tests/issue-1076-unnamed-bitfield-alignment.rs b/tests/expectations/tests/issue-1076-unnamed-bitfield-alignment.rs index 00b3f11ba8..a8a520995e 100644 --- a/tests/expectations/tests/issue-1076-unnamed-bitfield-alignment.rs +++ b/tests/expectations/tests/issue-1076-unnamed-bitfield-alignment.rs @@ -4,10 +4,89 @@ #![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] +#[repr(C)] +#[derive(Copy, Clone, Debug, Default, Eq, Hash, Ord, PartialEq, PartialOrd)] +pub struct __BindgenBitfieldUnit +where + Storage: AsRef<[u8]> + AsMut<[u8]>, +{ + storage: Storage, + align: [Align; 0], +} + +impl __BindgenBitfieldUnit +where + Storage: AsRef<[u8]> + AsMut<[u8]>, +{ + #[inline] + pub fn new(storage: Storage) -> Self { + Self { storage, align: [] } + } + + #[inline] + pub fn get_bit(&self, index: usize) -> bool { + debug_assert!(index / 8 < self.storage.as_ref().len()); + + let byte_index = index / 8; + let byte = self.storage.as_ref()[byte_index]; + + let bit_index = index % 8; + let mask = 1 << bit_index; + + byte & mask == mask + } + + #[inline] + pub fn set_bit(&mut self, index: usize, val: bool) { + debug_assert!(index / 8 < self.storage.as_ref().len()); + + let byte_index = index / 8; + let byte = &mut self.storage.as_mut()[byte_index]; + + let bit_index = index % 8; + let mask = 1 << bit_index; + + if val { + *byte |= mask; + } else { + *byte &= !mask; + } + } + + #[inline] + pub fn get(&self, bit_offset: usize, bit_width: u8) -> u64 { + debug_assert!(bit_width <= 64); + debug_assert!(bit_offset / 8 < self.storage.as_ref().len()); + debug_assert!((bit_offset + (bit_width as usize)) / 8 <= self.storage.as_ref().len()); + + let mut val = 0; + + for i in 0..(bit_width as usize) { + if self.get_bit(i + bit_offset) { + val |= 1 << i; + } + } + + val + } + + #[inline] + pub fn set(&mut self, bit_offset: usize, bit_width: u8, val: u64) { + debug_assert!(bit_width <= 64); + debug_assert!(bit_offset / 8 < self.storage.as_ref().len()); + debug_assert!((bit_offset + (bit_width as usize)) / 8 <= self.storage.as_ref().len()); + + for i in 0..(bit_width as usize) { + let mask = 1 << i; + let val_bit_is_set = val & mask == mask; + self.set_bit(i + bit_offset, val_bit_is_set); + } + } +} #[repr(C)] #[derive(Debug, Default, Copy, Clone)] pub struct S1 { - pub _bitfield_1: [u8; 2usize], + pub _bitfield_1: __BindgenBitfieldUnit<[u8; 2usize], u8>, pub __bindgen_padding_0: u8, } #[test] @@ -25,7 +104,9 @@ fn bindgen_test_layout_S1() { } impl S1 { #[inline] - pub fn new_bitfield_1() -> u16 { - 0 + pub fn new_bitfield_1() -> __BindgenBitfieldUnit<[u8; 2usize], u8> { + let mut __bindgen_bitfield_unit: __BindgenBitfieldUnit<[u8; 2usize], u8> = + Default::default(); + __bindgen_bitfield_unit } } diff --git a/tests/expectations/tests/issue-739-pointer-wide-bitfield.rs b/tests/expectations/tests/issue-739-pointer-wide-bitfield.rs index 96963ba553..806b3f161d 100644 --- a/tests/expectations/tests/issue-739-pointer-wide-bitfield.rs +++ b/tests/expectations/tests/issue-739-pointer-wide-bitfield.rs @@ -4,10 +4,89 @@ #![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] +#[repr(C)] +#[derive(Copy, Clone, Debug, Default, Eq, Hash, Ord, PartialEq, PartialOrd)] +pub struct __BindgenBitfieldUnit +where + Storage: AsRef<[u8]> + AsMut<[u8]>, +{ + storage: Storage, + align: [Align; 0], +} + +impl __BindgenBitfieldUnit +where + Storage: AsRef<[u8]> + AsMut<[u8]>, +{ + #[inline] + pub fn new(storage: Storage) -> Self { + Self { storage, align: [] } + } + + #[inline] + pub fn get_bit(&self, index: usize) -> bool { + debug_assert!(index / 8 < self.storage.as_ref().len()); + + let byte_index = index / 8; + let byte = self.storage.as_ref()[byte_index]; + + let bit_index = index % 8; + let mask = 1 << bit_index; + + byte & mask == mask + } + + #[inline] + pub fn set_bit(&mut self, index: usize, val: bool) { + debug_assert!(index / 8 < self.storage.as_ref().len()); + + let byte_index = index / 8; + let byte = &mut self.storage.as_mut()[byte_index]; + + let bit_index = index % 8; + let mask = 1 << bit_index; + + if val { + *byte |= mask; + } else { + *byte &= !mask; + } + } + + #[inline] + pub fn get(&self, bit_offset: usize, bit_width: u8) -> u64 { + debug_assert!(bit_width <= 64); + debug_assert!(bit_offset / 8 < self.storage.as_ref().len()); + debug_assert!((bit_offset + (bit_width as usize)) / 8 <= self.storage.as_ref().len()); + + let mut val = 0; + + for i in 0..(bit_width as usize) { + if self.get_bit(i + bit_offset) { + val |= 1 << i; + } + } + + val + } + + #[inline] + pub fn set(&mut self, bit_offset: usize, bit_width: u8, val: u64) { + debug_assert!(bit_width <= 64); + debug_assert!(bit_offset / 8 < self.storage.as_ref().len()); + debug_assert!((bit_offset + (bit_width as usize)) / 8 <= self.storage.as_ref().len()); + + for i in 0..(bit_width as usize) { + let mask = 1 << i; + let val_bit_is_set = val & mask == mask; + self.set_bit(i + bit_offset, val_bit_is_set); + } + } +} #[repr(C)] #[derive(Debug, Default, Copy, Clone)] pub struct Foo { - pub _bitfield_1: [u64; 4usize], + pub _bitfield_1: __BindgenBitfieldUnit<[u8; 32usize], u64>, pub __bindgen_align: [u64; 0usize], } #[test] @@ -23,3 +102,76 @@ fn bindgen_test_layout_Foo() { concat!("Alignment of ", stringify!(Foo)) ); } +impl Foo { + #[inline] + pub fn m_bitfield(&self) -> ::std::os::raw::c_ulong { + unsafe { ::std::mem::transmute(self._bitfield_1.get(0usize, 64u8) as u64) } + } + #[inline] + pub fn set_m_bitfield(&mut self, val: ::std::os::raw::c_ulong) { + unsafe { + let val: u64 = ::std::mem::transmute(val); + self._bitfield_1.set(0usize, 64u8, val as u64) + } + } + #[inline] + pub fn m_bar(&self) -> ::std::os::raw::c_ulong { + unsafe { ::std::mem::transmute(self._bitfield_1.get(64usize, 64u8) as u64) } + } + #[inline] + pub fn set_m_bar(&mut self, val: ::std::os::raw::c_ulong) { + unsafe { + let val: u64 = ::std::mem::transmute(val); + self._bitfield_1.set(64usize, 64u8, val as u64) + } + } + #[inline] + pub fn foo(&self) -> ::std::os::raw::c_ulong { + unsafe { ::std::mem::transmute(self._bitfield_1.get(128usize, 1u8) as u64) } + } + #[inline] + pub fn set_foo(&mut self, val: ::std::os::raw::c_ulong) { + unsafe { + let val: u64 = ::std::mem::transmute(val); + self._bitfield_1.set(128usize, 1u8, val as u64) + } + } + #[inline] + pub fn bar(&self) -> ::std::os::raw::c_ulong { + unsafe { ::std::mem::transmute(self._bitfield_1.get(192usize, 64u8) as u64) } + } + #[inline] + pub fn set_bar(&mut self, val: ::std::os::raw::c_ulong) { + unsafe { + let val: u64 = ::std::mem::transmute(val); + self._bitfield_1.set(192usize, 64u8, val as u64) + } + } + #[inline] + pub fn new_bitfield_1( + m_bitfield: ::std::os::raw::c_ulong, + m_bar: ::std::os::raw::c_ulong, + foo: ::std::os::raw::c_ulong, + bar: ::std::os::raw::c_ulong, + ) -> __BindgenBitfieldUnit<[u8; 32usize], u64> { + let mut __bindgen_bitfield_unit: __BindgenBitfieldUnit<[u8; 32usize], u64> = + Default::default(); + __bindgen_bitfield_unit.set(0usize, 64u8, { + let m_bitfield: u64 = unsafe { ::std::mem::transmute(m_bitfield) }; + m_bitfield as u64 + }); + __bindgen_bitfield_unit.set(64usize, 64u8, { + let m_bar: u64 = unsafe { ::std::mem::transmute(m_bar) }; + m_bar as u64 + }); + __bindgen_bitfield_unit.set(128usize, 1u8, { + let foo: u64 = unsafe { ::std::mem::transmute(foo) }; + foo as u64 + }); + __bindgen_bitfield_unit.set(192usize, 64u8, { + let bar: u64 = unsafe { ::std::mem::transmute(bar) }; + bar as u64 + }); + __bindgen_bitfield_unit + } +} diff --git a/tests/expectations/tests/jsval_layout_opaque.rs b/tests/expectations/tests/jsval_layout_opaque.rs index 8f06b93be6..d579dc6b97 100644 --- a/tests/expectations/tests/jsval_layout_opaque.rs +++ b/tests/expectations/tests/jsval_layout_opaque.rs @@ -4,6 +4,85 @@ #![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] +#[repr(C)] +#[derive(Copy, Clone, Debug, Default, Eq, Hash, Ord, PartialEq, PartialOrd)] +pub struct __BindgenBitfieldUnit +where + Storage: AsRef<[u8]> + AsMut<[u8]>, +{ + storage: Storage, + align: [Align; 0], +} + +impl __BindgenBitfieldUnit +where + Storage: AsRef<[u8]> + AsMut<[u8]>, +{ + #[inline] + pub fn new(storage: Storage) -> Self { + Self { storage, align: [] } + } + + #[inline] + pub fn get_bit(&self, index: usize) -> bool { + debug_assert!(index / 8 < self.storage.as_ref().len()); + + let byte_index = index / 8; + let byte = self.storage.as_ref()[byte_index]; + + let bit_index = index % 8; + let mask = 1 << bit_index; + + byte & mask == mask + } + + #[inline] + pub fn set_bit(&mut self, index: usize, val: bool) { + debug_assert!(index / 8 < self.storage.as_ref().len()); + + let byte_index = index / 8; + let byte = &mut self.storage.as_mut()[byte_index]; + + let bit_index = index % 8; + let mask = 1 << bit_index; + + if val { + *byte |= mask; + } else { + *byte &= !mask; + } + } + + #[inline] + pub fn get(&self, bit_offset: usize, bit_width: u8) -> u64 { + debug_assert!(bit_width <= 64); + debug_assert!(bit_offset / 8 < self.storage.as_ref().len()); + debug_assert!((bit_offset + (bit_width as usize)) / 8 <= self.storage.as_ref().len()); + + let mut val = 0; + + for i in 0..(bit_width as usize) { + if self.get_bit(i + bit_offset) { + val |= 1 << i; + } + } + + val + } + + #[inline] + pub fn set(&mut self, bit_offset: usize, bit_width: u8, val: u64) { + debug_assert!(bit_width <= 64); + debug_assert!(bit_offset / 8 < self.storage.as_ref().len()); + debug_assert!((bit_offset + (bit_width as usize)) / 8 <= self.storage.as_ref().len()); + + for i in 0..(bit_width as usize) { + let mask = 1 << i; + let val_bit_is_set = val & mask == mask; + self.set_bit(i + bit_offset, val_bit_is_set); + } + } +} pub const JSVAL_TAG_SHIFT: ::std::os::raw::c_uint = 47; pub const JSVAL_PAYLOAD_MASK: ::std::os::raw::c_ulonglong = 140737488355327; pub const JSVAL_TAG_MASK: ::std::os::raw::c_longlong = -140737488355328; @@ -86,7 +165,7 @@ pub union jsval_layout { #[repr(C)] #[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)] pub struct jsval_layout__bindgen_ty_1 { - pub _bitfield_1: u64, + pub _bitfield_1: __BindgenBitfieldUnit<[u8; 8usize], u64>, pub __bindgen_align: [u64; 0usize], } #[test] @@ -110,80 +189,42 @@ impl Default for jsval_layout__bindgen_ty_1 { impl jsval_layout__bindgen_ty_1 { #[inline] pub fn payload47(&self) -> u64 { - let mut unit_field_val: u64 = unsafe { ::std::mem::uninitialized() }; - unsafe { - ::std::ptr::copy_nonoverlapping( - &self._bitfield_1 as *const _ as *const u8, - &mut unit_field_val as *mut u64 as *mut u8, - 8usize, - ) - }; - let mask = 0x7fffffffffff as u64; - let val = (unit_field_val & mask) >> 0usize; - unsafe { ::std::mem::transmute(val as u64) } + unsafe { ::std::mem::transmute(self._bitfield_1.get(0usize, 47u8) as u64) } } #[inline] pub fn set_payload47(&mut self, val: u64) { - let mask = 0x7fffffffffff as u64; - let val = val as u64 as u64; - let mut unit_field_val: u64 = unsafe { ::std::mem::uninitialized() }; - unsafe { - ::std::ptr::copy_nonoverlapping( - &self._bitfield_1 as *const _ as *const u8, - &mut unit_field_val as *mut u64 as *mut u8, - 8usize, - ) - }; - unit_field_val &= !mask; - unit_field_val |= (val << 0usize) & mask; unsafe { - ::std::ptr::copy_nonoverlapping( - &unit_field_val as *const _ as *const u8, - &mut self._bitfield_1 as *mut _ as *mut u8, - 8usize, - ); + let val: u64 = ::std::mem::transmute(val); + self._bitfield_1.set(0usize, 47u8, val as u64) } } #[inline] pub fn tag(&self) -> JSValueTag { - let mut unit_field_val: u64 = unsafe { ::std::mem::uninitialized() }; - unsafe { - ::std::ptr::copy_nonoverlapping( - &self._bitfield_1 as *const _ as *const u8, - &mut unit_field_val as *mut u64 as *mut u8, - 8usize, - ) - }; - let mask = 0xffff800000000000 as u64; - let val = (unit_field_val & mask) >> 47usize; - unsafe { ::std::mem::transmute(val as u32) } + unsafe { ::std::mem::transmute(self._bitfield_1.get(47usize, 17u8) as u32) } } #[inline] pub fn set_tag(&mut self, val: JSValueTag) { - let mask = 0xffff800000000000 as u64; - let val = val as u32 as u64; - let mut unit_field_val: u64 = unsafe { ::std::mem::uninitialized() }; - unsafe { - ::std::ptr::copy_nonoverlapping( - &self._bitfield_1 as *const _ as *const u8, - &mut unit_field_val as *mut u64 as *mut u8, - 8usize, - ) - }; - unit_field_val &= !mask; - unit_field_val |= (val << 47usize) & mask; unsafe { - ::std::ptr::copy_nonoverlapping( - &unit_field_val as *const _ as *const u8, - &mut self._bitfield_1 as *mut _ as *mut u8, - 8usize, - ); + let val: u32 = ::std::mem::transmute(val); + self._bitfield_1.set(47usize, 17u8, val as u64) } } #[inline] - pub fn new_bitfield_1(payload47: u64, tag: JSValueTag) -> u64 { - ((0 | ((payload47 as u64 as u64) << 0usize) & (0x7fffffffffff as u64)) - | ((tag as u32 as u64) << 47usize) & (0xffff800000000000 as u64)) + pub fn new_bitfield_1( + payload47: u64, + tag: JSValueTag, + ) -> __BindgenBitfieldUnit<[u8; 8usize], u64> { + let mut __bindgen_bitfield_unit: __BindgenBitfieldUnit<[u8; 8usize], u64> = + Default::default(); + __bindgen_bitfield_unit.set(0usize, 47u8, { + let payload47: u64 = unsafe { ::std::mem::transmute(payload47) }; + payload47 as u64 + }); + __bindgen_bitfield_unit.set(47usize, 17u8, { + let tag: u32 = unsafe { ::std::mem::transmute(tag) }; + tag as u64 + }); + __bindgen_bitfield_unit } } #[repr(C)] diff --git a/tests/expectations/tests/jsval_layout_opaque_1_0.rs b/tests/expectations/tests/jsval_layout_opaque_1_0.rs index d0a79b53ee..c803f121c0 100644 --- a/tests/expectations/tests/jsval_layout_opaque_1_0.rs +++ b/tests/expectations/tests/jsval_layout_opaque_1_0.rs @@ -4,6 +4,85 @@ #![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] +#[repr(C)] +#[derive(Copy, Clone, Debug, Default, Eq, Hash, Ord, PartialEq, PartialOrd)] +pub struct __BindgenBitfieldUnit +where + Storage: AsRef<[u8]> + AsMut<[u8]>, +{ + storage: Storage, + align: [Align; 0], +} + +impl __BindgenBitfieldUnit +where + Storage: AsRef<[u8]> + AsMut<[u8]>, +{ + #[inline] + pub fn new(storage: Storage) -> Self { + Self { storage, align: [] } + } + + #[inline] + pub fn get_bit(&self, index: usize) -> bool { + debug_assert!(index / 8 < self.storage.as_ref().len()); + + let byte_index = index / 8; + let byte = self.storage.as_ref()[byte_index]; + + let bit_index = index % 8; + let mask = 1 << bit_index; + + byte & mask == mask + } + + #[inline] + pub fn set_bit(&mut self, index: usize, val: bool) { + debug_assert!(index / 8 < self.storage.as_ref().len()); + + let byte_index = index / 8; + let byte = &mut self.storage.as_mut()[byte_index]; + + let bit_index = index % 8; + let mask = 1 << bit_index; + + if val { + *byte |= mask; + } else { + *byte &= !mask; + } + } + + #[inline] + pub fn get(&self, bit_offset: usize, bit_width: u8) -> u64 { + debug_assert!(bit_width <= 64); + debug_assert!(bit_offset / 8 < self.storage.as_ref().len()); + debug_assert!((bit_offset + (bit_width as usize)) / 8 <= self.storage.as_ref().len()); + + let mut val = 0; + + for i in 0..(bit_width as usize) { + if self.get_bit(i + bit_offset) { + val |= 1 << i; + } + } + + val + } + + #[inline] + pub fn set(&mut self, bit_offset: usize, bit_width: u8, val: u64) { + debug_assert!(bit_width <= 64); + debug_assert!(bit_offset / 8 < self.storage.as_ref().len()); + debug_assert!((bit_offset + (bit_width as usize)) / 8 <= self.storage.as_ref().len()); + + for i in 0..(bit_width as usize) { + let mask = 1 << i; + let val_bit_is_set = val & mask == mask; + self.set_bit(i + bit_offset, val_bit_is_set); + } + } +} #[repr(C)] pub struct __BindgenUnionField(::std::marker::PhantomData); impl __BindgenUnionField { @@ -129,7 +208,7 @@ pub struct jsval_layout { #[repr(C)] #[derive(Debug, Copy, Hash, PartialEq, Eq)] pub struct jsval_layout__bindgen_ty_1 { - pub _bitfield_1: u64, + pub _bitfield_1: __BindgenBitfieldUnit<[u8; 8usize], u64>, pub __bindgen_align: [u64; 0usize], } #[test] @@ -158,80 +237,42 @@ impl Default for jsval_layout__bindgen_ty_1 { impl jsval_layout__bindgen_ty_1 { #[inline] pub fn payload47(&self) -> u64 { - let mut unit_field_val: u64 = unsafe { ::std::mem::uninitialized() }; - unsafe { - ::std::ptr::copy_nonoverlapping( - &self._bitfield_1 as *const _ as *const u8, - &mut unit_field_val as *mut u64 as *mut u8, - 8usize, - ) - }; - let mask = 0x7fffffffffff as u64; - let val = (unit_field_val & mask) >> 0usize; - unsafe { ::std::mem::transmute(val as u64) } + unsafe { ::std::mem::transmute(self._bitfield_1.get(0usize, 47u8) as u64) } } #[inline] pub fn set_payload47(&mut self, val: u64) { - let mask = 0x7fffffffffff as u64; - let val = val as u64 as u64; - let mut unit_field_val: u64 = unsafe { ::std::mem::uninitialized() }; - unsafe { - ::std::ptr::copy_nonoverlapping( - &self._bitfield_1 as *const _ as *const u8, - &mut unit_field_val as *mut u64 as *mut u8, - 8usize, - ) - }; - unit_field_val &= !mask; - unit_field_val |= (val << 0usize) & mask; unsafe { - ::std::ptr::copy_nonoverlapping( - &unit_field_val as *const _ as *const u8, - &mut self._bitfield_1 as *mut _ as *mut u8, - 8usize, - ); + let val: u64 = ::std::mem::transmute(val); + self._bitfield_1.set(0usize, 47u8, val as u64) } } #[inline] pub fn tag(&self) -> JSValueTag { - let mut unit_field_val: u64 = unsafe { ::std::mem::uninitialized() }; - unsafe { - ::std::ptr::copy_nonoverlapping( - &self._bitfield_1 as *const _ as *const u8, - &mut unit_field_val as *mut u64 as *mut u8, - 8usize, - ) - }; - let mask = 0xffff800000000000 as u64; - let val = (unit_field_val & mask) >> 47usize; - unsafe { ::std::mem::transmute(val as u32) } + unsafe { ::std::mem::transmute(self._bitfield_1.get(47usize, 17u8) as u32) } } #[inline] pub fn set_tag(&mut self, val: JSValueTag) { - let mask = 0xffff800000000000 as u64; - let val = val as u32 as u64; - let mut unit_field_val: u64 = unsafe { ::std::mem::uninitialized() }; - unsafe { - ::std::ptr::copy_nonoverlapping( - &self._bitfield_1 as *const _ as *const u8, - &mut unit_field_val as *mut u64 as *mut u8, - 8usize, - ) - }; - unit_field_val &= !mask; - unit_field_val |= (val << 47usize) & mask; unsafe { - ::std::ptr::copy_nonoverlapping( - &unit_field_val as *const _ as *const u8, - &mut self._bitfield_1 as *mut _ as *mut u8, - 8usize, - ); + let val: u32 = ::std::mem::transmute(val); + self._bitfield_1.set(47usize, 17u8, val as u64) } } #[inline] - pub fn new_bitfield_1(payload47: u64, tag: JSValueTag) -> u64 { - ((0 | ((payload47 as u64 as u64) << 0usize) & (0x7fffffffffff as u64)) - | ((tag as u32 as u64) << 47usize) & (0xffff800000000000 as u64)) + pub fn new_bitfield_1( + payload47: u64, + tag: JSValueTag, + ) -> __BindgenBitfieldUnit<[u8; 8usize], u64> { + let mut __bindgen_bitfield_unit: __BindgenBitfieldUnit<[u8; 8usize], u64> = + Default::default(); + __bindgen_bitfield_unit.set(0usize, 47u8, { + let payload47: u64 = unsafe { ::std::mem::transmute(payload47) }; + payload47 as u64 + }); + __bindgen_bitfield_unit.set(47usize, 17u8, { + let tag: u32 = unsafe { ::std::mem::transmute(tag) }; + tag as u64 + }); + __bindgen_bitfield_unit } } #[repr(C)] diff --git a/tests/expectations/tests/layout_align.rs b/tests/expectations/tests/layout_align.rs index 3555fbef9f..9eb804c3ee 100644 --- a/tests/expectations/tests/layout_align.rs +++ b/tests/expectations/tests/layout_align.rs @@ -4,6 +4,85 @@ #![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] +#[repr(C)] +#[derive(Copy, Clone, Debug, Default, Eq, Hash, Ord, PartialEq, PartialOrd)] +pub struct __BindgenBitfieldUnit +where + Storage: AsRef<[u8]> + AsMut<[u8]>, +{ + storage: Storage, + align: [Align; 0], +} + +impl __BindgenBitfieldUnit +where + Storage: AsRef<[u8]> + AsMut<[u8]>, +{ + #[inline] + pub fn new(storage: Storage) -> Self { + Self { storage, align: [] } + } + + #[inline] + pub fn get_bit(&self, index: usize) -> bool { + debug_assert!(index / 8 < self.storage.as_ref().len()); + + let byte_index = index / 8; + let byte = self.storage.as_ref()[byte_index]; + + let bit_index = index % 8; + let mask = 1 << bit_index; + + byte & mask == mask + } + + #[inline] + pub fn set_bit(&mut self, index: usize, val: bool) { + debug_assert!(index / 8 < self.storage.as_ref().len()); + + let byte_index = index / 8; + let byte = &mut self.storage.as_mut()[byte_index]; + + let bit_index = index % 8; + let mask = 1 << bit_index; + + if val { + *byte |= mask; + } else { + *byte &= !mask; + } + } + + #[inline] + pub fn get(&self, bit_offset: usize, bit_width: u8) -> u64 { + debug_assert!(bit_width <= 64); + debug_assert!(bit_offset / 8 < self.storage.as_ref().len()); + debug_assert!((bit_offset + (bit_width as usize)) / 8 <= self.storage.as_ref().len()); + + let mut val = 0; + + for i in 0..(bit_width as usize) { + if self.get_bit(i + bit_offset) { + val |= 1 << i; + } + } + + val + } + + #[inline] + pub fn set(&mut self, bit_offset: usize, bit_width: u8, val: u64) { + debug_assert!(bit_width <= 64); + debug_assert!(bit_offset / 8 < self.storage.as_ref().len()); + debug_assert!((bit_offset + (bit_width as usize)) / 8 <= self.storage.as_ref().len()); + + for i in 0..(bit_width as usize) { + let mask = 1 << i; + let val_bit_is_set = val & mask == mask; + self.set_bit(i + bit_offset, val_bit_is_set); + } + } +} #[repr(C)] #[derive(Default)] pub struct __IncompleteArrayField(::std::marker::PhantomData); @@ -79,7 +158,7 @@ impl Default for rte_kni_fifo { pub struct rte_eth_link { /// < ETH_SPEED_NUM_ pub link_speed: u32, - pub _bitfield_1: u8, + pub _bitfield_1: __BindgenBitfieldUnit<[u8; 1usize], u8>, pub __bindgen_padding_0: [u8; 3usize], pub __bindgen_align: [u64; 0usize], } @@ -109,116 +188,57 @@ fn bindgen_test_layout_rte_eth_link() { impl rte_eth_link { #[inline] pub fn link_duplex(&self) -> u16 { - let mut unit_field_val: u8 = unsafe { ::std::mem::uninitialized() }; - unsafe { - ::std::ptr::copy_nonoverlapping( - &self._bitfield_1 as *const _ as *const u8, - &mut unit_field_val as *mut u8 as *mut u8, - 1usize, - ) - }; - let mask = 0x1 as u8; - let val = (unit_field_val & mask) >> 0usize; - unsafe { ::std::mem::transmute(val as u16) } + unsafe { ::std::mem::transmute(self._bitfield_1.get(0usize, 1u8) as u16) } } #[inline] pub fn set_link_duplex(&mut self, val: u16) { - let mask = 0x1 as u8; - let val = val as u16 as u8; - let mut unit_field_val: u8 = unsafe { ::std::mem::uninitialized() }; - unsafe { - ::std::ptr::copy_nonoverlapping( - &self._bitfield_1 as *const _ as *const u8, - &mut unit_field_val as *mut u8 as *mut u8, - 1usize, - ) - }; - unit_field_val &= !mask; - unit_field_val |= (val << 0usize) & mask; unsafe { - ::std::ptr::copy_nonoverlapping( - &unit_field_val as *const _ as *const u8, - &mut self._bitfield_1 as *mut _ as *mut u8, - 1usize, - ); + let val: u16 = ::std::mem::transmute(val); + self._bitfield_1.set(0usize, 1u8, val as u64) } } #[inline] pub fn link_autoneg(&self) -> u16 { - let mut unit_field_val: u8 = unsafe { ::std::mem::uninitialized() }; - unsafe { - ::std::ptr::copy_nonoverlapping( - &self._bitfield_1 as *const _ as *const u8, - &mut unit_field_val as *mut u8 as *mut u8, - 1usize, - ) - }; - let mask = 0x2 as u8; - let val = (unit_field_val & mask) >> 1usize; - unsafe { ::std::mem::transmute(val as u16) } + unsafe { ::std::mem::transmute(self._bitfield_1.get(1usize, 1u8) as u16) } } #[inline] pub fn set_link_autoneg(&mut self, val: u16) { - let mask = 0x2 as u8; - let val = val as u16 as u8; - let mut unit_field_val: u8 = unsafe { ::std::mem::uninitialized() }; - unsafe { - ::std::ptr::copy_nonoverlapping( - &self._bitfield_1 as *const _ as *const u8, - &mut unit_field_val as *mut u8 as *mut u8, - 1usize, - ) - }; - unit_field_val &= !mask; - unit_field_val |= (val << 1usize) & mask; unsafe { - ::std::ptr::copy_nonoverlapping( - &unit_field_val as *const _ as *const u8, - &mut self._bitfield_1 as *mut _ as *mut u8, - 1usize, - ); + let val: u16 = ::std::mem::transmute(val); + self._bitfield_1.set(1usize, 1u8, val as u64) } } #[inline] pub fn link_status(&self) -> u16 { - let mut unit_field_val: u8 = unsafe { ::std::mem::uninitialized() }; - unsafe { - ::std::ptr::copy_nonoverlapping( - &self._bitfield_1 as *const _ as *const u8, - &mut unit_field_val as *mut u8 as *mut u8, - 1usize, - ) - }; - let mask = 0x4 as u8; - let val = (unit_field_val & mask) >> 2usize; - unsafe { ::std::mem::transmute(val as u16) } + unsafe { ::std::mem::transmute(self._bitfield_1.get(2usize, 1u8) as u16) } } #[inline] pub fn set_link_status(&mut self, val: u16) { - let mask = 0x4 as u8; - let val = val as u16 as u8; - let mut unit_field_val: u8 = unsafe { ::std::mem::uninitialized() }; - unsafe { - ::std::ptr::copy_nonoverlapping( - &self._bitfield_1 as *const _ as *const u8, - &mut unit_field_val as *mut u8 as *mut u8, - 1usize, - ) - }; - unit_field_val &= !mask; - unit_field_val |= (val << 2usize) & mask; unsafe { - ::std::ptr::copy_nonoverlapping( - &unit_field_val as *const _ as *const u8, - &mut self._bitfield_1 as *mut _ as *mut u8, - 1usize, - ); + let val: u16 = ::std::mem::transmute(val); + self._bitfield_1.set(2usize, 1u8, val as u64) } } #[inline] - pub fn new_bitfield_1(link_duplex: u16, link_autoneg: u16, link_status: u16) -> u8 { - (((0 | ((link_duplex as u16 as u8) << 0usize) & (0x1 as u8)) - | ((link_autoneg as u16 as u8) << 1usize) & (0x2 as u8)) - | ((link_status as u16 as u8) << 2usize) & (0x4 as u8)) + pub fn new_bitfield_1( + link_duplex: u16, + link_autoneg: u16, + link_status: u16, + ) -> __BindgenBitfieldUnit<[u8; 1usize], u8> { + let mut __bindgen_bitfield_unit: __BindgenBitfieldUnit<[u8; 1usize], u8> = + Default::default(); + __bindgen_bitfield_unit.set(0usize, 1u8, { + let link_duplex: u16 = unsafe { ::std::mem::transmute(link_duplex) }; + link_duplex as u64 + }); + __bindgen_bitfield_unit.set(1usize, 1u8, { + let link_autoneg: u16 = unsafe { ::std::mem::transmute(link_autoneg) }; + link_autoneg as u64 + }); + __bindgen_bitfield_unit.set(2usize, 1u8, { + let link_status: u16 = unsafe { ::std::mem::transmute(link_status) }; + link_status as u64 + }); + __bindgen_bitfield_unit } } diff --git a/tests/expectations/tests/layout_eth_conf.rs b/tests/expectations/tests/layout_eth_conf.rs index 1c2fdaa21f..4ee94522c8 100644 --- a/tests/expectations/tests/layout_eth_conf.rs +++ b/tests/expectations/tests/layout_eth_conf.rs @@ -4,6 +4,85 @@ #![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] +#[repr(C)] +#[derive(Copy, Clone, Debug, Default, Eq, Hash, Ord, PartialEq, PartialOrd)] +pub struct __BindgenBitfieldUnit +where + Storage: AsRef<[u8]> + AsMut<[u8]>, +{ + storage: Storage, + align: [Align; 0], +} + +impl __BindgenBitfieldUnit +where + Storage: AsRef<[u8]> + AsMut<[u8]>, +{ + #[inline] + pub fn new(storage: Storage) -> Self { + Self { storage, align: [] } + } + + #[inline] + pub fn get_bit(&self, index: usize) -> bool { + debug_assert!(index / 8 < self.storage.as_ref().len()); + + let byte_index = index / 8; + let byte = self.storage.as_ref()[byte_index]; + + let bit_index = index % 8; + let mask = 1 << bit_index; + + byte & mask == mask + } + + #[inline] + pub fn set_bit(&mut self, index: usize, val: bool) { + debug_assert!(index / 8 < self.storage.as_ref().len()); + + let byte_index = index / 8; + let byte = &mut self.storage.as_mut()[byte_index]; + + let bit_index = index % 8; + let mask = 1 << bit_index; + + if val { + *byte |= mask; + } else { + *byte &= !mask; + } + } + + #[inline] + pub fn get(&self, bit_offset: usize, bit_width: u8) -> u64 { + debug_assert!(bit_width <= 64); + debug_assert!(bit_offset / 8 < self.storage.as_ref().len()); + debug_assert!((bit_offset + (bit_width as usize)) / 8 <= self.storage.as_ref().len()); + + let mut val = 0; + + for i in 0..(bit_width as usize) { + if self.get_bit(i + bit_offset) { + val |= 1 << i; + } + } + + val + } + + #[inline] + pub fn set(&mut self, bit_offset: usize, bit_width: u8, val: u64) { + debug_assert!(bit_width <= 64); + debug_assert!(bit_offset / 8 < self.storage.as_ref().len()); + debug_assert!((bit_offset + (bit_width as usize)) / 8 <= self.storage.as_ref().len()); + + for i in 0..(bit_width as usize) { + let mask = 1 << i; + let val_bit_is_set = val & mask == mask; + self.set_bit(i + bit_offset, val_bit_is_set); + } + } +} pub const ETH_MQ_RX_RSS_FLAG: ::std::os::raw::c_uint = 1; pub const ETH_MQ_RX_DCB_FLAG: ::std::os::raw::c_uint = 2; pub const ETH_MQ_RX_VMDQ_FLAG: ::std::os::raw::c_uint = 4; @@ -60,7 +139,7 @@ pub struct rte_eth_rxmode { pub max_rx_pkt_len: u32, /// < hdr buf size (header_split enabled). pub split_hdr_size: u16, - pub _bitfield_1: [u8; 2usize], + pub _bitfield_1: __BindgenBitfieldUnit<[u8; 2usize], u8>, } #[test] fn bindgen_test_layout_rte_eth_rxmode() { @@ -113,326 +192,101 @@ impl Default for rte_eth_rxmode { impl rte_eth_rxmode { #[inline] pub fn header_split(&self) -> u16 { - let mut unit_field_val: u16 = unsafe { ::std::mem::uninitialized() }; - unsafe { - ::std::ptr::copy_nonoverlapping( - &self._bitfield_1 as *const _ as *const u8, - &mut unit_field_val as *mut u16 as *mut u8, - 2usize, - ) - }; - let mask = 0x1 as u16; - let val = (unit_field_val & mask) >> 0usize; - unsafe { ::std::mem::transmute(val as u16) } + unsafe { ::std::mem::transmute(self._bitfield_1.get(0usize, 1u8) as u16) } } #[inline] pub fn set_header_split(&mut self, val: u16) { - let mask = 0x1 as u16; - let val = val as u16 as u16; - let mut unit_field_val: u16 = unsafe { ::std::mem::uninitialized() }; unsafe { - ::std::ptr::copy_nonoverlapping( - &self._bitfield_1 as *const _ as *const u8, - &mut unit_field_val as *mut u16 as *mut u8, - 2usize, - ) - }; - unit_field_val &= !mask; - unit_field_val |= (val << 0usize) & mask; - unsafe { - ::std::ptr::copy_nonoverlapping( - &unit_field_val as *const _ as *const u8, - &mut self._bitfield_1 as *mut _ as *mut u8, - 2usize, - ); + let val: u16 = ::std::mem::transmute(val); + self._bitfield_1.set(0usize, 1u8, val as u64) } } #[inline] pub fn hw_ip_checksum(&self) -> u16 { - let mut unit_field_val: u16 = unsafe { ::std::mem::uninitialized() }; - unsafe { - ::std::ptr::copy_nonoverlapping( - &self._bitfield_1 as *const _ as *const u8, - &mut unit_field_val as *mut u16 as *mut u8, - 2usize, - ) - }; - let mask = 0x2 as u16; - let val = (unit_field_val & mask) >> 1usize; - unsafe { ::std::mem::transmute(val as u16) } + unsafe { ::std::mem::transmute(self._bitfield_1.get(1usize, 1u8) as u16) } } #[inline] pub fn set_hw_ip_checksum(&mut self, val: u16) { - let mask = 0x2 as u16; - let val = val as u16 as u16; - let mut unit_field_val: u16 = unsafe { ::std::mem::uninitialized() }; - unsafe { - ::std::ptr::copy_nonoverlapping( - &self._bitfield_1 as *const _ as *const u8, - &mut unit_field_val as *mut u16 as *mut u8, - 2usize, - ) - }; - unit_field_val &= !mask; - unit_field_val |= (val << 1usize) & mask; unsafe { - ::std::ptr::copy_nonoverlapping( - &unit_field_val as *const _ as *const u8, - &mut self._bitfield_1 as *mut _ as *mut u8, - 2usize, - ); + let val: u16 = ::std::mem::transmute(val); + self._bitfield_1.set(1usize, 1u8, val as u64) } } #[inline] pub fn hw_vlan_filter(&self) -> u16 { - let mut unit_field_val: u16 = unsafe { ::std::mem::uninitialized() }; - unsafe { - ::std::ptr::copy_nonoverlapping( - &self._bitfield_1 as *const _ as *const u8, - &mut unit_field_val as *mut u16 as *mut u8, - 2usize, - ) - }; - let mask = 0x4 as u16; - let val = (unit_field_val & mask) >> 2usize; - unsafe { ::std::mem::transmute(val as u16) } + unsafe { ::std::mem::transmute(self._bitfield_1.get(2usize, 1u8) as u16) } } #[inline] pub fn set_hw_vlan_filter(&mut self, val: u16) { - let mask = 0x4 as u16; - let val = val as u16 as u16; - let mut unit_field_val: u16 = unsafe { ::std::mem::uninitialized() }; - unsafe { - ::std::ptr::copy_nonoverlapping( - &self._bitfield_1 as *const _ as *const u8, - &mut unit_field_val as *mut u16 as *mut u8, - 2usize, - ) - }; - unit_field_val &= !mask; - unit_field_val |= (val << 2usize) & mask; unsafe { - ::std::ptr::copy_nonoverlapping( - &unit_field_val as *const _ as *const u8, - &mut self._bitfield_1 as *mut _ as *mut u8, - 2usize, - ); + let val: u16 = ::std::mem::transmute(val); + self._bitfield_1.set(2usize, 1u8, val as u64) } } #[inline] pub fn hw_vlan_strip(&self) -> u16 { - let mut unit_field_val: u16 = unsafe { ::std::mem::uninitialized() }; - unsafe { - ::std::ptr::copy_nonoverlapping( - &self._bitfield_1 as *const _ as *const u8, - &mut unit_field_val as *mut u16 as *mut u8, - 2usize, - ) - }; - let mask = 0x8 as u16; - let val = (unit_field_val & mask) >> 3usize; - unsafe { ::std::mem::transmute(val as u16) } + unsafe { ::std::mem::transmute(self._bitfield_1.get(3usize, 1u8) as u16) } } #[inline] pub fn set_hw_vlan_strip(&mut self, val: u16) { - let mask = 0x8 as u16; - let val = val as u16 as u16; - let mut unit_field_val: u16 = unsafe { ::std::mem::uninitialized() }; - unsafe { - ::std::ptr::copy_nonoverlapping( - &self._bitfield_1 as *const _ as *const u8, - &mut unit_field_val as *mut u16 as *mut u8, - 2usize, - ) - }; - unit_field_val &= !mask; - unit_field_val |= (val << 3usize) & mask; unsafe { - ::std::ptr::copy_nonoverlapping( - &unit_field_val as *const _ as *const u8, - &mut self._bitfield_1 as *mut _ as *mut u8, - 2usize, - ); + let val: u16 = ::std::mem::transmute(val); + self._bitfield_1.set(3usize, 1u8, val as u64) } } #[inline] pub fn hw_vlan_extend(&self) -> u16 { - let mut unit_field_val: u16 = unsafe { ::std::mem::uninitialized() }; - unsafe { - ::std::ptr::copy_nonoverlapping( - &self._bitfield_1 as *const _ as *const u8, - &mut unit_field_val as *mut u16 as *mut u8, - 2usize, - ) - }; - let mask = 0x10 as u16; - let val = (unit_field_val & mask) >> 4usize; - unsafe { ::std::mem::transmute(val as u16) } + unsafe { ::std::mem::transmute(self._bitfield_1.get(4usize, 1u8) as u16) } } #[inline] pub fn set_hw_vlan_extend(&mut self, val: u16) { - let mask = 0x10 as u16; - let val = val as u16 as u16; - let mut unit_field_val: u16 = unsafe { ::std::mem::uninitialized() }; - unsafe { - ::std::ptr::copy_nonoverlapping( - &self._bitfield_1 as *const _ as *const u8, - &mut unit_field_val as *mut u16 as *mut u8, - 2usize, - ) - }; - unit_field_val &= !mask; - unit_field_val |= (val << 4usize) & mask; unsafe { - ::std::ptr::copy_nonoverlapping( - &unit_field_val as *const _ as *const u8, - &mut self._bitfield_1 as *mut _ as *mut u8, - 2usize, - ); + let val: u16 = ::std::mem::transmute(val); + self._bitfield_1.set(4usize, 1u8, val as u64) } } #[inline] pub fn jumbo_frame(&self) -> u16 { - let mut unit_field_val: u16 = unsafe { ::std::mem::uninitialized() }; - unsafe { - ::std::ptr::copy_nonoverlapping( - &self._bitfield_1 as *const _ as *const u8, - &mut unit_field_val as *mut u16 as *mut u8, - 2usize, - ) - }; - let mask = 0x20 as u16; - let val = (unit_field_val & mask) >> 5usize; - unsafe { ::std::mem::transmute(val as u16) } + unsafe { ::std::mem::transmute(self._bitfield_1.get(5usize, 1u8) as u16) } } #[inline] pub fn set_jumbo_frame(&mut self, val: u16) { - let mask = 0x20 as u16; - let val = val as u16 as u16; - let mut unit_field_val: u16 = unsafe { ::std::mem::uninitialized() }; unsafe { - ::std::ptr::copy_nonoverlapping( - &self._bitfield_1 as *const _ as *const u8, - &mut unit_field_val as *mut u16 as *mut u8, - 2usize, - ) - }; - unit_field_val &= !mask; - unit_field_val |= (val << 5usize) & mask; - unsafe { - ::std::ptr::copy_nonoverlapping( - &unit_field_val as *const _ as *const u8, - &mut self._bitfield_1 as *mut _ as *mut u8, - 2usize, - ); + let val: u16 = ::std::mem::transmute(val); + self._bitfield_1.set(5usize, 1u8, val as u64) } } #[inline] pub fn hw_strip_crc(&self) -> u16 { - let mut unit_field_val: u16 = unsafe { ::std::mem::uninitialized() }; - unsafe { - ::std::ptr::copy_nonoverlapping( - &self._bitfield_1 as *const _ as *const u8, - &mut unit_field_val as *mut u16 as *mut u8, - 2usize, - ) - }; - let mask = 0x40 as u16; - let val = (unit_field_val & mask) >> 6usize; - unsafe { ::std::mem::transmute(val as u16) } + unsafe { ::std::mem::transmute(self._bitfield_1.get(6usize, 1u8) as u16) } } #[inline] pub fn set_hw_strip_crc(&mut self, val: u16) { - let mask = 0x40 as u16; - let val = val as u16 as u16; - let mut unit_field_val: u16 = unsafe { ::std::mem::uninitialized() }; unsafe { - ::std::ptr::copy_nonoverlapping( - &self._bitfield_1 as *const _ as *const u8, - &mut unit_field_val as *mut u16 as *mut u8, - 2usize, - ) - }; - unit_field_val &= !mask; - unit_field_val |= (val << 6usize) & mask; - unsafe { - ::std::ptr::copy_nonoverlapping( - &unit_field_val as *const _ as *const u8, - &mut self._bitfield_1 as *mut _ as *mut u8, - 2usize, - ); + let val: u16 = ::std::mem::transmute(val); + self._bitfield_1.set(6usize, 1u8, val as u64) } } #[inline] pub fn enable_scatter(&self) -> u16 { - let mut unit_field_val: u16 = unsafe { ::std::mem::uninitialized() }; - unsafe { - ::std::ptr::copy_nonoverlapping( - &self._bitfield_1 as *const _ as *const u8, - &mut unit_field_val as *mut u16 as *mut u8, - 2usize, - ) - }; - let mask = 0x80 as u16; - let val = (unit_field_val & mask) >> 7usize; - unsafe { ::std::mem::transmute(val as u16) } + unsafe { ::std::mem::transmute(self._bitfield_1.get(7usize, 1u8) as u16) } } #[inline] pub fn set_enable_scatter(&mut self, val: u16) { - let mask = 0x80 as u16; - let val = val as u16 as u16; - let mut unit_field_val: u16 = unsafe { ::std::mem::uninitialized() }; unsafe { - ::std::ptr::copy_nonoverlapping( - &self._bitfield_1 as *const _ as *const u8, - &mut unit_field_val as *mut u16 as *mut u8, - 2usize, - ) - }; - unit_field_val &= !mask; - unit_field_val |= (val << 7usize) & mask; - unsafe { - ::std::ptr::copy_nonoverlapping( - &unit_field_val as *const _ as *const u8, - &mut self._bitfield_1 as *mut _ as *mut u8, - 2usize, - ); + let val: u16 = ::std::mem::transmute(val); + self._bitfield_1.set(7usize, 1u8, val as u64) } } #[inline] pub fn enable_lro(&self) -> u16 { - let mut unit_field_val: u16 = unsafe { ::std::mem::uninitialized() }; - unsafe { - ::std::ptr::copy_nonoverlapping( - &self._bitfield_1 as *const _ as *const u8, - &mut unit_field_val as *mut u16 as *mut u8, - 2usize, - ) - }; - let mask = 0x100 as u16; - let val = (unit_field_val & mask) >> 8usize; - unsafe { ::std::mem::transmute(val as u16) } + unsafe { ::std::mem::transmute(self._bitfield_1.get(8usize, 1u8) as u16) } } #[inline] pub fn set_enable_lro(&mut self, val: u16) { - let mask = 0x100 as u16; - let val = val as u16 as u16; - let mut unit_field_val: u16 = unsafe { ::std::mem::uninitialized() }; - unsafe { - ::std::ptr::copy_nonoverlapping( - &self._bitfield_1 as *const _ as *const u8, - &mut unit_field_val as *mut u16 as *mut u8, - 2usize, - ) - }; - unit_field_val &= !mask; - unit_field_val |= (val << 8usize) & mask; unsafe { - ::std::ptr::copy_nonoverlapping( - &unit_field_val as *const _ as *const u8, - &mut self._bitfield_1 as *mut _ as *mut u8, - 2usize, - ); + let val: u16 = ::std::mem::transmute(val); + self._bitfield_1.set(8usize, 1u8, val as u64) } } #[inline] @@ -446,16 +300,46 @@ impl rte_eth_rxmode { hw_strip_crc: u16, enable_scatter: u16, enable_lro: u16, - ) -> u16 { - (((((((((0 | ((header_split as u16 as u16) << 0usize) & (0x1 as u16)) - | ((hw_ip_checksum as u16 as u16) << 1usize) & (0x2 as u16)) - | ((hw_vlan_filter as u16 as u16) << 2usize) & (0x4 as u16)) - | ((hw_vlan_strip as u16 as u16) << 3usize) & (0x8 as u16)) - | ((hw_vlan_extend as u16 as u16) << 4usize) & (0x10 as u16)) - | ((jumbo_frame as u16 as u16) << 5usize) & (0x20 as u16)) - | ((hw_strip_crc as u16 as u16) << 6usize) & (0x40 as u16)) - | ((enable_scatter as u16 as u16) << 7usize) & (0x80 as u16)) - | ((enable_lro as u16 as u16) << 8usize) & (0x100 as u16)) + ) -> __BindgenBitfieldUnit<[u8; 2usize], u8> { + let mut __bindgen_bitfield_unit: __BindgenBitfieldUnit<[u8; 2usize], u8> = + Default::default(); + __bindgen_bitfield_unit.set(0usize, 1u8, { + let header_split: u16 = unsafe { ::std::mem::transmute(header_split) }; + header_split as u64 + }); + __bindgen_bitfield_unit.set(1usize, 1u8, { + let hw_ip_checksum: u16 = unsafe { ::std::mem::transmute(hw_ip_checksum) }; + hw_ip_checksum as u64 + }); + __bindgen_bitfield_unit.set(2usize, 1u8, { + let hw_vlan_filter: u16 = unsafe { ::std::mem::transmute(hw_vlan_filter) }; + hw_vlan_filter as u64 + }); + __bindgen_bitfield_unit.set(3usize, 1u8, { + let hw_vlan_strip: u16 = unsafe { ::std::mem::transmute(hw_vlan_strip) }; + hw_vlan_strip as u64 + }); + __bindgen_bitfield_unit.set(4usize, 1u8, { + let hw_vlan_extend: u16 = unsafe { ::std::mem::transmute(hw_vlan_extend) }; + hw_vlan_extend as u64 + }); + __bindgen_bitfield_unit.set(5usize, 1u8, { + let jumbo_frame: u16 = unsafe { ::std::mem::transmute(jumbo_frame) }; + jumbo_frame as u64 + }); + __bindgen_bitfield_unit.set(6usize, 1u8, { + let hw_strip_crc: u16 = unsafe { ::std::mem::transmute(hw_strip_crc) }; + hw_strip_crc as u64 + }); + __bindgen_bitfield_unit.set(7usize, 1u8, { + let enable_scatter: u16 = unsafe { ::std::mem::transmute(enable_scatter) }; + enable_scatter as u64 + }); + __bindgen_bitfield_unit.set(8usize, 1u8, { + let enable_lro: u16 = unsafe { ::std::mem::transmute(enable_lro) }; + enable_lro as u64 + }); + __bindgen_bitfield_unit } } #[repr(u32)] @@ -475,7 +359,7 @@ pub struct rte_eth_txmode { /// < TX multi-queues mode. pub mq_mode: rte_eth_tx_mq_mode, pub pvid: u16, - pub _bitfield_1: u8, + pub _bitfield_1: __BindgenBitfieldUnit<[u8; 1usize], u8>, pub __bindgen_padding_0: u8, } #[test] @@ -519,110 +403,35 @@ impl Default for rte_eth_txmode { impl rte_eth_txmode { #[inline] pub fn hw_vlan_reject_tagged(&self) -> u8 { - let mut unit_field_val: u8 = unsafe { ::std::mem::uninitialized() }; - unsafe { - ::std::ptr::copy_nonoverlapping( - &self._bitfield_1 as *const _ as *const u8, - &mut unit_field_val as *mut u8 as *mut u8, - 1usize, - ) - }; - let mask = 0x1 as u8; - let val = (unit_field_val & mask) >> 0usize; - unsafe { ::std::mem::transmute(val as u8) } + unsafe { ::std::mem::transmute(self._bitfield_1.get(0usize, 1u8) as u8) } } #[inline] pub fn set_hw_vlan_reject_tagged(&mut self, val: u8) { - let mask = 0x1 as u8; - let val = val as u8 as u8; - let mut unit_field_val: u8 = unsafe { ::std::mem::uninitialized() }; - unsafe { - ::std::ptr::copy_nonoverlapping( - &self._bitfield_1 as *const _ as *const u8, - &mut unit_field_val as *mut u8 as *mut u8, - 1usize, - ) - }; - unit_field_val &= !mask; - unit_field_val |= (val << 0usize) & mask; unsafe { - ::std::ptr::copy_nonoverlapping( - &unit_field_val as *const _ as *const u8, - &mut self._bitfield_1 as *mut _ as *mut u8, - 1usize, - ); + let val: u8 = ::std::mem::transmute(val); + self._bitfield_1.set(0usize, 1u8, val as u64) } } #[inline] pub fn hw_vlan_reject_untagged(&self) -> u8 { - let mut unit_field_val: u8 = unsafe { ::std::mem::uninitialized() }; - unsafe { - ::std::ptr::copy_nonoverlapping( - &self._bitfield_1 as *const _ as *const u8, - &mut unit_field_val as *mut u8 as *mut u8, - 1usize, - ) - }; - let mask = 0x2 as u8; - let val = (unit_field_val & mask) >> 1usize; - unsafe { ::std::mem::transmute(val as u8) } + unsafe { ::std::mem::transmute(self._bitfield_1.get(1usize, 1u8) as u8) } } #[inline] pub fn set_hw_vlan_reject_untagged(&mut self, val: u8) { - let mask = 0x2 as u8; - let val = val as u8 as u8; - let mut unit_field_val: u8 = unsafe { ::std::mem::uninitialized() }; unsafe { - ::std::ptr::copy_nonoverlapping( - &self._bitfield_1 as *const _ as *const u8, - &mut unit_field_val as *mut u8 as *mut u8, - 1usize, - ) - }; - unit_field_val &= !mask; - unit_field_val |= (val << 1usize) & mask; - unsafe { - ::std::ptr::copy_nonoverlapping( - &unit_field_val as *const _ as *const u8, - &mut self._bitfield_1 as *mut _ as *mut u8, - 1usize, - ); + let val: u8 = ::std::mem::transmute(val); + self._bitfield_1.set(1usize, 1u8, val as u64) } } #[inline] pub fn hw_vlan_insert_pvid(&self) -> u8 { - let mut unit_field_val: u8 = unsafe { ::std::mem::uninitialized() }; - unsafe { - ::std::ptr::copy_nonoverlapping( - &self._bitfield_1 as *const _ as *const u8, - &mut unit_field_val as *mut u8 as *mut u8, - 1usize, - ) - }; - let mask = 0x4 as u8; - let val = (unit_field_val & mask) >> 2usize; - unsafe { ::std::mem::transmute(val as u8) } + unsafe { ::std::mem::transmute(self._bitfield_1.get(2usize, 1u8) as u8) } } #[inline] pub fn set_hw_vlan_insert_pvid(&mut self, val: u8) { - let mask = 0x4 as u8; - let val = val as u8 as u8; - let mut unit_field_val: u8 = unsafe { ::std::mem::uninitialized() }; - unsafe { - ::std::ptr::copy_nonoverlapping( - &self._bitfield_1 as *const _ as *const u8, - &mut unit_field_val as *mut u8 as *mut u8, - 1usize, - ) - }; - unit_field_val &= !mask; - unit_field_val |= (val << 2usize) & mask; unsafe { - ::std::ptr::copy_nonoverlapping( - &unit_field_val as *const _ as *const u8, - &mut self._bitfield_1 as *mut _ as *mut u8, - 1usize, - ); + let val: u8 = ::std::mem::transmute(val); + self._bitfield_1.set(2usize, 1u8, val as u64) } } #[inline] @@ -630,10 +439,23 @@ impl rte_eth_txmode { hw_vlan_reject_tagged: u8, hw_vlan_reject_untagged: u8, hw_vlan_insert_pvid: u8, - ) -> u8 { - (((0 | ((hw_vlan_reject_tagged as u8 as u8) << 0usize) & (0x1 as u8)) - | ((hw_vlan_reject_untagged as u8 as u8) << 1usize) & (0x2 as u8)) - | ((hw_vlan_insert_pvid as u8 as u8) << 2usize) & (0x4 as u8)) + ) -> __BindgenBitfieldUnit<[u8; 1usize], u8> { + let mut __bindgen_bitfield_unit: __BindgenBitfieldUnit<[u8; 1usize], u8> = + Default::default(); + __bindgen_bitfield_unit.set(0usize, 1u8, { + let hw_vlan_reject_tagged: u8 = unsafe { ::std::mem::transmute(hw_vlan_reject_tagged) }; + hw_vlan_reject_tagged as u64 + }); + __bindgen_bitfield_unit.set(1usize, 1u8, { + let hw_vlan_reject_untagged: u8 = + unsafe { ::std::mem::transmute(hw_vlan_reject_untagged) }; + hw_vlan_reject_untagged as u64 + }); + __bindgen_bitfield_unit.set(2usize, 1u8, { + let hw_vlan_insert_pvid: u8 = unsafe { ::std::mem::transmute(hw_vlan_insert_pvid) }; + hw_vlan_insert_pvid as u64 + }); + __bindgen_bitfield_unit } } /// A structure used to configure the Receive Side Scaling (RSS) feature diff --git a/tests/expectations/tests/layout_eth_conf_1_0.rs b/tests/expectations/tests/layout_eth_conf_1_0.rs index 2ff4e87e3b..8b7bfb638e 100644 --- a/tests/expectations/tests/layout_eth_conf_1_0.rs +++ b/tests/expectations/tests/layout_eth_conf_1_0.rs @@ -4,6 +4,85 @@ #![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] +#[repr(C)] +#[derive(Copy, Clone, Debug, Default, Eq, Hash, Ord, PartialEq, PartialOrd)] +pub struct __BindgenBitfieldUnit +where + Storage: AsRef<[u8]> + AsMut<[u8]>, +{ + storage: Storage, + align: [Align; 0], +} + +impl __BindgenBitfieldUnit +where + Storage: AsRef<[u8]> + AsMut<[u8]>, +{ + #[inline] + pub fn new(storage: Storage) -> Self { + Self { storage, align: [] } + } + + #[inline] + pub fn get_bit(&self, index: usize) -> bool { + debug_assert!(index / 8 < self.storage.as_ref().len()); + + let byte_index = index / 8; + let byte = self.storage.as_ref()[byte_index]; + + let bit_index = index % 8; + let mask = 1 << bit_index; + + byte & mask == mask + } + + #[inline] + pub fn set_bit(&mut self, index: usize, val: bool) { + debug_assert!(index / 8 < self.storage.as_ref().len()); + + let byte_index = index / 8; + let byte = &mut self.storage.as_mut()[byte_index]; + + let bit_index = index % 8; + let mask = 1 << bit_index; + + if val { + *byte |= mask; + } else { + *byte &= !mask; + } + } + + #[inline] + pub fn get(&self, bit_offset: usize, bit_width: u8) -> u64 { + debug_assert!(bit_width <= 64); + debug_assert!(bit_offset / 8 < self.storage.as_ref().len()); + debug_assert!((bit_offset + (bit_width as usize)) / 8 <= self.storage.as_ref().len()); + + let mut val = 0; + + for i in 0..(bit_width as usize) { + if self.get_bit(i + bit_offset) { + val |= 1 << i; + } + } + + val + } + + #[inline] + pub fn set(&mut self, bit_offset: usize, bit_width: u8, val: u64) { + debug_assert!(bit_width <= 64); + debug_assert!(bit_offset / 8 < self.storage.as_ref().len()); + debug_assert!((bit_offset + (bit_width as usize)) / 8 <= self.storage.as_ref().len()); + + for i in 0..(bit_width as usize) { + let mask = 1 << i; + let val_bit_is_set = val & mask == mask; + self.set_bit(i + bit_offset, val_bit_is_set); + } + } +} #[repr(C)] pub struct __BindgenUnionField(::std::marker::PhantomData); impl __BindgenUnionField { @@ -103,7 +182,7 @@ pub struct rte_eth_rxmode { pub max_rx_pkt_len: u32, /// < hdr buf size (header_split enabled). pub split_hdr_size: u16, - pub _bitfield_1: [u8; 2usize], + pub _bitfield_1: __BindgenBitfieldUnit<[u8; 2usize], u8>, } #[test] fn bindgen_test_layout_rte_eth_rxmode() { @@ -161,326 +240,101 @@ impl Default for rte_eth_rxmode { impl rte_eth_rxmode { #[inline] pub fn header_split(&self) -> u16 { - let mut unit_field_val: u16 = unsafe { ::std::mem::uninitialized() }; - unsafe { - ::std::ptr::copy_nonoverlapping( - &self._bitfield_1 as *const _ as *const u8, - &mut unit_field_val as *mut u16 as *mut u8, - 2usize, - ) - }; - let mask = 0x1 as u16; - let val = (unit_field_val & mask) >> 0usize; - unsafe { ::std::mem::transmute(val as u16) } + unsafe { ::std::mem::transmute(self._bitfield_1.get(0usize, 1u8) as u16) } } #[inline] pub fn set_header_split(&mut self, val: u16) { - let mask = 0x1 as u16; - let val = val as u16 as u16; - let mut unit_field_val: u16 = unsafe { ::std::mem::uninitialized() }; unsafe { - ::std::ptr::copy_nonoverlapping( - &self._bitfield_1 as *const _ as *const u8, - &mut unit_field_val as *mut u16 as *mut u8, - 2usize, - ) - }; - unit_field_val &= !mask; - unit_field_val |= (val << 0usize) & mask; - unsafe { - ::std::ptr::copy_nonoverlapping( - &unit_field_val as *const _ as *const u8, - &mut self._bitfield_1 as *mut _ as *mut u8, - 2usize, - ); + let val: u16 = ::std::mem::transmute(val); + self._bitfield_1.set(0usize, 1u8, val as u64) } } #[inline] pub fn hw_ip_checksum(&self) -> u16 { - let mut unit_field_val: u16 = unsafe { ::std::mem::uninitialized() }; - unsafe { - ::std::ptr::copy_nonoverlapping( - &self._bitfield_1 as *const _ as *const u8, - &mut unit_field_val as *mut u16 as *mut u8, - 2usize, - ) - }; - let mask = 0x2 as u16; - let val = (unit_field_val & mask) >> 1usize; - unsafe { ::std::mem::transmute(val as u16) } + unsafe { ::std::mem::transmute(self._bitfield_1.get(1usize, 1u8) as u16) } } #[inline] pub fn set_hw_ip_checksum(&mut self, val: u16) { - let mask = 0x2 as u16; - let val = val as u16 as u16; - let mut unit_field_val: u16 = unsafe { ::std::mem::uninitialized() }; - unsafe { - ::std::ptr::copy_nonoverlapping( - &self._bitfield_1 as *const _ as *const u8, - &mut unit_field_val as *mut u16 as *mut u8, - 2usize, - ) - }; - unit_field_val &= !mask; - unit_field_val |= (val << 1usize) & mask; unsafe { - ::std::ptr::copy_nonoverlapping( - &unit_field_val as *const _ as *const u8, - &mut self._bitfield_1 as *mut _ as *mut u8, - 2usize, - ); + let val: u16 = ::std::mem::transmute(val); + self._bitfield_1.set(1usize, 1u8, val as u64) } } #[inline] pub fn hw_vlan_filter(&self) -> u16 { - let mut unit_field_val: u16 = unsafe { ::std::mem::uninitialized() }; - unsafe { - ::std::ptr::copy_nonoverlapping( - &self._bitfield_1 as *const _ as *const u8, - &mut unit_field_val as *mut u16 as *mut u8, - 2usize, - ) - }; - let mask = 0x4 as u16; - let val = (unit_field_val & mask) >> 2usize; - unsafe { ::std::mem::transmute(val as u16) } + unsafe { ::std::mem::transmute(self._bitfield_1.get(2usize, 1u8) as u16) } } #[inline] pub fn set_hw_vlan_filter(&mut self, val: u16) { - let mask = 0x4 as u16; - let val = val as u16 as u16; - let mut unit_field_val: u16 = unsafe { ::std::mem::uninitialized() }; - unsafe { - ::std::ptr::copy_nonoverlapping( - &self._bitfield_1 as *const _ as *const u8, - &mut unit_field_val as *mut u16 as *mut u8, - 2usize, - ) - }; - unit_field_val &= !mask; - unit_field_val |= (val << 2usize) & mask; unsafe { - ::std::ptr::copy_nonoverlapping( - &unit_field_val as *const _ as *const u8, - &mut self._bitfield_1 as *mut _ as *mut u8, - 2usize, - ); + let val: u16 = ::std::mem::transmute(val); + self._bitfield_1.set(2usize, 1u8, val as u64) } } #[inline] pub fn hw_vlan_strip(&self) -> u16 { - let mut unit_field_val: u16 = unsafe { ::std::mem::uninitialized() }; - unsafe { - ::std::ptr::copy_nonoverlapping( - &self._bitfield_1 as *const _ as *const u8, - &mut unit_field_val as *mut u16 as *mut u8, - 2usize, - ) - }; - let mask = 0x8 as u16; - let val = (unit_field_val & mask) >> 3usize; - unsafe { ::std::mem::transmute(val as u16) } + unsafe { ::std::mem::transmute(self._bitfield_1.get(3usize, 1u8) as u16) } } #[inline] pub fn set_hw_vlan_strip(&mut self, val: u16) { - let mask = 0x8 as u16; - let val = val as u16 as u16; - let mut unit_field_val: u16 = unsafe { ::std::mem::uninitialized() }; - unsafe { - ::std::ptr::copy_nonoverlapping( - &self._bitfield_1 as *const _ as *const u8, - &mut unit_field_val as *mut u16 as *mut u8, - 2usize, - ) - }; - unit_field_val &= !mask; - unit_field_val |= (val << 3usize) & mask; unsafe { - ::std::ptr::copy_nonoverlapping( - &unit_field_val as *const _ as *const u8, - &mut self._bitfield_1 as *mut _ as *mut u8, - 2usize, - ); + let val: u16 = ::std::mem::transmute(val); + self._bitfield_1.set(3usize, 1u8, val as u64) } } #[inline] pub fn hw_vlan_extend(&self) -> u16 { - let mut unit_field_val: u16 = unsafe { ::std::mem::uninitialized() }; - unsafe { - ::std::ptr::copy_nonoverlapping( - &self._bitfield_1 as *const _ as *const u8, - &mut unit_field_val as *mut u16 as *mut u8, - 2usize, - ) - }; - let mask = 0x10 as u16; - let val = (unit_field_val & mask) >> 4usize; - unsafe { ::std::mem::transmute(val as u16) } + unsafe { ::std::mem::transmute(self._bitfield_1.get(4usize, 1u8) as u16) } } #[inline] pub fn set_hw_vlan_extend(&mut self, val: u16) { - let mask = 0x10 as u16; - let val = val as u16 as u16; - let mut unit_field_val: u16 = unsafe { ::std::mem::uninitialized() }; - unsafe { - ::std::ptr::copy_nonoverlapping( - &self._bitfield_1 as *const _ as *const u8, - &mut unit_field_val as *mut u16 as *mut u8, - 2usize, - ) - }; - unit_field_val &= !mask; - unit_field_val |= (val << 4usize) & mask; unsafe { - ::std::ptr::copy_nonoverlapping( - &unit_field_val as *const _ as *const u8, - &mut self._bitfield_1 as *mut _ as *mut u8, - 2usize, - ); + let val: u16 = ::std::mem::transmute(val); + self._bitfield_1.set(4usize, 1u8, val as u64) } } #[inline] pub fn jumbo_frame(&self) -> u16 { - let mut unit_field_val: u16 = unsafe { ::std::mem::uninitialized() }; - unsafe { - ::std::ptr::copy_nonoverlapping( - &self._bitfield_1 as *const _ as *const u8, - &mut unit_field_val as *mut u16 as *mut u8, - 2usize, - ) - }; - let mask = 0x20 as u16; - let val = (unit_field_val & mask) >> 5usize; - unsafe { ::std::mem::transmute(val as u16) } + unsafe { ::std::mem::transmute(self._bitfield_1.get(5usize, 1u8) as u16) } } #[inline] pub fn set_jumbo_frame(&mut self, val: u16) { - let mask = 0x20 as u16; - let val = val as u16 as u16; - let mut unit_field_val: u16 = unsafe { ::std::mem::uninitialized() }; unsafe { - ::std::ptr::copy_nonoverlapping( - &self._bitfield_1 as *const _ as *const u8, - &mut unit_field_val as *mut u16 as *mut u8, - 2usize, - ) - }; - unit_field_val &= !mask; - unit_field_val |= (val << 5usize) & mask; - unsafe { - ::std::ptr::copy_nonoverlapping( - &unit_field_val as *const _ as *const u8, - &mut self._bitfield_1 as *mut _ as *mut u8, - 2usize, - ); + let val: u16 = ::std::mem::transmute(val); + self._bitfield_1.set(5usize, 1u8, val as u64) } } #[inline] pub fn hw_strip_crc(&self) -> u16 { - let mut unit_field_val: u16 = unsafe { ::std::mem::uninitialized() }; - unsafe { - ::std::ptr::copy_nonoverlapping( - &self._bitfield_1 as *const _ as *const u8, - &mut unit_field_val as *mut u16 as *mut u8, - 2usize, - ) - }; - let mask = 0x40 as u16; - let val = (unit_field_val & mask) >> 6usize; - unsafe { ::std::mem::transmute(val as u16) } + unsafe { ::std::mem::transmute(self._bitfield_1.get(6usize, 1u8) as u16) } } #[inline] pub fn set_hw_strip_crc(&mut self, val: u16) { - let mask = 0x40 as u16; - let val = val as u16 as u16; - let mut unit_field_val: u16 = unsafe { ::std::mem::uninitialized() }; unsafe { - ::std::ptr::copy_nonoverlapping( - &self._bitfield_1 as *const _ as *const u8, - &mut unit_field_val as *mut u16 as *mut u8, - 2usize, - ) - }; - unit_field_val &= !mask; - unit_field_val |= (val << 6usize) & mask; - unsafe { - ::std::ptr::copy_nonoverlapping( - &unit_field_val as *const _ as *const u8, - &mut self._bitfield_1 as *mut _ as *mut u8, - 2usize, - ); + let val: u16 = ::std::mem::transmute(val); + self._bitfield_1.set(6usize, 1u8, val as u64) } } #[inline] pub fn enable_scatter(&self) -> u16 { - let mut unit_field_val: u16 = unsafe { ::std::mem::uninitialized() }; - unsafe { - ::std::ptr::copy_nonoverlapping( - &self._bitfield_1 as *const _ as *const u8, - &mut unit_field_val as *mut u16 as *mut u8, - 2usize, - ) - }; - let mask = 0x80 as u16; - let val = (unit_field_val & mask) >> 7usize; - unsafe { ::std::mem::transmute(val as u16) } + unsafe { ::std::mem::transmute(self._bitfield_1.get(7usize, 1u8) as u16) } } #[inline] pub fn set_enable_scatter(&mut self, val: u16) { - let mask = 0x80 as u16; - let val = val as u16 as u16; - let mut unit_field_val: u16 = unsafe { ::std::mem::uninitialized() }; unsafe { - ::std::ptr::copy_nonoverlapping( - &self._bitfield_1 as *const _ as *const u8, - &mut unit_field_val as *mut u16 as *mut u8, - 2usize, - ) - }; - unit_field_val &= !mask; - unit_field_val |= (val << 7usize) & mask; - unsafe { - ::std::ptr::copy_nonoverlapping( - &unit_field_val as *const _ as *const u8, - &mut self._bitfield_1 as *mut _ as *mut u8, - 2usize, - ); + let val: u16 = ::std::mem::transmute(val); + self._bitfield_1.set(7usize, 1u8, val as u64) } } #[inline] pub fn enable_lro(&self) -> u16 { - let mut unit_field_val: u16 = unsafe { ::std::mem::uninitialized() }; - unsafe { - ::std::ptr::copy_nonoverlapping( - &self._bitfield_1 as *const _ as *const u8, - &mut unit_field_val as *mut u16 as *mut u8, - 2usize, - ) - }; - let mask = 0x100 as u16; - let val = (unit_field_val & mask) >> 8usize; - unsafe { ::std::mem::transmute(val as u16) } + unsafe { ::std::mem::transmute(self._bitfield_1.get(8usize, 1u8) as u16) } } #[inline] pub fn set_enable_lro(&mut self, val: u16) { - let mask = 0x100 as u16; - let val = val as u16 as u16; - let mut unit_field_val: u16 = unsafe { ::std::mem::uninitialized() }; - unsafe { - ::std::ptr::copy_nonoverlapping( - &self._bitfield_1 as *const _ as *const u8, - &mut unit_field_val as *mut u16 as *mut u8, - 2usize, - ) - }; - unit_field_val &= !mask; - unit_field_val |= (val << 8usize) & mask; unsafe { - ::std::ptr::copy_nonoverlapping( - &unit_field_val as *const _ as *const u8, - &mut self._bitfield_1 as *mut _ as *mut u8, - 2usize, - ); + let val: u16 = ::std::mem::transmute(val); + self._bitfield_1.set(8usize, 1u8, val as u64) } } #[inline] @@ -494,16 +348,46 @@ impl rte_eth_rxmode { hw_strip_crc: u16, enable_scatter: u16, enable_lro: u16, - ) -> u16 { - (((((((((0 | ((header_split as u16 as u16) << 0usize) & (0x1 as u16)) - | ((hw_ip_checksum as u16 as u16) << 1usize) & (0x2 as u16)) - | ((hw_vlan_filter as u16 as u16) << 2usize) & (0x4 as u16)) - | ((hw_vlan_strip as u16 as u16) << 3usize) & (0x8 as u16)) - | ((hw_vlan_extend as u16 as u16) << 4usize) & (0x10 as u16)) - | ((jumbo_frame as u16 as u16) << 5usize) & (0x20 as u16)) - | ((hw_strip_crc as u16 as u16) << 6usize) & (0x40 as u16)) - | ((enable_scatter as u16 as u16) << 7usize) & (0x80 as u16)) - | ((enable_lro as u16 as u16) << 8usize) & (0x100 as u16)) + ) -> __BindgenBitfieldUnit<[u8; 2usize], u8> { + let mut __bindgen_bitfield_unit: __BindgenBitfieldUnit<[u8; 2usize], u8> = + Default::default(); + __bindgen_bitfield_unit.set(0usize, 1u8, { + let header_split: u16 = unsafe { ::std::mem::transmute(header_split) }; + header_split as u64 + }); + __bindgen_bitfield_unit.set(1usize, 1u8, { + let hw_ip_checksum: u16 = unsafe { ::std::mem::transmute(hw_ip_checksum) }; + hw_ip_checksum as u64 + }); + __bindgen_bitfield_unit.set(2usize, 1u8, { + let hw_vlan_filter: u16 = unsafe { ::std::mem::transmute(hw_vlan_filter) }; + hw_vlan_filter as u64 + }); + __bindgen_bitfield_unit.set(3usize, 1u8, { + let hw_vlan_strip: u16 = unsafe { ::std::mem::transmute(hw_vlan_strip) }; + hw_vlan_strip as u64 + }); + __bindgen_bitfield_unit.set(4usize, 1u8, { + let hw_vlan_extend: u16 = unsafe { ::std::mem::transmute(hw_vlan_extend) }; + hw_vlan_extend as u64 + }); + __bindgen_bitfield_unit.set(5usize, 1u8, { + let jumbo_frame: u16 = unsafe { ::std::mem::transmute(jumbo_frame) }; + jumbo_frame as u64 + }); + __bindgen_bitfield_unit.set(6usize, 1u8, { + let hw_strip_crc: u16 = unsafe { ::std::mem::transmute(hw_strip_crc) }; + hw_strip_crc as u64 + }); + __bindgen_bitfield_unit.set(7usize, 1u8, { + let enable_scatter: u16 = unsafe { ::std::mem::transmute(enable_scatter) }; + enable_scatter as u64 + }); + __bindgen_bitfield_unit.set(8usize, 1u8, { + let enable_lro: u16 = unsafe { ::std::mem::transmute(enable_lro) }; + enable_lro as u64 + }); + __bindgen_bitfield_unit } } #[repr(u32)] @@ -523,7 +407,7 @@ pub struct rte_eth_txmode { /// < TX multi-queues mode. pub mq_mode: rte_eth_tx_mq_mode, pub pvid: u16, - pub _bitfield_1: u8, + pub _bitfield_1: __BindgenBitfieldUnit<[u8; 1usize], u8>, pub __bindgen_padding_0: u8, } #[test] @@ -572,110 +456,35 @@ impl Default for rte_eth_txmode { impl rte_eth_txmode { #[inline] pub fn hw_vlan_reject_tagged(&self) -> u8 { - let mut unit_field_val: u8 = unsafe { ::std::mem::uninitialized() }; - unsafe { - ::std::ptr::copy_nonoverlapping( - &self._bitfield_1 as *const _ as *const u8, - &mut unit_field_val as *mut u8 as *mut u8, - 1usize, - ) - }; - let mask = 0x1 as u8; - let val = (unit_field_val & mask) >> 0usize; - unsafe { ::std::mem::transmute(val as u8) } + unsafe { ::std::mem::transmute(self._bitfield_1.get(0usize, 1u8) as u8) } } #[inline] pub fn set_hw_vlan_reject_tagged(&mut self, val: u8) { - let mask = 0x1 as u8; - let val = val as u8 as u8; - let mut unit_field_val: u8 = unsafe { ::std::mem::uninitialized() }; - unsafe { - ::std::ptr::copy_nonoverlapping( - &self._bitfield_1 as *const _ as *const u8, - &mut unit_field_val as *mut u8 as *mut u8, - 1usize, - ) - }; - unit_field_val &= !mask; - unit_field_val |= (val << 0usize) & mask; unsafe { - ::std::ptr::copy_nonoverlapping( - &unit_field_val as *const _ as *const u8, - &mut self._bitfield_1 as *mut _ as *mut u8, - 1usize, - ); + let val: u8 = ::std::mem::transmute(val); + self._bitfield_1.set(0usize, 1u8, val as u64) } } #[inline] pub fn hw_vlan_reject_untagged(&self) -> u8 { - let mut unit_field_val: u8 = unsafe { ::std::mem::uninitialized() }; - unsafe { - ::std::ptr::copy_nonoverlapping( - &self._bitfield_1 as *const _ as *const u8, - &mut unit_field_val as *mut u8 as *mut u8, - 1usize, - ) - }; - let mask = 0x2 as u8; - let val = (unit_field_val & mask) >> 1usize; - unsafe { ::std::mem::transmute(val as u8) } + unsafe { ::std::mem::transmute(self._bitfield_1.get(1usize, 1u8) as u8) } } #[inline] pub fn set_hw_vlan_reject_untagged(&mut self, val: u8) { - let mask = 0x2 as u8; - let val = val as u8 as u8; - let mut unit_field_val: u8 = unsafe { ::std::mem::uninitialized() }; unsafe { - ::std::ptr::copy_nonoverlapping( - &self._bitfield_1 as *const _ as *const u8, - &mut unit_field_val as *mut u8 as *mut u8, - 1usize, - ) - }; - unit_field_val &= !mask; - unit_field_val |= (val << 1usize) & mask; - unsafe { - ::std::ptr::copy_nonoverlapping( - &unit_field_val as *const _ as *const u8, - &mut self._bitfield_1 as *mut _ as *mut u8, - 1usize, - ); + let val: u8 = ::std::mem::transmute(val); + self._bitfield_1.set(1usize, 1u8, val as u64) } } #[inline] pub fn hw_vlan_insert_pvid(&self) -> u8 { - let mut unit_field_val: u8 = unsafe { ::std::mem::uninitialized() }; - unsafe { - ::std::ptr::copy_nonoverlapping( - &self._bitfield_1 as *const _ as *const u8, - &mut unit_field_val as *mut u8 as *mut u8, - 1usize, - ) - }; - let mask = 0x4 as u8; - let val = (unit_field_val & mask) >> 2usize; - unsafe { ::std::mem::transmute(val as u8) } + unsafe { ::std::mem::transmute(self._bitfield_1.get(2usize, 1u8) as u8) } } #[inline] pub fn set_hw_vlan_insert_pvid(&mut self, val: u8) { - let mask = 0x4 as u8; - let val = val as u8 as u8; - let mut unit_field_val: u8 = unsafe { ::std::mem::uninitialized() }; - unsafe { - ::std::ptr::copy_nonoverlapping( - &self._bitfield_1 as *const _ as *const u8, - &mut unit_field_val as *mut u8 as *mut u8, - 1usize, - ) - }; - unit_field_val &= !mask; - unit_field_val |= (val << 2usize) & mask; unsafe { - ::std::ptr::copy_nonoverlapping( - &unit_field_val as *const _ as *const u8, - &mut self._bitfield_1 as *mut _ as *mut u8, - 1usize, - ); + let val: u8 = ::std::mem::transmute(val); + self._bitfield_1.set(2usize, 1u8, val as u64) } } #[inline] @@ -683,10 +492,23 @@ impl rte_eth_txmode { hw_vlan_reject_tagged: u8, hw_vlan_reject_untagged: u8, hw_vlan_insert_pvid: u8, - ) -> u8 { - (((0 | ((hw_vlan_reject_tagged as u8 as u8) << 0usize) & (0x1 as u8)) - | ((hw_vlan_reject_untagged as u8 as u8) << 1usize) & (0x2 as u8)) - | ((hw_vlan_insert_pvid as u8 as u8) << 2usize) & (0x4 as u8)) + ) -> __BindgenBitfieldUnit<[u8; 1usize], u8> { + let mut __bindgen_bitfield_unit: __BindgenBitfieldUnit<[u8; 1usize], u8> = + Default::default(); + __bindgen_bitfield_unit.set(0usize, 1u8, { + let hw_vlan_reject_tagged: u8 = unsafe { ::std::mem::transmute(hw_vlan_reject_tagged) }; + hw_vlan_reject_tagged as u64 + }); + __bindgen_bitfield_unit.set(1usize, 1u8, { + let hw_vlan_reject_untagged: u8 = + unsafe { ::std::mem::transmute(hw_vlan_reject_untagged) }; + hw_vlan_reject_untagged as u64 + }); + __bindgen_bitfield_unit.set(2usize, 1u8, { + let hw_vlan_insert_pvid: u8 = unsafe { ::std::mem::transmute(hw_vlan_insert_pvid) }; + hw_vlan_insert_pvid as u64 + }); + __bindgen_bitfield_unit } } /// A structure used to configure the Receive Side Scaling (RSS) feature diff --git a/tests/expectations/tests/layout_mbuf.rs b/tests/expectations/tests/layout_mbuf.rs index 339771d906..683dbd23eb 100644 --- a/tests/expectations/tests/layout_mbuf.rs +++ b/tests/expectations/tests/layout_mbuf.rs @@ -4,6 +4,85 @@ #![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] +#[repr(C)] +#[derive(Copy, Clone, Debug, Default, Eq, Hash, Ord, PartialEq, PartialOrd)] +pub struct __BindgenBitfieldUnit +where + Storage: AsRef<[u8]> + AsMut<[u8]>, +{ + storage: Storage, + align: [Align; 0], +} + +impl __BindgenBitfieldUnit +where + Storage: AsRef<[u8]> + AsMut<[u8]>, +{ + #[inline] + pub fn new(storage: Storage) -> Self { + Self { storage, align: [] } + } + + #[inline] + pub fn get_bit(&self, index: usize) -> bool { + debug_assert!(index / 8 < self.storage.as_ref().len()); + + let byte_index = index / 8; + let byte = self.storage.as_ref()[byte_index]; + + let bit_index = index % 8; + let mask = 1 << bit_index; + + byte & mask == mask + } + + #[inline] + pub fn set_bit(&mut self, index: usize, val: bool) { + debug_assert!(index / 8 < self.storage.as_ref().len()); + + let byte_index = index / 8; + let byte = &mut self.storage.as_mut()[byte_index]; + + let bit_index = index % 8; + let mask = 1 << bit_index; + + if val { + *byte |= mask; + } else { + *byte &= !mask; + } + } + + #[inline] + pub fn get(&self, bit_offset: usize, bit_width: u8) -> u64 { + debug_assert!(bit_width <= 64); + debug_assert!(bit_offset / 8 < self.storage.as_ref().len()); + debug_assert!((bit_offset + (bit_width as usize)) / 8 <= self.storage.as_ref().len()); + + let mut val = 0; + + for i in 0..(bit_width as usize) { + if self.get_bit(i + bit_offset) { + val |= 1 << i; + } + } + + val + } + + #[inline] + pub fn set(&mut self, bit_offset: usize, bit_width: u8, val: u64) { + debug_assert!(bit_width <= 64); + debug_assert!(bit_offset / 8 < self.storage.as_ref().len()); + debug_assert!((bit_offset + (bit_width as usize)) / 8 <= self.storage.as_ref().len()); + + for i in 0..(bit_width as usize) { + let mask = 1 << i; + let val_bit_is_set = val & mask == mask; + self.set_bit(i + bit_offset, val_bit_is_set); + } + } +} pub const RTE_CACHE_LINE_MIN_SIZE: ::std::os::raw::c_uint = 64; pub const RTE_CACHE_LINE_SIZE: ::std::os::raw::c_uint = 64; pub type phys_addr_t = u64; @@ -151,7 +230,7 @@ pub union rte_mbuf__bindgen_ty_2 { #[repr(C)] #[derive(Debug, Default, Copy, Clone, Hash, PartialEq, Eq)] pub struct rte_mbuf__bindgen_ty_2__bindgen_ty_1 { - pub _bitfield_1: [u8; 4usize], + pub _bitfield_1: __BindgenBitfieldUnit<[u8; 4usize], u8>, pub __bindgen_align: [u32; 0usize], } #[test] @@ -176,254 +255,79 @@ fn bindgen_test_layout_rte_mbuf__bindgen_ty_2__bindgen_ty_1() { impl rte_mbuf__bindgen_ty_2__bindgen_ty_1 { #[inline] pub fn l2_type(&self) -> u32 { - let mut unit_field_val: u32 = unsafe { ::std::mem::uninitialized() }; - unsafe { - ::std::ptr::copy_nonoverlapping( - &self._bitfield_1 as *const _ as *const u8, - &mut unit_field_val as *mut u32 as *mut u8, - 4usize, - ) - }; - let mask = 0xf as u32; - let val = (unit_field_val & mask) >> 0usize; - unsafe { ::std::mem::transmute(val as u32) } + unsafe { ::std::mem::transmute(self._bitfield_1.get(0usize, 4u8) as u32) } } #[inline] pub fn set_l2_type(&mut self, val: u32) { - let mask = 0xf as u32; - let val = val as u32 as u32; - let mut unit_field_val: u32 = unsafe { ::std::mem::uninitialized() }; - unsafe { - ::std::ptr::copy_nonoverlapping( - &self._bitfield_1 as *const _ as *const u8, - &mut unit_field_val as *mut u32 as *mut u8, - 4usize, - ) - }; - unit_field_val &= !mask; - unit_field_val |= (val << 0usize) & mask; unsafe { - ::std::ptr::copy_nonoverlapping( - &unit_field_val as *const _ as *const u8, - &mut self._bitfield_1 as *mut _ as *mut u8, - 4usize, - ); + let val: u32 = ::std::mem::transmute(val); + self._bitfield_1.set(0usize, 4u8, val as u64) } } #[inline] pub fn l3_type(&self) -> u32 { - let mut unit_field_val: u32 = unsafe { ::std::mem::uninitialized() }; - unsafe { - ::std::ptr::copy_nonoverlapping( - &self._bitfield_1 as *const _ as *const u8, - &mut unit_field_val as *mut u32 as *mut u8, - 4usize, - ) - }; - let mask = 0xf0 as u32; - let val = (unit_field_val & mask) >> 4usize; - unsafe { ::std::mem::transmute(val as u32) } + unsafe { ::std::mem::transmute(self._bitfield_1.get(4usize, 4u8) as u32) } } #[inline] pub fn set_l3_type(&mut self, val: u32) { - let mask = 0xf0 as u32; - let val = val as u32 as u32; - let mut unit_field_val: u32 = unsafe { ::std::mem::uninitialized() }; - unsafe { - ::std::ptr::copy_nonoverlapping( - &self._bitfield_1 as *const _ as *const u8, - &mut unit_field_val as *mut u32 as *mut u8, - 4usize, - ) - }; - unit_field_val &= !mask; - unit_field_val |= (val << 4usize) & mask; unsafe { - ::std::ptr::copy_nonoverlapping( - &unit_field_val as *const _ as *const u8, - &mut self._bitfield_1 as *mut _ as *mut u8, - 4usize, - ); + let val: u32 = ::std::mem::transmute(val); + self._bitfield_1.set(4usize, 4u8, val as u64) } } #[inline] pub fn l4_type(&self) -> u32 { - let mut unit_field_val: u32 = unsafe { ::std::mem::uninitialized() }; - unsafe { - ::std::ptr::copy_nonoverlapping( - &self._bitfield_1 as *const _ as *const u8, - &mut unit_field_val as *mut u32 as *mut u8, - 4usize, - ) - }; - let mask = 0xf00 as u32; - let val = (unit_field_val & mask) >> 8usize; - unsafe { ::std::mem::transmute(val as u32) } + unsafe { ::std::mem::transmute(self._bitfield_1.get(8usize, 4u8) as u32) } } #[inline] pub fn set_l4_type(&mut self, val: u32) { - let mask = 0xf00 as u32; - let val = val as u32 as u32; - let mut unit_field_val: u32 = unsafe { ::std::mem::uninitialized() }; unsafe { - ::std::ptr::copy_nonoverlapping( - &self._bitfield_1 as *const _ as *const u8, - &mut unit_field_val as *mut u32 as *mut u8, - 4usize, - ) - }; - unit_field_val &= !mask; - unit_field_val |= (val << 8usize) & mask; - unsafe { - ::std::ptr::copy_nonoverlapping( - &unit_field_val as *const _ as *const u8, - &mut self._bitfield_1 as *mut _ as *mut u8, - 4usize, - ); + let val: u32 = ::std::mem::transmute(val); + self._bitfield_1.set(8usize, 4u8, val as u64) } } #[inline] pub fn tun_type(&self) -> u32 { - let mut unit_field_val: u32 = unsafe { ::std::mem::uninitialized() }; - unsafe { - ::std::ptr::copy_nonoverlapping( - &self._bitfield_1 as *const _ as *const u8, - &mut unit_field_val as *mut u32 as *mut u8, - 4usize, - ) - }; - let mask = 0xf000 as u32; - let val = (unit_field_val & mask) >> 12usize; - unsafe { ::std::mem::transmute(val as u32) } + unsafe { ::std::mem::transmute(self._bitfield_1.get(12usize, 4u8) as u32) } } #[inline] pub fn set_tun_type(&mut self, val: u32) { - let mask = 0xf000 as u32; - let val = val as u32 as u32; - let mut unit_field_val: u32 = unsafe { ::std::mem::uninitialized() }; unsafe { - ::std::ptr::copy_nonoverlapping( - &self._bitfield_1 as *const _ as *const u8, - &mut unit_field_val as *mut u32 as *mut u8, - 4usize, - ) - }; - unit_field_val &= !mask; - unit_field_val |= (val << 12usize) & mask; - unsafe { - ::std::ptr::copy_nonoverlapping( - &unit_field_val as *const _ as *const u8, - &mut self._bitfield_1 as *mut _ as *mut u8, - 4usize, - ); + let val: u32 = ::std::mem::transmute(val); + self._bitfield_1.set(12usize, 4u8, val as u64) } } #[inline] pub fn inner_l2_type(&self) -> u32 { - let mut unit_field_val: u32 = unsafe { ::std::mem::uninitialized() }; - unsafe { - ::std::ptr::copy_nonoverlapping( - &self._bitfield_1 as *const _ as *const u8, - &mut unit_field_val as *mut u32 as *mut u8, - 4usize, - ) - }; - let mask = 0xf0000 as u32; - let val = (unit_field_val & mask) >> 16usize; - unsafe { ::std::mem::transmute(val as u32) } + unsafe { ::std::mem::transmute(self._bitfield_1.get(16usize, 4u8) as u32) } } #[inline] pub fn set_inner_l2_type(&mut self, val: u32) { - let mask = 0xf0000 as u32; - let val = val as u32 as u32; - let mut unit_field_val: u32 = unsafe { ::std::mem::uninitialized() }; unsafe { - ::std::ptr::copy_nonoverlapping( - &self._bitfield_1 as *const _ as *const u8, - &mut unit_field_val as *mut u32 as *mut u8, - 4usize, - ) - }; - unit_field_val &= !mask; - unit_field_val |= (val << 16usize) & mask; - unsafe { - ::std::ptr::copy_nonoverlapping( - &unit_field_val as *const _ as *const u8, - &mut self._bitfield_1 as *mut _ as *mut u8, - 4usize, - ); + let val: u32 = ::std::mem::transmute(val); + self._bitfield_1.set(16usize, 4u8, val as u64) } } #[inline] pub fn inner_l3_type(&self) -> u32 { - let mut unit_field_val: u32 = unsafe { ::std::mem::uninitialized() }; - unsafe { - ::std::ptr::copy_nonoverlapping( - &self._bitfield_1 as *const _ as *const u8, - &mut unit_field_val as *mut u32 as *mut u8, - 4usize, - ) - }; - let mask = 0xf00000 as u32; - let val = (unit_field_val & mask) >> 20usize; - unsafe { ::std::mem::transmute(val as u32) } + unsafe { ::std::mem::transmute(self._bitfield_1.get(20usize, 4u8) as u32) } } #[inline] pub fn set_inner_l3_type(&mut self, val: u32) { - let mask = 0xf00000 as u32; - let val = val as u32 as u32; - let mut unit_field_val: u32 = unsafe { ::std::mem::uninitialized() }; - unsafe { - ::std::ptr::copy_nonoverlapping( - &self._bitfield_1 as *const _ as *const u8, - &mut unit_field_val as *mut u32 as *mut u8, - 4usize, - ) - }; - unit_field_val &= !mask; - unit_field_val |= (val << 20usize) & mask; unsafe { - ::std::ptr::copy_nonoverlapping( - &unit_field_val as *const _ as *const u8, - &mut self._bitfield_1 as *mut _ as *mut u8, - 4usize, - ); + let val: u32 = ::std::mem::transmute(val); + self._bitfield_1.set(20usize, 4u8, val as u64) } } #[inline] pub fn inner_l4_type(&self) -> u32 { - let mut unit_field_val: u32 = unsafe { ::std::mem::uninitialized() }; - unsafe { - ::std::ptr::copy_nonoverlapping( - &self._bitfield_1 as *const _ as *const u8, - &mut unit_field_val as *mut u32 as *mut u8, - 4usize, - ) - }; - let mask = 0xf000000 as u32; - let val = (unit_field_val & mask) >> 24usize; - unsafe { ::std::mem::transmute(val as u32) } + unsafe { ::std::mem::transmute(self._bitfield_1.get(24usize, 4u8) as u32) } } #[inline] pub fn set_inner_l4_type(&mut self, val: u32) { - let mask = 0xf000000 as u32; - let val = val as u32 as u32; - let mut unit_field_val: u32 = unsafe { ::std::mem::uninitialized() }; - unsafe { - ::std::ptr::copy_nonoverlapping( - &self._bitfield_1 as *const _ as *const u8, - &mut unit_field_val as *mut u32 as *mut u8, - 4usize, - ) - }; - unit_field_val &= !mask; - unit_field_val |= (val << 24usize) & mask; unsafe { - ::std::ptr::copy_nonoverlapping( - &unit_field_val as *const _ as *const u8, - &mut self._bitfield_1 as *mut _ as *mut u8, - 4usize, - ); + let val: u32 = ::std::mem::transmute(val); + self._bitfield_1.set(24usize, 4u8, val as u64) } } #[inline] @@ -435,14 +339,38 @@ impl rte_mbuf__bindgen_ty_2__bindgen_ty_1 { inner_l2_type: u32, inner_l3_type: u32, inner_l4_type: u32, - ) -> u32 { - (((((((0 | ((l2_type as u32 as u32) << 0usize) & (0xf as u32)) - | ((l3_type as u32 as u32) << 4usize) & (0xf0 as u32)) - | ((l4_type as u32 as u32) << 8usize) & (0xf00 as u32)) - | ((tun_type as u32 as u32) << 12usize) & (0xf000 as u32)) - | ((inner_l2_type as u32 as u32) << 16usize) & (0xf0000 as u32)) - | ((inner_l3_type as u32 as u32) << 20usize) & (0xf00000 as u32)) - | ((inner_l4_type as u32 as u32) << 24usize) & (0xf000000 as u32)) + ) -> __BindgenBitfieldUnit<[u8; 4usize], u8> { + let mut __bindgen_bitfield_unit: __BindgenBitfieldUnit<[u8; 4usize], u8> = + Default::default(); + __bindgen_bitfield_unit.set(0usize, 4u8, { + let l2_type: u32 = unsafe { ::std::mem::transmute(l2_type) }; + l2_type as u64 + }); + __bindgen_bitfield_unit.set(4usize, 4u8, { + let l3_type: u32 = unsafe { ::std::mem::transmute(l3_type) }; + l3_type as u64 + }); + __bindgen_bitfield_unit.set(8usize, 4u8, { + let l4_type: u32 = unsafe { ::std::mem::transmute(l4_type) }; + l4_type as u64 + }); + __bindgen_bitfield_unit.set(12usize, 4u8, { + let tun_type: u32 = unsafe { ::std::mem::transmute(tun_type) }; + tun_type as u64 + }); + __bindgen_bitfield_unit.set(16usize, 4u8, { + let inner_l2_type: u32 = unsafe { ::std::mem::transmute(inner_l2_type) }; + inner_l2_type as u64 + }); + __bindgen_bitfield_unit.set(20usize, 4u8, { + let inner_l3_type: u32 = unsafe { ::std::mem::transmute(inner_l3_type) }; + inner_l3_type as u64 + }); + __bindgen_bitfield_unit.set(24usize, 4u8, { + let inner_l4_type: u32 = unsafe { ::std::mem::transmute(inner_l4_type) }; + inner_l4_type as u64 + }); + __bindgen_bitfield_unit } } #[test] @@ -782,7 +710,7 @@ pub union rte_mbuf__bindgen_ty_5 { #[repr(C)] #[derive(Debug, Default, Copy, Clone, Hash, PartialEq, Eq)] pub struct rte_mbuf__bindgen_ty_5__bindgen_ty_1 { - pub _bitfield_1: [u16; 4usize], + pub _bitfield_1: __BindgenBitfieldUnit<[u8; 8usize], u16>, pub __bindgen_align: [u64; 0usize], } #[test] @@ -807,218 +735,68 @@ fn bindgen_test_layout_rte_mbuf__bindgen_ty_5__bindgen_ty_1() { impl rte_mbuf__bindgen_ty_5__bindgen_ty_1 { #[inline] pub fn l2_len(&self) -> u64 { - let mut unit_field_val: u64 = unsafe { ::std::mem::uninitialized() }; - unsafe { - ::std::ptr::copy_nonoverlapping( - &self._bitfield_1 as *const _ as *const u8, - &mut unit_field_val as *mut u64 as *mut u8, - 8usize, - ) - }; - let mask = 0x7f as u64; - let val = (unit_field_val & mask) >> 0usize; - unsafe { ::std::mem::transmute(val as u64) } + unsafe { ::std::mem::transmute(self._bitfield_1.get(0usize, 7u8) as u64) } } #[inline] pub fn set_l2_len(&mut self, val: u64) { - let mask = 0x7f as u64; - let val = val as u64 as u64; - let mut unit_field_val: u64 = unsafe { ::std::mem::uninitialized() }; - unsafe { - ::std::ptr::copy_nonoverlapping( - &self._bitfield_1 as *const _ as *const u8, - &mut unit_field_val as *mut u64 as *mut u8, - 8usize, - ) - }; - unit_field_val &= !mask; - unit_field_val |= (val << 0usize) & mask; unsafe { - ::std::ptr::copy_nonoverlapping( - &unit_field_val as *const _ as *const u8, - &mut self._bitfield_1 as *mut _ as *mut u8, - 8usize, - ); + let val: u64 = ::std::mem::transmute(val); + self._bitfield_1.set(0usize, 7u8, val as u64) } } #[inline] pub fn l3_len(&self) -> u64 { - let mut unit_field_val: u64 = unsafe { ::std::mem::uninitialized() }; - unsafe { - ::std::ptr::copy_nonoverlapping( - &self._bitfield_1 as *const _ as *const u8, - &mut unit_field_val as *mut u64 as *mut u8, - 8usize, - ) - }; - let mask = 0xff80 as u64; - let val = (unit_field_val & mask) >> 7usize; - unsafe { ::std::mem::transmute(val as u64) } + unsafe { ::std::mem::transmute(self._bitfield_1.get(7usize, 9u8) as u64) } } #[inline] pub fn set_l3_len(&mut self, val: u64) { - let mask = 0xff80 as u64; - let val = val as u64 as u64; - let mut unit_field_val: u64 = unsafe { ::std::mem::uninitialized() }; - unsafe { - ::std::ptr::copy_nonoverlapping( - &self._bitfield_1 as *const _ as *const u8, - &mut unit_field_val as *mut u64 as *mut u8, - 8usize, - ) - }; - unit_field_val &= !mask; - unit_field_val |= (val << 7usize) & mask; unsafe { - ::std::ptr::copy_nonoverlapping( - &unit_field_val as *const _ as *const u8, - &mut self._bitfield_1 as *mut _ as *mut u8, - 8usize, - ); + let val: u64 = ::std::mem::transmute(val); + self._bitfield_1.set(7usize, 9u8, val as u64) } } #[inline] pub fn l4_len(&self) -> u64 { - let mut unit_field_val: u64 = unsafe { ::std::mem::uninitialized() }; - unsafe { - ::std::ptr::copy_nonoverlapping( - &self._bitfield_1 as *const _ as *const u8, - &mut unit_field_val as *mut u64 as *mut u8, - 8usize, - ) - }; - let mask = 0xff0000 as u64; - let val = (unit_field_val & mask) >> 16usize; - unsafe { ::std::mem::transmute(val as u64) } + unsafe { ::std::mem::transmute(self._bitfield_1.get(16usize, 8u8) as u64) } } #[inline] pub fn set_l4_len(&mut self, val: u64) { - let mask = 0xff0000 as u64; - let val = val as u64 as u64; - let mut unit_field_val: u64 = unsafe { ::std::mem::uninitialized() }; unsafe { - ::std::ptr::copy_nonoverlapping( - &self._bitfield_1 as *const _ as *const u8, - &mut unit_field_val as *mut u64 as *mut u8, - 8usize, - ) - }; - unit_field_val &= !mask; - unit_field_val |= (val << 16usize) & mask; - unsafe { - ::std::ptr::copy_nonoverlapping( - &unit_field_val as *const _ as *const u8, - &mut self._bitfield_1 as *mut _ as *mut u8, - 8usize, - ); + let val: u64 = ::std::mem::transmute(val); + self._bitfield_1.set(16usize, 8u8, val as u64) } } #[inline] pub fn tso_segsz(&self) -> u64 { - let mut unit_field_val: u64 = unsafe { ::std::mem::uninitialized() }; - unsafe { - ::std::ptr::copy_nonoverlapping( - &self._bitfield_1 as *const _ as *const u8, - &mut unit_field_val as *mut u64 as *mut u8, - 8usize, - ) - }; - let mask = 0xffff000000 as u64; - let val = (unit_field_val & mask) >> 24usize; - unsafe { ::std::mem::transmute(val as u64) } + unsafe { ::std::mem::transmute(self._bitfield_1.get(24usize, 16u8) as u64) } } #[inline] pub fn set_tso_segsz(&mut self, val: u64) { - let mask = 0xffff000000 as u64; - let val = val as u64 as u64; - let mut unit_field_val: u64 = unsafe { ::std::mem::uninitialized() }; unsafe { - ::std::ptr::copy_nonoverlapping( - &self._bitfield_1 as *const _ as *const u8, - &mut unit_field_val as *mut u64 as *mut u8, - 8usize, - ) - }; - unit_field_val &= !mask; - unit_field_val |= (val << 24usize) & mask; - unsafe { - ::std::ptr::copy_nonoverlapping( - &unit_field_val as *const _ as *const u8, - &mut self._bitfield_1 as *mut _ as *mut u8, - 8usize, - ); + let val: u64 = ::std::mem::transmute(val); + self._bitfield_1.set(24usize, 16u8, val as u64) } } #[inline] pub fn outer_l3_len(&self) -> u64 { - let mut unit_field_val: u64 = unsafe { ::std::mem::uninitialized() }; - unsafe { - ::std::ptr::copy_nonoverlapping( - &self._bitfield_1 as *const _ as *const u8, - &mut unit_field_val as *mut u64 as *mut u8, - 8usize, - ) - }; - let mask = 0x1ff0000000000 as u64; - let val = (unit_field_val & mask) >> 40usize; - unsafe { ::std::mem::transmute(val as u64) } + unsafe { ::std::mem::transmute(self._bitfield_1.get(40usize, 9u8) as u64) } } #[inline] pub fn set_outer_l3_len(&mut self, val: u64) { - let mask = 0x1ff0000000000 as u64; - let val = val as u64 as u64; - let mut unit_field_val: u64 = unsafe { ::std::mem::uninitialized() }; unsafe { - ::std::ptr::copy_nonoverlapping( - &self._bitfield_1 as *const _ as *const u8, - &mut unit_field_val as *mut u64 as *mut u8, - 8usize, - ) - }; - unit_field_val &= !mask; - unit_field_val |= (val << 40usize) & mask; - unsafe { - ::std::ptr::copy_nonoverlapping( - &unit_field_val as *const _ as *const u8, - &mut self._bitfield_1 as *mut _ as *mut u8, - 8usize, - ); + let val: u64 = ::std::mem::transmute(val); + self._bitfield_1.set(40usize, 9u8, val as u64) } } #[inline] pub fn outer_l2_len(&self) -> u64 { - let mut unit_field_val: u64 = unsafe { ::std::mem::uninitialized() }; - unsafe { - ::std::ptr::copy_nonoverlapping( - &self._bitfield_1 as *const _ as *const u8, - &mut unit_field_val as *mut u64 as *mut u8, - 8usize, - ) - }; - let mask = 0xfe000000000000 as u64; - let val = (unit_field_val & mask) >> 49usize; - unsafe { ::std::mem::transmute(val as u64) } + unsafe { ::std::mem::transmute(self._bitfield_1.get(49usize, 7u8) as u64) } } #[inline] pub fn set_outer_l2_len(&mut self, val: u64) { - let mask = 0xfe000000000000 as u64; - let val = val as u64 as u64; - let mut unit_field_val: u64 = unsafe { ::std::mem::uninitialized() }; - unsafe { - ::std::ptr::copy_nonoverlapping( - &self._bitfield_1 as *const _ as *const u8, - &mut unit_field_val as *mut u64 as *mut u8, - 8usize, - ) - }; - unit_field_val &= !mask; - unit_field_val |= (val << 49usize) & mask; unsafe { - ::std::ptr::copy_nonoverlapping( - &unit_field_val as *const _ as *const u8, - &mut self._bitfield_1 as *mut _ as *mut u8, - 8usize, - ); + let val: u64 = ::std::mem::transmute(val); + self._bitfield_1.set(49usize, 7u8, val as u64) } } #[inline] @@ -1029,13 +807,34 @@ impl rte_mbuf__bindgen_ty_5__bindgen_ty_1 { tso_segsz: u64, outer_l3_len: u64, outer_l2_len: u64, - ) -> u64 { - ((((((0 | ((l2_len as u64 as u64) << 0usize) & (0x7f as u64)) - | ((l3_len as u64 as u64) << 7usize) & (0xff80 as u64)) - | ((l4_len as u64 as u64) << 16usize) & (0xff0000 as u64)) - | ((tso_segsz as u64 as u64) << 24usize) & (0xffff000000 as u64)) - | ((outer_l3_len as u64 as u64) << 40usize) & (0x1ff0000000000 as u64)) - | ((outer_l2_len as u64 as u64) << 49usize) & (0xfe000000000000 as u64)) + ) -> __BindgenBitfieldUnit<[u8; 8usize], u16> { + let mut __bindgen_bitfield_unit: __BindgenBitfieldUnit<[u8; 8usize], u16> = + Default::default(); + __bindgen_bitfield_unit.set(0usize, 7u8, { + let l2_len: u64 = unsafe { ::std::mem::transmute(l2_len) }; + l2_len as u64 + }); + __bindgen_bitfield_unit.set(7usize, 9u8, { + let l3_len: u64 = unsafe { ::std::mem::transmute(l3_len) }; + l3_len as u64 + }); + __bindgen_bitfield_unit.set(16usize, 8u8, { + let l4_len: u64 = unsafe { ::std::mem::transmute(l4_len) }; + l4_len as u64 + }); + __bindgen_bitfield_unit.set(24usize, 16u8, { + let tso_segsz: u64 = unsafe { ::std::mem::transmute(tso_segsz) }; + tso_segsz as u64 + }); + __bindgen_bitfield_unit.set(40usize, 9u8, { + let outer_l3_len: u64 = unsafe { ::std::mem::transmute(outer_l3_len) }; + outer_l3_len as u64 + }); + __bindgen_bitfield_unit.set(49usize, 7u8, { + let outer_l2_len: u64 = unsafe { ::std::mem::transmute(outer_l2_len) }; + outer_l2_len as u64 + }); + __bindgen_bitfield_unit } } #[test] diff --git a/tests/expectations/tests/layout_mbuf_1_0.rs b/tests/expectations/tests/layout_mbuf_1_0.rs index 891dd6659c..a666f3c938 100644 --- a/tests/expectations/tests/layout_mbuf_1_0.rs +++ b/tests/expectations/tests/layout_mbuf_1_0.rs @@ -4,6 +4,85 @@ #![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] +#[repr(C)] +#[derive(Copy, Clone, Debug, Default, Eq, Hash, Ord, PartialEq, PartialOrd)] +pub struct __BindgenBitfieldUnit +where + Storage: AsRef<[u8]> + AsMut<[u8]>, +{ + storage: Storage, + align: [Align; 0], +} + +impl __BindgenBitfieldUnit +where + Storage: AsRef<[u8]> + AsMut<[u8]>, +{ + #[inline] + pub fn new(storage: Storage) -> Self { + Self { storage, align: [] } + } + + #[inline] + pub fn get_bit(&self, index: usize) -> bool { + debug_assert!(index / 8 < self.storage.as_ref().len()); + + let byte_index = index / 8; + let byte = self.storage.as_ref()[byte_index]; + + let bit_index = index % 8; + let mask = 1 << bit_index; + + byte & mask == mask + } + + #[inline] + pub fn set_bit(&mut self, index: usize, val: bool) { + debug_assert!(index / 8 < self.storage.as_ref().len()); + + let byte_index = index / 8; + let byte = &mut self.storage.as_mut()[byte_index]; + + let bit_index = index % 8; + let mask = 1 << bit_index; + + if val { + *byte |= mask; + } else { + *byte &= !mask; + } + } + + #[inline] + pub fn get(&self, bit_offset: usize, bit_width: u8) -> u64 { + debug_assert!(bit_width <= 64); + debug_assert!(bit_offset / 8 < self.storage.as_ref().len()); + debug_assert!((bit_offset + (bit_width as usize)) / 8 <= self.storage.as_ref().len()); + + let mut val = 0; + + for i in 0..(bit_width as usize) { + if self.get_bit(i + bit_offset) { + val |= 1 << i; + } + } + + val + } + + #[inline] + pub fn set(&mut self, bit_offset: usize, bit_width: u8, val: u64) { + debug_assert!(bit_width <= 64); + debug_assert!(bit_offset / 8 < self.storage.as_ref().len()); + debug_assert!((bit_offset + (bit_width as usize)) / 8 <= self.storage.as_ref().len()); + + for i in 0..(bit_width as usize) { + let mask = 1 << i; + let val_bit_is_set = val & mask == mask; + self.set_bit(i + bit_offset, val_bit_is_set); + } + } +} #[repr(C)] pub struct __BindgenUnionField(::std::marker::PhantomData); impl __BindgenUnionField { @@ -199,7 +278,7 @@ pub struct rte_mbuf__bindgen_ty_2 { #[repr(C)] #[derive(Debug, Default, Copy, Hash, PartialEq, Eq)] pub struct rte_mbuf__bindgen_ty_2__bindgen_ty_1 { - pub _bitfield_1: [u8; 4usize], + pub _bitfield_1: __BindgenBitfieldUnit<[u8; 4usize], u8>, pub __bindgen_align: [u32; 0usize], } #[test] @@ -229,254 +308,79 @@ impl Clone for rte_mbuf__bindgen_ty_2__bindgen_ty_1 { impl rte_mbuf__bindgen_ty_2__bindgen_ty_1 { #[inline] pub fn l2_type(&self) -> u32 { - let mut unit_field_val: u32 = unsafe { ::std::mem::uninitialized() }; - unsafe { - ::std::ptr::copy_nonoverlapping( - &self._bitfield_1 as *const _ as *const u8, - &mut unit_field_val as *mut u32 as *mut u8, - 4usize, - ) - }; - let mask = 0xf as u32; - let val = (unit_field_val & mask) >> 0usize; - unsafe { ::std::mem::transmute(val as u32) } + unsafe { ::std::mem::transmute(self._bitfield_1.get(0usize, 4u8) as u32) } } #[inline] pub fn set_l2_type(&mut self, val: u32) { - let mask = 0xf as u32; - let val = val as u32 as u32; - let mut unit_field_val: u32 = unsafe { ::std::mem::uninitialized() }; - unsafe { - ::std::ptr::copy_nonoverlapping( - &self._bitfield_1 as *const _ as *const u8, - &mut unit_field_val as *mut u32 as *mut u8, - 4usize, - ) - }; - unit_field_val &= !mask; - unit_field_val |= (val << 0usize) & mask; unsafe { - ::std::ptr::copy_nonoverlapping( - &unit_field_val as *const _ as *const u8, - &mut self._bitfield_1 as *mut _ as *mut u8, - 4usize, - ); + let val: u32 = ::std::mem::transmute(val); + self._bitfield_1.set(0usize, 4u8, val as u64) } } #[inline] pub fn l3_type(&self) -> u32 { - let mut unit_field_val: u32 = unsafe { ::std::mem::uninitialized() }; - unsafe { - ::std::ptr::copy_nonoverlapping( - &self._bitfield_1 as *const _ as *const u8, - &mut unit_field_val as *mut u32 as *mut u8, - 4usize, - ) - }; - let mask = 0xf0 as u32; - let val = (unit_field_val & mask) >> 4usize; - unsafe { ::std::mem::transmute(val as u32) } + unsafe { ::std::mem::transmute(self._bitfield_1.get(4usize, 4u8) as u32) } } #[inline] pub fn set_l3_type(&mut self, val: u32) { - let mask = 0xf0 as u32; - let val = val as u32 as u32; - let mut unit_field_val: u32 = unsafe { ::std::mem::uninitialized() }; - unsafe { - ::std::ptr::copy_nonoverlapping( - &self._bitfield_1 as *const _ as *const u8, - &mut unit_field_val as *mut u32 as *mut u8, - 4usize, - ) - }; - unit_field_val &= !mask; - unit_field_val |= (val << 4usize) & mask; unsafe { - ::std::ptr::copy_nonoverlapping( - &unit_field_val as *const _ as *const u8, - &mut self._bitfield_1 as *mut _ as *mut u8, - 4usize, - ); + let val: u32 = ::std::mem::transmute(val); + self._bitfield_1.set(4usize, 4u8, val as u64) } } #[inline] pub fn l4_type(&self) -> u32 { - let mut unit_field_val: u32 = unsafe { ::std::mem::uninitialized() }; - unsafe { - ::std::ptr::copy_nonoverlapping( - &self._bitfield_1 as *const _ as *const u8, - &mut unit_field_val as *mut u32 as *mut u8, - 4usize, - ) - }; - let mask = 0xf00 as u32; - let val = (unit_field_val & mask) >> 8usize; - unsafe { ::std::mem::transmute(val as u32) } + unsafe { ::std::mem::transmute(self._bitfield_1.get(8usize, 4u8) as u32) } } #[inline] pub fn set_l4_type(&mut self, val: u32) { - let mask = 0xf00 as u32; - let val = val as u32 as u32; - let mut unit_field_val: u32 = unsafe { ::std::mem::uninitialized() }; unsafe { - ::std::ptr::copy_nonoverlapping( - &self._bitfield_1 as *const _ as *const u8, - &mut unit_field_val as *mut u32 as *mut u8, - 4usize, - ) - }; - unit_field_val &= !mask; - unit_field_val |= (val << 8usize) & mask; - unsafe { - ::std::ptr::copy_nonoverlapping( - &unit_field_val as *const _ as *const u8, - &mut self._bitfield_1 as *mut _ as *mut u8, - 4usize, - ); + let val: u32 = ::std::mem::transmute(val); + self._bitfield_1.set(8usize, 4u8, val as u64) } } #[inline] pub fn tun_type(&self) -> u32 { - let mut unit_field_val: u32 = unsafe { ::std::mem::uninitialized() }; - unsafe { - ::std::ptr::copy_nonoverlapping( - &self._bitfield_1 as *const _ as *const u8, - &mut unit_field_val as *mut u32 as *mut u8, - 4usize, - ) - }; - let mask = 0xf000 as u32; - let val = (unit_field_val & mask) >> 12usize; - unsafe { ::std::mem::transmute(val as u32) } + unsafe { ::std::mem::transmute(self._bitfield_1.get(12usize, 4u8) as u32) } } #[inline] pub fn set_tun_type(&mut self, val: u32) { - let mask = 0xf000 as u32; - let val = val as u32 as u32; - let mut unit_field_val: u32 = unsafe { ::std::mem::uninitialized() }; unsafe { - ::std::ptr::copy_nonoverlapping( - &self._bitfield_1 as *const _ as *const u8, - &mut unit_field_val as *mut u32 as *mut u8, - 4usize, - ) - }; - unit_field_val &= !mask; - unit_field_val |= (val << 12usize) & mask; - unsafe { - ::std::ptr::copy_nonoverlapping( - &unit_field_val as *const _ as *const u8, - &mut self._bitfield_1 as *mut _ as *mut u8, - 4usize, - ); + let val: u32 = ::std::mem::transmute(val); + self._bitfield_1.set(12usize, 4u8, val as u64) } } #[inline] pub fn inner_l2_type(&self) -> u32 { - let mut unit_field_val: u32 = unsafe { ::std::mem::uninitialized() }; - unsafe { - ::std::ptr::copy_nonoverlapping( - &self._bitfield_1 as *const _ as *const u8, - &mut unit_field_val as *mut u32 as *mut u8, - 4usize, - ) - }; - let mask = 0xf0000 as u32; - let val = (unit_field_val & mask) >> 16usize; - unsafe { ::std::mem::transmute(val as u32) } + unsafe { ::std::mem::transmute(self._bitfield_1.get(16usize, 4u8) as u32) } } #[inline] pub fn set_inner_l2_type(&mut self, val: u32) { - let mask = 0xf0000 as u32; - let val = val as u32 as u32; - let mut unit_field_val: u32 = unsafe { ::std::mem::uninitialized() }; unsafe { - ::std::ptr::copy_nonoverlapping( - &self._bitfield_1 as *const _ as *const u8, - &mut unit_field_val as *mut u32 as *mut u8, - 4usize, - ) - }; - unit_field_val &= !mask; - unit_field_val |= (val << 16usize) & mask; - unsafe { - ::std::ptr::copy_nonoverlapping( - &unit_field_val as *const _ as *const u8, - &mut self._bitfield_1 as *mut _ as *mut u8, - 4usize, - ); + let val: u32 = ::std::mem::transmute(val); + self._bitfield_1.set(16usize, 4u8, val as u64) } } #[inline] pub fn inner_l3_type(&self) -> u32 { - let mut unit_field_val: u32 = unsafe { ::std::mem::uninitialized() }; - unsafe { - ::std::ptr::copy_nonoverlapping( - &self._bitfield_1 as *const _ as *const u8, - &mut unit_field_val as *mut u32 as *mut u8, - 4usize, - ) - }; - let mask = 0xf00000 as u32; - let val = (unit_field_val & mask) >> 20usize; - unsafe { ::std::mem::transmute(val as u32) } + unsafe { ::std::mem::transmute(self._bitfield_1.get(20usize, 4u8) as u32) } } #[inline] pub fn set_inner_l3_type(&mut self, val: u32) { - let mask = 0xf00000 as u32; - let val = val as u32 as u32; - let mut unit_field_val: u32 = unsafe { ::std::mem::uninitialized() }; - unsafe { - ::std::ptr::copy_nonoverlapping( - &self._bitfield_1 as *const _ as *const u8, - &mut unit_field_val as *mut u32 as *mut u8, - 4usize, - ) - }; - unit_field_val &= !mask; - unit_field_val |= (val << 20usize) & mask; unsafe { - ::std::ptr::copy_nonoverlapping( - &unit_field_val as *const _ as *const u8, - &mut self._bitfield_1 as *mut _ as *mut u8, - 4usize, - ); + let val: u32 = ::std::mem::transmute(val); + self._bitfield_1.set(20usize, 4u8, val as u64) } } #[inline] pub fn inner_l4_type(&self) -> u32 { - let mut unit_field_val: u32 = unsafe { ::std::mem::uninitialized() }; - unsafe { - ::std::ptr::copy_nonoverlapping( - &self._bitfield_1 as *const _ as *const u8, - &mut unit_field_val as *mut u32 as *mut u8, - 4usize, - ) - }; - let mask = 0xf000000 as u32; - let val = (unit_field_val & mask) >> 24usize; - unsafe { ::std::mem::transmute(val as u32) } + unsafe { ::std::mem::transmute(self._bitfield_1.get(24usize, 4u8) as u32) } } #[inline] pub fn set_inner_l4_type(&mut self, val: u32) { - let mask = 0xf000000 as u32; - let val = val as u32 as u32; - let mut unit_field_val: u32 = unsafe { ::std::mem::uninitialized() }; - unsafe { - ::std::ptr::copy_nonoverlapping( - &self._bitfield_1 as *const _ as *const u8, - &mut unit_field_val as *mut u32 as *mut u8, - 4usize, - ) - }; - unit_field_val &= !mask; - unit_field_val |= (val << 24usize) & mask; unsafe { - ::std::ptr::copy_nonoverlapping( - &unit_field_val as *const _ as *const u8, - &mut self._bitfield_1 as *mut _ as *mut u8, - 4usize, - ); + let val: u32 = ::std::mem::transmute(val); + self._bitfield_1.set(24usize, 4u8, val as u64) } } #[inline] @@ -488,14 +392,38 @@ impl rte_mbuf__bindgen_ty_2__bindgen_ty_1 { inner_l2_type: u32, inner_l3_type: u32, inner_l4_type: u32, - ) -> u32 { - (((((((0 | ((l2_type as u32 as u32) << 0usize) & (0xf as u32)) - | ((l3_type as u32 as u32) << 4usize) & (0xf0 as u32)) - | ((l4_type as u32 as u32) << 8usize) & (0xf00 as u32)) - | ((tun_type as u32 as u32) << 12usize) & (0xf000 as u32)) - | ((inner_l2_type as u32 as u32) << 16usize) & (0xf0000 as u32)) - | ((inner_l3_type as u32 as u32) << 20usize) & (0xf00000 as u32)) - | ((inner_l4_type as u32 as u32) << 24usize) & (0xf000000 as u32)) + ) -> __BindgenBitfieldUnit<[u8; 4usize], u8> { + let mut __bindgen_bitfield_unit: __BindgenBitfieldUnit<[u8; 4usize], u8> = + Default::default(); + __bindgen_bitfield_unit.set(0usize, 4u8, { + let l2_type: u32 = unsafe { ::std::mem::transmute(l2_type) }; + l2_type as u64 + }); + __bindgen_bitfield_unit.set(4usize, 4u8, { + let l3_type: u32 = unsafe { ::std::mem::transmute(l3_type) }; + l3_type as u64 + }); + __bindgen_bitfield_unit.set(8usize, 4u8, { + let l4_type: u32 = unsafe { ::std::mem::transmute(l4_type) }; + l4_type as u64 + }); + __bindgen_bitfield_unit.set(12usize, 4u8, { + let tun_type: u32 = unsafe { ::std::mem::transmute(tun_type) }; + tun_type as u64 + }); + __bindgen_bitfield_unit.set(16usize, 4u8, { + let inner_l2_type: u32 = unsafe { ::std::mem::transmute(inner_l2_type) }; + inner_l2_type as u64 + }); + __bindgen_bitfield_unit.set(20usize, 4u8, { + let inner_l3_type: u32 = unsafe { ::std::mem::transmute(inner_l3_type) }; + inner_l3_type as u64 + }); + __bindgen_bitfield_unit.set(24usize, 4u8, { + let inner_l4_type: u32 = unsafe { ::std::mem::transmute(inner_l4_type) }; + inner_l4_type as u64 + }); + __bindgen_bitfield_unit } } #[test] @@ -846,7 +774,7 @@ pub struct rte_mbuf__bindgen_ty_5 { #[repr(C)] #[derive(Debug, Default, Copy, Hash, PartialEq, Eq)] pub struct rte_mbuf__bindgen_ty_5__bindgen_ty_1 { - pub _bitfield_1: [u16; 4usize], + pub _bitfield_1: __BindgenBitfieldUnit<[u8; 8usize], u16>, pub __bindgen_align: [u64; 0usize], } #[test] @@ -876,218 +804,68 @@ impl Clone for rte_mbuf__bindgen_ty_5__bindgen_ty_1 { impl rte_mbuf__bindgen_ty_5__bindgen_ty_1 { #[inline] pub fn l2_len(&self) -> u64 { - let mut unit_field_val: u64 = unsafe { ::std::mem::uninitialized() }; - unsafe { - ::std::ptr::copy_nonoverlapping( - &self._bitfield_1 as *const _ as *const u8, - &mut unit_field_val as *mut u64 as *mut u8, - 8usize, - ) - }; - let mask = 0x7f as u64; - let val = (unit_field_val & mask) >> 0usize; - unsafe { ::std::mem::transmute(val as u64) } + unsafe { ::std::mem::transmute(self._bitfield_1.get(0usize, 7u8) as u64) } } #[inline] pub fn set_l2_len(&mut self, val: u64) { - let mask = 0x7f as u64; - let val = val as u64 as u64; - let mut unit_field_val: u64 = unsafe { ::std::mem::uninitialized() }; - unsafe { - ::std::ptr::copy_nonoverlapping( - &self._bitfield_1 as *const _ as *const u8, - &mut unit_field_val as *mut u64 as *mut u8, - 8usize, - ) - }; - unit_field_val &= !mask; - unit_field_val |= (val << 0usize) & mask; unsafe { - ::std::ptr::copy_nonoverlapping( - &unit_field_val as *const _ as *const u8, - &mut self._bitfield_1 as *mut _ as *mut u8, - 8usize, - ); + let val: u64 = ::std::mem::transmute(val); + self._bitfield_1.set(0usize, 7u8, val as u64) } } #[inline] pub fn l3_len(&self) -> u64 { - let mut unit_field_val: u64 = unsafe { ::std::mem::uninitialized() }; - unsafe { - ::std::ptr::copy_nonoverlapping( - &self._bitfield_1 as *const _ as *const u8, - &mut unit_field_val as *mut u64 as *mut u8, - 8usize, - ) - }; - let mask = 0xff80 as u64; - let val = (unit_field_val & mask) >> 7usize; - unsafe { ::std::mem::transmute(val as u64) } + unsafe { ::std::mem::transmute(self._bitfield_1.get(7usize, 9u8) as u64) } } #[inline] pub fn set_l3_len(&mut self, val: u64) { - let mask = 0xff80 as u64; - let val = val as u64 as u64; - let mut unit_field_val: u64 = unsafe { ::std::mem::uninitialized() }; - unsafe { - ::std::ptr::copy_nonoverlapping( - &self._bitfield_1 as *const _ as *const u8, - &mut unit_field_val as *mut u64 as *mut u8, - 8usize, - ) - }; - unit_field_val &= !mask; - unit_field_val |= (val << 7usize) & mask; unsafe { - ::std::ptr::copy_nonoverlapping( - &unit_field_val as *const _ as *const u8, - &mut self._bitfield_1 as *mut _ as *mut u8, - 8usize, - ); + let val: u64 = ::std::mem::transmute(val); + self._bitfield_1.set(7usize, 9u8, val as u64) } } #[inline] pub fn l4_len(&self) -> u64 { - let mut unit_field_val: u64 = unsafe { ::std::mem::uninitialized() }; - unsafe { - ::std::ptr::copy_nonoverlapping( - &self._bitfield_1 as *const _ as *const u8, - &mut unit_field_val as *mut u64 as *mut u8, - 8usize, - ) - }; - let mask = 0xff0000 as u64; - let val = (unit_field_val & mask) >> 16usize; - unsafe { ::std::mem::transmute(val as u64) } + unsafe { ::std::mem::transmute(self._bitfield_1.get(16usize, 8u8) as u64) } } #[inline] pub fn set_l4_len(&mut self, val: u64) { - let mask = 0xff0000 as u64; - let val = val as u64 as u64; - let mut unit_field_val: u64 = unsafe { ::std::mem::uninitialized() }; unsafe { - ::std::ptr::copy_nonoverlapping( - &self._bitfield_1 as *const _ as *const u8, - &mut unit_field_val as *mut u64 as *mut u8, - 8usize, - ) - }; - unit_field_val &= !mask; - unit_field_val |= (val << 16usize) & mask; - unsafe { - ::std::ptr::copy_nonoverlapping( - &unit_field_val as *const _ as *const u8, - &mut self._bitfield_1 as *mut _ as *mut u8, - 8usize, - ); + let val: u64 = ::std::mem::transmute(val); + self._bitfield_1.set(16usize, 8u8, val as u64) } } #[inline] pub fn tso_segsz(&self) -> u64 { - let mut unit_field_val: u64 = unsafe { ::std::mem::uninitialized() }; - unsafe { - ::std::ptr::copy_nonoverlapping( - &self._bitfield_1 as *const _ as *const u8, - &mut unit_field_val as *mut u64 as *mut u8, - 8usize, - ) - }; - let mask = 0xffff000000 as u64; - let val = (unit_field_val & mask) >> 24usize; - unsafe { ::std::mem::transmute(val as u64) } + unsafe { ::std::mem::transmute(self._bitfield_1.get(24usize, 16u8) as u64) } } #[inline] pub fn set_tso_segsz(&mut self, val: u64) { - let mask = 0xffff000000 as u64; - let val = val as u64 as u64; - let mut unit_field_val: u64 = unsafe { ::std::mem::uninitialized() }; unsafe { - ::std::ptr::copy_nonoverlapping( - &self._bitfield_1 as *const _ as *const u8, - &mut unit_field_val as *mut u64 as *mut u8, - 8usize, - ) - }; - unit_field_val &= !mask; - unit_field_val |= (val << 24usize) & mask; - unsafe { - ::std::ptr::copy_nonoverlapping( - &unit_field_val as *const _ as *const u8, - &mut self._bitfield_1 as *mut _ as *mut u8, - 8usize, - ); + let val: u64 = ::std::mem::transmute(val); + self._bitfield_1.set(24usize, 16u8, val as u64) } } #[inline] pub fn outer_l3_len(&self) -> u64 { - let mut unit_field_val: u64 = unsafe { ::std::mem::uninitialized() }; - unsafe { - ::std::ptr::copy_nonoverlapping( - &self._bitfield_1 as *const _ as *const u8, - &mut unit_field_val as *mut u64 as *mut u8, - 8usize, - ) - }; - let mask = 0x1ff0000000000 as u64; - let val = (unit_field_val & mask) >> 40usize; - unsafe { ::std::mem::transmute(val as u64) } + unsafe { ::std::mem::transmute(self._bitfield_1.get(40usize, 9u8) as u64) } } #[inline] pub fn set_outer_l3_len(&mut self, val: u64) { - let mask = 0x1ff0000000000 as u64; - let val = val as u64 as u64; - let mut unit_field_val: u64 = unsafe { ::std::mem::uninitialized() }; unsafe { - ::std::ptr::copy_nonoverlapping( - &self._bitfield_1 as *const _ as *const u8, - &mut unit_field_val as *mut u64 as *mut u8, - 8usize, - ) - }; - unit_field_val &= !mask; - unit_field_val |= (val << 40usize) & mask; - unsafe { - ::std::ptr::copy_nonoverlapping( - &unit_field_val as *const _ as *const u8, - &mut self._bitfield_1 as *mut _ as *mut u8, - 8usize, - ); + let val: u64 = ::std::mem::transmute(val); + self._bitfield_1.set(40usize, 9u8, val as u64) } } #[inline] pub fn outer_l2_len(&self) -> u64 { - let mut unit_field_val: u64 = unsafe { ::std::mem::uninitialized() }; - unsafe { - ::std::ptr::copy_nonoverlapping( - &self._bitfield_1 as *const _ as *const u8, - &mut unit_field_val as *mut u64 as *mut u8, - 8usize, - ) - }; - let mask = 0xfe000000000000 as u64; - let val = (unit_field_val & mask) >> 49usize; - unsafe { ::std::mem::transmute(val as u64) } + unsafe { ::std::mem::transmute(self._bitfield_1.get(49usize, 7u8) as u64) } } #[inline] pub fn set_outer_l2_len(&mut self, val: u64) { - let mask = 0xfe000000000000 as u64; - let val = val as u64 as u64; - let mut unit_field_val: u64 = unsafe { ::std::mem::uninitialized() }; - unsafe { - ::std::ptr::copy_nonoverlapping( - &self._bitfield_1 as *const _ as *const u8, - &mut unit_field_val as *mut u64 as *mut u8, - 8usize, - ) - }; - unit_field_val &= !mask; - unit_field_val |= (val << 49usize) & mask; unsafe { - ::std::ptr::copy_nonoverlapping( - &unit_field_val as *const _ as *const u8, - &mut self._bitfield_1 as *mut _ as *mut u8, - 8usize, - ); + let val: u64 = ::std::mem::transmute(val); + self._bitfield_1.set(49usize, 7u8, val as u64) } } #[inline] @@ -1098,13 +876,34 @@ impl rte_mbuf__bindgen_ty_5__bindgen_ty_1 { tso_segsz: u64, outer_l3_len: u64, outer_l2_len: u64, - ) -> u64 { - ((((((0 | ((l2_len as u64 as u64) << 0usize) & (0x7f as u64)) - | ((l3_len as u64 as u64) << 7usize) & (0xff80 as u64)) - | ((l4_len as u64 as u64) << 16usize) & (0xff0000 as u64)) - | ((tso_segsz as u64 as u64) << 24usize) & (0xffff000000 as u64)) - | ((outer_l3_len as u64 as u64) << 40usize) & (0x1ff0000000000 as u64)) - | ((outer_l2_len as u64 as u64) << 49usize) & (0xfe000000000000 as u64)) + ) -> __BindgenBitfieldUnit<[u8; 8usize], u16> { + let mut __bindgen_bitfield_unit: __BindgenBitfieldUnit<[u8; 8usize], u16> = + Default::default(); + __bindgen_bitfield_unit.set(0usize, 7u8, { + let l2_len: u64 = unsafe { ::std::mem::transmute(l2_len) }; + l2_len as u64 + }); + __bindgen_bitfield_unit.set(7usize, 9u8, { + let l3_len: u64 = unsafe { ::std::mem::transmute(l3_len) }; + l3_len as u64 + }); + __bindgen_bitfield_unit.set(16usize, 8u8, { + let l4_len: u64 = unsafe { ::std::mem::transmute(l4_len) }; + l4_len as u64 + }); + __bindgen_bitfield_unit.set(24usize, 16u8, { + let tso_segsz: u64 = unsafe { ::std::mem::transmute(tso_segsz) }; + tso_segsz as u64 + }); + __bindgen_bitfield_unit.set(40usize, 9u8, { + let outer_l3_len: u64 = unsafe { ::std::mem::transmute(outer_l3_len) }; + outer_l3_len as u64 + }); + __bindgen_bitfield_unit.set(49usize, 7u8, { + let outer_l2_len: u64 = unsafe { ::std::mem::transmute(outer_l2_len) }; + outer_l2_len as u64 + }); + __bindgen_bitfield_unit } } #[test] diff --git a/tests/expectations/tests/only_bitfields.rs b/tests/expectations/tests/only_bitfields.rs index f5f852710a..09bd8737ee 100644 --- a/tests/expectations/tests/only_bitfields.rs +++ b/tests/expectations/tests/only_bitfields.rs @@ -4,10 +4,89 @@ #![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] +#[repr(C)] +#[derive(Copy, Clone, Debug, Default, Eq, Hash, Ord, PartialEq, PartialOrd)] +pub struct __BindgenBitfieldUnit +where + Storage: AsRef<[u8]> + AsMut<[u8]>, +{ + storage: Storage, + align: [Align; 0], +} + +impl __BindgenBitfieldUnit +where + Storage: AsRef<[u8]> + AsMut<[u8]>, +{ + #[inline] + pub fn new(storage: Storage) -> Self { + Self { storage, align: [] } + } + + #[inline] + pub fn get_bit(&self, index: usize) -> bool { + debug_assert!(index / 8 < self.storage.as_ref().len()); + + let byte_index = index / 8; + let byte = self.storage.as_ref()[byte_index]; + + let bit_index = index % 8; + let mask = 1 << bit_index; + + byte & mask == mask + } + + #[inline] + pub fn set_bit(&mut self, index: usize, val: bool) { + debug_assert!(index / 8 < self.storage.as_ref().len()); + + let byte_index = index / 8; + let byte = &mut self.storage.as_mut()[byte_index]; + + let bit_index = index % 8; + let mask = 1 << bit_index; + + if val { + *byte |= mask; + } else { + *byte &= !mask; + } + } + + #[inline] + pub fn get(&self, bit_offset: usize, bit_width: u8) -> u64 { + debug_assert!(bit_width <= 64); + debug_assert!(bit_offset / 8 < self.storage.as_ref().len()); + debug_assert!((bit_offset + (bit_width as usize)) / 8 <= self.storage.as_ref().len()); + + let mut val = 0; + + for i in 0..(bit_width as usize) { + if self.get_bit(i + bit_offset) { + val |= 1 << i; + } + } + + val + } + + #[inline] + pub fn set(&mut self, bit_offset: usize, bit_width: u8, val: u64) { + debug_assert!(bit_width <= 64); + debug_assert!(bit_offset / 8 < self.storage.as_ref().len()); + debug_assert!((bit_offset + (bit_width as usize)) / 8 <= self.storage.as_ref().len()); + + for i in 0..(bit_width as usize) { + let mask = 1 << i; + let val_bit_is_set = val & mask == mask; + self.set_bit(i + bit_offset, val_bit_is_set); + } + } +} #[repr(C, packed)] #[derive(Debug, Default, Copy, Clone)] pub struct C { - pub _bitfield_1: u8, + pub _bitfield_1: __BindgenBitfieldUnit<[u8; 1usize], u8>, } #[test] fn bindgen_test_layout_C() { @@ -25,79 +104,38 @@ fn bindgen_test_layout_C() { impl C { #[inline] pub fn a(&self) -> bool { - let mut unit_field_val: u8 = unsafe { ::std::mem::uninitialized() }; - unsafe { - ::std::ptr::copy_nonoverlapping( - &self._bitfield_1 as *const _ as *const u8, - &mut unit_field_val as *mut u8 as *mut u8, - 1usize, - ) - }; - let mask = 0x1 as u8; - let val = (unit_field_val & mask) >> 0usize; - unsafe { ::std::mem::transmute(val as u8) } + unsafe { ::std::mem::transmute(self._bitfield_1.get(0usize, 1u8) as u8) } } #[inline] pub fn set_a(&mut self, val: bool) { - let mask = 0x1 as u8; - let val = val as u8 as u8; - let mut unit_field_val: u8 = unsafe { ::std::mem::uninitialized() }; - unsafe { - ::std::ptr::copy_nonoverlapping( - &self._bitfield_1 as *const _ as *const u8, - &mut unit_field_val as *mut u8 as *mut u8, - 1usize, - ) - }; - unit_field_val &= !mask; - unit_field_val |= (val << 0usize) & mask; unsafe { - ::std::ptr::copy_nonoverlapping( - &unit_field_val as *const _ as *const u8, - &mut self._bitfield_1 as *mut _ as *mut u8, - 1usize, - ); + let val: u8 = ::std::mem::transmute(val); + self._bitfield_1.set(0usize, 1u8, val as u64) } } #[inline] pub fn b(&self) -> bool { - let mut unit_field_val: u8 = unsafe { ::std::mem::uninitialized() }; - unsafe { - ::std::ptr::copy_nonoverlapping( - &self._bitfield_1 as *const _ as *const u8, - &mut unit_field_val as *mut u8 as *mut u8, - 1usize, - ) - }; - let mask = 0xfe as u8; - let val = (unit_field_val & mask) >> 1usize; - unsafe { ::std::mem::transmute(val as u8) } + unsafe { ::std::mem::transmute(self._bitfield_1.get(1usize, 7u8) as u8) } } #[inline] pub fn set_b(&mut self, val: bool) { - let mask = 0xfe as u8; - let val = val as u8 as u8; - let mut unit_field_val: u8 = unsafe { ::std::mem::uninitialized() }; - unsafe { - ::std::ptr::copy_nonoverlapping( - &self._bitfield_1 as *const _ as *const u8, - &mut unit_field_val as *mut u8 as *mut u8, - 1usize, - ) - }; - unit_field_val &= !mask; - unit_field_val |= (val << 1usize) & mask; unsafe { - ::std::ptr::copy_nonoverlapping( - &unit_field_val as *const _ as *const u8, - &mut self._bitfield_1 as *mut _ as *mut u8, - 1usize, - ); + let val: u8 = ::std::mem::transmute(val); + self._bitfield_1.set(1usize, 7u8, val as u64) } } #[inline] - pub fn new_bitfield_1(a: bool, b: bool) -> u8 { - ((0 | ((a as u8 as u8) << 0usize) & (0x1 as u8)) - | ((b as u8 as u8) << 1usize) & (0xfe as u8)) + pub fn new_bitfield_1(a: bool, b: bool) -> __BindgenBitfieldUnit<[u8; 1usize], u8> { + let mut __bindgen_bitfield_unit: __BindgenBitfieldUnit<[u8; 1usize], u8> = + Default::default(); + __bindgen_bitfield_unit.set(0usize, 1u8, { + let a: u8 = unsafe { ::std::mem::transmute(a) }; + a as u64 + }); + __bindgen_bitfield_unit.set(1usize, 7u8, { + let b: u8 = unsafe { ::std::mem::transmute(b) }; + b as u64 + }); + __bindgen_bitfield_unit } } diff --git a/tests/expectations/tests/struct_with_bitfields.rs b/tests/expectations/tests/struct_with_bitfields.rs index 5e6298e0cb..653a4288f3 100644 --- a/tests/expectations/tests/struct_with_bitfields.rs +++ b/tests/expectations/tests/struct_with_bitfields.rs @@ -4,12 +4,91 @@ #![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] +#[repr(C)] +#[derive(Copy, Clone, Debug, Default, Eq, Hash, Ord, PartialEq, PartialOrd)] +pub struct __BindgenBitfieldUnit +where + Storage: AsRef<[u8]> + AsMut<[u8]>, +{ + storage: Storage, + align: [Align; 0], +} + +impl __BindgenBitfieldUnit +where + Storage: AsRef<[u8]> + AsMut<[u8]>, +{ + #[inline] + pub fn new(storage: Storage) -> Self { + Self { storage, align: [] } + } + + #[inline] + pub fn get_bit(&self, index: usize) -> bool { + debug_assert!(index / 8 < self.storage.as_ref().len()); + + let byte_index = index / 8; + let byte = self.storage.as_ref()[byte_index]; + + let bit_index = index % 8; + let mask = 1 << bit_index; + + byte & mask == mask + } + + #[inline] + pub fn set_bit(&mut self, index: usize, val: bool) { + debug_assert!(index / 8 < self.storage.as_ref().len()); + + let byte_index = index / 8; + let byte = &mut self.storage.as_mut()[byte_index]; + + let bit_index = index % 8; + let mask = 1 << bit_index; + + if val { + *byte |= mask; + } else { + *byte &= !mask; + } + } + + #[inline] + pub fn get(&self, bit_offset: usize, bit_width: u8) -> u64 { + debug_assert!(bit_width <= 64); + debug_assert!(bit_offset / 8 < self.storage.as_ref().len()); + debug_assert!((bit_offset + (bit_width as usize)) / 8 <= self.storage.as_ref().len()); + + let mut val = 0; + + for i in 0..(bit_width as usize) { + if self.get_bit(i + bit_offset) { + val |= 1 << i; + } + } + + val + } + + #[inline] + pub fn set(&mut self, bit_offset: usize, bit_width: u8, val: u64) { + debug_assert!(bit_width <= 64); + debug_assert!(bit_offset / 8 < self.storage.as_ref().len()); + debug_assert!((bit_offset + (bit_width as usize)) / 8 <= self.storage.as_ref().len()); + + for i in 0..(bit_width as usize) { + let mask = 1 << i; + let val_bit_is_set = val & mask == mask; + self.set_bit(i + bit_offset, val_bit_is_set); + } + } +} #[repr(C)] #[derive(Debug, Default, Copy, Clone, Hash, PartialEq, Eq)] pub struct bitfield { - pub _bitfield_1: u8, + pub _bitfield_1: __BindgenBitfieldUnit<[u8; 1usize], u8>, pub e: ::std::os::raw::c_int, - pub _bitfield_2: [u32; 2usize], + pub _bitfield_2: __BindgenBitfieldUnit<[u8; 8usize], u32>, } #[test] fn bindgen_test_layout_bitfield() { @@ -37,146 +116,46 @@ fn bindgen_test_layout_bitfield() { impl bitfield { #[inline] pub fn a(&self) -> ::std::os::raw::c_ushort { - let mut unit_field_val: u8 = unsafe { ::std::mem::uninitialized() }; - unsafe { - ::std::ptr::copy_nonoverlapping( - &self._bitfield_1 as *const _ as *const u8, - &mut unit_field_val as *mut u8 as *mut u8, - 1usize, - ) - }; - let mask = 0x1 as u8; - let val = (unit_field_val & mask) >> 0usize; - unsafe { ::std::mem::transmute(val as u16) } + unsafe { ::std::mem::transmute(self._bitfield_1.get(0usize, 1u8) as u16) } } #[inline] pub fn set_a(&mut self, val: ::std::os::raw::c_ushort) { - let mask = 0x1 as u8; - let val = val as u16 as u8; - let mut unit_field_val: u8 = unsafe { ::std::mem::uninitialized() }; - unsafe { - ::std::ptr::copy_nonoverlapping( - &self._bitfield_1 as *const _ as *const u8, - &mut unit_field_val as *mut u8 as *mut u8, - 1usize, - ) - }; - unit_field_val &= !mask; - unit_field_val |= (val << 0usize) & mask; unsafe { - ::std::ptr::copy_nonoverlapping( - &unit_field_val as *const _ as *const u8, - &mut self._bitfield_1 as *mut _ as *mut u8, - 1usize, - ); + let val: u16 = ::std::mem::transmute(val); + self._bitfield_1.set(0usize, 1u8, val as u64) } } #[inline] pub fn b(&self) -> ::std::os::raw::c_ushort { - let mut unit_field_val: u8 = unsafe { ::std::mem::uninitialized() }; - unsafe { - ::std::ptr::copy_nonoverlapping( - &self._bitfield_1 as *const _ as *const u8, - &mut unit_field_val as *mut u8 as *mut u8, - 1usize, - ) - }; - let mask = 0x2 as u8; - let val = (unit_field_val & mask) >> 1usize; - unsafe { ::std::mem::transmute(val as u16) } + unsafe { ::std::mem::transmute(self._bitfield_1.get(1usize, 1u8) as u16) } } #[inline] pub fn set_b(&mut self, val: ::std::os::raw::c_ushort) { - let mask = 0x2 as u8; - let val = val as u16 as u8; - let mut unit_field_val: u8 = unsafe { ::std::mem::uninitialized() }; - unsafe { - ::std::ptr::copy_nonoverlapping( - &self._bitfield_1 as *const _ as *const u8, - &mut unit_field_val as *mut u8 as *mut u8, - 1usize, - ) - }; - unit_field_val &= !mask; - unit_field_val |= (val << 1usize) & mask; unsafe { - ::std::ptr::copy_nonoverlapping( - &unit_field_val as *const _ as *const u8, - &mut self._bitfield_1 as *mut _ as *mut u8, - 1usize, - ); + let val: u16 = ::std::mem::transmute(val); + self._bitfield_1.set(1usize, 1u8, val as u64) } } #[inline] pub fn c(&self) -> ::std::os::raw::c_ushort { - let mut unit_field_val: u8 = unsafe { ::std::mem::uninitialized() }; - unsafe { - ::std::ptr::copy_nonoverlapping( - &self._bitfield_1 as *const _ as *const u8, - &mut unit_field_val as *mut u8 as *mut u8, - 1usize, - ) - }; - let mask = 0x4 as u8; - let val = (unit_field_val & mask) >> 2usize; - unsafe { ::std::mem::transmute(val as u16) } + unsafe { ::std::mem::transmute(self._bitfield_1.get(2usize, 1u8) as u16) } } #[inline] pub fn set_c(&mut self, val: ::std::os::raw::c_ushort) { - let mask = 0x4 as u8; - let val = val as u16 as u8; - let mut unit_field_val: u8 = unsafe { ::std::mem::uninitialized() }; unsafe { - ::std::ptr::copy_nonoverlapping( - &self._bitfield_1 as *const _ as *const u8, - &mut unit_field_val as *mut u8 as *mut u8, - 1usize, - ) - }; - unit_field_val &= !mask; - unit_field_val |= (val << 2usize) & mask; - unsafe { - ::std::ptr::copy_nonoverlapping( - &unit_field_val as *const _ as *const u8, - &mut self._bitfield_1 as *mut _ as *mut u8, - 1usize, - ); + let val: u16 = ::std::mem::transmute(val); + self._bitfield_1.set(2usize, 1u8, val as u64) } } #[inline] pub fn d(&self) -> ::std::os::raw::c_ushort { - let mut unit_field_val: u8 = unsafe { ::std::mem::uninitialized() }; - unsafe { - ::std::ptr::copy_nonoverlapping( - &self._bitfield_1 as *const _ as *const u8, - &mut unit_field_val as *mut u8 as *mut u8, - 1usize, - ) - }; - let mask = 0xc0 as u8; - let val = (unit_field_val & mask) >> 6usize; - unsafe { ::std::mem::transmute(val as u16) } + unsafe { ::std::mem::transmute(self._bitfield_1.get(6usize, 2u8) as u16) } } #[inline] pub fn set_d(&mut self, val: ::std::os::raw::c_ushort) { - let mask = 0xc0 as u8; - let val = val as u16 as u8; - let mut unit_field_val: u8 = unsafe { ::std::mem::uninitialized() }; unsafe { - ::std::ptr::copy_nonoverlapping( - &self._bitfield_1 as *const _ as *const u8, - &mut unit_field_val as *mut u8 as *mut u8, - 1usize, - ) - }; - unit_field_val &= !mask; - unit_field_val |= (val << 6usize) & mask; - unsafe { - ::std::ptr::copy_nonoverlapping( - &unit_field_val as *const _ as *const u8, - &mut self._bitfield_1 as *mut _ as *mut u8, - 1usize, - ); + let val: u16 = ::std::mem::transmute(val); + self._bitfield_1.set(6usize, 2u8, val as u64) } } #[inline] @@ -185,87 +164,64 @@ impl bitfield { b: ::std::os::raw::c_ushort, c: ::std::os::raw::c_ushort, d: ::std::os::raw::c_ushort, - ) -> u8 { - ((((0 | ((a as u16 as u8) << 0usize) & (0x1 as u8)) - | ((b as u16 as u8) << 1usize) & (0x2 as u8)) - | ((c as u16 as u8) << 2usize) & (0x4 as u8)) - | ((d as u16 as u8) << 6usize) & (0xc0 as u8)) + ) -> __BindgenBitfieldUnit<[u8; 1usize], u8> { + let mut __bindgen_bitfield_unit: __BindgenBitfieldUnit<[u8; 1usize], u8> = + Default::default(); + __bindgen_bitfield_unit.set(0usize, 1u8, { + let a: u16 = unsafe { ::std::mem::transmute(a) }; + a as u64 + }); + __bindgen_bitfield_unit.set(1usize, 1u8, { + let b: u16 = unsafe { ::std::mem::transmute(b) }; + b as u64 + }); + __bindgen_bitfield_unit.set(2usize, 1u8, { + let c: u16 = unsafe { ::std::mem::transmute(c) }; + c as u64 + }); + __bindgen_bitfield_unit.set(6usize, 2u8, { + let d: u16 = unsafe { ::std::mem::transmute(d) }; + d as u64 + }); + __bindgen_bitfield_unit } #[inline] pub fn f(&self) -> ::std::os::raw::c_uint { - let mut unit_field_val: u64 = unsafe { ::std::mem::uninitialized() }; - unsafe { - ::std::ptr::copy_nonoverlapping( - &self._bitfield_2 as *const _ as *const u8, - &mut unit_field_val as *mut u64 as *mut u8, - 8usize, - ) - }; - let mask = 0x3 as u64; - let val = (unit_field_val & mask) >> 0usize; - unsafe { ::std::mem::transmute(val as u32) } + unsafe { ::std::mem::transmute(self._bitfield_2.get(0usize, 2u8) as u32) } } #[inline] pub fn set_f(&mut self, val: ::std::os::raw::c_uint) { - let mask = 0x3 as u64; - let val = val as u32 as u64; - let mut unit_field_val: u64 = unsafe { ::std::mem::uninitialized() }; - unsafe { - ::std::ptr::copy_nonoverlapping( - &self._bitfield_2 as *const _ as *const u8, - &mut unit_field_val as *mut u64 as *mut u8, - 8usize, - ) - }; - unit_field_val &= !mask; - unit_field_val |= (val << 0usize) & mask; unsafe { - ::std::ptr::copy_nonoverlapping( - &unit_field_val as *const _ as *const u8, - &mut self._bitfield_2 as *mut _ as *mut u8, - 8usize, - ); + let val: u32 = ::std::mem::transmute(val); + self._bitfield_2.set(0usize, 2u8, val as u64) } } #[inline] pub fn g(&self) -> ::std::os::raw::c_uint { - let mut unit_field_val: u64 = unsafe { ::std::mem::uninitialized() }; - unsafe { - ::std::ptr::copy_nonoverlapping( - &self._bitfield_2 as *const _ as *const u8, - &mut unit_field_val as *mut u64 as *mut u8, - 8usize, - ) - }; - let mask = 0xffffffff00000000 as u64; - let val = (unit_field_val & mask) >> 32usize; - unsafe { ::std::mem::transmute(val as u32) } + unsafe { ::std::mem::transmute(self._bitfield_2.get(32usize, 32u8) as u32) } } #[inline] pub fn set_g(&mut self, val: ::std::os::raw::c_uint) { - let mask = 0xffffffff00000000 as u64; - let val = val as u32 as u64; - let mut unit_field_val: u64 = unsafe { ::std::mem::uninitialized() }; - unsafe { - ::std::ptr::copy_nonoverlapping( - &self._bitfield_2 as *const _ as *const u8, - &mut unit_field_val as *mut u64 as *mut u8, - 8usize, - ) - }; - unit_field_val &= !mask; - unit_field_val |= (val << 32usize) & mask; unsafe { - ::std::ptr::copy_nonoverlapping( - &unit_field_val as *const _ as *const u8, - &mut self._bitfield_2 as *mut _ as *mut u8, - 8usize, - ); + let val: u32 = ::std::mem::transmute(val); + self._bitfield_2.set(32usize, 32u8, val as u64) } } #[inline] - 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) & (0x3 as u64)) - | ((g as u32 as u64) << 32usize) & (0xffffffff00000000 as u64)) + pub fn new_bitfield_2( + f: ::std::os::raw::c_uint, + g: ::std::os::raw::c_uint, + ) -> __BindgenBitfieldUnit<[u8; 8usize], u32> { + let mut __bindgen_bitfield_unit: __BindgenBitfieldUnit<[u8; 8usize], u32> = + Default::default(); + __bindgen_bitfield_unit.set(0usize, 2u8, { + let f: u32 = unsafe { ::std::mem::transmute(f) }; + f as u64 + }); + __bindgen_bitfield_unit.set(32usize, 32u8, { + let g: u32 = unsafe { ::std::mem::transmute(g) }; + g as u64 + }); + __bindgen_bitfield_unit } } diff --git a/tests/expectations/tests/union_bitfield.rs b/tests/expectations/tests/union_bitfield.rs index 72064c110b..1f75ee4de3 100644 --- a/tests/expectations/tests/union_bitfield.rs +++ b/tests/expectations/tests/union_bitfield.rs @@ -4,10 +4,89 @@ #![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] +#[repr(C)] +#[derive(Copy, Clone, Debug, Default, Eq, Hash, Ord, PartialEq, PartialOrd)] +pub struct __BindgenBitfieldUnit +where + Storage: AsRef<[u8]> + AsMut<[u8]>, +{ + storage: Storage, + align: [Align; 0], +} + +impl __BindgenBitfieldUnit +where + Storage: AsRef<[u8]> + AsMut<[u8]>, +{ + #[inline] + pub fn new(storage: Storage) -> Self { + Self { storage, align: [] } + } + + #[inline] + pub fn get_bit(&self, index: usize) -> bool { + debug_assert!(index / 8 < self.storage.as_ref().len()); + + let byte_index = index / 8; + let byte = self.storage.as_ref()[byte_index]; + + let bit_index = index % 8; + let mask = 1 << bit_index; + + byte & mask == mask + } + + #[inline] + pub fn set_bit(&mut self, index: usize, val: bool) { + debug_assert!(index / 8 < self.storage.as_ref().len()); + + let byte_index = index / 8; + let byte = &mut self.storage.as_mut()[byte_index]; + + let bit_index = index % 8; + let mask = 1 << bit_index; + + if val { + *byte |= mask; + } else { + *byte &= !mask; + } + } + + #[inline] + pub fn get(&self, bit_offset: usize, bit_width: u8) -> u64 { + debug_assert!(bit_width <= 64); + debug_assert!(bit_offset / 8 < self.storage.as_ref().len()); + debug_assert!((bit_offset + (bit_width as usize)) / 8 <= self.storage.as_ref().len()); + + let mut val = 0; + + for i in 0..(bit_width as usize) { + if self.get_bit(i + bit_offset) { + val |= 1 << i; + } + } + + val + } + + #[inline] + pub fn set(&mut self, bit_offset: usize, bit_width: u8, val: u64) { + debug_assert!(bit_width <= 64); + debug_assert!(bit_offset / 8 < self.storage.as_ref().len()); + debug_assert!((bit_offset + (bit_width as usize)) / 8 <= self.storage.as_ref().len()); + + for i in 0..(bit_width as usize) { + let mask = 1 << i; + let val_bit_is_set = val & mask == mask; + self.set_bit(i + bit_offset, val_bit_is_set); + } + } +} #[repr(C)] #[derive(Copy, Clone)] pub union U4 { - pub _bitfield_1: u8, + pub _bitfield_1: __BindgenBitfieldUnit<[u8; 1usize], u8>, _bindgen_union_align: u32, } #[test] @@ -31,49 +110,30 @@ impl Default for U4 { impl U4 { #[inline] pub fn derp(&self) -> ::std::os::raw::c_uint { - let mut unit_field_val: u8 = unsafe { ::std::mem::uninitialized() }; - unsafe { - ::std::ptr::copy_nonoverlapping( - &self._bitfield_1 as *const _ as *const u8, - &mut unit_field_val as *mut u8 as *mut u8, - 1usize, - ) - }; - let mask = 0x1 as u8; - let val = (unit_field_val & mask) >> 0usize; - unsafe { ::std::mem::transmute(val as u32) } + unsafe { ::std::mem::transmute(self._bitfield_1.get(0usize, 1u8) as u32) } } #[inline] pub fn set_derp(&mut self, val: ::std::os::raw::c_uint) { - let mask = 0x1 as u8; - let val = val as u32 as u8; - let mut unit_field_val: u8 = unsafe { ::std::mem::uninitialized() }; - unsafe { - ::std::ptr::copy_nonoverlapping( - &self._bitfield_1 as *const _ as *const u8, - &mut unit_field_val as *mut u8 as *mut u8, - 1usize, - ) - }; - unit_field_val &= !mask; - unit_field_val |= (val << 0usize) & mask; unsafe { - ::std::ptr::copy_nonoverlapping( - &unit_field_val as *const _ as *const u8, - &mut self._bitfield_1 as *mut _ as *mut u8, - 1usize, - ); + let val: u32 = ::std::mem::transmute(val); + self._bitfield_1.set(0usize, 1u8, val as u64) } } #[inline] - pub fn new_bitfield_1(derp: ::std::os::raw::c_uint) -> u8 { - (0 | ((derp as u32 as u8) << 0usize) & (0x1 as u8)) + pub fn new_bitfield_1(derp: ::std::os::raw::c_uint) -> __BindgenBitfieldUnit<[u8; 1usize], u8> { + let mut __bindgen_bitfield_unit: __BindgenBitfieldUnit<[u8; 1usize], u8> = + Default::default(); + __bindgen_bitfield_unit.set(0usize, 1u8, { + let derp: u32 = unsafe { ::std::mem::transmute(derp) }; + derp as u64 + }); + __bindgen_bitfield_unit } } #[repr(C)] #[derive(Copy, Clone)] pub union B { - pub _bitfield_1: u32, + pub _bitfield_1: __BindgenBitfieldUnit<[u8; 4usize], u32>, _bindgen_union_align: u32, } #[test] @@ -97,79 +157,41 @@ impl Default for B { impl B { #[inline] pub fn foo(&self) -> ::std::os::raw::c_uint { - let mut unit_field_val: u32 = unsafe { ::std::mem::uninitialized() }; - unsafe { - ::std::ptr::copy_nonoverlapping( - &self._bitfield_1 as *const _ as *const u8, - &mut unit_field_val as *mut u32 as *mut u8, - 4usize, - ) - }; - let mask = 0x7fffffff as u32; - let val = (unit_field_val & mask) >> 0usize; - unsafe { ::std::mem::transmute(val as u32) } + unsafe { ::std::mem::transmute(self._bitfield_1.get(0usize, 31u8) as u32) } } #[inline] pub fn set_foo(&mut self, val: ::std::os::raw::c_uint) { - let mask = 0x7fffffff as u32; - let val = val as u32 as u32; - let mut unit_field_val: u32 = unsafe { ::std::mem::uninitialized() }; - unsafe { - ::std::ptr::copy_nonoverlapping( - &self._bitfield_1 as *const _ as *const u8, - &mut unit_field_val as *mut u32 as *mut u8, - 4usize, - ) - }; - unit_field_val &= !mask; - unit_field_val |= (val << 0usize) & mask; unsafe { - ::std::ptr::copy_nonoverlapping( - &unit_field_val as *const _ as *const u8, - &mut self._bitfield_1 as *mut _ as *mut u8, - 4usize, - ); + let val: u32 = ::std::mem::transmute(val); + self._bitfield_1.set(0usize, 31u8, val as u64) } } #[inline] pub fn bar(&self) -> ::std::os::raw::c_uchar { - let mut unit_field_val: u32 = unsafe { ::std::mem::uninitialized() }; - unsafe { - ::std::ptr::copy_nonoverlapping( - &self._bitfield_1 as *const _ as *const u8, - &mut unit_field_val as *mut u32 as *mut u8, - 4usize, - ) - }; - let mask = 0x80000000 as u32; - let val = (unit_field_val & mask) >> 31usize; - unsafe { ::std::mem::transmute(val as u8) } + unsafe { ::std::mem::transmute(self._bitfield_1.get(31usize, 1u8) as u8) } } #[inline] pub fn set_bar(&mut self, val: ::std::os::raw::c_uchar) { - let mask = 0x80000000 as u32; - let val = val as u8 as u32; - let mut unit_field_val: u32 = unsafe { ::std::mem::uninitialized() }; - unsafe { - ::std::ptr::copy_nonoverlapping( - &self._bitfield_1 as *const _ as *const u8, - &mut unit_field_val as *mut u32 as *mut u8, - 4usize, - ) - }; - unit_field_val &= !mask; - unit_field_val |= (val << 31usize) & mask; unsafe { - ::std::ptr::copy_nonoverlapping( - &unit_field_val as *const _ as *const u8, - &mut self._bitfield_1 as *mut _ as *mut u8, - 4usize, - ); + let val: u8 = ::std::mem::transmute(val); + self._bitfield_1.set(31usize, 1u8, val as u64) } } #[inline] - pub fn new_bitfield_1(foo: ::std::os::raw::c_uint, bar: ::std::os::raw::c_uchar) -> u32 { - ((0 | ((foo as u32 as u32) << 0usize) & (0x7fffffff as u32)) - | ((bar as u8 as u32) << 31usize) & (0x80000000 as u32)) + pub fn new_bitfield_1( + foo: ::std::os::raw::c_uint, + bar: ::std::os::raw::c_uchar, + ) -> __BindgenBitfieldUnit<[u8; 4usize], u32> { + let mut __bindgen_bitfield_unit: __BindgenBitfieldUnit<[u8; 4usize], u32> = + Default::default(); + __bindgen_bitfield_unit.set(0usize, 31u8, { + let foo: u32 = unsafe { ::std::mem::transmute(foo) }; + foo as u64 + }); + __bindgen_bitfield_unit.set(31usize, 1u8, { + let bar: u8 = unsafe { ::std::mem::transmute(bar) }; + bar as u64 + }); + __bindgen_bitfield_unit } } diff --git a/tests/expectations/tests/union_bitfield_1_0.rs b/tests/expectations/tests/union_bitfield_1_0.rs index 16aa85526d..a85fad4c2e 100644 --- a/tests/expectations/tests/union_bitfield_1_0.rs +++ b/tests/expectations/tests/union_bitfield_1_0.rs @@ -4,6 +4,85 @@ #![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] +#[repr(C)] +#[derive(Copy, Clone, Debug, Default, Eq, Hash, Ord, PartialEq, PartialOrd)] +pub struct __BindgenBitfieldUnit +where + Storage: AsRef<[u8]> + AsMut<[u8]>, +{ + storage: Storage, + align: [Align; 0], +} + +impl __BindgenBitfieldUnit +where + Storage: AsRef<[u8]> + AsMut<[u8]>, +{ + #[inline] + pub fn new(storage: Storage) -> Self { + Self { storage, align: [] } + } + + #[inline] + pub fn get_bit(&self, index: usize) -> bool { + debug_assert!(index / 8 < self.storage.as_ref().len()); + + let byte_index = index / 8; + let byte = self.storage.as_ref()[byte_index]; + + let bit_index = index % 8; + let mask = 1 << bit_index; + + byte & mask == mask + } + + #[inline] + pub fn set_bit(&mut self, index: usize, val: bool) { + debug_assert!(index / 8 < self.storage.as_ref().len()); + + let byte_index = index / 8; + let byte = &mut self.storage.as_mut()[byte_index]; + + let bit_index = index % 8; + let mask = 1 << bit_index; + + if val { + *byte |= mask; + } else { + *byte &= !mask; + } + } + + #[inline] + pub fn get(&self, bit_offset: usize, bit_width: u8) -> u64 { + debug_assert!(bit_width <= 64); + debug_assert!(bit_offset / 8 < self.storage.as_ref().len()); + debug_assert!((bit_offset + (bit_width as usize)) / 8 <= self.storage.as_ref().len()); + + let mut val = 0; + + for i in 0..(bit_width as usize) { + if self.get_bit(i + bit_offset) { + val |= 1 << i; + } + } + + val + } + + #[inline] + pub fn set(&mut self, bit_offset: usize, bit_width: u8, val: u64) { + debug_assert!(bit_width <= 64); + debug_assert!(bit_offset / 8 < self.storage.as_ref().len()); + debug_assert!((bit_offset + (bit_width as usize)) / 8 <= self.storage.as_ref().len()); + + for i in 0..(bit_width as usize) { + let mask = 1 << i; + let val_bit_is_set = val & mask == mask; + self.set_bit(i + bit_offset, val_bit_is_set); + } + } +} #[repr(C)] pub struct __BindgenUnionField(::std::marker::PhantomData); impl __BindgenUnionField { @@ -50,7 +129,7 @@ impl ::std::cmp::Eq for __BindgenUnionField {} #[repr(C)] #[derive(Debug, Default, Copy, Hash, PartialEq, Eq)] pub struct U4 { - pub _bitfield_1: __BindgenUnionField, + pub _bitfield_1: __BindgenUnionField<__BindgenBitfieldUnit<[u8; 1usize], u8>>, pub bindgen_union_field: u32, } #[test] @@ -74,49 +153,30 @@ impl Clone for U4 { impl U4 { #[inline] pub fn derp(&self) -> ::std::os::raw::c_uint { - let mut unit_field_val: u8 = unsafe { ::std::mem::uninitialized() }; - unsafe { - ::std::ptr::copy_nonoverlapping( - &self._bitfield_1 as *const _ as *const u8, - &mut unit_field_val as *mut u8 as *mut u8, - 1usize, - ) - }; - let mask = 0x1 as u8; - let val = (unit_field_val & mask) >> 0usize; - unsafe { ::std::mem::transmute(val as u32) } + unsafe { ::std::mem::transmute(self._bitfield_1.as_ref().get(0usize, 1u8) as u32) } } #[inline] pub fn set_derp(&mut self, val: ::std::os::raw::c_uint) { - let mask = 0x1 as u8; - let val = val as u32 as u8; - let mut unit_field_val: u8 = unsafe { ::std::mem::uninitialized() }; - unsafe { - ::std::ptr::copy_nonoverlapping( - &self._bitfield_1 as *const _ as *const u8, - &mut unit_field_val as *mut u8 as *mut u8, - 1usize, - ) - }; - unit_field_val &= !mask; - unit_field_val |= (val << 0usize) & mask; unsafe { - ::std::ptr::copy_nonoverlapping( - &unit_field_val as *const _ as *const u8, - &mut self._bitfield_1 as *mut _ as *mut u8, - 1usize, - ); + let val: u32 = ::std::mem::transmute(val); + self._bitfield_1.as_mut().set(0usize, 1u8, val as u64) } } #[inline] - pub fn new_bitfield_1(derp: ::std::os::raw::c_uint) -> u8 { - (0 | ((derp as u32 as u8) << 0usize) & (0x1 as u8)) + pub fn new_bitfield_1(derp: ::std::os::raw::c_uint) -> __BindgenBitfieldUnit<[u8; 1usize], u8> { + let mut __bindgen_bitfield_unit: __BindgenBitfieldUnit<[u8; 1usize], u8> = + Default::default(); + __bindgen_bitfield_unit.set(0usize, 1u8, { + let derp: u32 = unsafe { ::std::mem::transmute(derp) }; + derp as u64 + }); + __bindgen_bitfield_unit } } #[repr(C)] #[derive(Debug, Default, Copy, Hash, PartialEq, Eq)] pub struct B { - pub _bitfield_1: __BindgenUnionField, + pub _bitfield_1: __BindgenUnionField<__BindgenBitfieldUnit<[u8; 4usize], u32>>, pub bindgen_union_field: u32, } #[test] @@ -140,86 +200,48 @@ impl Clone for B { impl B { #[inline] pub fn foo(&self) -> ::std::os::raw::c_uint { - let mut unit_field_val: u32 = unsafe { ::std::mem::uninitialized() }; - unsafe { - ::std::ptr::copy_nonoverlapping( - &self._bitfield_1 as *const _ as *const u8, - &mut unit_field_val as *mut u32 as *mut u8, - 4usize, - ) - }; - let mask = 0x7fffffff as u32; - let val = (unit_field_val & mask) >> 0usize; - unsafe { ::std::mem::transmute(val as u32) } + unsafe { ::std::mem::transmute(self._bitfield_1.as_ref().get(0usize, 31u8) as u32) } } #[inline] pub fn set_foo(&mut self, val: ::std::os::raw::c_uint) { - let mask = 0x7fffffff as u32; - let val = val as u32 as u32; - let mut unit_field_val: u32 = unsafe { ::std::mem::uninitialized() }; - unsafe { - ::std::ptr::copy_nonoverlapping( - &self._bitfield_1 as *const _ as *const u8, - &mut unit_field_val as *mut u32 as *mut u8, - 4usize, - ) - }; - unit_field_val &= !mask; - unit_field_val |= (val << 0usize) & mask; unsafe { - ::std::ptr::copy_nonoverlapping( - &unit_field_val as *const _ as *const u8, - &mut self._bitfield_1 as *mut _ as *mut u8, - 4usize, - ); + let val: u32 = ::std::mem::transmute(val); + self._bitfield_1.as_mut().set(0usize, 31u8, val as u64) } } #[inline] pub fn bar(&self) -> ::std::os::raw::c_uchar { - let mut unit_field_val: u32 = unsafe { ::std::mem::uninitialized() }; - unsafe { - ::std::ptr::copy_nonoverlapping( - &self._bitfield_1 as *const _ as *const u8, - &mut unit_field_val as *mut u32 as *mut u8, - 4usize, - ) - }; - let mask = 0x80000000 as u32; - let val = (unit_field_val & mask) >> 31usize; - unsafe { ::std::mem::transmute(val as u8) } + unsafe { ::std::mem::transmute(self._bitfield_1.as_ref().get(31usize, 1u8) as u8) } } #[inline] pub fn set_bar(&mut self, val: ::std::os::raw::c_uchar) { - let mask = 0x80000000 as u32; - let val = val as u8 as u32; - let mut unit_field_val: u32 = unsafe { ::std::mem::uninitialized() }; - unsafe { - ::std::ptr::copy_nonoverlapping( - &self._bitfield_1 as *const _ as *const u8, - &mut unit_field_val as *mut u32 as *mut u8, - 4usize, - ) - }; - unit_field_val &= !mask; - unit_field_val |= (val << 31usize) & mask; unsafe { - ::std::ptr::copy_nonoverlapping( - &unit_field_val as *const _ as *const u8, - &mut self._bitfield_1 as *mut _ as *mut u8, - 4usize, - ); + let val: u8 = ::std::mem::transmute(val); + self._bitfield_1.as_mut().set(31usize, 1u8, val as u64) } } #[inline] - pub fn new_bitfield_1(foo: ::std::os::raw::c_uint, bar: ::std::os::raw::c_uchar) -> u32 { - ((0 | ((foo as u32 as u32) << 0usize) & (0x7fffffff as u32)) - | ((bar as u8 as u32) << 31usize) & (0x80000000 as u32)) + pub fn new_bitfield_1( + foo: ::std::os::raw::c_uint, + bar: ::std::os::raw::c_uchar, + ) -> __BindgenBitfieldUnit<[u8; 4usize], u32> { + let mut __bindgen_bitfield_unit: __BindgenBitfieldUnit<[u8; 4usize], u32> = + Default::default(); + __bindgen_bitfield_unit.set(0usize, 31u8, { + let foo: u32 = unsafe { ::std::mem::transmute(foo) }; + foo as u64 + }); + __bindgen_bitfield_unit.set(31usize, 1u8, { + let bar: u8 = unsafe { ::std::mem::transmute(bar) }; + bar as u64 + }); + __bindgen_bitfield_unit } } #[repr(C)] #[derive(Copy)] pub struct HasBigBitfield { - pub _bitfield_1: __BindgenUnionField<[u8; 16usize]>, + pub _bitfield_1: __BindgenUnionField<__BindgenBitfieldUnit<[u8; 16usize], u64>>, pub bindgen_union_field: [u8; 16usize], } #[test] diff --git a/tests/expectations/tests/union_with_anon_struct_bitfield.rs b/tests/expectations/tests/union_with_anon_struct_bitfield.rs index 0e12a1caf8..3e357a145b 100644 --- a/tests/expectations/tests/union_with_anon_struct_bitfield.rs +++ b/tests/expectations/tests/union_with_anon_struct_bitfield.rs @@ -4,6 +4,85 @@ #![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] +#[repr(C)] +#[derive(Copy, Clone, Debug, Default, Eq, Hash, Ord, PartialEq, PartialOrd)] +pub struct __BindgenBitfieldUnit +where + Storage: AsRef<[u8]> + AsMut<[u8]>, +{ + storage: Storage, + align: [Align; 0], +} + +impl __BindgenBitfieldUnit +where + Storage: AsRef<[u8]> + AsMut<[u8]>, +{ + #[inline] + pub fn new(storage: Storage) -> Self { + Self { storage, align: [] } + } + + #[inline] + pub fn get_bit(&self, index: usize) -> bool { + debug_assert!(index / 8 < self.storage.as_ref().len()); + + let byte_index = index / 8; + let byte = self.storage.as_ref()[byte_index]; + + let bit_index = index % 8; + let mask = 1 << bit_index; + + byte & mask == mask + } + + #[inline] + pub fn set_bit(&mut self, index: usize, val: bool) { + debug_assert!(index / 8 < self.storage.as_ref().len()); + + let byte_index = index / 8; + let byte = &mut self.storage.as_mut()[byte_index]; + + let bit_index = index % 8; + let mask = 1 << bit_index; + + if val { + *byte |= mask; + } else { + *byte &= !mask; + } + } + + #[inline] + pub fn get(&self, bit_offset: usize, bit_width: u8) -> u64 { + debug_assert!(bit_width <= 64); + debug_assert!(bit_offset / 8 < self.storage.as_ref().len()); + debug_assert!((bit_offset + (bit_width as usize)) / 8 <= self.storage.as_ref().len()); + + let mut val = 0; + + for i in 0..(bit_width as usize) { + if self.get_bit(i + bit_offset) { + val |= 1 << i; + } + } + + val + } + + #[inline] + pub fn set(&mut self, bit_offset: usize, bit_width: u8, val: u64) { + debug_assert!(bit_width <= 64); + debug_assert!(bit_offset / 8 < self.storage.as_ref().len()); + debug_assert!((bit_offset + (bit_width as usize)) / 8 <= self.storage.as_ref().len()); + + for i in 0..(bit_width as usize) { + let mask = 1 << i; + let val_bit_is_set = val & mask == mask; + self.set_bit(i + bit_offset, val_bit_is_set); + } + } +} #[repr(C)] #[derive(Copy, Clone)] pub union foo { @@ -14,7 +93,7 @@ pub union foo { #[repr(C)] #[derive(Debug, Default, Copy, Clone, Hash, PartialEq, Eq)] pub struct foo__bindgen_ty_1 { - pub _bitfield_1: u32, + pub _bitfield_1: __BindgenBitfieldUnit<[u8; 4usize], u32>, pub __bindgen_align: [u32; 0usize], } #[test] @@ -33,80 +112,42 @@ fn bindgen_test_layout_foo__bindgen_ty_1() { impl foo__bindgen_ty_1 { #[inline] pub fn b(&self) -> ::std::os::raw::c_int { - let mut unit_field_val: u32 = unsafe { ::std::mem::uninitialized() }; - unsafe { - ::std::ptr::copy_nonoverlapping( - &self._bitfield_1 as *const _ as *const u8, - &mut unit_field_val as *mut u32 as *mut u8, - 4usize, - ) - }; - let mask = 0x7f as u32; - let val = (unit_field_val & mask) >> 0usize; - unsafe { ::std::mem::transmute(val as u32) } + unsafe { ::std::mem::transmute(self._bitfield_1.get(0usize, 7u8) as u32) } } #[inline] pub fn set_b(&mut self, val: ::std::os::raw::c_int) { - let mask = 0x7f as u32; - let val = val as u32 as u32; - let mut unit_field_val: u32 = unsafe { ::std::mem::uninitialized() }; - unsafe { - ::std::ptr::copy_nonoverlapping( - &self._bitfield_1 as *const _ as *const u8, - &mut unit_field_val as *mut u32 as *mut u8, - 4usize, - ) - }; - unit_field_val &= !mask; - unit_field_val |= (val << 0usize) & mask; unsafe { - ::std::ptr::copy_nonoverlapping( - &unit_field_val as *const _ as *const u8, - &mut self._bitfield_1 as *mut _ as *mut u8, - 4usize, - ); + let val: u32 = ::std::mem::transmute(val); + self._bitfield_1.set(0usize, 7u8, val as u64) } } #[inline] pub fn c(&self) -> ::std::os::raw::c_int { - let mut unit_field_val: u32 = unsafe { ::std::mem::uninitialized() }; - unsafe { - ::std::ptr::copy_nonoverlapping( - &self._bitfield_1 as *const _ as *const u8, - &mut unit_field_val as *mut u32 as *mut u8, - 4usize, - ) - }; - let mask = 0xffffff80 as u32; - let val = (unit_field_val & mask) >> 7usize; - unsafe { ::std::mem::transmute(val as u32) } + unsafe { ::std::mem::transmute(self._bitfield_1.get(7usize, 25u8) as u32) } } #[inline] pub fn set_c(&mut self, val: ::std::os::raw::c_int) { - let mask = 0xffffff80 as u32; - let val = val as u32 as u32; - let mut unit_field_val: u32 = unsafe { ::std::mem::uninitialized() }; - unsafe { - ::std::ptr::copy_nonoverlapping( - &self._bitfield_1 as *const _ as *const u8, - &mut unit_field_val as *mut u32 as *mut u8, - 4usize, - ) - }; - unit_field_val &= !mask; - unit_field_val |= (val << 7usize) & mask; unsafe { - ::std::ptr::copy_nonoverlapping( - &unit_field_val as *const _ as *const u8, - &mut self._bitfield_1 as *mut _ as *mut u8, - 4usize, - ); + let val: u32 = ::std::mem::transmute(val); + self._bitfield_1.set(7usize, 25u8, val as u64) } } #[inline] - pub fn new_bitfield_1(b: ::std::os::raw::c_int, c: ::std::os::raw::c_int) -> u32 { - ((0 | ((b as u32 as u32) << 0usize) & (0x7f as u32)) - | ((c as u32 as u32) << 7usize) & (0xffffff80 as u32)) + pub fn new_bitfield_1( + b: ::std::os::raw::c_int, + c: ::std::os::raw::c_int, + ) -> __BindgenBitfieldUnit<[u8; 4usize], u32> { + let mut __bindgen_bitfield_unit: __BindgenBitfieldUnit<[u8; 4usize], u32> = + Default::default(); + __bindgen_bitfield_unit.set(0usize, 7u8, { + let b: u32 = unsafe { ::std::mem::transmute(b) }; + b as u64 + }); + __bindgen_bitfield_unit.set(7usize, 25u8, { + let c: u32 = unsafe { ::std::mem::transmute(c) }; + c as u64 + }); + __bindgen_bitfield_unit } } #[test] diff --git a/tests/expectations/tests/union_with_anon_struct_bitfield_1_0.rs b/tests/expectations/tests/union_with_anon_struct_bitfield_1_0.rs index 3a445a37b0..fb9ce34fd7 100644 --- a/tests/expectations/tests/union_with_anon_struct_bitfield_1_0.rs +++ b/tests/expectations/tests/union_with_anon_struct_bitfield_1_0.rs @@ -4,6 +4,85 @@ #![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] +#[repr(C)] +#[derive(Copy, Clone, Debug, Default, Eq, Hash, Ord, PartialEq, PartialOrd)] +pub struct __BindgenBitfieldUnit +where + Storage: AsRef<[u8]> + AsMut<[u8]>, +{ + storage: Storage, + align: [Align; 0], +} + +impl __BindgenBitfieldUnit +where + Storage: AsRef<[u8]> + AsMut<[u8]>, +{ + #[inline] + pub fn new(storage: Storage) -> Self { + Self { storage, align: [] } + } + + #[inline] + pub fn get_bit(&self, index: usize) -> bool { + debug_assert!(index / 8 < self.storage.as_ref().len()); + + let byte_index = index / 8; + let byte = self.storage.as_ref()[byte_index]; + + let bit_index = index % 8; + let mask = 1 << bit_index; + + byte & mask == mask + } + + #[inline] + pub fn set_bit(&mut self, index: usize, val: bool) { + debug_assert!(index / 8 < self.storage.as_ref().len()); + + let byte_index = index / 8; + let byte = &mut self.storage.as_mut()[byte_index]; + + let bit_index = index % 8; + let mask = 1 << bit_index; + + if val { + *byte |= mask; + } else { + *byte &= !mask; + } + } + + #[inline] + pub fn get(&self, bit_offset: usize, bit_width: u8) -> u64 { + debug_assert!(bit_width <= 64); + debug_assert!(bit_offset / 8 < self.storage.as_ref().len()); + debug_assert!((bit_offset + (bit_width as usize)) / 8 <= self.storage.as_ref().len()); + + let mut val = 0; + + for i in 0..(bit_width as usize) { + if self.get_bit(i + bit_offset) { + val |= 1 << i; + } + } + + val + } + + #[inline] + pub fn set(&mut self, bit_offset: usize, bit_width: u8, val: u64) { + debug_assert!(bit_width <= 64); + debug_assert!(bit_offset / 8 < self.storage.as_ref().len()); + debug_assert!((bit_offset + (bit_width as usize)) / 8 <= self.storage.as_ref().len()); + + for i in 0..(bit_width as usize) { + let mask = 1 << i; + let val_bit_is_set = val & mask == mask; + self.set_bit(i + bit_offset, val_bit_is_set); + } + } +} #[repr(C)] pub struct __BindgenUnionField(::std::marker::PhantomData); impl __BindgenUnionField { @@ -57,7 +136,7 @@ pub struct foo { #[repr(C)] #[derive(Debug, Default, Copy, Hash, PartialEq, Eq)] pub struct foo__bindgen_ty_1 { - pub _bitfield_1: u32, + pub _bitfield_1: __BindgenBitfieldUnit<[u8; 4usize], u32>, pub __bindgen_align: [u32; 0usize], } #[test] @@ -81,80 +160,42 @@ impl Clone for foo__bindgen_ty_1 { impl foo__bindgen_ty_1 { #[inline] pub fn b(&self) -> ::std::os::raw::c_int { - let mut unit_field_val: u32 = unsafe { ::std::mem::uninitialized() }; - unsafe { - ::std::ptr::copy_nonoverlapping( - &self._bitfield_1 as *const _ as *const u8, - &mut unit_field_val as *mut u32 as *mut u8, - 4usize, - ) - }; - let mask = 0x7f as u32; - let val = (unit_field_val & mask) >> 0usize; - unsafe { ::std::mem::transmute(val as u32) } + unsafe { ::std::mem::transmute(self._bitfield_1.get(0usize, 7u8) as u32) } } #[inline] pub fn set_b(&mut self, val: ::std::os::raw::c_int) { - let mask = 0x7f as u32; - let val = val as u32 as u32; - let mut unit_field_val: u32 = unsafe { ::std::mem::uninitialized() }; - unsafe { - ::std::ptr::copy_nonoverlapping( - &self._bitfield_1 as *const _ as *const u8, - &mut unit_field_val as *mut u32 as *mut u8, - 4usize, - ) - }; - unit_field_val &= !mask; - unit_field_val |= (val << 0usize) & mask; unsafe { - ::std::ptr::copy_nonoverlapping( - &unit_field_val as *const _ as *const u8, - &mut self._bitfield_1 as *mut _ as *mut u8, - 4usize, - ); + let val: u32 = ::std::mem::transmute(val); + self._bitfield_1.set(0usize, 7u8, val as u64) } } #[inline] pub fn c(&self) -> ::std::os::raw::c_int { - let mut unit_field_val: u32 = unsafe { ::std::mem::uninitialized() }; - unsafe { - ::std::ptr::copy_nonoverlapping( - &self._bitfield_1 as *const _ as *const u8, - &mut unit_field_val as *mut u32 as *mut u8, - 4usize, - ) - }; - let mask = 0xffffff80 as u32; - let val = (unit_field_val & mask) >> 7usize; - unsafe { ::std::mem::transmute(val as u32) } + unsafe { ::std::mem::transmute(self._bitfield_1.get(7usize, 25u8) as u32) } } #[inline] pub fn set_c(&mut self, val: ::std::os::raw::c_int) { - let mask = 0xffffff80 as u32; - let val = val as u32 as u32; - let mut unit_field_val: u32 = unsafe { ::std::mem::uninitialized() }; - unsafe { - ::std::ptr::copy_nonoverlapping( - &self._bitfield_1 as *const _ as *const u8, - &mut unit_field_val as *mut u32 as *mut u8, - 4usize, - ) - }; - unit_field_val &= !mask; - unit_field_val |= (val << 7usize) & mask; unsafe { - ::std::ptr::copy_nonoverlapping( - &unit_field_val as *const _ as *const u8, - &mut self._bitfield_1 as *mut _ as *mut u8, - 4usize, - ); + let val: u32 = ::std::mem::transmute(val); + self._bitfield_1.set(7usize, 25u8, val as u64) } } #[inline] - pub fn new_bitfield_1(b: ::std::os::raw::c_int, c: ::std::os::raw::c_int) -> u32 { - ((0 | ((b as u32 as u32) << 0usize) & (0x7f as u32)) - | ((c as u32 as u32) << 7usize) & (0xffffff80 as u32)) + pub fn new_bitfield_1( + b: ::std::os::raw::c_int, + c: ::std::os::raw::c_int, + ) -> __BindgenBitfieldUnit<[u8; 4usize], u32> { + let mut __bindgen_bitfield_unit: __BindgenBitfieldUnit<[u8; 4usize], u32> = + Default::default(); + __bindgen_bitfield_unit.set(0usize, 7u8, { + let b: u32 = unsafe { ::std::mem::transmute(b) }; + b as u64 + }); + __bindgen_bitfield_unit.set(7usize, 25u8, { + let c: u32 = unsafe { ::std::mem::transmute(c) }; + c as u64 + }); + __bindgen_bitfield_unit } } #[test] diff --git a/tests/expectations/tests/weird_bitfields.rs b/tests/expectations/tests/weird_bitfields.rs index ce54e743e2..f18da25c4a 100644 --- a/tests/expectations/tests/weird_bitfields.rs +++ b/tests/expectations/tests/weird_bitfields.rs @@ -4,6 +4,85 @@ #![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] +#[repr(C)] +#[derive(Copy, Clone, Debug, Default, Eq, Hash, Ord, PartialEq, PartialOrd)] +pub struct __BindgenBitfieldUnit +where + Storage: AsRef<[u8]> + AsMut<[u8]>, +{ + storage: Storage, + align: [Align; 0], +} + +impl __BindgenBitfieldUnit +where + Storage: AsRef<[u8]> + AsMut<[u8]>, +{ + #[inline] + pub fn new(storage: Storage) -> Self { + Self { storage, align: [] } + } + + #[inline] + pub fn get_bit(&self, index: usize) -> bool { + debug_assert!(index / 8 < self.storage.as_ref().len()); + + let byte_index = index / 8; + let byte = self.storage.as_ref()[byte_index]; + + let bit_index = index % 8; + let mask = 1 << bit_index; + + byte & mask == mask + } + + #[inline] + pub fn set_bit(&mut self, index: usize, val: bool) { + debug_assert!(index / 8 < self.storage.as_ref().len()); + + let byte_index = index / 8; + let byte = &mut self.storage.as_mut()[byte_index]; + + let bit_index = index % 8; + let mask = 1 << bit_index; + + if val { + *byte |= mask; + } else { + *byte &= !mask; + } + } + + #[inline] + pub fn get(&self, bit_offset: usize, bit_width: u8) -> u64 { + debug_assert!(bit_width <= 64); + debug_assert!(bit_offset / 8 < self.storage.as_ref().len()); + debug_assert!((bit_offset + (bit_width as usize)) / 8 <= self.storage.as_ref().len()); + + let mut val = 0; + + for i in 0..(bit_width as usize) { + if self.get_bit(i + bit_offset) { + val |= 1 << i; + } + } + + val + } + + #[inline] + pub fn set(&mut self, bit_offset: usize, bit_width: u8, val: u64) { + debug_assert!(bit_width <= 64); + debug_assert!(bit_offset / 8 < self.storage.as_ref().len()); + debug_assert!((bit_offset + (bit_width as usize)) / 8 <= self.storage.as_ref().len()); + + for i in 0..(bit_width as usize) { + let mask = 1 << i; + let val_bit_is_set = val & mask == mask; + self.set_bit(i + bit_offset, val_bit_is_set); + } + } +} #[repr(u32)] #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)] pub enum nsStyleSVGOpacitySource { @@ -15,7 +94,7 @@ pub enum nsStyleSVGOpacitySource { #[derive(Debug, Copy, Clone)] pub struct Weird { pub mStrokeDasharrayLength: ::std::os::raw::c_uint, - pub _bitfield_1: [u16; 2usize], + pub _bitfield_1: __BindgenBitfieldUnit<[u8; 4usize], u16>, pub mClipRule: ::std::os::raw::c_uchar, pub mColorInterpolation: ::std::os::raw::c_uchar, pub mColorInterpolationFilters: ::std::os::raw::c_uchar, @@ -27,7 +106,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; 2usize], + pub _bitfield_2: __BindgenBitfieldUnit<[u8; 2usize], u8>, pub __bindgen_padding_0: [u8; 3usize], } #[test] @@ -171,262 +250,96 @@ impl Default for Weird { impl Weird { #[inline] pub fn bitTest(&self) -> ::std::os::raw::c_uint { - let mut unit_field_val: u32 = unsafe { ::std::mem::uninitialized() }; - unsafe { - ::std::ptr::copy_nonoverlapping( - &self._bitfield_1 as *const _ as *const u8, - &mut unit_field_val as *mut u32 as *mut u8, - 4usize, - ) - }; - let mask = 0xffff as u32; - let val = (unit_field_val & mask) >> 0usize; - unsafe { ::std::mem::transmute(val as u32) } + unsafe { ::std::mem::transmute(self._bitfield_1.get(0usize, 16u8) as u32) } } #[inline] pub fn set_bitTest(&mut self, val: ::std::os::raw::c_uint) { - let mask = 0xffff as u32; - let val = val as u32 as u32; - let mut unit_field_val: u32 = unsafe { ::std::mem::uninitialized() }; unsafe { - ::std::ptr::copy_nonoverlapping( - &self._bitfield_1 as *const _ as *const u8, - &mut unit_field_val as *mut u32 as *mut u8, - 4usize, - ) - }; - unit_field_val &= !mask; - unit_field_val |= (val << 0usize) & mask; - unsafe { - ::std::ptr::copy_nonoverlapping( - &unit_field_val as *const _ as *const u8, - &mut self._bitfield_1 as *mut _ as *mut u8, - 4usize, - ); + let val: u32 = ::std::mem::transmute(val); + self._bitfield_1.set(0usize, 16u8, val as u64) } } #[inline] pub fn bitTest2(&self) -> ::std::os::raw::c_uint { - let mut unit_field_val: u32 = unsafe { ::std::mem::uninitialized() }; - unsafe { - ::std::ptr::copy_nonoverlapping( - &self._bitfield_1 as *const _ as *const u8, - &mut unit_field_val as *mut u32 as *mut u8, - 4usize, - ) - }; - let mask = 0x7fff0000 as u32; - let val = (unit_field_val & mask) >> 16usize; - unsafe { ::std::mem::transmute(val as u32) } + unsafe { ::std::mem::transmute(self._bitfield_1.get(16usize, 15u8) as u32) } } #[inline] pub fn set_bitTest2(&mut self, val: ::std::os::raw::c_uint) { - let mask = 0x7fff0000 as u32; - let val = val as u32 as u32; - let mut unit_field_val: u32 = unsafe { ::std::mem::uninitialized() }; unsafe { - ::std::ptr::copy_nonoverlapping( - &self._bitfield_1 as *const _ as *const u8, - &mut unit_field_val as *mut u32 as *mut u8, - 4usize, - ) - }; - unit_field_val &= !mask; - unit_field_val |= (val << 16usize) & mask; - unsafe { - ::std::ptr::copy_nonoverlapping( - &unit_field_val as *const _ as *const u8, - &mut self._bitfield_1 as *mut _ as *mut u8, - 4usize, - ); + let val: u32 = ::std::mem::transmute(val); + self._bitfield_1.set(16usize, 15u8, val as u64) } } #[inline] pub fn new_bitfield_1( bitTest: ::std::os::raw::c_uint, bitTest2: ::std::os::raw::c_uint, - ) -> u32 { - ((0 | ((bitTest as u32 as u32) << 0usize) & (0xffff as u32)) - | ((bitTest2 as u32 as u32) << 16usize) & (0x7fff0000 as u32)) + ) -> __BindgenBitfieldUnit<[u8; 4usize], u16> { + let mut __bindgen_bitfield_unit: __BindgenBitfieldUnit<[u8; 4usize], u16> = + Default::default(); + __bindgen_bitfield_unit.set(0usize, 16u8, { + let bitTest: u32 = unsafe { ::std::mem::transmute(bitTest) }; + bitTest as u64 + }); + __bindgen_bitfield_unit.set(16usize, 15u8, { + let bitTest2: u32 = unsafe { ::std::mem::transmute(bitTest2) }; + bitTest2 as u64 + }); + __bindgen_bitfield_unit } #[inline] pub fn mFillOpacitySource(&self) -> nsStyleSVGOpacitySource { - let mut unit_field_val: u16 = unsafe { ::std::mem::uninitialized() }; - unsafe { - ::std::ptr::copy_nonoverlapping( - &self._bitfield_2 as *const _ as *const u8, - &mut unit_field_val as *mut u16 as *mut u8, - 2usize, - ) - }; - let mask = 0x7 as u16; - let val = (unit_field_val & mask) >> 0usize; - unsafe { ::std::mem::transmute(val as u32) } + unsafe { ::std::mem::transmute(self._bitfield_2.get(0usize, 3u8) as u32) } } #[inline] pub fn set_mFillOpacitySource(&mut self, val: nsStyleSVGOpacitySource) { - let mask = 0x7 as u16; - let val = val as u32 as u16; - let mut unit_field_val: u16 = unsafe { ::std::mem::uninitialized() }; - unsafe { - ::std::ptr::copy_nonoverlapping( - &self._bitfield_2 as *const _ as *const u8, - &mut unit_field_val as *mut u16 as *mut u8, - 2usize, - ) - }; - unit_field_val &= !mask; - unit_field_val |= (val << 0usize) & mask; unsafe { - ::std::ptr::copy_nonoverlapping( - &unit_field_val as *const _ as *const u8, - &mut self._bitfield_2 as *mut _ as *mut u8, - 2usize, - ); + let val: u32 = ::std::mem::transmute(val); + self._bitfield_2.set(0usize, 3u8, val as u64) } } #[inline] pub fn mStrokeOpacitySource(&self) -> nsStyleSVGOpacitySource { - let mut unit_field_val: u16 = unsafe { ::std::mem::uninitialized() }; - unsafe { - ::std::ptr::copy_nonoverlapping( - &self._bitfield_2 as *const _ as *const u8, - &mut unit_field_val as *mut u16 as *mut u8, - 2usize, - ) - }; - let mask = 0x38 as u16; - let val = (unit_field_val & mask) >> 3usize; - unsafe { ::std::mem::transmute(val as u32) } + unsafe { ::std::mem::transmute(self._bitfield_2.get(3usize, 3u8) as u32) } } #[inline] pub fn set_mStrokeOpacitySource(&mut self, val: nsStyleSVGOpacitySource) { - let mask = 0x38 as u16; - let val = val as u32 as u16; - let mut unit_field_val: u16 = unsafe { ::std::mem::uninitialized() }; - unsafe { - ::std::ptr::copy_nonoverlapping( - &self._bitfield_2 as *const _ as *const u8, - &mut unit_field_val as *mut u16 as *mut u8, - 2usize, - ) - }; - unit_field_val &= !mask; - unit_field_val |= (val << 3usize) & mask; unsafe { - ::std::ptr::copy_nonoverlapping( - &unit_field_val as *const _ as *const u8, - &mut self._bitfield_2 as *mut _ as *mut u8, - 2usize, - ); + let val: u32 = ::std::mem::transmute(val); + self._bitfield_2.set(3usize, 3u8, val as u64) } } #[inline] pub fn mStrokeDasharrayFromObject(&self) -> bool { - let mut unit_field_val: u16 = unsafe { ::std::mem::uninitialized() }; - unsafe { - ::std::ptr::copy_nonoverlapping( - &self._bitfield_2 as *const _ as *const u8, - &mut unit_field_val as *mut u16 as *mut u8, - 2usize, - ) - }; - let mask = 0x40 as u16; - let val = (unit_field_val & mask) >> 6usize; - unsafe { ::std::mem::transmute(val as u8) } + unsafe { ::std::mem::transmute(self._bitfield_2.get(6usize, 1u8) as u8) } } #[inline] pub fn set_mStrokeDasharrayFromObject(&mut self, val: bool) { - let mask = 0x40 as u16; - let val = val as u8 as u16; - let mut unit_field_val: u16 = unsafe { ::std::mem::uninitialized() }; unsafe { - ::std::ptr::copy_nonoverlapping( - &self._bitfield_2 as *const _ as *const u8, - &mut unit_field_val as *mut u16 as *mut u8, - 2usize, - ) - }; - unit_field_val &= !mask; - unit_field_val |= (val << 6usize) & mask; - unsafe { - ::std::ptr::copy_nonoverlapping( - &unit_field_val as *const _ as *const u8, - &mut self._bitfield_2 as *mut _ as *mut u8, - 2usize, - ); + let val: u8 = ::std::mem::transmute(val); + self._bitfield_2.set(6usize, 1u8, val as u64) } } #[inline] pub fn mStrokeDashoffsetFromObject(&self) -> bool { - let mut unit_field_val: u16 = unsafe { ::std::mem::uninitialized() }; - unsafe { - ::std::ptr::copy_nonoverlapping( - &self._bitfield_2 as *const _ as *const u8, - &mut unit_field_val as *mut u16 as *mut u8, - 2usize, - ) - }; - let mask = 0x80 as u16; - let val = (unit_field_val & mask) >> 7usize; - unsafe { ::std::mem::transmute(val as u8) } + unsafe { ::std::mem::transmute(self._bitfield_2.get(7usize, 1u8) as u8) } } #[inline] pub fn set_mStrokeDashoffsetFromObject(&mut self, val: bool) { - let mask = 0x80 as u16; - let val = val as u8 as u16; - let mut unit_field_val: u16 = unsafe { ::std::mem::uninitialized() }; - unsafe { - ::std::ptr::copy_nonoverlapping( - &self._bitfield_2 as *const _ as *const u8, - &mut unit_field_val as *mut u16 as *mut u8, - 2usize, - ) - }; - unit_field_val &= !mask; - unit_field_val |= (val << 7usize) & mask; unsafe { - ::std::ptr::copy_nonoverlapping( - &unit_field_val as *const _ as *const u8, - &mut self._bitfield_2 as *mut _ as *mut u8, - 2usize, - ); + let val: u8 = ::std::mem::transmute(val); + self._bitfield_2.set(7usize, 1u8, val as u64) } } #[inline] pub fn mStrokeWidthFromObject(&self) -> bool { - let mut unit_field_val: u16 = unsafe { ::std::mem::uninitialized() }; - unsafe { - ::std::ptr::copy_nonoverlapping( - &self._bitfield_2 as *const _ as *const u8, - &mut unit_field_val as *mut u16 as *mut u8, - 2usize, - ) - }; - let mask = 0x100 as u16; - let val = (unit_field_val & mask) >> 8usize; - unsafe { ::std::mem::transmute(val as u8) } + unsafe { ::std::mem::transmute(self._bitfield_2.get(8usize, 1u8) as u8) } } #[inline] pub fn set_mStrokeWidthFromObject(&mut self, val: bool) { - let mask = 0x100 as u16; - let val = val as u8 as u16; - let mut unit_field_val: u16 = unsafe { ::std::mem::uninitialized() }; - unsafe { - ::std::ptr::copy_nonoverlapping( - &self._bitfield_2 as *const _ as *const u8, - &mut unit_field_val as *mut u16 as *mut u8, - 2usize, - ) - }; - unit_field_val &= !mask; - unit_field_val |= (val << 8usize) & mask; unsafe { - ::std::ptr::copy_nonoverlapping( - &unit_field_val as *const _ as *const u8, - &mut self._bitfield_2 as *mut _ as *mut u8, - 2usize, - ); + let val: u8 = ::std::mem::transmute(val); + self._bitfield_2.set(8usize, 1u8, val as u64) } } #[inline] @@ -436,11 +349,32 @@ impl Weird { mStrokeDasharrayFromObject: bool, mStrokeDashoffsetFromObject: bool, mStrokeWidthFromObject: bool, - ) -> u16 { - (((((0 | ((mFillOpacitySource as u32 as u16) << 0usize) & (0x7 as u16)) - | ((mStrokeOpacitySource as u32 as u16) << 3usize) & (0x38 as u16)) - | ((mStrokeDasharrayFromObject as u8 as u16) << 6usize) & (0x40 as u16)) - | ((mStrokeDashoffsetFromObject as u8 as u16) << 7usize) & (0x80 as u16)) - | ((mStrokeWidthFromObject as u8 as u16) << 8usize) & (0x100 as u16)) + ) -> __BindgenBitfieldUnit<[u8; 2usize], u8> { + let mut __bindgen_bitfield_unit: __BindgenBitfieldUnit<[u8; 2usize], u8> = + Default::default(); + __bindgen_bitfield_unit.set(0usize, 3u8, { + let mFillOpacitySource: u32 = unsafe { ::std::mem::transmute(mFillOpacitySource) }; + mFillOpacitySource as u64 + }); + __bindgen_bitfield_unit.set(3usize, 3u8, { + let mStrokeOpacitySource: u32 = unsafe { ::std::mem::transmute(mStrokeOpacitySource) }; + mStrokeOpacitySource as u64 + }); + __bindgen_bitfield_unit.set(6usize, 1u8, { + let mStrokeDasharrayFromObject: u8 = + unsafe { ::std::mem::transmute(mStrokeDasharrayFromObject) }; + mStrokeDasharrayFromObject as u64 + }); + __bindgen_bitfield_unit.set(7usize, 1u8, { + let mStrokeDashoffsetFromObject: u8 = + unsafe { ::std::mem::transmute(mStrokeDashoffsetFromObject) }; + mStrokeDashoffsetFromObject as u64 + }); + __bindgen_bitfield_unit.set(8usize, 1u8, { + let mStrokeWidthFromObject: u8 = + unsafe { ::std::mem::transmute(mStrokeWidthFromObject) }; + mStrokeWidthFromObject as u64 + }); + __bindgen_bitfield_unit } }