summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorEmilio Cobos Álvarez <emilio@crisal.io>2018-09-26 12:26:38 +0200
committerEmilio Cobos Álvarez <emilio@crisal.io>2018-09-26 12:33:50 +0200
commitc75b62d1a19b79a053996642f4915269e38f877c (patch)
tree4a4dcb262f29838cc6d20c396ddf0ae6880ac265 /src
parent4a3eec8c4f996b78a1f7ae4ff8fee06bebd963b6 (diff)
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.
Diffstat (limited to 'src')
-rw-r--r--src/ir/function.rs11
-rw-r--r--src/ir/ty.rs27
2 files changed, 11 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)