Skip to content

Commit 5487e44

Browse files
author
bors-servo
authored
Auto merge of #486 - emilio:unresolved-nasty-thingie, r=fitzgen
ir: Don't parse non-semantic-children cursor as inner structs. r? @fitzgen
2 parents 8264afa + 9f745ab commit 5487e44

File tree

9 files changed

+150
-103
lines changed

9 files changed

+150
-103
lines changed

src/clang.rs

+12-14
Original file line numberDiff line numberDiff line change
@@ -132,11 +132,11 @@ impl Cursor {
132132
// `clang_Cursor_getNumTemplateArguments` is totally unreliable.
133133
// Therefore, try former first, and only fallback to the latter if we
134134
// have to.
135-
self.cur_type().num_template_args()
135+
self.cur_type()
136+
.num_template_args()
136137
.or_else(|| {
137-
let n: c_int = unsafe {
138-
clang_Cursor_getNumTemplateArguments(self.x)
139-
};
138+
let n: c_int =
139+
unsafe { clang_Cursor_getNumTemplateArguments(self.x) };
140140

141141
if n >= 0 {
142142
Some(n as u32)
@@ -723,10 +723,12 @@ impl Type {
723723
/// If this type is a class template specialization, return its
724724
/// template arguments. Otherwise, return None.
725725
pub fn template_args(&self) -> Option<TypeTemplateArgIterator> {
726-
self.num_template_args().map(|n| TypeTemplateArgIterator {
727-
x: self.x,
728-
length: n,
729-
index: 0,
726+
self.num_template_args().map(|n| {
727+
TypeTemplateArgIterator {
728+
x: self.x,
729+
length: n,
730+
index: 0,
731+
}
730732
})
731733
}
732734

@@ -828,9 +830,8 @@ impl Type {
828830
// Yep, the spelling of this containing type-parameter is extremely
829831
// nasty... But can happen in <type_traits>. Unfortunately I couldn't
830832
// reduce it enough :(
831-
self.template_args().map_or(false, |args| {
832-
args.len() > 0
833-
}) && match self.declaration().kind() {
833+
self.template_args().map_or(false, |args| args.len() > 0) &&
834+
match self.declaration().kind() {
834835
CXCursor_ClassTemplatePartialSpecialization |
835836
CXCursor_TypeAliasTemplateDecl |
836837
CXCursor_TemplateTemplateParameter => false,
@@ -1392,7 +1393,6 @@ pub fn ast_dump(c: &Cursor, depth: isize) -> CXChildVisitResult {
13921393
print_cursor(depth,
13931394
String::from(prefix) + "referenced.",
13941395
&refd);
1395-
print_cursor(depth, String::from(prefix) + "referenced.", &refd);
13961396
}
13971397
}
13981398

@@ -1402,7 +1402,6 @@ pub fn ast_dump(c: &Cursor, depth: isize) -> CXChildVisitResult {
14021402
print_cursor(depth,
14031403
String::from(prefix) + "canonical.",
14041404
&canonical);
1405-
print_cursor(depth, String::from(prefix) + "canonical.", &canonical);
14061405
}
14071406

14081407
if let Some(specialized) = c.specialized() {
@@ -1411,7 +1410,6 @@ pub fn ast_dump(c: &Cursor, depth: isize) -> CXChildVisitResult {
14111410
print_cursor(depth,
14121411
String::from(prefix) + "specialized.",
14131412
&specialized);
1414-
print_cursor(depth, String::from(prefix) + "specialized.", &specialized);
14151413
}
14161414
}
14171415
}

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
@@ -676,11 +676,20 @@ impl CompInfo {
676676
CXCursor_UnionDecl |
677677
CXCursor_ClassTemplate |
678678
CXCursor_ClassDecl => {
679+
// We can find non-semantic children here, clang uses a
680+
// StructDecl to note incomplete structs that hasn't been
681+
// forward-declared before, see:
682+
//
683+
// https://github.com/servo/rust-bindgen/issues/482
684+
if cur.semantic_parent() != cursor {
685+
return CXChildVisit_Continue;
686+
}
687+
679688
let inner = Item::parse(cur, Some(potential_id), ctx)
680689
.expect("Inner ClassDecl");
681-
if !ci.inner_types.contains(&inner) {
682-
ci.inner_types.push(inner);
683-
}
690+
691+
ci.inner_types.push(inner);
692+
684693
// A declaration of an union or a struct without name could
685694
// also be an unnamed field, unfortunately.
686695
if cur.spelling().is_empty() &&

tests/expectations/tests/class_nested.rs

+43
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,34 @@ 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, Default, 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+
}
57+
impl <T> Default for A_D<T> {
58+
fn default() -> Self { unsafe { ::std::mem::zeroed() } }
59+
}
3260
#[test]
3361
fn bindgen_test_layout_A() {
3462
assert_eq!(::std::mem::size_of::<A>() , 4usize , concat ! (
@@ -48,6 +76,21 @@ extern "C" {
4876
#[link_name = "var"]
4977
pub static mut var: A_B;
5078
}
79+
#[test]
80+
fn __bindgen_test_layout_template_1() {
81+
assert_eq!(::std::mem::size_of::<A_D<::std::os::raw::c_int>>() , 4usize ,
82+
concat ! (
83+
"Size of template specialization: " , stringify ! (
84+
A_D<::std::os::raw::c_int> ) ));
85+
assert_eq!(::std::mem::align_of::<A_D<::std::os::raw::c_int>>() , 4usize ,
86+
concat ! (
87+
"Alignment of template specialization: " , stringify ! (
88+
A_D<::std::os::raw::c_int> ) ));
89+
}
90+
extern "C" {
91+
#[link_name = "baz"]
92+
pub static mut baz: A_D<::std::os::raw::c_int>;
93+
}
5194
#[repr(C)]
5295
#[derive(Debug, Default, Copy)]
5396
pub struct D {

tests/expectations/tests/layout_array.rs

-3
Original file line numberDiff line numberDiff line change
@@ -202,9 +202,6 @@ pub struct malloc_heap {
202202
pub struct malloc_heap__bindgen_ty_1 {
203203
pub lh_first: *mut malloc_heap__bindgen_ty_1_malloc_elem,
204204
}
205-
#[repr(C)]
206-
#[derive(Debug, Copy, Clone)]
207-
pub struct malloc_heap__bindgen_ty_1_malloc_elem([u8; 0]);
208205
#[test]
209206
fn bindgen_test_layout_malloc_heap__bindgen_ty_1() {
210207
assert_eq!(::std::mem::size_of::<malloc_heap__bindgen_ty_1>() , 8usize ,

tests/expectations/tests/layout_cmdline_token.rs

+49-58
Original file line numberDiff line numberDiff line change
@@ -11,9 +11,33 @@
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+
impl Default for cmdline_token_hdr {
38+
fn default() -> Self { unsafe { ::std::mem::zeroed() } }
39+
}
40+
pub type cmdline_parse_token_hdr_t = cmdline_token_hdr;
1741
/**
1842
* A token is defined by this structure.
1943
*
@@ -35,7 +59,7 @@ pub struct cmdline_token_hdr {
3559
*/
3660
#[repr(C)]
3761
#[derive(Debug, Copy)]
38-
pub struct cmdline_token_hdr_cmdline_token_ops {
62+
pub struct cmdline_token_ops {
3963
/** parse(token ptr, buf, res pts, buf len) */
4064
pub parse: ::std::option::Option<unsafe extern "C" fn(arg1:
4165
*mut cmdline_parse_token_hdr_t,
@@ -70,71 +94,38 @@ pub struct cmdline_token_hdr_cmdline_token_ops {
7094
-> ::std::os::raw::c_int>,
7195
}
7296
#[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 ) ));
97+
fn bindgen_test_layout_cmdline_token_ops() {
98+
assert_eq!(::std::mem::size_of::<cmdline_token_ops>() , 32usize , concat !
99+
( "Size of: " , stringify ! ( cmdline_token_ops ) ));
100+
assert_eq! (::std::mem::align_of::<cmdline_token_ops>() , 8usize , concat
101+
! ( "Alignment of " , stringify ! ( cmdline_token_ops ) ));
82102
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 ) ));
103+
& ( * ( 0 as * const cmdline_token_ops ) ) . parse as * const
104+
_ as usize } , 0usize , concat ! (
105+
"Alignment of field: " , stringify ! ( cmdline_token_ops ) ,
106+
"::" , stringify ! ( parse ) ));
88107
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 ) ));
108+
& ( * ( 0 as * const cmdline_token_ops ) ) . complete_get_nb
109+
as * const _ as usize } , 8usize , concat ! (
110+
"Alignment of field: " , stringify ! ( cmdline_token_ops ) ,
111+
"::" , stringify ! ( complete_get_nb ) ));
94112
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 ) ));
113+
& ( * ( 0 as * const cmdline_token_ops ) ) . complete_get_elt
114+
as * const _ as usize } , 16usize , concat ! (
115+
"Alignment of field: " , stringify ! ( cmdline_token_ops ) ,
116+
"::" , stringify ! ( complete_get_elt ) ));
101117
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 ) ));
118+
& ( * ( 0 as * const cmdline_token_ops ) ) . get_help as *
119+
const _ as usize } , 24usize , concat ! (
120+
"Alignment of field: " , stringify ! ( cmdline_token_ops ) ,
121+
"::" , stringify ! ( get_help ) ));
107122
}
108-
impl Clone for cmdline_token_hdr_cmdline_token_ops {
123+
impl Clone for cmdline_token_ops {
109124
fn clone(&self) -> Self { *self }
110125
}
111-
impl Default for cmdline_token_hdr_cmdline_token_ops {
126+
impl Default for cmdline_token_ops {
112127
fn default() -> Self { unsafe { ::std::mem::zeroed() } }
113128
}
114-
#[test]
115-
fn bindgen_test_layout_cmdline_token_hdr() {
116-
assert_eq!(::std::mem::size_of::<cmdline_token_hdr>() , 16usize , concat !
117-
( "Size of: " , stringify ! ( cmdline_token_hdr ) ));
118-
assert_eq! (::std::mem::align_of::<cmdline_token_hdr>() , 8usize , concat
119-
! ( "Alignment of " , stringify ! ( cmdline_token_hdr ) ));
120-
assert_eq! (unsafe {
121-
& ( * ( 0 as * const cmdline_token_hdr ) ) . ops as * const _
122-
as usize } , 0usize , concat ! (
123-
"Alignment of field: " , stringify ! ( cmdline_token_hdr ) ,
124-
"::" , stringify ! ( ops ) ));
125-
assert_eq! (unsafe {
126-
& ( * ( 0 as * const cmdline_token_hdr ) ) . offset as * const
127-
_ as usize } , 8usize , concat ! (
128-
"Alignment of field: " , stringify ! ( cmdline_token_hdr ) ,
129-
"::" , stringify ! ( offset ) ));
130-
}
131-
impl Clone for cmdline_token_hdr {
132-
fn clone(&self) -> Self { *self }
133-
}
134-
impl Default for cmdline_token_hdr {
135-
fn default() -> Self { unsafe { ::std::mem::zeroed() } }
136-
}
137-
pub type cmdline_parse_token_hdr_t = cmdline_token_hdr;
138129
#[repr(u32)]
139130
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
140131
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, Default, 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, Default, 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() {
@@ -47,3 +27,23 @@ impl Clone for a {
4727
impl Default for a {
4828
fn default() -> Self { unsafe { ::std::mem::zeroed() } }
4929
}
30+
#[repr(C)]
31+
#[derive(Debug, Default, Copy)]
32+
pub struct b {
33+
pub val_b: ::std::os::raw::c_int,
34+
}
35+
#[test]
36+
fn bindgen_test_layout_b() {
37+
assert_eq!(::std::mem::size_of::<b>() , 4usize , concat ! (
38+
"Size of: " , stringify ! ( b ) ));
39+
assert_eq! (::std::mem::align_of::<b>() , 4usize , concat ! (
40+
"Alignment of " , stringify ! ( b ) ));
41+
assert_eq! (unsafe {
42+
& ( * ( 0 as * const b ) ) . val_b as * const _ as usize } ,
43+
0usize , concat ! (
44+
"Alignment of field: " , stringify ! ( b ) , "::" , stringify
45+
! ( val_b ) ));
46+
}
47+
impl Clone for b {
48+
fn clone(&self) -> Self { *self }
49+
}

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)