Skip to content

Commit 5dbdadc

Browse files
author
bors-servo
authored
Auto merge of #1066 - pepyakin:bitfields-in-unions, r=fitzgen
Bitfields in unions Fixes #744 I think it is WIP for the moment as I didn't run tests locally.
2 parents 745d606 + c187b9f commit 5dbdadc

File tree

6 files changed

+467
-2
lines changed

6 files changed

+467
-2
lines changed

src/codegen/mod.rs

+15-1
Original file line numberDiff line numberDiff line change
@@ -1152,7 +1152,21 @@ impl<'a> FieldCodegen<'a> for BitfieldUnit {
11521152
F: Extend<quote::Tokens>,
11531153
M: Extend<quote::Tokens>,
11541154
{
1155-
let field_ty = helpers::blob(self.layout());
1155+
let field_ty = if parent.is_union() && !parent.can_be_rust_union(ctx) {
1156+
let ty = helpers::blob(self.layout());
1157+
if ctx.options().enable_cxx_namespaces {
1158+
quote! {
1159+
root::__BindgenUnionField<#ty>
1160+
}
1161+
} else {
1162+
quote! {
1163+
__BindgenUnionField<#ty>
1164+
}
1165+
}
1166+
} else {
1167+
helpers::blob(self.layout())
1168+
};
1169+
11561170
let unit_field_name = format!("_bitfield_{}", self.nth());
11571171
let unit_field_ident = ctx.rust_ident(&unit_field_name);
11581172

src/ir/comp.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -1498,7 +1498,7 @@ impl CompInfo {
14981498
Field::DataMember(ref field_data) => {
14991499
field_data.ty().can_derive_copy(ctx)
15001500
}
1501-
Field::Bitfields(_) => false,
1501+
Field::Bitfields(_) => true,
15021502
})
15031503
}
15041504
}
+185
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,185 @@
1+
/* automatically generated by rust-bindgen */
2+
3+
4+
#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)]
5+
6+
7+
#[repr(C)]
8+
#[derive(Copy)]
9+
pub union U4 {
10+
pub _bitfield_1: u8,
11+
_bindgen_union_align: u32,
12+
}
13+
#[test]
14+
fn bindgen_test_layout_U4() {
15+
assert_eq!(
16+
::std::mem::size_of::<U4>(),
17+
4usize,
18+
concat!("Size of: ", stringify!(U4))
19+
);
20+
assert_eq!(
21+
::std::mem::align_of::<U4>(),
22+
4usize,
23+
concat!("Alignment of ", stringify!(U4))
24+
);
25+
}
26+
impl Clone for U4 {
27+
fn clone(&self) -> Self {
28+
*self
29+
}
30+
}
31+
impl Default for U4 {
32+
fn default() -> Self {
33+
unsafe { ::std::mem::zeroed() }
34+
}
35+
}
36+
impl U4 {
37+
#[inline]
38+
pub fn derp(&self) -> ::std::os::raw::c_uint {
39+
let mut unit_field_val: u8 = unsafe { ::std::mem::uninitialized() };
40+
unsafe {
41+
::std::ptr::copy_nonoverlapping(
42+
&self._bitfield_1 as *const _ as *const u8,
43+
&mut unit_field_val as *mut u8 as *mut u8,
44+
::std::mem::size_of::<u8>(),
45+
)
46+
};
47+
let mask = 1u64 as u8;
48+
let val = (unit_field_val & mask) >> 0usize;
49+
unsafe { ::std::mem::transmute(val as u32) }
50+
}
51+
#[inline]
52+
pub fn set_derp(&mut self, val: ::std::os::raw::c_uint) {
53+
let mask = 1u64 as u8;
54+
let val = val as u32 as u8;
55+
let mut unit_field_val: u8 = unsafe { ::std::mem::uninitialized() };
56+
unsafe {
57+
::std::ptr::copy_nonoverlapping(
58+
&self._bitfield_1 as *const _ as *const u8,
59+
&mut unit_field_val as *mut u8 as *mut u8,
60+
::std::mem::size_of::<u8>(),
61+
)
62+
};
63+
unit_field_val &= !mask;
64+
unit_field_val |= (val << 0usize) & mask;
65+
unsafe {
66+
::std::ptr::copy_nonoverlapping(
67+
&unit_field_val as *const _ as *const u8,
68+
&mut self._bitfield_1 as *mut _ as *mut u8,
69+
::std::mem::size_of::<u8>(),
70+
);
71+
}
72+
}
73+
#[inline]
74+
pub fn new_bitfield_1(derp: ::std::os::raw::c_uint) -> u8 {
75+
(0 | ((derp as u32 as u8) << 0usize) & (1u64 as u8))
76+
}
77+
}
78+
#[repr(C)]
79+
#[derive(Copy)]
80+
pub union B {
81+
pub _bitfield_1: u32,
82+
_bindgen_union_align: u32,
83+
}
84+
#[test]
85+
fn bindgen_test_layout_B() {
86+
assert_eq!(
87+
::std::mem::size_of::<B>(),
88+
4usize,
89+
concat!("Size of: ", stringify!(B))
90+
);
91+
assert_eq!(
92+
::std::mem::align_of::<B>(),
93+
4usize,
94+
concat!("Alignment of ", stringify!(B))
95+
);
96+
}
97+
impl Clone for B {
98+
fn clone(&self) -> Self {
99+
*self
100+
}
101+
}
102+
impl Default for B {
103+
fn default() -> Self {
104+
unsafe { ::std::mem::zeroed() }
105+
}
106+
}
107+
impl B {
108+
#[inline]
109+
pub fn foo(&self) -> ::std::os::raw::c_uint {
110+
let mut unit_field_val: u32 = unsafe { ::std::mem::uninitialized() };
111+
unsafe {
112+
::std::ptr::copy_nonoverlapping(
113+
&self._bitfield_1 as *const _ as *const u8,
114+
&mut unit_field_val as *mut u32 as *mut u8,
115+
::std::mem::size_of::<u32>(),
116+
)
117+
};
118+
let mask = 2147483647u64 as u32;
119+
let val = (unit_field_val & mask) >> 0usize;
120+
unsafe { ::std::mem::transmute(val as u32) }
121+
}
122+
#[inline]
123+
pub fn set_foo(&mut self, val: ::std::os::raw::c_uint) {
124+
let mask = 2147483647u64 as u32;
125+
let val = val as u32 as u32;
126+
let mut unit_field_val: u32 = unsafe { ::std::mem::uninitialized() };
127+
unsafe {
128+
::std::ptr::copy_nonoverlapping(
129+
&self._bitfield_1 as *const _ as *const u8,
130+
&mut unit_field_val as *mut u32 as *mut u8,
131+
::std::mem::size_of::<u32>(),
132+
)
133+
};
134+
unit_field_val &= !mask;
135+
unit_field_val |= (val << 0usize) & mask;
136+
unsafe {
137+
::std::ptr::copy_nonoverlapping(
138+
&unit_field_val as *const _ as *const u8,
139+
&mut self._bitfield_1 as *mut _ as *mut u8,
140+
::std::mem::size_of::<u32>(),
141+
);
142+
}
143+
}
144+
#[inline]
145+
pub fn bar(&self) -> ::std::os::raw::c_uchar {
146+
let mut unit_field_val: u32 = unsafe { ::std::mem::uninitialized() };
147+
unsafe {
148+
::std::ptr::copy_nonoverlapping(
149+
&self._bitfield_1 as *const _ as *const u8,
150+
&mut unit_field_val as *mut u32 as *mut u8,
151+
::std::mem::size_of::<u32>(),
152+
)
153+
};
154+
let mask = 2147483648u64 as u32;
155+
let val = (unit_field_val & mask) >> 31usize;
156+
unsafe { ::std::mem::transmute(val as u8) }
157+
}
158+
#[inline]
159+
pub fn set_bar(&mut self, val: ::std::os::raw::c_uchar) {
160+
let mask = 2147483648u64 as u32;
161+
let val = val as u8 as u32;
162+
let mut unit_field_val: u32 = unsafe { ::std::mem::uninitialized() };
163+
unsafe {
164+
::std::ptr::copy_nonoverlapping(
165+
&self._bitfield_1 as *const _ as *const u8,
166+
&mut unit_field_val as *mut u32 as *mut u8,
167+
::std::mem::size_of::<u32>(),
168+
)
169+
};
170+
unit_field_val &= !mask;
171+
unit_field_val |= (val << 31usize) & mask;
172+
unsafe {
173+
::std::ptr::copy_nonoverlapping(
174+
&unit_field_val as *const _ as *const u8,
175+
&mut self._bitfield_1 as *mut _ as *mut u8,
176+
::std::mem::size_of::<u32>(),
177+
);
178+
}
179+
}
180+
#[inline]
181+
pub fn new_bitfield_1(foo: ::std::os::raw::c_uint, bar: ::std::os::raw::c_uchar) -> u32 {
182+
((0 | ((foo as u32 as u32) << 0usize) & (2147483647u64 as u32))
183+
| ((bar as u8 as u32) << 31usize) & (2147483648u64 as u32))
184+
}
185+
}

0 commit comments

Comments
 (0)