summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChristopher Chambers <chris.chambers@peanutcode.com>2014-12-18 11:13:50 -0600
committerChristopher Chambers <chris.chambers@peanutcode.com>2014-12-19 07:38:42 -0600
commit94c75a2e2e398d1d206aaed8146de9c333c4d6ed (patch)
treebae1209e1d0c3de0d4b2522dd92187408fe37e33
parent010ce680336355af484ef2e171c2bb6cc4c0c34b (diff)
Improves argument name parsing in function pointers.
Previously, all function pointer types always had their arguments bound as arg1, arg2, etc. This change preserves the argument names, when they are available. parser.rs - Uses the type cursor to visit children and gather argument names and types. tests/func_ptr.rs - Binds tests/headers/func_ptr.h and tests/headers/func_ptr_in_struct.h and ensures that argument names are correctly bound.
-rw-r--r--src/parser.rs11
-rw-r--r--tests/func_ptr.rs17
-rw-r--r--tests/headers/func_ptr.h1
-rw-r--r--tests/headers/func_ptr_in_struct.h3
4 files changed, 29 insertions, 3 deletions
diff --git a/src/parser.rs b/src/parser.rs
index 5b06b0e9..e26ce4f5 100644
--- a/src/parser.rs
+++ b/src/parser.rs
@@ -167,9 +167,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 args_lst = ty.arg_types().iter().map(|arg| {
- ("".to_string(), conv_ty(ctx, arg, cursor))
- }).collect();
+ 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());
diff --git a/tests/func_ptr.rs b/tests/func_ptr.rs
new file mode 100644
index 00000000..7851c4ff
--- /dev/null
+++ b/tests/func_ptr.rs
@@ -0,0 +1,17 @@
+extern crate bindgen;
+extern crate regex;
+extern crate syntax;
+
+mod util;
+
+#[test]
+fn test_func_ptr() {
+ let output = util::generate_unpretty_output("tests/headers/func_ptr.h");
+ assert_eq!(output, r##"extern "C" { pub static mut foo: ::std::option::Option<extern "C" fn(x: ::libc::c_int, y: ::libc::c_int) -> ::libc::c_int>; }"##);
+}
+
+#[test]
+fn test_func_ptr_in_struct() {
+ let output = util::generate_unpretty_output("tests/headers/func_ptr_in_struct.h");
+ assert_eq!(output, r##"#[repr(C)] #[deriving(Copy)] pub struct Struct_Foo { pub bar: ::std::option::Option<extern "C" fn(x: ::libc::c_int, y: ::libc::c_int) -> Enum_baz>, } extern "C" { }"##);
+}
diff --git a/tests/headers/func_ptr.h b/tests/headers/func_ptr.h
new file mode 100644
index 00000000..a4662f3d
--- /dev/null
+++ b/tests/headers/func_ptr.h
@@ -0,0 +1 @@
+int (*foo) (int x, int y);
diff --git a/tests/headers/func_ptr_in_struct.h b/tests/headers/func_ptr_in_struct.h
new file mode 100644
index 00000000..8e9bf60c
--- /dev/null
+++ b/tests/headers/func_ptr_in_struct.h
@@ -0,0 +1,3 @@
+struct Foo {
+ enum baz (*bar) (int x, int y);
+};