diff options
author | Emilio Cobos Álvarez <emilio@crisal.io> | 2020-05-14 04:24:32 +0200 |
---|---|---|
committer | Emilio Cobos Álvarez <emilio@crisal.io> | 2020-05-14 12:58:30 +0200 |
commit | b1a1ebc918e44f4aa928878dae20fa7be6c87043 (patch) | |
tree | 3b0c3cb839aac0c2f056cc06126b1e139058312e | |
parent | fcc10961dbfe128d2e592cb302316122938d7b58 (diff) |
ir: Fall back to get the cursors from the type if we find no param decls.
It seems libclang sometimes doesn't expose the right paramdecl cursors.
This should be reported upstream, but it's easy enough to workaround. It
loses the parameter names which is a bit unfortunate but...
Fixes #1778
-rw-r--r-- | src/ir/function.rs | 13 | ||||
-rw-r--r-- | tests/expectations/tests/function-typedef-stdcall.rs | 19 | ||||
-rw-r--r-- | tests/expectations/tests/objc_property_fnptr.rs | 6 | ||||
-rw-r--r-- | tests/headers/function-typedef-stdcall.h | 12 |
4 files changed, 47 insertions, 3 deletions
diff --git a/src/ir/function.rs b/src/ir/function.rs index 7efeb1b6..e811a721 100644 --- a/src/ir/function.rs +++ b/src/ir/function.rs @@ -311,7 +311,7 @@ fn args_from_ty_and_cursor( cursor: &clang::Cursor, ctx: &mut BindgenContext, ) -> Vec<(Option<String>, TypeId)> { - let cursor_args = cursor.args().unwrap().into_iter(); + let cursor_args = cursor.args().unwrap_or_default().into_iter(); let type_args = ty.args().unwrap_or_default().into_iter(); // Argument types can be found in either the cursor or the type, but argument names may only be @@ -421,7 +421,16 @@ impl FunctionSig { } CXChildVisit_Continue }); - args + + 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 + 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 new file mode 100644 index 00000000..2c77c1b5 --- /dev/null +++ b/tests/expectations/tests/function-typedef-stdcall.rs @@ -0,0 +1,19 @@ +/* automatically generated by rust-bindgen */ + +#![allow( + dead_code, + non_snake_case, + non_camel_case_types, + non_upper_case_globals +)] + +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, + ), +>; diff --git a/tests/expectations/tests/objc_property_fnptr.rs b/tests/expectations/tests/objc_property_fnptr.rs index 8b5ab0ac..1ff55e5a 100644 --- a/tests/expectations/tests/objc_property_fnptr.rs +++ b/tests/expectations/tests/objc_property_fnptr.rs @@ -46,7 +46,11 @@ pub trait IFoo: Sized + std::ops::Deref { unsafe fn setFunc_( self, func: ::std::option::Option< - unsafe extern "C" fn() -> ::std::os::raw::c_int, + unsafe extern "C" fn( + arg1: ::std::os::raw::c_char, + arg2: ::std::os::raw::c_short, + arg3: f32, + ) -> ::std::os::raw::c_int, >, ) where <Self as std::ops::Deref>::Target: objc::Message + Sized, diff --git a/tests/headers/function-typedef-stdcall.h b/tests/headers/function-typedef-stdcall.h new file mode 100644 index 00000000..05d1e78a --- /dev/null +++ b/tests/headers/function-typedef-stdcall.h @@ -0,0 +1,12 @@ +typedef + void __stdcall + EVT_VIGEM_X360_NOTIFICATION( + void* Client, + void* Target, + unsigned char LargeMotor, + unsigned char SmallMotor, + unsigned char LedNumber, + void* UserData + ); + +typedef EVT_VIGEM_X360_NOTIFICATION *PFN_VIGEM_X360_NOTIFICATION; |