Skip to content

Commit

Permalink
Merge pull request #1536 from flowbish/fix_1535
Browse files Browse the repository at this point in the history
Fix issue #1535: use correct names for function parameters in function pointer arguments.
  • Loading branch information
emilio authored Mar 11, 2019
2 parents 185a5f3 + 0c9c665 commit 00c3295
Show file tree
Hide file tree
Showing 3 changed files with 49 additions and 21 deletions.
49 changes: 31 additions & 18 deletions src/ir/function.rs
Original file line number Diff line number Diff line change
Expand Up @@ -314,24 +314,37 @@ fn args_from_ty_and_cursor(
cursor: &clang::Cursor,
ctx: &mut BindgenContext,
) -> Vec<(Option<String>, TypeId)> {
match (cursor.args(), ty.args()) {
(Some(cursor_args), Some(ty_args)) => {
ty_args.iter().enumerate().map(|(i, ty)| {
let name = cursor_args.get(i)
.map(|c| c.spelling())
.and_then(|name| if name.is_empty() { None } else { Some(name) });
(name, Item::from_ty_or_ref(*ty, *cursor, None, ctx))
}).collect()
}
(Some(cursor_args), None) => {
cursor_args.iter().map(|cursor| {
let name = cursor.spelling();
let name = if name.is_empty() { None } else { Some(name) };
(name, Item::from_ty_or_ref(cursor.cur_type(), *cursor, None, ctx))
}).collect()
}
_ => panic!()
}
let cursor_args = cursor.args().unwrap().into_iter();
let type_args = ty.args().unwrap_or_default().into_iter();

// Argument types can be found in either the cursor or the type, but argument names may only be
// found on the cursor. We often have access to both a type and a cursor for each argument, but
// in some cases we may only have one.
//
// Prefer using the type as the source of truth for the argument's type, but fall back to
// inspecting the cursor (this happens for Objective C interfaces).
//
// Prefer using the cursor for the argument's type, but fall back to using the parent's cursor
// (this happens for function pointer return types).
cursor_args
.map(Some)
.chain(std::iter::repeat(None))
.zip(
type_args
.map(Some)
.chain(std::iter::repeat(None))
)
.take_while(|(cur, ty)| cur.is_some() || ty.is_some())
.map(|(arg_cur, arg_ty)| {
let name = arg_cur
.map(|a| a.spelling())
.and_then(|name| if name.is_empty() { None} else { Some(name) });

let cursor = arg_cur.unwrap_or(*cursor);
let ty = arg_ty.unwrap_or(cursor.cur_type());
(name, Item::from_ty_or_ref(ty, cursor, None, ctx))
})
.collect()
}

impl FunctionSig {
Expand Down
19 changes: 16 additions & 3 deletions tests/expectations/tests/func_with_func_ptr_arg.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,22 @@
/* automatically generated by rust-bindgen */


#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)]

#![allow(
dead_code,
non_snake_case,
non_camel_case_types,
non_upper_case_globals
)]

extern "C" {
pub fn foo(bar: ::std::option::Option<unsafe extern "C" fn()>);
}
extern "C" {
pub fn bar(
one: ::std::option::Option<
unsafe extern "C" fn(a: ::std::os::raw::c_int, b: ::std::os::raw::c_int),
>,
two: ::std::option::Option<
unsafe extern "C" fn(c: ::std::os::raw::c_int, d: ::std::os::raw::c_int),
>,
);
}
2 changes: 2 additions & 0 deletions tests/headers/func_with_func_ptr_arg.h
Original file line number Diff line number Diff line change
@@ -1 +1,3 @@
void foo(void (*bar)());

void bar(void (*one)(int a, int b), void (*two)(int c, int d));

0 comments on commit 00c3295

Please sign in to comment.