summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/gen.rs38
-rw-r--r--src/lib.rs2
-rw-r--r--src/parser.rs72
-rw-r--r--src/types.rs18
4 files changed, 93 insertions, 37 deletions
diff --git a/src/gen.rs b/src/gen.rs
index 84006b3c..4d331c9e 100644
--- a/src/gen.rs
+++ b/src/gen.rs
@@ -211,10 +211,11 @@ pub fn gen_mod(links: &[(String, LinkType)], globs: Vec<Global>, span: Span) ->
GFunc(vi) => {
let v = vi.borrow();
match v.ty {
- TFunc(ref rty, ref aty, var, abi) => {
+ TFuncPtr(ref sig) => {
let decl = cfunc_to_rs(&mut ctx, v.name.clone(),
- &**rty, aty.as_slice(), var);
- (abi, decl)
+ &*sig.ret_ty, sig.args.as_slice(),
+ sig.is_variadic);
+ (sig.abi, decl)
}
_ => unreachable!()
}
@@ -237,7 +238,9 @@ pub fn gen_mod(links: &[(String, LinkType)], globs: Vec<Global>, span: Span) ->
map
};
- defs.push(mk_extern(&mut ctx, links, vars, abi::C));
+ if !Vec::is_empty(&vars) {
+ 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));
@@ -489,7 +492,7 @@ fn cstruct_to_rs(ctx: &mut GenCtx, name: String, members: Vec<CompMember>) -> Ve
} else {
rust_type_id(ctx, f.name.clone())
};
-
+
let f_ty = P(cty_to_rs(ctx, &f.ty));
fields.push(respan(ctx.span, ast::StructField_ {
@@ -926,9 +929,13 @@ 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, abi) => {
- let decl = cfuncty_to_rs(ctx, &**rty, atys.as_slice(), var);
- mk_fnty(ctx, &decl, abi)
+ &TFuncPtr(ref sig) => {
+ let decl = cfuncty_to_rs(ctx, &*sig.ret_ty, sig.args.as_slice(), sig.is_variadic);
+ mk_fnty(ctx, &decl, sig.abi)
+ },
+ &TFuncProto(ref sig) => {
+ let decl = cfuncty_to_rs(ctx, &*sig.ret_ty, sig.args.as_slice(), sig.is_variadic);
+ mk_fn_proto_ty(ctx, &decl, sig.abi)
},
&TNamed(ref ti) => {
let id = rust_type_id(ctx, ti.borrow().name.clone());
@@ -1005,6 +1012,21 @@ fn mk_arrty(ctx: &GenCtx, base: &ast::Ty, n: uint) -> ast::Ty {
};
}
+fn mk_fn_proto_ty(ctx: &mut GenCtx, decl: &ast::FnDecl, abi: abi::Abi) -> ast::Ty {
+ let fnty = ast::TyBareFn(P(ast::BareFnTy {
+ unsafety: ast::Unsafety::Normal,
+ abi: abi,
+ lifetimes: Vec::new(),
+ decl: P(decl.clone())
+ }));
+
+ ast::Ty {
+ id: ast::DUMMY_NODE_ID,
+ node: fnty,
+ span: ctx.span,
+ }
+}
+
fn mk_fnty(ctx: &mut GenCtx, decl: &ast::FnDecl, abi: abi::Abi) -> ast::Ty {
let fnty = ast::TyBareFn(P(ast::BareFnTy {
unsafety: ast::Unsafety::Normal,
diff --git a/src/lib.rs b/src/lib.rs
index f87b4aac..73b6358f 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -22,6 +22,7 @@ use types::Global;
mod types;
mod clangll;
+#[allow(dead_code)]
mod clang;
mod gen;
mod parser;
@@ -59,6 +60,7 @@ impl Default for BindgenOptions {
}
}
+#[deriving(Copy)]
pub enum LinkType {
Default,
Static,
diff --git a/src/parser.rs b/src/parser.rs
index c4291d5e..2622a944 100644
--- a/src/parser.rs
+++ b/src/parser.rs
@@ -168,22 +168,14 @@ fn conv_ptr_ty(ctx: &mut ClangParserCtx, ty: &cx::Type, cursor: &Cursor, layout:
let ret_ty = ty.ret_type();
let decl = ty.declaration();
return if ret_ty.kind() != CXType_Invalid {
- let mut args_lst = vec!();
- cursor.visit(|c, _| {
- if c.kind() == CXCursor_ParmDecl {
- args_lst.push((c.spelling(), conv_ty(ctx, &c.cur_type(), c)));
- }
- CXChildVisit_Continue
- });
-
- 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(), abi)
+ TFuncPtr(mk_fn_sig(ctx, ty, cursor))
} else if decl.kind() != CXCursor_NoDeclFound {
- TPtr(box conv_decl_ty(ctx, &decl), is_const, layout)
+ TPtr(box conv_decl_ty(ctx, &decl), ty.is_const(), layout)
+ } else if cursor.kind() == CXCursor_VarDecl {
+ let can_ty = ty.canonical_type();
+ conv_ty(ctx, &can_ty, cursor)
} else {
- TPtr(box TVoid, is_const, layout)
+ TPtr(box TVoid, ty.is_const(), layout)
};
}
CXType_Typedef => {
@@ -200,6 +192,41 @@ fn conv_ptr_ty(ctx: &mut ClangParserCtx, ty: &cx::Type, cursor: &Cursor, layout:
}
}
+fn mk_fn_sig(ctx: &mut ClangParserCtx, ty: &cx::Type, cursor: &Cursor) -> il::FuncSig {
+ let args_lst: Vec<(String, il::Type)> = match cursor.kind() {
+ CXCursor_FunctionDecl => {
+ // For CXCursor_FunctionDecl, cursor.args() is the reliable way to
+ // get parameter names and types.
+ cursor.args().iter().map(|arg| {
+ let arg_name = arg.spelling();
+ (arg_name, conv_ty(ctx, &arg.cur_type(), arg))
+ }).collect()
+ }
+ _ => {
+ // For non-CXCursor_FunctionDecl, visiting the cursor's children is
+ // the only reliable way to get parameter names.
+ let mut args_lst = vec!();
+ cursor.visit(|c, _| {
+ if c.kind() == CXCursor_ParmDecl {
+ args_lst.push((c.spelling(), conv_ty(ctx, &c.cur_type(), c)));
+ }
+ CXChildVisit_Continue
+ });
+ args_lst
+ }
+ };
+
+ let ret_ty = box conv_ty(ctx, &ty.ret_type(), cursor);
+ let abi = get_abi(ty.call_conv());
+
+ il::FuncSig {
+ ret_ty: ret_ty,
+ args: args_lst,
+ is_variadic: ty.is_variadic(),
+ abi: abi,
+ }
+}
+
fn conv_decl_ty(ctx: &mut ClangParserCtx, cursor: &Cursor) -> il::Type {
return match cursor.kind() {
CXCursor_StructDecl => {
@@ -227,7 +254,7 @@ fn conv_decl_ty(ctx: &mut ClangParserCtx, cursor: &Cursor) -> il::Type {
}
fn conv_ty(ctx: &mut ClangParserCtx, ty: &cx::Type, cursor: &Cursor) -> il::Type {
- debug!("conv_ty: ty=`{}`", type_to_str(ty.kind()));
+ debug!("conv_ty: ty=`{}` sp=`{}` loc=`{}`", type_to_str(ty.kind()), cursor.spelling(), cursor.location());
let layout = Layout::new(ty.size(), ty.align());
return match ty.kind() {
CXType_Void | CXType_Invalid => TVoid,
@@ -251,6 +278,7 @@ fn conv_ty(ctx: &mut ClangParserCtx, ty: &cx::Type, cursor: &Cursor) -> il::Type
CXType_VariableArray | CXType_DependentSizedArray | CXType_IncompleteArray => {
conv_ptr_ty(ctx, &ty.elem_type(), cursor, layout)
}
+ CXType_FunctionProto => TFuncProto(mk_fn_sig(ctx, ty, cursor)),
CXType_Record |
CXType_Typedef |
CXType_Unexposed |
@@ -349,7 +377,7 @@ fn visit_composite(cursor: &Cursor, parent: &Cursor,
if let Some(CompMember::Comp(c)) = members.pop() {
members.push(CompMember::CompField(c, field));
} else {
- panic!(); // Checks in is_composite make this unreachable.
+ unreachable!(); // Checks in is_composite make this unreachable.
}
} else {
members.push(CompMember::Field(field));
@@ -431,19 +459,11 @@ fn visit_top<'r>(cursor: &Cursor,
return CXChildVisit_Continue;
}
- let args_lst: Vec<(String, il::Type)> = cursor.args().iter().map(|arg| {
- let arg_name = arg.spelling();
- (arg_name, conv_ty(ctx, &arg.cur_type(), cursor))
- }).collect();
-
- 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(), abi);
+
+ vi.ty = TFuncPtr(mk_fn_sig(ctx, &cursor.cur_type(), cursor));
ctx.globals.push(func);
return CXChildVisit_Continue;
diff --git a/src/types.rs b/src/types.rs
index 1a0b353b..fbd108b2 100644
--- a/src/types.rs
+++ b/src/types.rs
@@ -70,18 +70,28 @@ impl fmt::Show for Global {
}
#[deriving(Clone, PartialEq)]
+pub struct FuncSig {
+ pub ret_ty: Box<Type>,
+ pub args: Vec<(String, Type)>,
+ pub is_variadic: bool,
+ pub abi: abi::Abi,
+}
+
+#[deriving(Clone, PartialEq)]
pub enum Type {
TVoid,
TInt(IKind, Layout),
TFloat(FKind, Layout),
TPtr(Box<Type>, bool, Layout),
TArray(Box<Type>, uint, Layout),
- TFunc(Box<Type>, Vec<(String, Type)>, bool, abi::Abi),
+ TFuncProto(FuncSig),
+ TFuncPtr(FuncSig),
TNamed(Rc<RefCell<TypeInfo>>),
TComp(Rc<RefCell<CompInfo>>),
TEnum(Rc<RefCell<EnumInfo>>)
}
+#[allow(dead_code)]
impl Type {
pub fn size(&self) -> uint {
match self {
@@ -93,7 +103,8 @@ impl Type {
&TComp(ref ci) => ci.borrow().layout.size,
&TEnum(ref ei) => ei.borrow().layout.size,
&TVoid => 0,
- &TFunc(..) => 0,
+ &TFuncProto(..) => 0,
+ &TFuncPtr(..) => 0,
}
}
@@ -107,7 +118,8 @@ impl Type {
&TComp(ref ci) => ci.borrow().layout.align,
&TEnum(ref ei) => ei.borrow().layout.align,
&TVoid => 0,
- &TFunc(..) => 0,
+ &TFuncProto(..) => 0,
+ &TFuncPtr(..) => 0,
}
}
}