From f0e05310b43e88e541ed011d20994c02fdcc1a3a Mon Sep 17 00:00:00 2001 From: Nick Fitzgerald Date: Wed, 25 Oct 2017 17:31:21 -0700 Subject: [PATCH] Support bitfield allocation units larger than 64 bits Individual bitfields are still limited to at most 64 bits, but this restriction can be weakened when Rust supports u128. This implements issue #816. Usage notes: * Since common code is added to each generated binding, a program which uses more than one binding may need to work around the duplication by including each binding in its own module. * The values created by bitfield allocation unit constructors can be assigned directly to the corresponding struct fields with no need for transmutation. Implementation notes: __BindgenBitfieldUnit represents a bitfield allocation unit using a Storage type accessible as a slice of u8. The alignment of the unit is inherited from an Align type by virtue of the field: align: [Align; 0], The position of this field in the struct is irrelevant. The alignment of the Storage type is intended to be no larger than the alignment of the Align type, which will be true if the Storage type is, for example, an array of u8. Although the double underscore (__) prefix is reserved for implementations of C++, there are precedents for this convention elsewhere in bindgen and so the convention is adopted here too. Acknowledgement: Thanks to @fitzgen for an initial implementation of __BindgenBitfieldUnit and code to integrate it into bindgen. --- bindgen-integration/build.rs | 2 +- bindgen-integration/cpp/Test.cc | 45 +- bindgen-integration/cpp/Test.h | 18 + bindgen-integration/src/lib.rs | 33 +- src/codegen/bitfield_unit.rs | 82 ++ src/codegen/bitfield_unit_tests.rs | 284 ++++ src/codegen/helpers.rs | 42 +- src/codegen/mod.rs | 248 ++-- src/features.rs | 3 - .../tests/bitfield-32bit-overflow.rs | 1274 ++++------------- tests/expectations/tests/bitfield-large.rs | 83 +- .../tests/bitfield-method-same-name.rs | 125 +- tests/expectations/tests/bitfield_align.rs | 1099 ++++---------- tests/expectations/tests/bitfield_align_2.rs | 161 ++- .../tests/bitfield_method_mangling.rs | 161 ++- .../tests/derive-bitfield-method-same-name.rs | 125 +- .../tests/derive-debug-bitfield.rs | 158 +- .../tests/derive-partialeq-bitfield.rs | 158 +- .../tests/divide-by-zero-in-struct-layout.rs | 103 +- tests/expectations/tests/issue-1034.rs | 87 +- .../issue-1076-unnamed-bitfield-alignment.rs | 87 +- .../tests/issue-739-pointer-wide-bitfield.rs | 154 +- .../expectations/tests/jsval_layout_opaque.rs | 161 ++- .../tests/jsval_layout_opaque_1_0.rs | 161 ++- tests/expectations/tests/layout_align.rs | 198 +-- tests/expectations/tests/layout_eth_conf.rs | 526 +++---- .../expectations/tests/layout_eth_conf_1_0.rs | 526 +++---- tests/expectations/tests/layout_mbuf.rs | 561 +++----- tests/expectations/tests/layout_mbuf_1_0.rs | 561 +++----- tests/expectations/tests/only_bitfields.rs | 158 +- .../tests/struct_with_bitfields.rs | 312 ++-- tests/expectations/tests/union_bitfield.rs | 204 +-- .../expectations/tests/union_bitfield_1_0.rs | 206 +-- .../tests/union_with_anon_struct_bitfield.rs | 161 ++- .../union_with_anon_struct_bitfield_1_0.rs | 161 ++- tests/expectations/tests/weird_bitfields.rs | 348 ++--- 36 files changed, 4147 insertions(+), 4629 deletions(-) create mode 100755 src/codegen/bitfield_unit.rs create mode 100644 src/codegen/bitfield_unit_tests.rs 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 } }