rust-bindgen
rust-bindgen copied to clipboard
Generate getters/setters to contained anonymous struct/union members
We often see code like this:
struct JSJitInfo {
// ...
union {
uint16_t protoID;
js::jit::InlinableNative inlinableNative;
};
// ...
};
which generates members and types like __bindgen_anon_1: JSJitInfo__bindgen_ty_1.
It would be cool if we generated getters/setters on the containing struct for these anonymous structs/unions members, so that using them was easier and more like their usage in C/C++.
Not sure if related, but would it be possible to support anonymous structs by flattening their properties (like C does) instead of generating __bindgen_anon_1? That's our primary case for using anonymous struct fields, and I guess we're not alone.
Assuming that they don't affect the layout of the type, it'd be doable, yeah... But I don't think that's the case, for example:
struct Foo {
struct {
uint64_t word;
uint32_t bar;
};
uint32_t baz;
};
I think bar and baz would be collapsed if we flatten the structs, but not otherwise.
@emilio Not sure I follow, why would they collapse?
Oh wait, got it now, you mean because of the padding on 64-bit architecture. Yeah, guess it will need to be still generated as a separate field, but, as far as I remember, bindgen already does that in other places.
Right, adding padding and alignment bits should be doable, though it may not be as trivial.
Will open a different issue about this, seems a somewhat different scope from this one :).
This would be nice for my use case, which depends on a third party header.
I'd like to implement it, but would like confirmation on the expected output before I start.
Input:
struct Foo {
struct {
uint8_t a;
uint16_t b;
union {
uint8_t reserved1[64];
uint8_t c;
};
};
union {
uint8_t reserved2[128];
struct {
uint8_t d;
};
};
};
Output:
struct Foo {
pub a: u8,
pub b: u16,
// TODO: alignment/padding ^
union_storage_1: [u8; 64],
// TODO: alignment/padding ^
union_storage_2: [u8; 128],
// TODO: alignment/padding ^
// Consecutive union and padding could be merged, but it doesn't provide significant value.
}
impl Foo {
#[inline]
unsafe fn reserved1(&self) -> &[u8; 64] { ... }
// Non-mut primites can be by value
#[inline]
unsafe fn c(&self) -> u8 { ... }
// Mut primites are by mut ref
#[inline]
unsafe fn c_mut(&mut self) -> &mut u8 { ... }
// ...
}
Accessors for rust primitives that can store any bit pattern wouldn't necessarily need to be unsafe (e.g. u8), but I wouldn't want to have to deal with that in the first pass.