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, ), >;