Recurse through type references to find argument names in some cases.
This fixes the names in function-typedef-stdcall.h
We still keep the fallback introduced in the previous patch because the
objective-c test that it fixed is not fixed by this (the cursors aren't
even there).
diff --git a/src/ir/function.rs b/src/ir/function.rs
index e811a72..2a36ad8 100644
--- a/src/ir/function.rs
+++ b/src/ir/function.rs
@@ -407,26 +407,40 @@
args_from_ty_and_cursor(&ty, &cursor, ctx)
}
_ => {
+ fn collect_args(
+ cursor: clang::Cursor,
+ args: &mut Vec<(Option<String>, TypeId)>,
+ ctx: &mut BindgenContext,
+ ) {
+ cursor.visit(|c| {
+ let kind = c.kind();
+ if kind == CXCursor_TypeRef {
+ collect_args(c.referenced().unwrap(), args, ctx);
+ } else if kind == CXCursor_ParmDecl {
+ let ty = Item::from_ty_or_ref(
+ c.cur_type(),
+ c,
+ None,
+ ctx,
+ );
+ let name = c.spelling();
+ let name =
+ if name.is_empty() { None } else { Some(name) };
+ args.push((name, ty));
+ }
+ CXChildVisit_Continue
+ });
+ }
+
// For non-CXCursor_FunctionDecl, visiting the cursor's children
// is the only reliable way to get parameter names.
let mut args = vec![];
- cursor.visit(|c| {
- if c.kind() == CXCursor_ParmDecl {
- let ty =
- Item::from_ty_or_ref(c.cur_type(), c, None, ctx);
- let name = c.spelling();
- let name =
- if name.is_empty() { None } else { Some(name) };
- args.push((name, ty));
- }
- CXChildVisit_Continue
- });
+
+ collect_args(cursor, &mut args, ctx);
if args.is_empty() {
// FIXME(emilio): Sometimes libclang doesn't expose the
- // right AST for functions tagged as stdcall and such...
- //
- // https://bugs.llvm.org/show_bug.cgi?id=45919
+ // right params for some cursors.
args_from_ty_and_cursor(&ty, &cursor, ctx)
} else {
args
diff --git a/tests/expectations/tests/function-typedef-stdcall.rs b/tests/expectations/tests/function-typedef-stdcall.rs
index 2c77c1b..5a47a9d 100644
--- a/tests/expectations/tests/function-typedef-stdcall.rs
+++ b/tests/expectations/tests/function-typedef-stdcall.rs
@@ -9,11 +9,11 @@
pub type PFN_VIGEM_X360_NOTIFICATION = ::std::option::Option<
unsafe extern "C" fn(
- arg1: *mut ::std::os::raw::c_void,
- arg2: *mut ::std::os::raw::c_void,
- arg3: ::std::os::raw::c_uchar,
- arg4: ::std::os::raw::c_uchar,
- arg5: ::std::os::raw::c_uchar,
- arg6: *mut ::std::os::raw::c_void,
+ Client: *mut ::std::os::raw::c_void,
+ Target: *mut ::std::os::raw::c_void,
+ LargeMotor: ::std::os::raw::c_uchar,
+ SmallMotor: ::std::os::raw::c_uchar,
+ LedNumber: ::std::os::raw::c_uchar,
+ UserData: *mut ::std::os::raw::c_void,
),
>;