Skip to content

Commit 00c3295

Browse files
authored
Merge pull request #1536 from flowbish/fix_1535
Fix issue #1535: use correct names for function parameters in function pointer arguments.
2 parents 185a5f3 + 0c9c665 commit 00c3295

File tree

3 files changed

+49
-21
lines changed

3 files changed

+49
-21
lines changed

src/ir/function.rs

+31-18
Original file line numberDiff line numberDiff line change
@@ -314,24 +314,37 @@ fn args_from_ty_and_cursor(
314314
cursor: &clang::Cursor,
315315
ctx: &mut BindgenContext,
316316
) -> Vec<(Option<String>, TypeId)> {
317-
match (cursor.args(), ty.args()) {
318-
(Some(cursor_args), Some(ty_args)) => {
319-
ty_args.iter().enumerate().map(|(i, ty)| {
320-
let name = cursor_args.get(i)
321-
.map(|c| c.spelling())
322-
.and_then(|name| if name.is_empty() { None } else { Some(name) });
323-
(name, Item::from_ty_or_ref(*ty, *cursor, None, ctx))
324-
}).collect()
325-
}
326-
(Some(cursor_args), None) => {
327-
cursor_args.iter().map(|cursor| {
328-
let name = cursor.spelling();
329-
let name = if name.is_empty() { None } else { Some(name) };
330-
(name, Item::from_ty_or_ref(cursor.cur_type(), *cursor, None, ctx))
331-
}).collect()
332-
}
333-
_ => panic!()
334-
}
317+
let cursor_args = cursor.args().unwrap().into_iter();
318+
let type_args = ty.args().unwrap_or_default().into_iter();
319+
320+
// Argument types can be found in either the cursor or the type, but argument names may only be
321+
// found on the cursor. We often have access to both a type and a cursor for each argument, but
322+
// in some cases we may only have one.
323+
//
324+
// Prefer using the type as the source of truth for the argument's type, but fall back to
325+
// inspecting the cursor (this happens for Objective C interfaces).
326+
//
327+
// Prefer using the cursor for the argument's type, but fall back to using the parent's cursor
328+
// (this happens for function pointer return types).
329+
cursor_args
330+
.map(Some)
331+
.chain(std::iter::repeat(None))
332+
.zip(
333+
type_args
334+
.map(Some)
335+
.chain(std::iter::repeat(None))
336+
)
337+
.take_while(|(cur, ty)| cur.is_some() || ty.is_some())
338+
.map(|(arg_cur, arg_ty)| {
339+
let name = arg_cur
340+
.map(|a| a.spelling())
341+
.and_then(|name| if name.is_empty() { None} else { Some(name) });
342+
343+
let cursor = arg_cur.unwrap_or(*cursor);
344+
let ty = arg_ty.unwrap_or(cursor.cur_type());
345+
(name, Item::from_ty_or_ref(ty, cursor, None, ctx))
346+
})
347+
.collect()
335348
}
336349

337350
impl FunctionSig {
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,22 @@
11
/* automatically generated by rust-bindgen */
22

3-
4-
#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)]
5-
3+
#![allow(
4+
dead_code,
5+
non_snake_case,
6+
non_camel_case_types,
7+
non_upper_case_globals
8+
)]
69

710
extern "C" {
811
pub fn foo(bar: ::std::option::Option<unsafe extern "C" fn()>);
912
}
13+
extern "C" {
14+
pub fn bar(
15+
one: ::std::option::Option<
16+
unsafe extern "C" fn(a: ::std::os::raw::c_int, b: ::std::os::raw::c_int),
17+
>,
18+
two: ::std::option::Option<
19+
unsafe extern "C" fn(c: ::std::os::raw::c_int, d: ::std::os::raw::c_int),
20+
>,
21+
);
22+
}
+2
Original file line numberDiff line numberDiff line change
@@ -1 +1,3 @@
11
void foo(void (*bar)());
2+
3+
void bar(void (*one)(int a, int b), void (*two)(int c, int d));

0 commit comments

Comments
 (0)