-
Notifications
You must be signed in to change notification settings - Fork 724
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Do not generate names for typedefed anonymous structs and enums #427
Comments
The thing is that detecting this common pattern is not that easy in the case of C++. Old bindgen did this looking at the AST of libclang, and got it wrong a lot of times, over all in presence of anonymous structs in classes (which I believe are also legal in C11). I'm not really fond in supporting this. What we could do, is using a type alias instead of a re-export. The re-exports are done for convenience when using enums (#396), but we can definitely make it configurable. |
BTW, thanks for filling all these issues, they're really helpful. |
I don't think type aliases would fix the documentation or the error messages. pub struct bindgen_ty {
pub a_field: u32
}
pub type Typed = bindgen_ty;
pub use bindgen_ty as Used;
fn main() {
let t: Typed = Typed{a_field:2};
t.not_a_field;
let u: Used = Used{a_field:2};
u.not_a_field;
}
Besides, type aliases are not the same as re-exports. Crucially, tuple-struct constructors are not available through a type alias. |
What's hard about this? Is such a definition split into two AST nodes with an anonymous struct definition and a related typedef? |
Thanks for being so receptive of my issues! Otherwise I'm pretty happy with the new features such as string macros, 128-bit integer support, probably more... |
Yes, I remember it being specially tricky to handle correctly under some circumstances in C++, that's why I used this approach. |
TL;DR: This is how the simplest case looks like:
That is, first we find the anonymous struct, then we find a typedef declaration that happens to contain a node pointing to that same struct. I guess I could try to handle it somewhat correctly given the definition of the anonymous struct (I expect) points to the inner item, but it's tricky. |
I hadn't look into this for a while, actually doesn't look that terrible if what I say above is true, we could try to special-case this. But need to see how more complex cases are handled. |
This is a huge problem for me. In C the |
I've tried to implement this, but there are too many things called Given this header: typedef struct {
} TYPEDEFED_NAME; In bindgen items there is an item |
So the way to implement this is not in the code generation phase, but on the type parsing phase. Concretely, in the If so, you'd have to walk to its next sibling (this would be hacky, but you'd have to re-visit the cursors I think), and see if the exact next cursor is a An alternative approach, which may work better, is looking at the type definition, and see if it's inside a typedef. And if so, do the same. |
That is to say, you don't want to look at the You can look at the clang ast with |
In edit: oh! let mut name = cursor.spelling(); changing to let mut name = ty.spelling(); makes it save the struct name, although I see that |
typedef struct {} name Fixes #427 It looks like clang is doing the hard work of getting the right name from the typedef, but it falls back to arbitrary pretty-printed descriptions if it can't find a typedef. I couldn't find an API to check whether the name comes from a typedef, so I just filter out non-ident-like spellings.
A common pattern in a lot of C code is to do
bindgen 0.20 translates this using a made-up type name and a re-export. This makes the rustdoc documentation look awful (and potentially error messages as well). These bogus type names were not introduced in bindgen 0.19. I think there is no reason not to detect this common pattern and avoid them.
The text was updated successfully, but these errors were encountered: