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 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
83 changes: 83 additions & 0 deletions bindgen-tests/tests/expectations/tests/struct_ptr.rs

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

12 changes: 12 additions & 0 deletions bindgen-tests/tests/headers/struct_ptr.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
typedef const struct foo {
char inner;
} *foo;

typedef struct bar {
char inner;
} *bar;
pvdrz marked this conversation as resolved.
Show resolved Hide resolved

void takes_foo_ptr(foo);
void takes_foo_struct(struct foo);
void takes_bar_ptr(bar);
void takes_bar_struct(struct bar);
29 changes: 26 additions & 3 deletions bindgen/ir/ty.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1094,17 +1094,40 @@ 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 `const
// struct` with the same name and add the `_ptr` suffix to it to avoid name
// collisions.
if !ctx.options().c_naming {
pvdrz marked this conversation as resolved.
Show resolved Hide resolved
if let Some(pointee_spelling) =
inner.pointee_type().map(|ty| ty.spelling())
{
if let (Some(pointee_name), Some(name)) = (
pointee_spelling
.strip_prefix("const struct ")
pvdrz marked this conversation as resolved.
Show resolved Hide resolved
.or_else(|| {
pointee_spelling
.strip_prefix("struct ")
}),
name.as_mut(),
) {
if pointee_name == name {
*name += "_ptr";
}
}
}
}

TypeKind::Alias(inner_id)
}
}
CXType_Enum => {
Expand Down