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