Skip to content

Commit f979b14

Browse files
committed
ir: Don't parse non-semantic-children cursor as inner structs.
Fixes: rust-lang#482
1 parent 19c7d93 commit f979b14

File tree

5 files changed

+64
-19
lines changed

5 files changed

+64
-19
lines changed

src/codegen/mod.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -519,8 +519,8 @@ impl CodeGenerator for Type {
519519
TypeKind::BlockPointer |
520520
TypeKind::Reference(..) |
521521
TypeKind::TemplateRef(..) |
522-
TypeKind::Function(..) |
523522
TypeKind::ResolvedTypeRef(..) |
523+
TypeKind::Function(..) |
524524
TypeKind::Named => {
525525
// These items don't need code generation, they only need to be
526526
// converted to rust types in fields, arguments, and such.
@@ -2057,7 +2057,7 @@ impl ToRustTy for Type {
20572057
.map(|arg| arg.to_rust_ty(ctx))
20582058
.collect::<Vec<_>>();
20592059

2060-
path.segments.last_mut().unwrap().parameters = if
2060+
path.segments.last_mut().unwrap().parameters = if
20612061
template_args.is_empty() {
20622062
None
20632063
} else {

src/ir/comp.rs

+9-3
Original file line numberDiff line numberDiff line change
@@ -605,11 +605,17 @@ impl CompInfo {
605605
CXCursor_UnionDecl |
606606
CXCursor_ClassTemplate |
607607
CXCursor_ClassDecl => {
608+
// We can find non-semantic children here, see:
609+
// https://github.com/servo/rust-bindgen/issues/482
610+
if cur.semantic_parent() != cursor {
611+
return CXChildVisit_Continue;
612+
}
613+
608614
let inner = Item::parse(cur, Some(potential_id), ctx)
609615
.expect("Inner ClassDecl");
610-
if !ci.inner_types.contains(&inner) {
611-
ci.inner_types.push(inner);
612-
}
616+
617+
ci.inner_types.push(inner);
618+
613619
// A declaration of an union or a struct without name could
614620
// also be an unnamed field, unfortunately.
615621
if cur.spelling().is_empty() &&

tests/expectations/tests/class_nested.rs

+27
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,24 @@ fn bindgen_test_layout_A_B() {
2222
impl Clone for A_B {
2323
fn clone(&self) -> Self { *self }
2424
}
25+
#[repr(C)]
26+
#[derive(Debug, Copy)]
27+
pub struct A_C {
28+
pub baz: ::std::os::raw::c_int,
29+
}
30+
#[test]
31+
fn bindgen_test_layout_A_C() {
32+
assert_eq!(::std::mem::size_of::<A_C>() , 4usize);
33+
assert_eq!(::std::mem::align_of::<A_C>() , 4usize);
34+
}
35+
impl Clone for A_C {
36+
fn clone(&self) -> Self { *self }
37+
}
38+
#[repr(C)]
39+
#[derive(Debug, Copy, Clone)]
40+
pub struct A_D<T> {
41+
pub foo: T,
42+
}
2543
#[test]
2644
fn bindgen_test_layout_A() {
2745
assert_eq!(::std::mem::size_of::<A>() , 4usize);
@@ -34,6 +52,15 @@ extern "C" {
3452
#[link_name = "var"]
3553
pub static mut var: A_B;
3654
}
55+
#[test]
56+
fn __bindgen_test_layout_template_1() {
57+
assert_eq!(::std::mem::size_of::<A_D<::std::os::raw::c_int>>() , 4usize);
58+
assert_eq!(::std::mem::align_of::<A_D<::std::os::raw::c_int>>() , 4usize);
59+
}
60+
extern "C" {
61+
#[link_name = "baz"]
62+
pub static mut baz: A_D<::std::os::raw::c_int>;
63+
}
3764
#[repr(C)]
3865
#[derive(Debug, Copy)]
3966
pub struct D {

tests/expectations/tests/struct_containing_forward_declared_struct.rs

+14-14
Original file line numberDiff line numberDiff line change
@@ -7,20 +7,7 @@
77
#[repr(C)]
88
#[derive(Debug, Copy)]
99
pub struct a {
10-
pub val_a: *mut a_b,
11-
}
12-
#[repr(C)]
13-
#[derive(Debug, Copy)]
14-
pub struct a_b {
15-
pub val_b: ::std::os::raw::c_int,
16-
}
17-
#[test]
18-
fn bindgen_test_layout_a_b() {
19-
assert_eq!(::std::mem::size_of::<a_b>() , 4usize);
20-
assert_eq!(::std::mem::align_of::<a_b>() , 4usize);
21-
}
22-
impl Clone for a_b {
23-
fn clone(&self) -> Self { *self }
10+
pub val_a: *mut b,
2411
}
2512
#[test]
2613
fn bindgen_test_layout_a() {
@@ -30,3 +17,16 @@ fn bindgen_test_layout_a() {
3017
impl Clone for a {
3118
fn clone(&self) -> Self { *self }
3219
}
20+
#[repr(C)]
21+
#[derive(Debug, Copy)]
22+
pub struct b {
23+
pub val_b: ::std::os::raw::c_int,
24+
}
25+
#[test]
26+
fn bindgen_test_layout_b() {
27+
assert_eq!(::std::mem::size_of::<b>() , 4usize);
28+
assert_eq!(::std::mem::align_of::<b>() , 4usize);
29+
}
30+
impl Clone for b {
31+
fn clone(&self) -> Self { *self }
32+
}

tests/headers/class_nested.hpp

+12
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,21 @@ class A {
44
class B {
55
int member_b;
66
};
7+
8+
class C;
9+
10+
template<typename T>
11+
class D {
12+
T foo;
13+
};
14+
};
15+
16+
class A::C {
17+
int baz;
718
};
819

920
A::B var;
21+
A::D<int> baz;
1022

1123
class D {
1224
A::B member;

0 commit comments

Comments
 (0)