summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--README.md4
-rw-r--r--src/bin/bindgen.rs5
-rw-r--r--src/clang.rs8
-rw-r--r--src/clangll.rs4
-rw-r--r--src/gen.rs80
-rw-r--r--src/lib.rs9
-rw-r--r--src/macro.rs7
-rw-r--r--src/parser.rs22
-rw-r--r--src/types.rs4
9 files changed, 82 insertions, 61 deletions
diff --git a/README.md b/README.md
index 433dcea5..7853fbf5 100644
--- a/README.md
+++ b/README.md
@@ -45,7 +45,6 @@ Options:
matching any rule are bound to
-builtins Output bindings for builtin definitions
(for example __builtin_va_list)
- -abi <abi> Indicate abi of extern functions (default C)
-allow-bitfields Don't fail if we encounter a bitfield
(note that bindgen does not support bitfields)
-allow-unknown-types Don't fail if we encounter types we do not support,
@@ -80,7 +79,6 @@ Options:
link_framework multiple strings
match multiple strings
emit_builtins bool true
- abi string "C"
allow_bitfields bool false
allow_unknown_types bool false
clang_args string
@@ -122,4 +120,4 @@ TODO
* bit field
[clay's bindgen]: https://github.com/jckarter/clay/blob/master/tools/bindgen.clay
-[issue 89]: https://github.com/crabtw/rust-bindgen/issues/89 \ No newline at end of file
+[issue 89]: https://github.com/crabtw/rust-bindgen/issues/89
diff --git a/src/bin/bindgen.rs b/src/bin/bindgen.rs
index 2189c553..4e3ffd11 100644
--- a/src/bin/bindgen.rs
+++ b/src/bin/bindgen.rs
@@ -100,10 +100,6 @@ fn parse_args(args: &[String]) -> ParseResult {
options.builtins = true;
ix += 1u;
}
- "-abi" => {
- options.abi = args[ix + 1u].clone();
- ix += 2u;
- }
"-allow-bitfields" => {
options.fail_on_bitfield = false;
ix += 1u;
@@ -147,7 +143,6 @@ Options:
matching any rule are bound to.
-builtins Output bindings for builtin definitions
(for example __builtin_va_list)
- -abi <abi> Indicate abi of extern functions (default C)
-allow-bitfields Don't fail if we encounter a bitfield
(note that bindgen does not support bitfields)
-allow-unknown-types Don't fail if we encounter types we do not support,
diff --git a/src/clang.rs b/src/clang.rs
index 9eff324f..c3da6ec7 100644
--- a/src/clang.rs
+++ b/src/clang.rs
@@ -1,4 +1,4 @@
-#![allow(non_uppercase_statics)]
+#![allow(non_upper_case_globals)]
use libc::{c_uint, c_char, c_int, c_ulong};
use std::{mem, io, ptr, string};
@@ -239,6 +239,12 @@ impl Type {
Type { x: clang_getResultType(self.x) }
}
}
+
+ pub fn call_conv(&self) -> Enum_CXCallingConv {
+ unsafe {
+ clang_getFunctionTypeCallingConv(self.x)
+ }
+ }
}
// SourceLocation
diff --git a/src/clangll.rs b/src/clangll.rs
index 02834274..68be6675 100644
--- a/src/clangll.rs
+++ b/src/clangll.rs
@@ -2,9 +2,9 @@
#![allow(non_camel_case_types)]
#![allow(dead_code)]
-#![allow(unused_attribute)]
+#![allow(unused_attributes)]
#![allow(non_snake_case)]
-#![allow(non_uppercase_statics)]
+#![allow(non_upper_case_globals)]
pub type ptrdiff_t = ::libc::c_long;
pub type size_t = ::libc::c_ulong;
diff --git a/src/gen.rs b/src/gen.rs
index 91c377a2..9dcc144f 100644
--- a/src/gen.rs
+++ b/src/gen.rs
@@ -5,6 +5,8 @@ use std::option;
use std::iter;
use std::vec::Vec;
use std::rc::Rc;
+use std::collections::HashMap;
+use std::collections::hashmap::{Occupied, Vacant};
use syntax::abi;
use syntax::ast;
@@ -22,7 +24,6 @@ use types::*;
struct GenCtx<'r> {
ext_cx: base::ExtCtxt<'r>,
unnamed_ty: uint,
- abi: abi::Abi,
span: Span
}
@@ -105,17 +106,7 @@ fn enum_name(name: String) -> String {
format!("Enum_{}", name)
}
-pub fn gen_mod(abi: &str, links: &[(String, Option<String>)], globs: Vec<Global>, span: Span) -> Vec<P<ast::Item>> {
- let abi = match abi {
- "cdecl" => abi::Cdecl,
- "stdcall" => abi::Stdcall,
- "fastcall" => abi::Fastcall,
- "aapcs" => abi::Aapcs,
- "Rust" => abi::Rust,
- "rust-intrinsic" => abi::RustIntrinsic,
- _ => abi::C
- };
-
+pub fn gen_mod(links: &[(String, Option<String>)], globs: Vec<Global>, span: Span) -> Vec<P<ast::Item>> {
// Create a dummy ExtCtxt. We only need this for string interning and that uses TLS.
let cfg = ExpansionConfig {
deriving_hash_type_parameter: false,
@@ -131,7 +122,6 @@ pub fn gen_mod(abi: &str, links: &[(String, Option<String>)], globs: Vec<Global>
cfg,
),
unnamed_ty: 0,
- abi: abi,
span: span
};
ctx.ext_cx.bt_push(ExpnInfo {
@@ -220,22 +210,43 @@ pub fn gen_mod(abi: &str, links: &[(String, Option<String>)], globs: Vec<Global>
}
}).collect();
- let funcs = fs.into_iter().map(|f| {
- match f {
- GFunc(vi) => {
- let v = vi.borrow();
- match v.ty {
- TFunc(ref rty, ref aty, var) =>
- cfunc_to_rs(&mut ctx, v.name.clone(),
- &**rty, aty.as_slice(), var),
- _ => unreachable!()
+ let funcs = {
+ let mut func_list = fs.into_iter().map(|f| {
+ match f {
+ GFunc(vi) => {
+ let v = vi.borrow();
+ match v.ty {
+ TFunc(ref rty, ref aty, var, abi) => {
+ let decl = cfunc_to_rs(&mut ctx, v.name.clone(),
+ &**rty, aty.as_slice(), var);
+ (abi, decl)
+ }
+ _ => unreachable!()
+ }
+ },
+ _ => unreachable!()
+ }
+ });
+
+ let mut map: HashMap<abi::Abi, Vec<_>> = HashMap::new();
+ for (abi, func) in func_list {
+ match map.entry(abi) {
+ Occupied(mut occ) => {
+ occ.get_mut().push(func);
}
- },
- _ => unreachable!()
+ Vacant(vac) => {
+ vac.set(vec!(func));
+ }
+ }
}
- }).collect();
+ map
+ };
- defs.push(mk_extern(&mut ctx, links, vars, funcs));
+ defs.push(mk_extern(&mut ctx, links, vars, abi::C));
+
+ for (abi, funcs) in funcs.into_iter() {
+ defs.push(mk_extern(&mut ctx, links, funcs, abi));
+ }
//let attrs = vec!(mk_attr_list(&mut ctx, "allow", ["dead_code", "non_camel_case_types", "uppercase_variables"]));
@@ -243,8 +254,8 @@ pub fn gen_mod(abi: &str, links: &[(String, Option<String>)], globs: Vec<Global>
}
fn mk_extern(ctx: &mut GenCtx, links: &[(String, Option<String>)],
- vars: Vec<P<ast::ForeignItem>>,
- funcs: Vec<P<ast::ForeignItem>>) -> P<ast::Item> {
+ foreign_items: Vec<P<ast::ForeignItem>>,
+ abi: abi::Abi) -> P<ast::Item> {
let attrs = if links.is_empty() {
Vec::new()
} else {
@@ -279,10 +290,9 @@ fn mk_extern(ctx: &mut GenCtx, links: &[(String, Option<String>)],
};
let mut items = Vec::new();
- items.extend(vars.into_iter());
- items.extend(funcs.into_iter());
+ items.extend(foreign_items.into_iter());
let ext = ast::ItemForeignMod(ast::ForeignMod {
- abi: ctx.abi,
+ abi: abi,
view_items: Vec::new(),
items: items
});
@@ -823,9 +833,9 @@ fn cty_to_rs(ctx: &mut GenCtx, ty: &Type) -> ast::Ty {
let ty = cty_to_rs(ctx, &**t);
mk_arrty(ctx, &ty, s)
},
- TFunc(ref rty, ref atys, var) => {
+ TFunc(ref rty, ref atys, var, abi) => {
let decl = cfuncty_to_rs(ctx, &**rty, atys.as_slice(), var);
- mk_fnty(ctx, &decl)
+ mk_fnty(ctx, &decl, abi)
},
TNamed(ref ti) => {
let id = rust_type_id(ctx, ti.borrow().name.clone());
@@ -904,10 +914,10 @@ fn mk_arrty(ctx: &mut GenCtx, base: &ast::Ty, n: uint) -> ast::Ty {
};
}
-fn mk_fnty(ctx: &mut GenCtx, decl: &ast::FnDecl) -> ast::Ty {
+fn mk_fnty(ctx: &mut GenCtx, decl: &ast::FnDecl, abi: abi::Abi) -> ast::Ty {
let fnty = ast::TyBareFn(P(ast::BareFnTy {
fn_style: ast::NormalFn,
- abi: ctx.abi,
+ abi: abi,
lifetimes: Vec::new(),
decl: P(decl.clone())
}));
diff --git a/src/lib.rs b/src/lib.rs
index e7cdd2ad..274f33e6 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -31,7 +31,6 @@ pub fn plugin_registrar(reg: &mut Registry) {
pub struct BindgenOptions {
pub match_pat: Vec<String>,
- pub abi: String,
pub builtins: bool,
pub links: Vec<(String, Option<String>)>,
pub emit_ast: bool,
@@ -45,7 +44,6 @@ impl Default for BindgenOptions {
fn default() -> BindgenOptions {
BindgenOptions {
match_pat: Vec::new(),
- abi: "C".to_string(),
builtins: false,
links: Vec::new(),
emit_ast: false,
@@ -71,15 +69,14 @@ pub fn generate_bindings(options: BindgenOptions, logger: Option<&Logger>, span:
}
};
let globals = try!(parse_headers(&options, logger));
- Ok(gen::gen_mod(options.abi.as_slice(), options.links.as_slice(), globals, span))
+ Ok(gen::gen_mod(options.links.as_slice(), globals, span))
}
struct DummyLogger;
-#[allow(unused_variable)]
impl Logger for DummyLogger {
- fn error(&self, msg: &str) { }
- fn warn(&self, msg: &str) { }
+ fn error(&self, _msg: &str) { }
+ fn warn(&self, _msg: &str) { }
}
fn parse_headers(options: &BindgenOptions, logger: &Logger) -> Result<Vec<Global>, ()> {
diff --git a/src/macro.rs b/src/macro.rs
index f3817072..e3b05a28 100644
--- a/src/macro.rs
+++ b/src/macro.rs
@@ -71,7 +71,6 @@ impl MacroArgsVisitor for BindgenArgsVisitor {
Some("link") => self.options.links.push((val.to_string(), None)),
Some("link_static") => self.options.links.push((val.to_string(), Some("static".to_string()))),
Some("link_framework") => self.options.links.push((val.to_string(), Some("framework".to_string()))),
- Some("abi") => self.options.abi = val.to_string(),
Some("match") => self.options.match_pat.push(val.to_string()),
Some("clang_args") => self.options.clang_args.push(val.to_string()),
_ => return false
@@ -79,8 +78,7 @@ impl MacroArgsVisitor for BindgenArgsVisitor {
true
}
- #[allow(unused_variable)]
- fn visit_int(&mut self, name: Option<&str>, val: i64) -> bool {
+ fn visit_int(&mut self, name: Option<&str>, _val: i64) -> bool {
if name.is_some() { self.seen_named = true; }
false
}
@@ -96,8 +94,7 @@ impl MacroArgsVisitor for BindgenArgsVisitor {
true
}
- #[allow(unused_variable)]
- fn visit_ident(&mut self, name: Option<&str>, val: &str) -> bool {
+ fn visit_ident(&mut self, name: Option<&str>, _val: &str) -> bool {
if name.is_some() { self.seen_named = true; }
false
}
diff --git a/src/parser.rs b/src/parser.rs
index 0eb9cc3d..7796604f 100644
--- a/src/parser.rs
+++ b/src/parser.rs
@@ -1,11 +1,13 @@
#![allow(unused_must_use)]
-#![allow(non_uppercase_statics)]
+#![allow(non_upper_case_globals)]
use std::collections::{HashMap, HashSet};
use std::collections::hashmap;
use std::cell::RefCell;
use std::rc::Rc;
+use syntax::abi;
+
use types as il;
use types::*;
use clang as cx;
@@ -141,6 +143,18 @@ fn fwd_decl(ctx: &mut ClangParserCtx, cursor: &Cursor, f: |ctx: &mut ClangParser
}
}
+fn get_abi(cc: Enum_CXCallingConv) -> abi::Abi {
+ match cc {
+ CXCallingConv_Default => abi::C,
+ CXCallingConv_C => abi::C,
+ CXCallingConv_X86StdCall => abi::Stdcall,
+ CXCallingConv_X86FastCall => abi::Fastcall,
+ CXCallingConv_AAPCS => abi::Aapcs,
+ CXCallingConv_X86_64Win64 => abi::Win64,
+ _other => panic!("unsupported calling convention: {}", _other),
+ }
+}
+
fn conv_ptr_ty(ctx: &mut ClangParserCtx, ty: &cx::Type, cursor: &Cursor, layout: Layout) -> il::Type {
let is_const = ty.is_const();
match ty.kind() {
@@ -157,8 +171,9 @@ fn conv_ptr_ty(ctx: &mut ClangParserCtx, ty: &cx::Type, cursor: &Cursor, layout:
("".to_string(), conv_ty(ctx, arg, cursor))
}).collect();
let ret_ty = box conv_ty(ctx, &ret_ty, cursor);
+ let abi = get_abi(ty.call_conv());
- TFunc(ret_ty, args_lst, ty.is_variadic())
+ TFunc(ret_ty, args_lst, ty.is_variadic(), abi)
} else if decl.kind() != CXCursor_NoDeclFound {
TPtr(box conv_decl_ty(ctx, &decl), is_const, layout)
} else {
@@ -374,11 +389,12 @@ fn visit_top<'r>(cur: &'r Cursor,
let ty = cursor.cur_type();
let ret_ty = box conv_ty(ctx, &cursor.ret_type(), cursor);
+ let abi = get_abi(ty.call_conv());
let func = decl_name(ctx, cursor);
let vi = func.varinfo();
let mut vi = vi.borrow_mut();
- vi.ty = TFunc(ret_ty.clone(), args_lst.clone(), ty.is_variadic());
+ vi.ty = TFunc(ret_ty.clone(), args_lst.clone(), ty.is_variadic(), abi);
ctx.globals.push(func);
return CXChildVisit_Continue;
diff --git a/src/types.rs b/src/types.rs
index c1a98891..76200c49 100644
--- a/src/types.rs
+++ b/src/types.rs
@@ -2,6 +2,8 @@ use std::cell::RefCell;
use std::fmt;
use std::rc::Rc;
+use syntax::abi;
+
#[deriving(Clone)]
pub enum Global {
GType(Rc<RefCell<TypeInfo>>),
@@ -69,7 +71,7 @@ pub enum Type {
TFloat(FKind, Layout),
TPtr(Box<Type>, bool, Layout),
TArray(Box<Type>, uint, Layout),
- TFunc(Box<Type>, Vec<(String, Type)>, bool),
+ TFunc(Box<Type>, Vec<(String, Type)>, bool, abi::Abi),
TNamed(Rc<RefCell<TypeInfo>>),
TComp(Rc<RefCell<CompInfo>>),
TEnum(Rc<RefCell<EnumInfo>>)