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

Conversation

pvdrz
Copy link
Contributor

@pvdrz pvdrz commented Oct 11, 2022

Given that C keeps a different namespace for structs and aliases. The following pattern

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.

Fixes: #2227

bindgen/ir/ty.rs Outdated Show resolved Hide resolved
bindgen/ir/ty.rs Outdated
if !ctx.options().c_naming {
if let Some(inner_name) = dbg!(inner_spelling
.strip_prefix("const struct ")
.and_then(|s| s.strip_suffix(" *")))
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This textual approach seems unreliable; what if there isn't a space before the *? Possibly other cases?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This textual representation is generated by clang and it doesn't seem to be affected by adding/removing spaces from the source code. For example:

typedef const struct foo {
    char bar;
}*foo;

works just fine.

@pvdrz pvdrz changed the title Handle the const struct * pattern. Handle the const struct * and struct * patterns Oct 18, 2022
@pvdrz
Copy link
Contributor Author

pvdrz commented Oct 18, 2022

@goffrie thanks for your review! I updated the PR with some changes if you want to give it a second look

@pvdrz pvdrz requested a review from emilio October 24, 2022 15:14
bindgen/ir/ty.rs Outdated
// collisions.
if !ctx.options().c_naming {
if let Some(inner_name) = inner_spelling
.strip_prefix("const struct ")
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This feels a bit hackish, relying on libclang's serialization... Can we use pointee_type() and cursor equality instead? If not I guess this is ok...

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I did a commit using pointee_type but I don't get the cursor equality part, wdym?

@pvdrz pvdrz force-pushed the const-struct-ptr branch 2 times, most recently from f7716a5 to e4ba626 Compare November 8, 2022 20:33
Given that C keeps a different namespace for `struct`s and aliases. The
following patterns
```c
typedef const struct foo {
    void *inner;
} *foo;

typedef struct bar {
    void *inner;
} *bar;
```
are valid C code and produces both a `struct` and a pointer called `foo`
and `bar` in different namespaces. Given that Rust does not make this
distinction, we add the `_ptr` prefix to the pointer type aliases to
avoid any name collisions.
bindgen/ir/ty.rs Outdated Show resolved Hide resolved
bindgen/ir/ty.rs Outdated Show resolved Hide resolved
bindgen-tests/tests/headers/struct_ptr.h Outdated Show resolved Hide resolved
Copy link
Contributor

@emilio emilio left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks!

@pvdrz pvdrz merged commit db4ea32 into rust-lang:master Nov 10, 2022
@pvdrz pvdrz deleted the const-struct-ptr branch November 10, 2022 15:43
LoganBarnett pushed a commit to LoganBarnett/rust-bindgen that referenced this pull request Dec 2, 2023
Given that C keeps a different namespace for `struct`/`enum`/`union` and `typedef` aliases. The
following patterns
```c
typedef const struct foo {
    void *inner;
} *foo;

typedef struct bar {
    void *inner;
} *bar;
```
are valid C code and produces both a `struct` and a pointer called `foo`
and `bar` in different namespaces. Given that Rust does not make this
distinction, we add the `_ptr` prefix to the pointer type aliases to
avoid any name collisions.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Multiple definitions when a pointer gets typedef’d to the same name as a struct
3 participants