summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/clang.rs6
-rw-r--r--src/parser.rs27
-rw-r--r--tests/forward_declared_struct.rs12
-rw-r--r--tests/headers/struct_containing_forward_declared_struct.h7
4 files changed, 30 insertions, 22 deletions
diff --git a/src/clang.rs b/src/clang.rs
index 6f7ab574..e5d7696c 100644
--- a/src/clang.rs
+++ b/src/clang.rs
@@ -50,6 +50,12 @@ impl Cursor {
}
}
+ pub fn canonical(&self) -> Cursor {
+ unsafe {
+ Cursor { x: clang_getCanonicalCursor(self.x) }
+ }
+ }
+
pub fn visit(&self, func: CursorVisitor) {
unsafe {
let data = mem::transmute::<&CursorVisitor, CXClientData>(&func);
diff --git a/src/parser.rs b/src/parser.rs
index 2b54b7e8..3cc77239 100644
--- a/src/parser.rs
+++ b/src/parser.rs
@@ -336,6 +336,7 @@ 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| {
@@ -382,8 +383,10 @@ fn visit_top<'r>(cur: &'r Cursor,
return CXChildVisit_Continue;
}
+ let cursor = &cursor.canonical();
+
match cursor.kind() {
- CXCursor_StructDecl => {
+ CXCursor_StructDecl | CXCursor_UnionDecl => {
fwd_decl(ctx, cursor, |ctx_| {
let decl = decl_name(ctx_, cursor);
let ci = decl.compinfo();
@@ -393,29 +396,9 @@ fn visit_top<'r>(cur: &'r Cursor,
});
ctx_.globals.push(GComp(ci));
});
-
- // XXX: Review this condition. I think it is no longer necessary.
- // @chris-chambers
- //return if cur.kind() == CXCursor_FieldDecl {
- // CXChildVisit_Break
- //} else {
- // CXChildVisit_Continue
- //};
-
+
CXChildVisit_Continue
}
- CXCursor_UnionDecl => {
- fwd_decl(ctx, cursor, |ctx_| {
- 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)
- });
- ctx_.globals.push(GComp(ci));
- });
- return CXChildVisit_Continue;
- }
CXCursor_EnumDecl => {
fwd_decl(ctx, cursor, |ctx_| {
let decl = decl_name(ctx_, cursor);
diff --git a/tests/forward_declared_struct.rs b/tests/forward_declared_struct.rs
new file mode 100644
index 00000000..7e9bfc8b
--- /dev/null
+++ b/tests/forward_declared_struct.rs
@@ -0,0 +1,12 @@
+#![feature(phase)]
+
+#[phase(plugin)]
+extern crate bindgen;
+
+extern crate libc;
+
+#[test]
+fn test_struct_containing_forward_declared_struct() {
+ mod ffi { bindgen!("headers/struct_containing_forward_declared_struct.h"); }
+ // Checking that struct b is not duplicated
+} \ No newline at end of file
diff --git a/tests/headers/struct_containing_forward_declared_struct.h b/tests/headers/struct_containing_forward_declared_struct.h
new file mode 100644
index 00000000..c68af042
--- /dev/null
+++ b/tests/headers/struct_containing_forward_declared_struct.h
@@ -0,0 +1,7 @@
+struct a {
+ struct b* val_a;
+};
+
+struct b {
+ int val_b;
+}; \ No newline at end of file