Skip to content

Commit

Permalink
codegen: Look through typedefs to detect void return type. (#2379)
Browse files Browse the repository at this point in the history
* codegen: Look through typedefs to detect void return type.

And reuse a bit more code.

Should fix #2377, but needs a test (can't run tests atm).

* Add tests

* Run rustfmt

* Update changelog

Co-authored-by: Christian Poveda <christian.poveda@ferrous-systems.com>
  • Loading branch information
emilio and pvdrz committed Jan 6, 2023
1 parent 1abaf7e commit 5875949
Show file tree
Hide file tree
Showing 6 changed files with 71 additions and 25 deletions.
3 changes: 2 additions & 1 deletion CHANGELOG.md
Expand Up @@ -159,7 +159,8 @@
* The `ParseCallbacks::generated_name_override` now receives `ItemInfo<'_>` as
argument instead of a `&str`.
* Updated the `clang-sys` crate version to 1.4.0 to support clang 15.

* The return type is now ommited in signatures of functions returning `void`.

## Removed

## Fixed
Expand Down

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

18 changes: 18 additions & 0 deletions bindgen-tests/tests/expectations/tests/void_typedef.rs

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

9 changes: 9 additions & 0 deletions bindgen-tests/tests/headers/void_typedef.h
@@ -0,0 +1,9 @@
typedef void VOID;

typedef VOID ALSO_VOID;

void this_api_returns_nothing(void);

VOID this_api_also_returns_nothing(VOID);

ALSO_VOID this_other_api_also_returns_nothing(ALSO_VOID);
2 changes: 1 addition & 1 deletion bindgen/codegen/dyngen.rs
Expand Up @@ -170,7 +170,7 @@ impl DynamicItems {
if !is_variadic {
self.struct_implementation.push(quote! {
#(#attributes)*
pub unsafe fn #ident ( &self, #( #args ),* ) -> #ret_ty {
pub unsafe fn #ident ( &self, #( #args ),* ) #ret_ty {
#call_body
}
});
Expand Down
62 changes: 40 additions & 22 deletions bindgen/codegen/mod.rs
Expand Up @@ -4135,11 +4135,7 @@ impl CodeGenerator for Function {
if is_dynamic_function {
let args_identifiers =
utils::fnsig_argument_identifiers(ctx, signature);
let return_item = ctx.resolve_item(signature.return_type());
let ret_ty = match *return_item.kind().expect_type().kind() {
TypeKind::Void => quote! {()},
_ => return_item.to_rust_ty_or_opaque(ctx, &()),
};
let ret_ty = utils::fnsig_return_ty(ctx, signature);
result.dynamic_items().push(
ident,
abi,
Expand Down Expand Up @@ -4811,25 +4807,52 @@ pub mod utils {
})
}

pub fn fnsig_return_ty(
fn fnsig_return_ty_internal(
ctx: &BindgenContext,
sig: &FunctionSig,
include_arrow: bool,
) -> proc_macro2::TokenStream {
if sig.is_divergent() {
return quote! { -> ! };
return if include_arrow {
quote! { -> ! }
} else {
quote! { ! }
};
}

let return_item = ctx.resolve_item(sig.return_type());
if let TypeKind::Void = *return_item.kind().expect_type().kind() {
quote! {}
let canonical_type_kind = sig
.return_type()
.into_resolver()
.through_type_refs()
.through_type_aliases()
.resolve(ctx)
.kind()
.expect_type()
.kind();

if let TypeKind::Void = canonical_type_kind {
return if include_arrow {
quote! {}
} else {
quote! { () }
};
}

let ret_ty = sig.return_type().to_rust_ty_or_opaque(ctx, &());
if include_arrow {
quote! { -> #ret_ty }
} else {
let ret_ty = return_item.to_rust_ty_or_opaque(ctx, &());
quote! {
-> #ret_ty
}
ret_ty
}
}

pub fn fnsig_return_ty(
ctx: &BindgenContext,
sig: &FunctionSig,
) -> proc_macro2::TokenStream {
fnsig_return_ty_internal(ctx, sig, /* include_arrow = */ true)
}

pub fn fnsig_arguments(
ctx: &BindgenContext,
sig: &FunctionSig,
Expand Down Expand Up @@ -4942,14 +4965,9 @@ pub mod utils {
arg_item.to_rust_ty_or_opaque(ctx, &())
});

let return_item = ctx.resolve_item(sig.return_type());
let ret_ty =
if let TypeKind::Void = *return_item.kind().expect_type().kind() {
quote! { () }
} else {
return_item.to_rust_ty_or_opaque(ctx, &())
};

let ret_ty = fnsig_return_ty_internal(
ctx, sig, /* include_arrow = */ false,
);
quote! {
*const ::block::Block<(#(#args,)*), #ret_ty>
}
Expand Down

0 comments on commit 5875949

Please sign in to comment.