rust-lang / rust-bindgen

Automatically generates Rust FFI bindings to C (and some C++) libraries.
https://rust-lang.github.io/rust-bindgen/
BSD 3-Clause "New" or "Revised" License
4.23k stars 679 forks source link

wrap-static-fns converts _Bool to bool, causing a compile error #2805

Open porglezomp opened 2 months ago

porglezomp commented 2 months ago

I made a little wrapper header using _Bool to avoid having to include stdbool.h since I was being lazy and didn't want to exclude a few symbols. It translated the _Bool to bool in the wrap-static-fns generated wrapper, which caused a compilation failure.

(Workaround: Just use stdbool. It’s not a big deal to filter out the few definitions.)

Input C/C++ Header

static inline _Bool example() { return 1; }

Bindgen Invocation

$ bindgen input.h --experimental --wrap-static-fns --wrap-static-fns-path=wrapper

Actual Results

It generates this wrapper, with _Bool translated to bool.

#include "input.h"

// Static wrappers

bool example__extern(void) { return example(); }

which produces this error:

wrapper.c:5:1: error: unknown type name 'bool'
bool example__extern(void) { return example(); }
^
1 error generated.

Expected Results

The generated wrappers should use _Bool as provided in the input.

pvdrz commented 2 months ago

hmmm... Well this is a hard one, clang is convinced that _Bool is the boolean type. If you pass this header to bindgen

_Bool example();

The AST produced by clang will be

(
 kind = FunctionDecl
 spelling = "example"
 location = input.h:1:7
 is-definition? false
 is-declaration? true
 is-inlined-function? false
 usr = "c:@F@example"
 number-of-args = 0
 ret-type = Bool

 semantic-parent.kind = TranslationUnit
 semantic-parent.spelling = "input.h"
 semantic-parent.location = builtin definitions
 semantic-parent.is-definition? false
 semantic-parent.is-declaration? false
 semantic-parent.is-inlined-function? false

 type.kind = FunctionNoProto
 type.cconv = 1
 type.spelling = "_Bool ()"
 type.is-variadic? true

 type.return.kind = Bool
 type.return.cconv = 100
 type.return.spelling = "_Bool"
 type.return.is-variadic? false
)

Where type.return.kind is Bool.

porglezomp commented 2 months ago

_Bool is the canonical boolean type in C, bool is a typedef from <stdbool.h>.

I guess the question is does type.return.spelling show for

#include <stdbool.h>
static inline bool example() { return 1; }

because I'm seeing the same in clang -Xclang -ast-dump -fsyntax-only so maybe the sugared type isn't properly manifested :(

pvdrz commented 2 months ago

I'm seeing the same kind here using your example:

(
 kind = FunctionDecl
 spelling = "example"
 location = hello3.c:2:20
 is-definition? true
 is-declaration? true
 is-inlined-function? true
 usr = "c:hello3.c@F@example"
 number-of-args = 0
 ret-type = Bool

 semantic-parent.kind = TranslationUnit
 semantic-parent.spelling = "hello3.c"
 semantic-parent.location = builtin definitions
 semantic-parent.is-definition? false
 semantic-parent.is-declaration? false
 semantic-parent.is-inlined-function? false

 type.kind = FunctionNoProto
 type.cconv = 1
 type.spelling = "_Bool ()"
 type.is-variadic? true

 type.return.kind = Bool
 type.return.cconv = 100
 type.return.spelling = "_Bool"
 type.return.is-variadic? false
 ...