Skip to content

Commit 2db8777

Browse files
committed
Handle the const struct * and struct * patterns.
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.
1 parent d241e95 commit 2db8777

File tree

3 files changed

+70
-0
lines changed

3 files changed

+70
-0
lines changed

bindgen-tests/tests/expectations/tests/struct_ptr.rs

+40
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
+12
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
typedef const struct foo {
2+
char inner;
3+
} *foo;
4+
5+
typedef struct bar {
6+
char inner;
7+
} *bar;
8+
9+
void takes_foo_ptr(foo);
10+
void takes_foo_struct(struct foo);
11+
void takes_bar_ptr(bar);
12+
void takes_bar_struct(struct bar);

bindgen/ir/ty.rs

+18
Original file line numberDiff line numberDiff line change
@@ -1089,6 +1089,7 @@ impl Type {
10891089
}
10901090
CXType_Typedef => {
10911091
let inner = cursor.typedef_type().expect("Not valid Type?");
1092+
let inner_spelling = inner.spelling();
10921093
let inner =
10931094
Item::from_ty_or_ref(inner, location, None, ctx);
10941095
if inner == potential_id {
@@ -1099,6 +1100,23 @@ impl Type {
10991100
// within the clang parsing.
11001101
TypeKind::Opaque
11011102
} else {
1103+
// Check if this type definition is an alias to a pointer of a `const
1104+
// struct` with the same name and add the `_ptr` suffix to it to avoid name
1105+
// collisions.
1106+
if !ctx.options().c_naming {
1107+
if let Some(inner_name) = inner_spelling
1108+
.strip_prefix("const struct ")
1109+
.or_else(|| {
1110+
inner_spelling.strip_prefix("struct ")
1111+
})
1112+
.and_then(|s| s.strip_suffix(" *"))
1113+
{
1114+
if inner_name == name {
1115+
name += "_ptr";
1116+
}
1117+
}
1118+
}
1119+
11021120
TypeKind::Alias(inner)
11031121
}
11041122
}

0 commit comments

Comments
 (0)