Skip to content

Commit

Permalink
add test for issue rust-lang#1535
Browse files Browse the repository at this point in the history
  • Loading branch information
flowbish committed Mar 9, 2019
1 parent 9b6d0e8 commit 7063b16
Show file tree
Hide file tree
Showing 3 changed files with 40 additions and 23 deletions.
43 changes: 25 additions & 18 deletions src/ir/function.rs
Original file line number Diff line number Diff line change
Expand Up @@ -314,24 +314,31 @@ 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_else(Vec::new).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, but in some cases we
// may only have one to reference.
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
18 changes: 14 additions & 4 deletions tests/expectations/tests/func_with_func_ptr_arg.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,19 @@
/* 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()>);
pub fn foo(
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: 1 addition & 1 deletion tests/headers/func_with_func_ptr_arg.h
Original file line number Diff line number Diff line change
@@ -1 +1 @@
void foo(void (*bar)());
void foo(void (*one)(int a, int b), void (*two)(int c, int d));

0 comments on commit 7063b16

Please sign in to comment.