Skip to content

Commit c8ce4a9

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

File tree

8 files changed

+131
-85
lines changed

8 files changed

+131
-85
lines changed

src/codegen/mod.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -522,8 +522,8 @@ impl CodeGenerator for Type {
522522
TypeKind::BlockPointer |
523523
TypeKind::Reference(..) |
524524
TypeKind::TemplateRef(..) |
525-
TypeKind::Function(..) |
526525
TypeKind::ResolvedTypeRef(..) |
526+
TypeKind::Function(..) |
527527
TypeKind::Named => {
528528
// These items don't need code generation, they only need to be
529529
// converted to rust types in fields, arguments, and such.

src/ir/comp.rs

+12-3
Original file line numberDiff line numberDiff line change
@@ -663,11 +663,20 @@ impl CompInfo {
663663
CXCursor_UnionDecl |
664664
CXCursor_ClassTemplate |
665665
CXCursor_ClassDecl => {
666+
// We can find non-semantic children here, clang uses a
667+
// StructDecl to note incomplete structs that hasn't been
668+
// forward-declared before, see:
669+
//
670+
// https://github.com/servo/rust-bindgen/issues/482
671+
if cur.semantic_parent() != cursor {
672+
return CXChildVisit_Continue;
673+
}
674+
666675
let inner = Item::parse(cur, Some(potential_id), ctx)
667676
.expect("Inner ClassDecl");
668-
if !ci.inner_types.contains(&inner) {
669-
ci.inner_types.push(inner);
670-
}
677+
678+
ci.inner_types.push(inner);
679+
671680
// A declaration of an union or a struct without name could
672681
// also be an unnamed field, unfortunately.
673682
if cur.spelling().is_empty() &&

tests/expectations/tests/class_nested.rs

+40
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,31 @@ fn bindgen_test_layout_A_B() {
2929
impl Clone for A_B {
3030
fn clone(&self) -> Self { *self }
3131
}
32+
#[repr(C)]
33+
#[derive(Debug, Copy)]
34+
pub struct A_C {
35+
pub baz: ::std::os::raw::c_int,
36+
}
37+
#[test]
38+
fn bindgen_test_layout_A_C() {
39+
assert_eq!(::std::mem::size_of::<A_C>() , 4usize , concat ! (
40+
"Size of: " , stringify ! ( A_C ) ));
41+
assert_eq! (::std::mem::align_of::<A_C>() , 4usize , concat ! (
42+
"Alignment of " , stringify ! ( A_C ) ));
43+
assert_eq! (unsafe {
44+
& ( * ( 0 as * const A_C ) ) . baz as * const _ as usize } ,
45+
0usize , concat ! (
46+
"Alignment of field: " , stringify ! ( A_C ) , "::" ,
47+
stringify ! ( baz ) ));
48+
}
49+
impl Clone for A_C {
50+
fn clone(&self) -> Self { *self }
51+
}
52+
#[repr(C)]
53+
#[derive(Debug, Copy, Clone)]
54+
pub struct A_D<T> {
55+
pub foo: T,
56+
}
3257
#[test]
3358
fn bindgen_test_layout_A() {
3459
assert_eq!(::std::mem::size_of::<A>() , 4usize , concat ! (
@@ -48,6 +73,21 @@ extern "C" {
4873
#[link_name = "var"]
4974
pub static mut var: A_B;
5075
}
76+
#[test]
77+
fn __bindgen_test_layout_template_1() {
78+
assert_eq!(::std::mem::size_of::<A_D<::std::os::raw::c_int>>() , 4usize ,
79+
concat ! (
80+
"Size of template specialization: " , stringify ! (
81+
A_D<::std::os::raw::c_int> ) ));
82+
assert_eq!(::std::mem::align_of::<A_D<::std::os::raw::c_int>>() , 4usize ,
83+
concat ! (
84+
"Alignment of template specialization: " , stringify ! (
85+
A_D<::std::os::raw::c_int> ) ));
86+
}
87+
extern "C" {
88+
#[link_name = "baz"]
89+
pub static mut baz: A_D<::std::os::raw::c_int>;
90+
}
5191
#[repr(C)]
5292
#[derive(Debug, Copy)]
5393
pub struct D {

tests/expectations/tests/layout_array.rs

-3
Original file line numberDiff line numberDiff line change
@@ -196,9 +196,6 @@ pub struct malloc_heap {
196196
pub struct malloc_heap__bindgen_ty_1 {
197197
pub lh_first: *mut malloc_heap__bindgen_ty_1_malloc_elem,
198198
}
199-
#[repr(C)]
200-
#[derive(Debug, Copy, Clone)]
201-
pub struct malloc_heap__bindgen_ty_1_malloc_elem([u8; 0]);
202199
#[test]
203200
fn bindgen_test_layout_malloc_heap__bindgen_ty_1() {
204201
assert_eq!(::std::mem::size_of::<malloc_heap__bindgen_ty_1>() , 8usize ,

tests/expectations/tests/layout_cmdline_token.rs

+45-54
Original file line numberDiff line numberDiff line change
@@ -11,9 +11,30 @@
1111
#[repr(C)]
1212
#[derive(Debug, Copy)]
1313
pub struct cmdline_token_hdr {
14-
pub ops: *mut cmdline_token_hdr_cmdline_token_ops,
14+
pub ops: *mut cmdline_token_ops,
1515
pub offset: ::std::os::raw::c_uint,
1616
}
17+
#[test]
18+
fn bindgen_test_layout_cmdline_token_hdr() {
19+
assert_eq!(::std::mem::size_of::<cmdline_token_hdr>() , 16usize , concat !
20+
( "Size of: " , stringify ! ( cmdline_token_hdr ) ));
21+
assert_eq! (::std::mem::align_of::<cmdline_token_hdr>() , 8usize , concat
22+
! ( "Alignment of " , stringify ! ( cmdline_token_hdr ) ));
23+
assert_eq! (unsafe {
24+
& ( * ( 0 as * const cmdline_token_hdr ) ) . ops as * const _
25+
as usize } , 0usize , concat ! (
26+
"Alignment of field: " , stringify ! ( cmdline_token_hdr ) ,
27+
"::" , stringify ! ( ops ) ));
28+
assert_eq! (unsafe {
29+
& ( * ( 0 as * const cmdline_token_hdr ) ) . offset as * const
30+
_ as usize } , 8usize , concat ! (
31+
"Alignment of field: " , stringify ! ( cmdline_token_hdr ) ,
32+
"::" , stringify ! ( offset ) ));
33+
}
34+
impl Clone for cmdline_token_hdr {
35+
fn clone(&self) -> Self { *self }
36+
}
37+
pub type cmdline_parse_token_hdr_t = cmdline_token_hdr;
1738
/**
1839
* A token is defined by this structure.
1940
*
@@ -35,7 +56,7 @@ pub struct cmdline_token_hdr {
3556
*/
3657
#[repr(C)]
3758
#[derive(Debug, Copy)]
38-
pub struct cmdline_token_hdr_cmdline_token_ops {
59+
pub struct cmdline_token_ops {
3960
/** parse(token ptr, buf, res pts, buf len) */
4061
pub parse: ::std::option::Option<unsafe extern "C" fn(arg1:
4162
*mut cmdline_parse_token_hdr_t,
@@ -70,65 +91,35 @@ pub struct cmdline_token_hdr_cmdline_token_ops {
7091
-> ::std::os::raw::c_int>,
7192
}
7293
#[test]
73-
fn bindgen_test_layout_cmdline_token_hdr_cmdline_token_ops() {
74-
assert_eq!(::std::mem::size_of::<cmdline_token_hdr_cmdline_token_ops>() ,
75-
32usize , concat ! (
76-
"Size of: " , stringify ! ( cmdline_token_hdr_cmdline_token_ops
77-
) ));
78-
assert_eq! (::std::mem::align_of::<cmdline_token_hdr_cmdline_token_ops>()
79-
, 8usize , concat ! (
80-
"Alignment of " , stringify ! (
81-
cmdline_token_hdr_cmdline_token_ops ) ));
94+
fn bindgen_test_layout_cmdline_token_ops() {
95+
assert_eq!(::std::mem::size_of::<cmdline_token_ops>() , 32usize , concat !
96+
( "Size of: " , stringify ! ( cmdline_token_ops ) ));
97+
assert_eq! (::std::mem::align_of::<cmdline_token_ops>() , 8usize , concat
98+
! ( "Alignment of " , stringify ! ( cmdline_token_ops ) ));
8299
assert_eq! (unsafe {
83-
& ( * ( 0 as * const cmdline_token_hdr_cmdline_token_ops ) ) .
84-
parse as * const _ as usize } , 0usize , concat ! (
85-
"Alignment of field: " , stringify ! (
86-
cmdline_token_hdr_cmdline_token_ops ) , "::" , stringify ! (
87-
parse ) ));
100+
& ( * ( 0 as * const cmdline_token_ops ) ) . parse as * const
101+
_ as usize } , 0usize , concat ! (
102+
"Alignment of field: " , stringify ! ( cmdline_token_ops ) ,
103+
"::" , stringify ! ( parse ) ));
88104
assert_eq! (unsafe {
89-
& ( * ( 0 as * const cmdline_token_hdr_cmdline_token_ops ) ) .
90-
complete_get_nb as * const _ as usize } , 8usize , concat ! (
91-
"Alignment of field: " , stringify ! (
92-
cmdline_token_hdr_cmdline_token_ops ) , "::" , stringify ! (
93-
complete_get_nb ) ));
105+
& ( * ( 0 as * const cmdline_token_ops ) ) . complete_get_nb
106+
as * const _ as usize } , 8usize , concat ! (
107+
"Alignment of field: " , stringify ! ( cmdline_token_ops ) ,
108+
"::" , stringify ! ( complete_get_nb ) ));
94109
assert_eq! (unsafe {
95-
& ( * ( 0 as * const cmdline_token_hdr_cmdline_token_ops ) ) .
96-
complete_get_elt as * const _ as usize } , 16usize , concat !
97-
(
98-
"Alignment of field: " , stringify ! (
99-
cmdline_token_hdr_cmdline_token_ops ) , "::" , stringify ! (
100-
complete_get_elt ) ));
110+
& ( * ( 0 as * const cmdline_token_ops ) ) . complete_get_elt
111+
as * const _ as usize } , 16usize , concat ! (
112+
"Alignment of field: " , stringify ! ( cmdline_token_ops ) ,
113+
"::" , stringify ! ( complete_get_elt ) ));
101114
assert_eq! (unsafe {
102-
& ( * ( 0 as * const cmdline_token_hdr_cmdline_token_ops ) ) .
103-
get_help as * const _ as usize } , 24usize , concat ! (
104-
"Alignment of field: " , stringify ! (
105-
cmdline_token_hdr_cmdline_token_ops ) , "::" , stringify ! (
106-
get_help ) ));
115+
& ( * ( 0 as * const cmdline_token_ops ) ) . get_help as *
116+
const _ as usize } , 24usize , concat ! (
117+
"Alignment of field: " , stringify ! ( cmdline_token_ops ) ,
118+
"::" , stringify ! ( get_help ) ));
107119
}
108-
impl Clone for cmdline_token_hdr_cmdline_token_ops {
120+
impl Clone for cmdline_token_ops {
109121
fn clone(&self) -> Self { *self }
110122
}
111-
#[test]
112-
fn bindgen_test_layout_cmdline_token_hdr() {
113-
assert_eq!(::std::mem::size_of::<cmdline_token_hdr>() , 16usize , concat !
114-
( "Size of: " , stringify ! ( cmdline_token_hdr ) ));
115-
assert_eq! (::std::mem::align_of::<cmdline_token_hdr>() , 8usize , concat
116-
! ( "Alignment of " , stringify ! ( cmdline_token_hdr ) ));
117-
assert_eq! (unsafe {
118-
& ( * ( 0 as * const cmdline_token_hdr ) ) . ops as * const _
119-
as usize } , 0usize , concat ! (
120-
"Alignment of field: " , stringify ! ( cmdline_token_hdr ) ,
121-
"::" , stringify ! ( ops ) ));
122-
assert_eq! (unsafe {
123-
& ( * ( 0 as * const cmdline_token_hdr ) ) . offset as * const
124-
_ as usize } , 8usize , concat ! (
125-
"Alignment of field: " , stringify ! ( cmdline_token_hdr ) ,
126-
"::" , stringify ! ( offset ) ));
127-
}
128-
impl Clone for cmdline_token_hdr {
129-
fn clone(&self) -> Self { *self }
130-
}
131-
pub type cmdline_parse_token_hdr_t = cmdline_token_hdr;
132123
#[repr(u32)]
133124
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
134125
pub enum cmdline_numtype {

tests/expectations/tests/layout_mbuf.rs

-3
Original file line numberDiff line numberDiff line change
@@ -490,9 +490,6 @@ impl Clone for rte_mbuf__bindgen_ty_4 {
490490
fn clone(&self) -> Self { *self }
491491
}
492492
#[repr(C)]
493-
#[derive(Debug, Copy, Clone)]
494-
pub struct rte_mbuf_rte_mempool([u8; 0]);
495-
#[repr(C)]
496493
#[derive(Debug, Copy)]
497494
pub struct rte_mbuf__bindgen_ty_5 {
498495
/**< combined for easy fetch */

tests/expectations/tests/struct_containing_forward_declared_struct.rs

+21-21
Original file line numberDiff line numberDiff line change
@@ -7,27 +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 , concat ! (
20-
"Size of: " , stringify ! ( a_b ) ));
21-
assert_eq! (::std::mem::align_of::<a_b>() , 4usize , concat ! (
22-
"Alignment of " , stringify ! ( a_b ) ));
23-
assert_eq! (unsafe {
24-
& ( * ( 0 as * const a_b ) ) . val_b as * const _ as usize } ,
25-
0usize , concat ! (
26-
"Alignment of field: " , stringify ! ( a_b ) , "::" ,
27-
stringify ! ( val_b ) ));
28-
}
29-
impl Clone for a_b {
30-
fn clone(&self) -> Self { *self }
10+
pub val_a: *mut b,
3111
}
3212
#[test]
3313
fn bindgen_test_layout_a() {
@@ -44,3 +24,23 @@ fn bindgen_test_layout_a() {
4424
impl Clone for a {
4525
fn clone(&self) -> Self { *self }
4626
}
27+
#[repr(C)]
28+
#[derive(Debug, Copy)]
29+
pub struct b {
30+
pub val_b: ::std::os::raw::c_int,
31+
}
32+
#[test]
33+
fn bindgen_test_layout_b() {
34+
assert_eq!(::std::mem::size_of::<b>() , 4usize , concat ! (
35+
"Size of: " , stringify ! ( b ) ));
36+
assert_eq! (::std::mem::align_of::<b>() , 4usize , concat ! (
37+
"Alignment of " , stringify ! ( b ) ));
38+
assert_eq! (unsafe {
39+
& ( * ( 0 as * const b ) ) . val_b as * const _ as usize } ,
40+
0usize , concat ! (
41+
"Alignment of field: " , stringify ! ( b ) , "::" , stringify
42+
! ( val_b ) ));
43+
}
44+
impl Clone for b {
45+
fn clone(&self) -> Self { *self }
46+
}

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)