Skip to content
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

Handle the const struct * and struct * patterns #2304

Merged
merged 2 commits into from Nov 10, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
153 changes: 153 additions & 0 deletions bindgen-tests/tests/expectations/tests/typedef-pointer-overlap.rs

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

30 changes: 30 additions & 0 deletions bindgen-tests/tests/headers/typedef-pointer-overlap.h
@@ -0,0 +1,30 @@
typedef const struct foo {
char inner;
} *foo;

typedef struct bar {
char inner;
} *bar;

typedef struct baz *baz;

typedef union cat {
int standard_issue;
} *cat;

typedef enum mad { scientist } *mad;

void takes_foo_ptr(foo);
void takes_foo_struct(struct foo);

void takes_bar_ptr(bar);
void takes_bar_struct(struct bar);

void takes_baz_ptr(baz);
void takes_baz_struct(struct baz);

void takes_cat_ptr(cat);
void takes_cat_union(union cat);

void takes_mad_ptr(mad);
void takes_mad_enum(enum mad);
21 changes: 18 additions & 3 deletions bindgen/ir/ty.rs
Expand Up @@ -1094,17 +1094,32 @@ impl Type {
}
CXType_Typedef => {
let inner = cursor.typedef_type().expect("Not valid Type?");
let inner =
let inner_id =
Item::from_ty_or_ref(inner, location, None, ctx);
if inner == potential_id {
if inner_id == potential_id {
warn!(
"Generating oqaque type instead of self-referential \
typedef");
// This can happen if we bail out of recursive situations
// within the clang parsing.
TypeKind::Opaque
} else {
TypeKind::Alias(inner)
// Check if this type definition is an alias to a pointer of a `struct` /
// `union` / `enum` with the same name and add the `_ptr` suffix to it to
// avoid name collisions.
if let Some(ref mut name) = name {
if inner.kind() == CXType_Pointer &&
!ctx.options().c_naming
{
let pointee = inner.pointee_type().unwrap();
if pointee.kind() == CXType_Elaborated &&
pointee.declaration().spelling() == *name
{
*name += "_ptr";
}
}
}
TypeKind::Alias(inner_id)
}
}
CXType_Enum => {
Expand Down