diff options
author | Edward Barnard <eabarnard@gmail.com> | 2014-12-29 19:10:08 +0100 |
---|---|---|
committer | Edward Barnard <eabarnard@gmail.com> | 2014-12-29 19:10:08 +0100 |
commit | 0e138a1a4c0f4a9b2ee2a76ef5db4a5e4bd061d8 (patch) | |
tree | 590d5f1a9b367af45694f967728b1222abfc22d1 | |
parent | dd96a0c5f416c6d0e0689079e228de536a643153 (diff) |
Fix a bug in forward declared structs.
-rw-r--r-- | src/parser.rs | 21 | ||||
-rw-r--r-- | tests/forward_declared_struct.rs | 11 | ||||
-rw-r--r-- | tests/headers/forward_declared_struct.h | 11 |
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 |