Skip to content

Commit c75b62d

Browse files
committed
A better fix for the calling convention madness.
Seems like a better fix, which allows us to preserve typedefs properly, and also to find the calling convention. Fixes #1402.
1 parent 4a3eec8 commit c75b62d

File tree

4 files changed

+29
-27
lines changed

4 files changed

+29
-27
lines changed

src/ir/function.rs

+10-1
Original file line numberDiff line numberDiff line change
@@ -442,7 +442,16 @@ impl FunctionSig {
442442
ty.ret_type().ok_or(ParseError::Continue)?
443443
};
444444
let ret = Item::from_ty_or_ref(ty_ret_type, cursor, None, ctx);
445-
let call_conv = ty.call_conv();
445+
446+
// Clang plays with us at "find the calling convention", see #549 and
447+
// co. This seems to be a better fix than that commit.
448+
let mut call_conv = ty.call_conv();
449+
if let Some(ty) = cursor.cur_type().canonical_type().pointee_type() {
450+
let cursor_call_conv = ty.call_conv();
451+
if cursor_call_conv != CXCallingConv_Invalid {
452+
call_conv = cursor_call_conv;
453+
}
454+
}
446455
let abi = get_abi(call_conv);
447456

448457
if abi.is_unknown() {

src/ir/ty.rs

+1-26
Original file line numberDiff line numberDiff line change
@@ -1054,32 +1054,7 @@ impl Type {
10541054
CXType_ObjCObjectPointer |
10551055
CXType_MemberPointer |
10561056
CXType_Pointer => {
1057-
// Fun fact: the canonical type of a pointer type may sometimes
1058-
// contain information we need but isn't present in the concrete
1059-
// type (yeah, I'm equally wat'd).
1060-
//
1061-
// Yet we still have trouble if we unconditionally trust the
1062-
// canonical type, like too-much desugaring (sigh).
1063-
//
1064-
// See tests/headers/call-conv-field.h for an example.
1065-
//
1066-
// Since for now the only identifier cause of breakage is the
1067-
// ABI for function pointers, and different ABI mixed with
1068-
// problematic stuff like that one is _extremely_ unlikely and
1069-
// can be bypassed via blacklisting, we do the check explicitly
1070-
// (as hacky as it is).
1071-
//
1072-
// Yet we should probably (somehow) get the best of both worlds,
1073-
// presumably special-casing function pointers as a whole, yet
1074-
// someone is going to need to care about typedef'd function
1075-
// pointers, etc, which isn't trivial given function pointers
1076-
// are mostly unexposed. I don't have the time for it right now.
1077-
let mut pointee = ty.pointee_type().unwrap();
1078-
let canonical_pointee =
1079-
canonical_ty.pointee_type().unwrap();
1080-
if pointee.call_conv() != canonical_pointee.call_conv() {
1081-
pointee = canonical_pointee;
1082-
}
1057+
let pointee = ty.pointee_type().unwrap();
10831058
let inner =
10841059
Item::from_ty_or_ref(pointee, location, None, ctx);
10851060
TypeKind::Pointer(inner)
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
/* automatically generated by rust-bindgen */
2+
3+
#![allow(
4+
dead_code,
5+
non_snake_case,
6+
non_camel_case_types,
7+
non_upper_case_globals
8+
)]
9+
#![cfg(not(test))]
10+
11+
pub type void_fn = ::std::option::Option<unsafe extern "stdcall" fn()>;
12+
pub type fn_ =
13+
::std::option::Option<unsafe extern "stdcall" fn(id: ::std::os::raw::c_int) -> void_fn>;

tests/headers/call-conv-typedef.h

+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
// bindgen-flags: --raw-line "#![cfg(not(test))]" -- --target=i686-pc-win32
2+
3+
4+
typedef void (__stdcall *void_fn)();
5+
typedef void_fn (__stdcall *fn)(int id);

0 commit comments

Comments
 (0)