summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEdward Barnard <eabarnard@gmail.com>2014-12-29 19:10:08 +0100
committerEdward Barnard <eabarnard@gmail.com>2014-12-29 19:10:08 +0100
commit0e138a1a4c0f4a9b2ee2a76ef5db4a5e4bd061d8 (patch)
tree590d5f1a9b367af45694f967728b1222abfc22d1
parentdd96a0c5f416c6d0e0689079e228de536a643153 (diff)
Fix a bug in forward declared structs.
-rw-r--r--src/parser.rs21
-rw-r--r--tests/forward_declared_struct.rs11
-rw-r--r--tests/headers/forward_declared_struct.h11
3 files changed, 34 insertions, 9 deletions
diff --git a/src/parser.rs b/src/parser.rs
index 3cc77239..e341617f 100644
--- a/src/parser.rs
+++ b/src/parser.rs
@@ -60,6 +60,7 @@ fn match_pattern(ctx: &mut ClangParserCtx, cursor: &Cursor) -> bool {
}
fn decl_name(ctx: &mut ClangParserCtx, cursor: &Cursor) -> Global {
+ let cursor = &cursor.canonical();
let mut new_decl = false;
let override_enum_ty = ctx.options.override_enum_ty;
let decl = match ctx.name.entry(*cursor) {
@@ -336,14 +337,18 @@ fn visit_composite(cursor: &Cursor, parent: &Cursor,
}
}
CXCursor_StructDecl | CXCursor_UnionDecl => {
- let cursor = &cursor.canonical();
- let decl = decl_name(ctx, cursor);
- let ci = decl.compinfo();
- cursor.visit(|c, p| {
- let mut ci_ = ci.borrow_mut();
- visit_composite(c, p, ctx, &mut ci_.members)
+ let decl = fwd_decl(ctx, cursor, |ctx_| {
+ // If the struct is anonymous (i.e. declared here) then it
+ // cannot be used elsewhere and so does not need to be added
+ // to globals otherwise it will be declared later and a global.
+ let decl = decl_name(ctx_, cursor);
+ let ci = decl.compinfo();
+ cursor.visit(|c, p| {
+ let mut ci_ = ci.borrow_mut();
+ visit_composite(c, p, ctx_, &mut ci_.members)
+ });
+ members.push(CompMember::Comp(decl.compinfo()));
});
- members.push(CompMember::Comp(ci));
}
_ => {
// XXX: Some kind of warning would be nice, but this produces far
@@ -383,8 +388,6 @@ fn visit_top<'r>(cur: &'r Cursor,
return CXChildVisit_Continue;
}
- let cursor = &cursor.canonical();
-
match cursor.kind() {
CXCursor_StructDecl | CXCursor_UnionDecl => {
fwd_decl(ctx, cursor, |ctx_| {
diff --git a/tests/forward_declared_struct.rs b/tests/forward_declared_struct.rs
index a5d95743..efd48e30 100644
--- a/tests/forward_declared_struct.rs
+++ b/tests/forward_declared_struct.rs
@@ -9,4 +9,15 @@ extern crate libc;
fn test_struct_containing_forward_declared_struct() {
mod ffi { bindgen!("headers/struct_containing_forward_declared_struct.h"); }
// Check that struct b is not duplicated
+}
+
+#[test]
+fn test_forward_declared_struct() {
+ mod ffi { bindgen!("headers/forward_declared_struct.h"); }
+
+ let a = ffi::Struct_a { b: 1 };
+ let c = ffi::Struct_c { d: 1 };
+
+ a.b;
+ c.d;
} \ No newline at end of file
diff --git a/tests/headers/forward_declared_struct.h b/tests/headers/forward_declared_struct.h
new file mode 100644
index 00000000..2a69450c
--- /dev/null
+++ b/tests/headers/forward_declared_struct.h
@@ -0,0 +1,11 @@
+struct a;
+
+struct a {
+ int b;
+};
+
+struct c {
+ int d;
+};
+
+struct c; \ No newline at end of file