Skip to content

Commit

Permalink
Handle the const struct * pattern.
Browse files Browse the repository at this point in the history
Given that C keeps a different namespace for `struct`s and aliases. The
following pattern
```c
typedef const struct foo {
    void *bar;
} *foo;
```
is valid C code and produces both a `struct` and a pointer called `foo`.
Given that Rust does not make this distinction, we add the `_ptr` prefix
to the pointer type alias to avoid any name collisions.
  • Loading branch information
pvdrz committed Oct 11, 2022
1 parent d241e95 commit 05ef029
Show file tree
Hide file tree
Showing 3 changed files with 61 additions and 0 deletions.
40 changes: 40 additions & 0 deletions bindgen-tests/tests/expectations/tests/const_struct_ptr.rs

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

6 changes: 6 additions & 0 deletions bindgen-tests/tests/headers/const_struct_ptr.h
@@ -0,0 +1,6 @@
typedef const struct foo {
char bar;
} *foo;

void takes_ptr(foo);
void takes_struct(struct foo);
15 changes: 15 additions & 0 deletions bindgen/ir/ty.rs
Expand Up @@ -1089,6 +1089,7 @@ impl Type {
}
CXType_Typedef => {
let inner = cursor.typedef_type().expect("Not valid Type?");
let inner_spelling = inner.spelling();
let inner =
Item::from_ty_or_ref(inner, location, None, ctx);
if inner == potential_id {
Expand All @@ -1099,6 +1100,20 @@ impl Type {
// within the clang parsing.
TypeKind::Opaque
} else {
// 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 {
if let Some(inner_name) = dbg!(inner_spelling
.strip_prefix("const struct ")
.and_then(|s| s.strip_suffix(" *")))
{
if inner_name == name {
name += "_ptr";
}
}
}

TypeKind::Alias(inner)
}
}
Expand Down

0 comments on commit 05ef029

Please sign in to comment.