Skip to content

Commit 5b74655

Browse files
author
bors-servo
authored
Auto merge of #641 - emilio:anon-struct-typedef, r=fitzgen
ir: Ensure we check for typedefs of anonymous structs at the right time. They appear later in the clang AST, so we need to check for them as a special-case before flushing the new field.
2 parents 65f672c + bcf1ba3 commit 5b74655

File tree

3 files changed

+110
-5
lines changed

3 files changed

+110
-5
lines changed

src/ir/comp.rs

Lines changed: 14 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -500,11 +500,19 @@ impl CompInfo {
500500
let mut maybe_anonymous_struct_field = None;
501501
cursor.visit(|cur| {
502502
if cur.kind() != CXCursor_FieldDecl {
503-
if let Some((ty, _, offset)) =
503+
if let Some((ty, clang_ty, offset)) =
504504
maybe_anonymous_struct_field.take() {
505-
let field =
506-
Field::new(None, ty, None, None, None, false, offset);
507-
ci.fields.push(field);
505+
if cur.kind() == CXCursor_TypedefDecl &&
506+
cur.typedef_type().unwrap().canonical_type() == clang_ty {
507+
// Typedefs of anonymous structs appear later in the ast
508+
// than the struct itself, that would otherwise be an
509+
// anonymous field. Detect that case here, and do
510+
// nothing.
511+
} else {
512+
let field =
513+
Field::new(None, ty, None, None, None, false, offset);
514+
ci.fields.push(field);
515+
}
508516
}
509517
}
510518

@@ -737,7 +745,8 @@ impl CompInfo {
737745
});
738746

739747
if let Some((ty, _, offset)) = maybe_anonymous_struct_field {
740-
let field = Field::new(None, ty, None, None, None, false, offset);
748+
let field =
749+
Field::new(None, ty, None, None, None, false, offset);
741750
ci.fields.push(field);
742751
}
743752

Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
/* automatically generated by rust-bindgen */
2+
3+
4+
#![allow(non_snake_case)]
5+
6+
7+
#[repr(C)]
8+
#[derive(Debug, Default, Copy)]
9+
pub struct Foo {
10+
pub bar: Foo_Bar,
11+
}
12+
#[repr(C)]
13+
#[derive(Debug, Default, Copy)]
14+
pub struct Foo_Bar {
15+
pub abc: ::std::os::raw::c_int,
16+
}
17+
#[test]
18+
fn bindgen_test_layout_Foo_Bar() {
19+
assert_eq!(::std::mem::size_of::<Foo_Bar>() , 4usize , concat ! (
20+
"Size of: " , stringify ! ( Foo_Bar ) ));
21+
assert_eq! (::std::mem::align_of::<Foo_Bar>() , 4usize , concat ! (
22+
"Alignment of " , stringify ! ( Foo_Bar ) ));
23+
assert_eq! (unsafe {
24+
& ( * ( 0 as * const Foo_Bar ) ) . abc as * const _ as usize }
25+
, 0usize , concat ! (
26+
"Alignment of field: " , stringify ! ( Foo_Bar ) , "::" ,
27+
stringify ! ( abc ) ));
28+
}
29+
impl Clone for Foo_Bar {
30+
fn clone(&self) -> Self { *self }
31+
}
32+
#[test]
33+
fn bindgen_test_layout_Foo() {
34+
assert_eq!(::std::mem::size_of::<Foo>() , 4usize , concat ! (
35+
"Size of: " , stringify ! ( Foo ) ));
36+
assert_eq! (::std::mem::align_of::<Foo>() , 4usize , concat ! (
37+
"Alignment of " , stringify ! ( Foo ) ));
38+
assert_eq! (unsafe {
39+
& ( * ( 0 as * const Foo ) ) . bar as * const _ as usize } ,
40+
0usize , concat ! (
41+
"Alignment of field: " , stringify ! ( Foo ) , "::" ,
42+
stringify ! ( bar ) ));
43+
}
44+
impl Clone for Foo {
45+
fn clone(&self) -> Self { *self }
46+
}
47+
#[repr(C)]
48+
#[derive(Debug, Default, Copy)]
49+
pub struct Baz {
50+
pub _address: u8,
51+
}
52+
#[repr(C)]
53+
#[derive(Debug, Default, Copy)]
54+
pub struct Baz_Bar {
55+
pub abc: ::std::os::raw::c_int,
56+
}
57+
#[test]
58+
fn bindgen_test_layout_Baz_Bar() {
59+
assert_eq!(::std::mem::size_of::<Baz_Bar>() , 4usize , concat ! (
60+
"Size of: " , stringify ! ( Baz_Bar ) ));
61+
assert_eq! (::std::mem::align_of::<Baz_Bar>() , 4usize , concat ! (
62+
"Alignment of " , stringify ! ( Baz_Bar ) ));
63+
assert_eq! (unsafe {
64+
& ( * ( 0 as * const Baz_Bar ) ) . abc as * const _ as usize }
65+
, 0usize , concat ! (
66+
"Alignment of field: " , stringify ! ( Baz_Bar ) , "::" ,
67+
stringify ! ( abc ) ));
68+
}
69+
impl Clone for Baz_Bar {
70+
fn clone(&self) -> Self { *self }
71+
}
72+
#[test]
73+
fn bindgen_test_layout_Baz() {
74+
assert_eq!(::std::mem::size_of::<Baz>() , 1usize , concat ! (
75+
"Size of: " , stringify ! ( Baz ) ));
76+
assert_eq! (::std::mem::align_of::<Baz>() , 1usize , concat ! (
77+
"Alignment of " , stringify ! ( Baz ) ));
78+
}
79+
impl Clone for Baz {
80+
fn clone(&self) -> Self { *self }
81+
}
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
class Foo {
2+
public:
3+
typedef struct {
4+
int abc;
5+
} Bar;
6+
7+
Bar bar;
8+
};
9+
10+
class Baz {
11+
public:
12+
typedef struct {
13+
int abc;
14+
} Bar;
15+
};

0 commit comments

Comments
 (0)