Skip to content

Commit c6f9fe0

Browse files
author
bors-servo
authored
Auto merge of #1403 - emilio:call-conv-madness, r=fitzgen
A better fix for the calling convention madness. See the commit message for details.
2 parents 1719ba1 + c75b62d commit c6f9fe0

File tree

5 files changed

+41
-29
lines changed

5 files changed

+41
-29
lines changed

src/ir/context.rs

+12-2
Original file line numberDiff line numberDiff line change
@@ -514,12 +514,19 @@ const HOST_TARGET: &'static str =
514514
fn find_effective_target(clang_args: &[String]) -> (String, bool) {
515515
use std::env;
516516

517-
for opt in clang_args {
517+
let mut args = clang_args.iter();
518+
while let Some(opt) = args.next() {
518519
if opt.starts_with("--target=") {
519520
let mut split = opt.split('=');
520521
split.next();
521522
return (split.next().unwrap().to_owned(), true);
522523
}
524+
525+
if opt == "-target" {
526+
if let Some(target) = args.next() {
527+
return (target.clone(), true);
528+
}
529+
}
523530
}
524531

525532
// If we're running from a build script, try to find the cargo target.
@@ -576,7 +583,10 @@ If you encounter an error missing from this list, please file an issue or a PR!"
576583
{
577584
if let Some(ref ti) = target_info {
578585
if effective_target == HOST_TARGET {
579-
assert_eq!(ti.pointer_width / 8, mem::size_of::<*mut ()>());
586+
assert_eq!(
587+
ti.pointer_width / 8, mem::size_of::<*mut ()>(),
588+
"{:?} {:?}", effective_target, HOST_TARGET
589+
);
580590
}
581591
}
582592
}

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)