summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEmilio Cobos Álvarez <emilio@crisal.io>2020-05-14 04:24:32 +0200
committerEmilio Cobos Álvarez <emilio@crisal.io>2020-05-14 12:58:30 +0200
commitb1a1ebc918e44f4aa928878dae20fa7be6c87043 (patch)
tree3b0c3cb839aac0c2f056cc06126b1e139058312e
parentfcc10961dbfe128d2e592cb302316122938d7b58 (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.rs13
-rw-r--r--tests/expectations/tests/function-typedef-stdcall.rs19
-rw-r--r--tests/expectations/tests/objc_property_fnptr.rs6
-rw-r--r--tests/headers/function-typedef-stdcall.h12
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;