diff options
author | Emilio Cobos Álvarez <ecoal95@gmail.com> | 2016-08-20 22:32:16 -0700 |
---|---|---|
committer | Emilio Cobos Álvarez <ecoal95@gmail.com> | 2016-09-16 11:34:07 -0700 |
commit | cfdf15f5d04d4fbca3e7fcb46a1dd658ade973cd (patch) | |
tree | f7d2087332f4506bb836dce901bc181e5ffc7fba /tests/expectations/struct_with_bitfields.rs | |
parent | bbd6b2c9919e02642a8874e5ceb2ba3b5c76adec (diff) |
Rewrite the core of the binding generator.
TL;DR: The binding generator is a mess as of right now. At first it was funny
(in a "this is challenging" sense) to improve on it, but this is not
sustainable.
The truth is that the current architecture of the binding generator is a huge
pile of hacks, so these few days I've been working on rewriting it with a few
goals.
1) Have the hacks as contained and identified as possible. They're sometimes
needed because how clang exposes the AST, but ideally those hacks are well
identified and don't interact randomly with each others.
As an example, in the current bindgen when scanning the parameters of a
function that references a struct clones all the struct information, then if
the struct name changes (because we mangle it), everything breaks.
2) Support extending the bindgen output without having to deal with clang. The
way I'm aiming to do this is separating completely the parsing stage from
the code generation one, and providing a single id for each item the binding
generator provides.
3) No more random mutation of the internal representation from anywhere. That
means no more Rc<RefCell<T>>, no more random circular references, no more
borrow_state... nothing.
4) No more deduplication of declarations before code generation.
Current bindgen has a stage, called `tag_dup_decl`[1], that takes care of
deduplicating declarations. That's completely buggy, and for C++ it's a
complete mess, since we YOLO modify the world.
I've managed to take rid of this using the clang canonical declaration, and
the definition, to avoid scanning any type/item twice.
5) Code generation should not modify any internal data structure. It can lookup
things, traverse whatever it needs, but not modifying randomly.
6) Each item should have a canonical name, and a single source of mangling
logic, and that should be computed from the inmutable state, at code
generation.
I've put a few canonical_name stuff in the code generation phase, but it's
still not complete, and should change if I implement namespaces.
Improvements pending until this can land:
1) Add support for missing core stuff, mainly generating functions (note that
we parse the signatures for types correctly though), bitfields, generating
C++ methods.
2) Add support for the necessary features that were added to work around some
C++ pitfalls, like opaque types, etc...
3) Add support for the sugar that Manish added recently.
4) Optionally (and I guess this can land without it, because basically nobody
uses it since it's so buggy), bring back namespace support.
These are not completely trivial, but I think I can do them quite easily with
the current architecture.
I'm putting the current state of affairs here as a request for comments... Any
thoughts? Note that there are still a few smells I want to eventually
re-redesign, like the ParseError::Recurse thing, but until that happens I'm
way happier with this kind of architecture.
I'm keeping the old `parser.rs` and `gen.rs` in tree just for reference while I
code, but they will go away.
[1]: https://github.com/Yamakaky/rust-bindgen/blob/master/src/gen.rs#L448
Diffstat (limited to 'tests/expectations/struct_with_bitfields.rs')
-rw-r--r-- | tests/expectations/struct_with_bitfields.rs | 150 |
1 files changed, 70 insertions, 80 deletions
diff --git a/tests/expectations/struct_with_bitfields.rs b/tests/expectations/struct_with_bitfields.rs index c2bfc543..3fb83a47 100644 --- a/tests/expectations/struct_with_bitfields.rs +++ b/tests/expectations/struct_with_bitfields.rs @@ -6,127 +6,117 @@ #[repr(C)] #[derive(Debug, Copy)] -pub struct Struct_bitfield { - pub _bitfield_1: ::std::os::raw::c_ushort, +pub struct bitfield { + pub _bitfield_1: u8, pub e: ::std::os::raw::c_int, - pub _bitfield_2: ::std::os::raw::c_uint, - pub _bitfield_3: ::std::os::raw::c_uint, + pub _bitfield_2: u8, + pub _bitfield_3: u32, } -impl Struct_bitfield { +#[test] +fn bindgen_test_layout_bitfield() { + assert_eq!(::std::mem::size_of::<bitfield>() , 16usize); + assert_eq!(::std::mem::align_of::<bitfield>() , 4usize); +} +impl Clone for bitfield { + fn clone(&self) -> Self { *self } +} +impl bitfield { #[inline] pub fn a(&self) -> ::std::os::raw::c_ushort { - (self._bitfield_1 & (1usize as ::std::os::raw::c_ushort)) >> 0usize + unsafe { + ::std::mem::transmute(((self._bitfield_1 & (1usize as u8)) >> + 0u32) as u16) + } } #[inline] - pub fn set_a(&mut self, val: bool) { - self._bitfield_1 &= !(1usize as ::std::os::raw::c_ushort); - self._bitfield_1 |= - ((val as ::std::os::raw::c_ushort) << 0usize) & - (1usize as ::std::os::raw::c_ushort); + pub fn set_a(&mut self, val: ::std::os::raw::c_ushort) { + self._bitfield_1 &= !(1usize as u8); + self._bitfield_1 |= ((val as u16 as u8) << 0u32) & (1usize as u8); } #[inline] pub fn b(&self) -> ::std::os::raw::c_ushort { - (self._bitfield_1 & (2usize as ::std::os::raw::c_ushort)) >> 1usize + unsafe { + ::std::mem::transmute(((self._bitfield_1 & (2usize as u8)) >> + 1u32) as u16) + } } #[inline] - pub fn set_b(&mut self, val: bool) { - self._bitfield_1 &= !(2usize as ::std::os::raw::c_ushort); - self._bitfield_1 |= - ((val as ::std::os::raw::c_ushort) << 1usize) & - (2usize as ::std::os::raw::c_ushort); + pub fn set_b(&mut self, val: ::std::os::raw::c_ushort) { + self._bitfield_1 &= !(2usize as u8); + self._bitfield_1 |= ((val as u16 as u8) << 1u32) & (2usize as u8); } #[inline] pub fn c(&self) -> ::std::os::raw::c_ushort { - (self._bitfield_1 & (4usize as ::std::os::raw::c_ushort)) >> 2usize + unsafe { + ::std::mem::transmute(((self._bitfield_1 & (4usize as u8)) >> + 2u32) as u16) + } } #[inline] - pub fn set_c(&mut self, val: bool) { - self._bitfield_1 &= !(4usize as ::std::os::raw::c_ushort); - self._bitfield_1 |= - ((val as ::std::os::raw::c_ushort) << 2usize) & - (4usize as ::std::os::raw::c_ushort); + pub fn set_c(&mut self, val: ::std::os::raw::c_ushort) { + self._bitfield_1 &= !(4usize as u8); + self._bitfield_1 |= ((val as u16 as u8) << 2u32) & (4usize as u8); } #[inline] pub fn at_offset_3(&self) -> ::std::os::raw::c_ushort { - (self._bitfield_1 & (8usize as ::std::os::raw::c_ushort)) >> 3usize + unsafe { + ::std::mem::transmute(((self._bitfield_1 & (8usize as u8)) >> + 3u32) as u16) + } } #[inline] - pub fn set_at_offset_3(&mut self, val: bool) { - self._bitfield_1 &= !(8usize as ::std::os::raw::c_ushort); - self._bitfield_1 |= - ((val as ::std::os::raw::c_ushort) << 3usize) & - (8usize as ::std::os::raw::c_ushort); + pub fn set_at_offset_3(&mut self, val: ::std::os::raw::c_ushort) { + self._bitfield_1 &= !(8usize as u8); + self._bitfield_1 |= ((val as u16 as u8) << 3u32) & (8usize as u8); } #[inline] pub fn at_offset_4(&self) -> ::std::os::raw::c_ushort { - (self._bitfield_1 & (48usize as ::std::os::raw::c_ushort)) >> 4usize + unsafe { + ::std::mem::transmute(((self._bitfield_1 & (48usize as u8)) >> + 4u32) as u16) + } } #[inline] - pub fn set_at_offset_4(&mut self, val: u8) { - self._bitfield_1 &= !(48usize as ::std::os::raw::c_ushort); - self._bitfield_1 |= - ((val as ::std::os::raw::c_ushort) << 4usize) & - (48usize as ::std::os::raw::c_ushort); + pub fn set_at_offset_4(&mut self, val: ::std::os::raw::c_ushort) { + self._bitfield_1 &= !(48usize as u8); + self._bitfield_1 |= ((val as u16 as u8) << 4u32) & (48usize as u8); } #[inline] pub fn d(&self) -> ::std::os::raw::c_ushort { - (self._bitfield_1 & (192usize as ::std::os::raw::c_ushort)) >> 6usize + unsafe { + ::std::mem::transmute(((self._bitfield_1 & (192usize as u8)) >> + 6u32) as u16) + } } #[inline] - pub fn set_d(&mut self, val: u8) { - self._bitfield_1 &= !(192usize as ::std::os::raw::c_ushort); - self._bitfield_1 |= - ((val as ::std::os::raw::c_ushort) << 6usize) & - (192usize as ::std::os::raw::c_ushort); - } - #[inline] - pub fn new_bitfield_1(a: bool, b: bool, c: bool, unnamed_bitfield1: bool, - unnamed_bitfield2: u8, d: u8) - -> ::std::os::raw::c_ushort { - 0 | ((a as ::std::os::raw::c_ushort) << 0u32) | - ((b as ::std::os::raw::c_ushort) << 1u32) | - ((c as ::std::os::raw::c_ushort) << 2u32) | - ((unnamed_bitfield1 as ::std::os::raw::c_ushort) << 3u32) | - ((unnamed_bitfield2 as ::std::os::raw::c_ushort) << 4u32) | - ((d as ::std::os::raw::c_ushort) << 6u32) + pub fn set_d(&mut self, val: ::std::os::raw::c_ushort) { + self._bitfield_1 &= !(192usize as u8); + self._bitfield_1 |= ((val as u16 as u8) << 6u32) & (192usize as u8); } #[inline] pub fn f(&self) -> ::std::os::raw::c_uint { - (self._bitfield_2 & (3usize as ::std::os::raw::c_uint)) >> 0usize - } - #[inline] - pub fn set_f(&mut self, val: u8) { - self._bitfield_2 &= !(3usize as ::std::os::raw::c_uint); - self._bitfield_2 |= - ((val as ::std::os::raw::c_uint) << 0usize) & - (3usize as ::std::os::raw::c_uint); + unsafe { + ::std::mem::transmute(((self._bitfield_2 & (3usize as u8)) >> + 0u32) as u32) + } } #[inline] - pub fn new_bitfield_2(f: u8) -> ::std::os::raw::c_uint { - 0 | ((f as ::std::os::raw::c_uint) << 0u32) + pub fn set_f(&mut self, val: ::std::os::raw::c_uint) { + self._bitfield_2 &= !(3usize as u8); + self._bitfield_2 |= ((val as u32 as u8) << 0u32) & (3usize as u8); } #[inline] pub fn g(&self) -> ::std::os::raw::c_uint { - (self._bitfield_3 & (4294967295usize as ::std::os::raw::c_uint)) >> - 0usize + unsafe { + ::std::mem::transmute(((self._bitfield_3 & + (4294967295usize as u32)) >> 0u32) as + u32) + } } #[inline] - pub fn set_g(&mut self, val: u32) { - self._bitfield_3 &= !(4294967295usize as ::std::os::raw::c_uint); + pub fn set_g(&mut self, val: ::std::os::raw::c_uint) { + self._bitfield_3 &= !(4294967295usize as u32); self._bitfield_3 |= - ((val as ::std::os::raw::c_uint) << 0usize) & - (4294967295usize as ::std::os::raw::c_uint); - } - #[inline] - pub fn new_bitfield_3(g: u32) -> ::std::os::raw::c_uint { - 0 | ((g as ::std::os::raw::c_uint) << 0u32) + ((val as u32 as u32) << 0u32) & (4294967295usize as u32); } } -impl ::std::clone::Clone for Struct_bitfield { - fn clone(&self) -> Self { *self } -} -#[test] -fn bindgen_test_layout_Struct_bitfield() { - assert_eq!(::std::mem::size_of::<Struct_bitfield>() , 16usize); - assert_eq!(::std::mem::align_of::<Struct_bitfield>() , 4usize); -} |