Skip to content

Commit 51a12a2

Browse files
committed
Merge remote-tracking branch 'origin/impl-default' into impl-default
2 parents 03f9b7e + 0314406 commit 51a12a2

File tree

6 files changed

+209
-85
lines changed

6 files changed

+209
-85
lines changed

src/clang.rs

+11
Original file line numberDiff line numberDiff line change
@@ -523,6 +523,14 @@ impl Cursor {
523523
pub fn evaluate(&self) -> Option<EvalResult> {
524524
EvalResult::new(*self)
525525
}
526+
527+
/// Return the result type for this cursor
528+
pub fn ret_type(&self) -> Option<Type> {
529+
let rt = Type {
530+
x: unsafe { clang_getCursorResultType(self.x) },
531+
};
532+
if rt.is_valid() { Some(rt) } else { None }
533+
}
526534
}
527535

528536
extern "C" fn visit_children<Visitor>(cur: CXCursor,
@@ -1363,6 +1371,9 @@ pub fn ast_dump(c: &Cursor, depth: isize) -> CXChildVisitResult {
13631371
prefix,
13641372
type_to_str(ty.kind())));
13651373
}
1374+
if let Some(ty) = c.ret_type() {
1375+
print_indent(depth, format!(" {}ret-type = {}", prefix, type_to_str(ty.kind())));
1376+
}
13661377

13671378
if let Some(refd) = c.referenced() {
13681379
if refd != *c {

src/codegen/mod.rs

+99-66
Original file line numberDiff line numberDiff line change
@@ -2198,61 +2198,8 @@ impl ToRustTy for FunctionSig {
21982198

21992199
fn to_rust_ty(&self, ctx: &BindgenContext, _item: &Item) -> P<ast::Ty> {
22002200
// TODO: we might want to consider ignoring the reference return value.
2201-
let return_item = ctx.resolve_item(self.return_type());
2202-
let ret =
2203-
if let TypeKind::Void = *return_item.kind().expect_type().kind() {
2204-
ast::FunctionRetTy::Default(ctx.span())
2205-
} else {
2206-
ast::FunctionRetTy::Ty(return_item.to_rust_ty(ctx))
2207-
};
2208-
2209-
let mut unnamed_arguments = 0;
2210-
let arguments = self.argument_types().iter().map(|&(ref name, ty)| {
2211-
let arg_item = ctx.resolve_item(ty);
2212-
let arg_ty = arg_item.kind().expect_type();
2213-
2214-
// From the C90 standard[1]:
2215-
//
2216-
// A declaration of a parameter as "array of type" shall be
2217-
// adjusted to "qualified pointer to type", where the type
2218-
// qualifiers (if any) are those specified within the [ and ] of
2219-
// the array type derivation.
2220-
//
2221-
// [1]: http://c0x.coding-guidelines.com/6.7.5.3.html
2222-
let arg_ty = match *arg_ty.canonical_type(ctx).kind() {
2223-
TypeKind::Array(t, _) => {
2224-
t.to_rust_ty(ctx).to_ptr(arg_ty.is_const(), ctx.span())
2225-
},
2226-
TypeKind::Pointer(inner) => {
2227-
let inner = ctx.resolve_item(inner);
2228-
let inner_ty = inner.expect_type();
2229-
if let TypeKind::ObjCInterface(_) = *inner_ty.canonical_type(ctx).kind() {
2230-
quote_ty!(ctx.ext_cx(), id)
2231-
} else {
2232-
arg_item.to_rust_ty(ctx)
2233-
}
2234-
},
2235-
_ => {
2236-
arg_item.to_rust_ty(ctx)
2237-
}
2238-
};
2239-
2240-
let arg_name = match *name {
2241-
Some(ref name) => ctx.rust_mangle(name).into_owned(),
2242-
None => {
2243-
unnamed_arguments += 1;
2244-
format!("arg{}", unnamed_arguments)
2245-
}
2246-
};
2247-
2248-
assert!(!arg_name.is_empty());
2249-
2250-
ast::Arg {
2251-
ty: arg_ty,
2252-
pat: aster::AstBuilder::new().pat().id(arg_name),
2253-
id: ast::DUMMY_NODE_ID,
2254-
}
2255-
}).collect::<Vec<_>>();
2201+
let ret = utils::fnsig_return_ty(ctx, &self);
2202+
let arguments = utils::fnsig_arguments(ctx, &self);
22562203

22572204
let decl = P(ast::FnDecl {
22582205
inputs: arguments,
@@ -2262,7 +2209,7 @@ impl ToRustTy for FunctionSig {
22622209

22632210
let fnty = ast::TyKind::BareFn(P(ast::BareFnTy {
22642211
unsafety: ast::Unsafety::Unsafe,
2265-
abi: self.abi(),
2212+
abi: self.abi().expect("Invalid abi for function!"),
22662213
lifetimes: vec![],
22672214
decl: decl,
22682215
}));
@@ -2342,7 +2289,8 @@ impl CodeGenerator for Function {
23422289
vis: ast::Visibility::Public,
23432290
};
23442291

2345-
let item = ForeignModBuilder::new(signature.abi())
2292+
let item = ForeignModBuilder::new(signature.abi()
2293+
.expect("Invalid abi for function!"))
23462294
.with_foreign_item(foreign_item)
23472295
.build(ctx);
23482296

@@ -2361,9 +2309,36 @@ impl CodeGenerator for ObjCInterface {
23612309
let mut trait_items = vec![];
23622310

23632311
for method in self.methods() {
2364-
let method_name = ctx.rust_ident(method.name());
2312+
let signature = method.signature();
2313+
let fn_args = utils::fnsig_arguments(ctx, signature);
2314+
let fn_ret = utils::fnsig_return_ty(ctx, signature);
2315+
let sig = aster::AstBuilder::new()
2316+
.method_sig()
2317+
.unsafe_()
2318+
.fn_decl()
2319+
.self_()
2320+
.build(ast::SelfKind::Value(ast::Mutability::Immutable))
2321+
.with_args(fn_args.clone())
2322+
.build(fn_ret);
2323+
2324+
// Collect the actual used argument names
2325+
let arg_names: Vec<_> = fn_args.iter()
2326+
.map(|ref arg| {
2327+
match arg.pat.node {
2328+
ast::PatKind::Ident(_, ref spanning, _) => {
2329+
spanning.node.name.as_str().to_string()
2330+
}
2331+
_ => {
2332+
panic!("odd argument!");
2333+
}
2334+
}
2335+
})
2336+
.collect();
23652337

2366-
let body = quote_stmt!(ctx.ext_cx(), msg_send![self, $method_name])
2338+
let methods_and_args =
2339+
ctx.rust_ident(&method.format_method_call(&arg_names));
2340+
let body =
2341+
quote_stmt!(ctx.ext_cx(), msg_send![self, $methods_and_args])
23672342
.unwrap();
23682343
let block = ast::Block {
23692344
stmts: vec![body],
@@ -2372,13 +2347,6 @@ impl CodeGenerator for ObjCInterface {
23722347
span: ctx.span(),
23732348
};
23742349

2375-
let sig = aster::AstBuilder::new()
2376-
.method_sig()
2377-
.unsafe_()
2378-
.fn_decl()
2379-
.self_()
2380-
.build(ast::SelfKind::Value(ast::Mutability::Immutable))
2381-
.build(ast::FunctionRetTy::Default(ctx.span()));
23822350
let attrs = vec![];
23832351

23842352
let impl_item = ast::ImplItem {
@@ -2743,4 +2711,69 @@ mod utils {
27432711
_ => panic!("How did this happen exactly?"),
27442712
}
27452713
}
2714+
2715+
pub fn fnsig_return_ty(ctx: &BindgenContext,
2716+
sig: &super::FunctionSig)
2717+
-> ast::FunctionRetTy {
2718+
let return_item = ctx.resolve_item(sig.return_type());
2719+
if let TypeKind::Void = *return_item.kind().expect_type().kind() {
2720+
ast::FunctionRetTy::Default(ctx.span())
2721+
} else {
2722+
ast::FunctionRetTy::Ty(return_item.to_rust_ty(ctx))
2723+
}
2724+
}
2725+
2726+
pub fn fnsig_arguments(ctx: &BindgenContext,
2727+
sig: &super::FunctionSig)
2728+
-> Vec<ast::Arg> {
2729+
use super::ToPtr;
2730+
let mut unnamed_arguments = 0;
2731+
sig.argument_types().iter().map(|&(ref name, ty)| {
2732+
let arg_item = ctx.resolve_item(ty);
2733+
let arg_ty = arg_item.kind().expect_type();
2734+
2735+
// From the C90 standard[1]:
2736+
//
2737+
// A declaration of a parameter as "array of type" shall be
2738+
// adjusted to "qualified pointer to type", where the type
2739+
// qualifiers (if any) are those specified within the [ and ] of
2740+
// the array type derivation.
2741+
//
2742+
// [1]: http://c0x.coding-guidelines.com/6.7.5.3.html
2743+
let arg_ty = match *arg_ty.canonical_type(ctx).kind() {
2744+
TypeKind::Array(t, _) => {
2745+
t.to_rust_ty(ctx).to_ptr(arg_ty.is_const(), ctx.span())
2746+
},
2747+
TypeKind::Pointer(inner) => {
2748+
let inner = ctx.resolve_item(inner);
2749+
let inner_ty = inner.expect_type();
2750+
if let TypeKind::ObjCInterface(_) = *inner_ty.canonical_type(ctx).kind() {
2751+
quote_ty!(ctx.ext_cx(), id)
2752+
} else {
2753+
arg_item.to_rust_ty(ctx)
2754+
}
2755+
},
2756+
_ => {
2757+
arg_item.to_rust_ty(ctx)
2758+
}
2759+
};
2760+
2761+
let arg_name = match *name {
2762+
Some(ref name) => ctx.rust_mangle(name).into_owned(),
2763+
None => {
2764+
unnamed_arguments += 1;
2765+
format!("arg{}", unnamed_arguments)
2766+
}
2767+
};
2768+
2769+
assert!(!arg_name.is_empty());
2770+
2771+
ast::Arg {
2772+
ty: arg_ty,
2773+
pat: aster::AstBuilder::new().pat().id(arg_name),
2774+
id: ast::DUMMY_NODE_ID,
2775+
}
2776+
}).collect::<Vec<_>>()
2777+
}
2778+
27462779
}

src/ir/function.rs

+23-12
Original file line numberDiff line numberDiff line change
@@ -73,18 +73,19 @@ pub struct FunctionSig {
7373
is_variadic: bool,
7474

7575
/// The ABI of this function.
76-
abi: abi::Abi,
76+
abi: Option<abi::Abi>,
7777
}
7878

79-
fn get_abi(cc: CXCallingConv) -> abi::Abi {
79+
fn get_abi(cc: CXCallingConv) -> Option<abi::Abi> {
8080
use clang_sys::*;
8181
match cc {
82-
CXCallingConv_Default => abi::Abi::C,
83-
CXCallingConv_C => abi::Abi::C,
84-
CXCallingConv_X86StdCall => abi::Abi::Stdcall,
85-
CXCallingConv_X86FastCall => abi::Abi::Fastcall,
86-
CXCallingConv_AAPCS => abi::Abi::Aapcs,
87-
CXCallingConv_X86_64Win64 => abi::Abi::Win64,
82+
CXCallingConv_Default => Some(abi::Abi::C),
83+
CXCallingConv_C => Some(abi::Abi::C),
84+
CXCallingConv_X86StdCall => Some(abi::Abi::Stdcall),
85+
CXCallingConv_X86FastCall => Some(abi::Abi::Fastcall),
86+
CXCallingConv_AAPCS => Some(abi::Abi::Aapcs),
87+
CXCallingConv_X86_64Win64 => Some(abi::Abi::Win64),
88+
CXCallingConv_Invalid => None,
8889
other => panic!("unsupported calling convention: {:?}", other),
8990
}
9091
}
@@ -116,7 +117,7 @@ impl FunctionSig {
116117
pub fn new(return_type: ItemId,
117118
arguments: Vec<(Option<String>, ItemId)>,
118119
is_variadic: bool,
119-
abi: abi::Abi)
120+
abi: Option<abi::Abi>)
120121
-> Self {
121122
FunctionSig {
122123
return_type: return_type,
@@ -154,7 +155,8 @@ impl FunctionSig {
154155
let mut args: Vec<_> = match cursor.kind() {
155156
CXCursor_FunctionDecl |
156157
CXCursor_Constructor |
157-
CXCursor_CXXMethod => {
158+
CXCursor_CXXMethod |
159+
CXCursor_ObjCInstanceMethodDecl => {
158160
// For CXCursor_FunctionDecl, cursor.args() is the reliable way
159161
// to get parameter names and types.
160162
cursor.args()
@@ -218,10 +220,19 @@ impl FunctionSig {
218220
}
219221
}
220222

221-
let ty_ret_type = try!(ty.ret_type().ok_or(ParseError::Continue));
223+
let ty_ret_type = if cursor.kind() == CXCursor_ObjCInstanceMethodDecl {
224+
try!(cursor.ret_type().ok_or(ParseError::Continue))
225+
} else {
226+
try!(ty.ret_type().ok_or(ParseError::Continue))
227+
};
222228
let ret = Item::from_ty_or_ref(ty_ret_type, None, None, ctx);
223229
let abi = get_abi(ty.call_conv());
224230

231+
if abi.is_none() {
232+
assert_eq!(cursor.kind(), CXCursor_ObjCInstanceMethodDecl,
233+
"Invalid ABI for function signature")
234+
}
235+
225236
Ok(Self::new(ret, args, ty.is_variadic(), abi))
226237
}
227238

@@ -236,7 +247,7 @@ impl FunctionSig {
236247
}
237248

238249
/// Get this function signature's ABI.
239-
pub fn abi(&self) -> abi::Abi {
250+
pub fn abi(&self) -> Option<abi::Abi> {
240251
self.abi
241252
}
242253

0 commit comments

Comments
 (0)