summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEmilio Cobos Álvarez <emilio@crisal.io>2023-01-06 19:07:28 +0100
committerGitHub <noreply@github.com>2023-01-06 13:07:28 -0500
commit5875949e8e598fa9b0e3a018b3547815e2654fc8 (patch)
tree51e136ee161b86d3b71fbb3934d7f708b0b9c29f
parent1abaf7ebbfee423ec524bd6e3b13f626cf32bc69 (diff)
codegen: Look through typedefs to detect void return type. (#2379)
* 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>
-rw-r--r--CHANGELOG.md3
-rw-r--r--bindgen-tests/tests/expectations/tests/dynamic_loading_with_class.rs2
-rw-r--r--bindgen-tests/tests/expectations/tests/void_typedef.rs18
-rw-r--r--bindgen-tests/tests/headers/void_typedef.h9
-rw-r--r--bindgen/codegen/dyngen.rs2
-rw-r--r--bindgen/codegen/mod.rs62
6 files changed, 71 insertions, 25 deletions
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 144805d1..322e65de 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -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
diff --git a/bindgen-tests/tests/expectations/tests/dynamic_loading_with_class.rs b/bindgen-tests/tests/expectations/tests/dynamic_loading_with_class.rs
index 514cff73..098ffa24 100644
--- a/bindgen-tests/tests/expectations/tests/dynamic_loading_with_class.rs
+++ b/bindgen-tests/tests/expectations/tests/dynamic_loading_with_class.rs
@@ -99,7 +99,7 @@ impl TestLib {
) -> ::std::os::raw::c_int {
(self.foo.as_ref().expect("Expected function, got error."))(x)
}
- pub unsafe fn bar(&self) -> () {
+ pub unsafe fn bar(&self) {
(self.bar.as_ref().expect("Expected function, got error."))()
}
}
diff --git a/bindgen-tests/tests/expectations/tests/void_typedef.rs b/bindgen-tests/tests/expectations/tests/void_typedef.rs
new file mode 100644
index 00000000..7e148e72
--- /dev/null
+++ b/bindgen-tests/tests/expectations/tests/void_typedef.rs
@@ -0,0 +1,18 @@
+#![allow(
+ dead_code,
+ non_snake_case,
+ non_camel_case_types,
+ non_upper_case_globals
+)]
+
+pub type VOID = ::std::os::raw::c_void;
+pub type ALSO_VOID = VOID;
+extern "C" {
+ pub fn this_api_returns_nothing();
+}
+extern "C" {
+ pub fn this_api_also_returns_nothing();
+}
+extern "C" {
+ pub fn this_other_api_also_returns_nothing();
+}
diff --git a/bindgen-tests/tests/headers/void_typedef.h b/bindgen-tests/tests/headers/void_typedef.h
new file mode 100644
index 00000000..405cbd0c
--- /dev/null
+++ b/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);
diff --git a/bindgen/codegen/dyngen.rs b/bindgen/codegen/dyngen.rs
index 5e734ccd..d8ea8117 100644
--- a/bindgen/codegen/dyngen.rs
+++ b/bindgen/codegen/dyngen.rs
@@ -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
}
});
diff --git a/bindgen/codegen/mod.rs b/bindgen/codegen/mod.rs
index c297aaab..041d3669 100644
--- a/bindgen/codegen/mod.rs
+++ b/bindgen/codegen/mod.rs
@@ -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,
@@ -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,
@@ -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>
}