diff options
-rw-r--r-- | src/ir/function.rs | 11 | ||||
-rw-r--r-- | src/ir/ty.rs | 27 | ||||
-rw-r--r-- | tests/expectations/tests/call-conv-typedef.rs | 13 | ||||
-rw-r--r-- | tests/headers/call-conv-typedef.h | 5 |
4 files changed, 29 insertions, 27 deletions
diff --git a/src/ir/function.rs b/src/ir/function.rs index f7f4398b..3f2c8254 100644 --- a/src/ir/function.rs +++ b/src/ir/function.rs @@ -442,7 +442,16 @@ impl FunctionSig { ty.ret_type().ok_or(ParseError::Continue)? }; let ret = Item::from_ty_or_ref(ty_ret_type, cursor, None, ctx); - let call_conv = ty.call_conv(); + + // Clang plays with us at "find the calling convention", see #549 and + // co. This seems to be a better fix than that commit. + let mut call_conv = ty.call_conv(); + if let Some(ty) = cursor.cur_type().canonical_type().pointee_type() { + let cursor_call_conv = ty.call_conv(); + if cursor_call_conv != CXCallingConv_Invalid { + call_conv = cursor_call_conv; + } + } let abi = get_abi(call_conv); if abi.is_unknown() { diff --git a/src/ir/ty.rs b/src/ir/ty.rs index 13153429..22ccdaa1 100644 --- a/src/ir/ty.rs +++ b/src/ir/ty.rs @@ -1054,32 +1054,7 @@ impl Type { CXType_ObjCObjectPointer | CXType_MemberPointer | CXType_Pointer => { - // Fun fact: the canonical type of a pointer type may sometimes - // contain information we need but isn't present in the concrete - // type (yeah, I'm equally wat'd). - // - // Yet we still have trouble if we unconditionally trust the - // canonical type, like too-much desugaring (sigh). - // - // See tests/headers/call-conv-field.h for an example. - // - // Since for now the only identifier cause of breakage is the - // ABI for function pointers, and different ABI mixed with - // problematic stuff like that one is _extremely_ unlikely and - // can be bypassed via blacklisting, we do the check explicitly - // (as hacky as it is). - // - // Yet we should probably (somehow) get the best of both worlds, - // presumably special-casing function pointers as a whole, yet - // someone is going to need to care about typedef'd function - // pointers, etc, which isn't trivial given function pointers - // are mostly unexposed. I don't have the time for it right now. - let mut pointee = ty.pointee_type().unwrap(); - let canonical_pointee = - canonical_ty.pointee_type().unwrap(); - if pointee.call_conv() != canonical_pointee.call_conv() { - pointee = canonical_pointee; - } + let pointee = ty.pointee_type().unwrap(); let inner = Item::from_ty_or_ref(pointee, location, None, ctx); TypeKind::Pointer(inner) diff --git a/tests/expectations/tests/call-conv-typedef.rs b/tests/expectations/tests/call-conv-typedef.rs new file mode 100644 index 00000000..f30d2356 --- /dev/null +++ b/tests/expectations/tests/call-conv-typedef.rs @@ -0,0 +1,13 @@ +/* automatically generated by rust-bindgen */ + +#![allow( + dead_code, + non_snake_case, + non_camel_case_types, + non_upper_case_globals +)] +#![cfg(not(test))] + +pub type void_fn = ::std::option::Option<unsafe extern "stdcall" fn()>; +pub type fn_ = + ::std::option::Option<unsafe extern "stdcall" fn(id: ::std::os::raw::c_int) -> void_fn>; diff --git a/tests/headers/call-conv-typedef.h b/tests/headers/call-conv-typedef.h new file mode 100644 index 00000000..3b911dda --- /dev/null +++ b/tests/headers/call-conv-typedef.h @@ -0,0 +1,5 @@ +// bindgen-flags: --raw-line "#![cfg(not(test))]" -- --target=i686-pc-win32 + + +typedef void (__stdcall *void_fn)(); +typedef void_fn (__stdcall *fn)(int id); |