Skip to content

Commit d23db77

Browse files
author
bors-servo
authored
Auto merge of rust-lang#926 - emilio:issue-888, r=fitzgen
ir: When something has a definition, return unresolved type references until we parse it. This fixes rust-lang#888
2 parents 28de37e + 8ecb50a commit d23db77

15 files changed

+250
-149
lines changed

src/ir/context.rs

+34
Original file line numberDiff line numberDiff line change
@@ -137,6 +137,14 @@ pub struct BindgenContext<'ctx> {
137137
/// Current module being traversed.
138138
current_module: ItemId,
139139

140+
/// A HashMap keyed on a type definition, and whose value is the parent id
141+
/// of the declaration.
142+
///
143+
/// This is used to handle the cases where the semantic and the lexical
144+
/// parents of the cursor differ, like when a nested class is defined
145+
/// outside of the parent class.
146+
semantic_parents: HashMap<clang::Cursor, ItemId>,
147+
140148
/// A stack with the current type declarations and types we're parsing. This
141149
/// is needed to avoid infinite recursion when parsing a type like:
142150
///
@@ -375,6 +383,7 @@ impl<'ctx> BindgenContext<'ctx> {
375383
next_item_id: ItemId(1),
376384
root_module: root_module.id(),
377385
current_module: root_module.id(),
386+
semantic_parents: Default::default(),
378387
currently_parsed_types: vec![],
379388
parsed_macros: Default::default(),
380389
replacements: Default::default(),
@@ -1187,6 +1196,31 @@ impl<'ctx> BindgenContext<'ctx> {
11871196
self.current_module
11881197
}
11891198

1199+
/// Add a semantic parent for a given type definition.
1200+
///
1201+
/// We do this from the type declaration, in order to be able to find the
1202+
/// correct type definition afterwards.
1203+
///
1204+
/// TODO(emilio): We could consider doing this only when
1205+
/// declaration.lexical_parent() != definition.lexical_parent(), but it's
1206+
/// not sure it's worth it.
1207+
pub fn add_semantic_parent(
1208+
&mut self,
1209+
definition: clang::Cursor,
1210+
parent_id: ItemId,
1211+
) {
1212+
self.semantic_parents.insert(definition, parent_id);
1213+
}
1214+
1215+
/// Returns a known semantic parent for a given definition.
1216+
pub fn known_semantic_parent(
1217+
&self,
1218+
definition: clang::Cursor
1219+
) -> Option<ItemId> {
1220+
self.semantic_parents.get(&definition).cloned()
1221+
}
1222+
1223+
11901224
/// Given a cursor pointing to the location of a template instantiation,
11911225
/// return a tuple of the form `(declaration_cursor, declaration_id,
11921226
/// num_expected_template_args)`.

src/ir/item.rs

+22-2
Original file line numberDiff line numberDiff line change
@@ -1194,11 +1194,31 @@ impl ClangItemParser for Item {
11941194
// Types are sort of special, so to avoid parsing template classes
11951195
// twice, handle them separately.
11961196
{
1197-
let applicable_cursor = cursor.definition().unwrap_or(cursor);
1197+
let definition = cursor.definition();
1198+
let applicable_cursor = definition.unwrap_or(cursor);
1199+
1200+
1201+
let relevant_parent_id = match definition {
1202+
Some(definition) => {
1203+
if definition != cursor {
1204+
ctx.add_semantic_parent(definition, relevant_parent_id);
1205+
return Ok(Item::from_ty_or_ref(
1206+
applicable_cursor.cur_type(),
1207+
cursor,
1208+
parent_id,
1209+
ctx,
1210+
));
1211+
}
1212+
parent_id.or_else(|| ctx.known_semantic_parent(definition))
1213+
.unwrap_or(ctx.current_module())
1214+
}
1215+
None => relevant_parent_id,
1216+
};
1217+
11981218
match Item::from_ty(
11991219
&applicable_cursor.cur_type(),
12001220
applicable_cursor,
1201-
parent_id,
1221+
Some(relevant_parent_id),
12021222
ctx,
12031223
) {
12041224
Ok(ty) => return Ok(ty),

tests/expectations/tests/class_nested.rs

+20-20
Original file line numberDiff line numberDiff line change
@@ -30,26 +30,6 @@ impl Clone for A_B {
3030
fn clone(&self) -> Self { *self }
3131
}
3232
#[repr(C)]
33-
#[derive(Debug, Default, Copy, Hash, PartialEq, Eq)]
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)]
5333
#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)]
5434
pub struct A_D<T> {
5535
pub foo: T,
@@ -73,6 +53,26 @@ fn bindgen_test_layout_A() {
7353
impl Clone for A {
7454
fn clone(&self) -> Self { *self }
7555
}
56+
#[repr(C)]
57+
#[derive(Debug, Default, Copy, Hash, PartialEq, Eq)]
58+
pub struct A_C {
59+
pub baz: ::std::os::raw::c_int,
60+
}
61+
#[test]
62+
fn bindgen_test_layout_A_C() {
63+
assert_eq!(::std::mem::size_of::<A_C>() , 4usize , concat ! (
64+
"Size of: " , stringify ! ( A_C ) ));
65+
assert_eq! (::std::mem::align_of::<A_C>() , 4usize , concat ! (
66+
"Alignment of " , stringify ! ( A_C ) ));
67+
assert_eq! (unsafe {
68+
& ( * ( 0 as * const A_C ) ) . baz as * const _ as usize } ,
69+
0usize , concat ! (
70+
"Alignment of field: " , stringify ! ( A_C ) , "::" ,
71+
stringify ! ( baz ) ));
72+
}
73+
impl Clone for A_C {
74+
fn clone(&self) -> Self { *self }
75+
}
7676
extern "C" {
7777
#[link_name = "var"]
7878
pub static mut var: A_B;

tests/expectations/tests/forward-inherit-struct-with-fields.rs

+7-7
Original file line numberDiff line numberDiff line change
@@ -6,20 +6,20 @@
66

77
#[repr(C)]
88
#[derive(Debug, Copy, Clone)]
9-
pub struct Rooted<T> {
10-
pub _base: js_RootedBase<T>,
9+
pub struct js_RootedBase<T> {
10+
pub foo: *mut T,
11+
pub next: *mut Rooted<T>,
1112
pub _phantom_0: ::std::marker::PhantomData<::std::cell::UnsafeCell<T>>,
1213
}
13-
impl <T> Default for Rooted<T> {
14+
impl <T> Default for js_RootedBase<T> {
1415
fn default() -> Self { unsafe { ::std::mem::zeroed() } }
1516
}
1617
#[repr(C)]
1718
#[derive(Debug, Copy, Clone)]
18-
pub struct js_RootedBase<T> {
19-
pub foo: *mut T,
20-
pub next: *mut Rooted<T>,
19+
pub struct Rooted<T> {
20+
pub _base: js_RootedBase<T>,
2121
pub _phantom_0: ::std::marker::PhantomData<::std::cell::UnsafeCell<T>>,
2222
}
23-
impl <T> Default for js_RootedBase<T> {
23+
impl <T> Default for Rooted<T> {
2424
fn default() -> Self { unsafe { ::std::mem::zeroed() } }
2525
}

tests/expectations/tests/forward-inherit-struct.rs

+5-5
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,11 @@
44
#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)]
55

66

7+
#[repr(C)]
8+
#[derive(Debug, Default, Copy, Clone)]
9+
pub struct js_RootedBase {
10+
pub _address: u8,
11+
}
712
#[repr(C)]
813
#[derive(Debug, Copy, Clone)]
914
pub struct Rooted {
@@ -12,8 +17,3 @@ pub struct Rooted {
1217
impl Default for Rooted {
1318
fn default() -> Self { unsafe { ::std::mem::zeroed() } }
1419
}
15-
#[repr(C)]
16-
#[derive(Debug, Default, Copy, Clone)]
17-
pub struct js_RootedBase {
18-
pub _address: u8,
19-
}

tests/expectations/tests/issue-372.rs

+23-23
Original file line numberDiff line numberDiff line change
@@ -10,29 +10,6 @@ pub mod root {
1010
use self::super::root;
1111
#[repr(C)]
1212
#[derive(Debug, Copy)]
13-
pub struct d {
14-
pub m: root::i,
15-
}
16-
#[test]
17-
fn bindgen_test_layout_d() {
18-
assert_eq!(::std::mem::size_of::<d>() , 24usize , concat ! (
19-
"Size of: " , stringify ! ( d ) ));
20-
assert_eq! (::std::mem::align_of::<d>() , 8usize , concat ! (
21-
"Alignment of " , stringify ! ( d ) ));
22-
assert_eq! (unsafe {
23-
& ( * ( 0 as * const d ) ) . m as * const _ as usize } ,
24-
0usize , concat ! (
25-
"Alignment of field: " , stringify ! ( d ) , "::" ,
26-
stringify ! ( m ) ));
27-
}
28-
impl Clone for d {
29-
fn clone(&self) -> Self { *self }
30-
}
31-
impl Default for d {
32-
fn default() -> Self { unsafe { ::std::mem::zeroed() } }
33-
}
34-
#[repr(C)]
35-
#[derive(Debug, Copy)]
3613
pub struct i {
3714
pub j: *mut root::i,
3815
pub k: *mut root::i,
@@ -66,6 +43,29 @@ pub mod root {
6643
impl Default for i {
6744
fn default() -> Self { unsafe { ::std::mem::zeroed() } }
6845
}
46+
#[repr(C)]
47+
#[derive(Debug, Copy)]
48+
pub struct d {
49+
pub m: root::i,
50+
}
51+
#[test]
52+
fn bindgen_test_layout_d() {
53+
assert_eq!(::std::mem::size_of::<d>() , 24usize , concat ! (
54+
"Size of: " , stringify ! ( d ) ));
55+
assert_eq! (::std::mem::align_of::<d>() , 8usize , concat ! (
56+
"Alignment of " , stringify ! ( d ) ));
57+
assert_eq! (unsafe {
58+
& ( * ( 0 as * const d ) ) . m as * const _ as usize } ,
59+
0usize , concat ! (
60+
"Alignment of field: " , stringify ! ( d ) , "::" ,
61+
stringify ! ( m ) ));
62+
}
63+
impl Clone for d {
64+
fn clone(&self) -> Self { *self }
65+
}
66+
impl Default for d {
67+
fn default() -> Self { unsafe { ::std::mem::zeroed() } }
68+
}
6969
#[repr(u32)]
7070
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
7171
pub enum n {

tests/expectations/tests/issue-584-stylo-template-analysis-panic.rs

+18-18
Original file line numberDiff line numberDiff line change
@@ -5,24 +5,6 @@
55

66
pub type RefPtr<T> = T;
77

8-
#[repr(C)]
9-
#[derive(Debug, Copy)]
10-
pub struct b {
11-
pub _base: g,
12-
}
13-
#[test]
14-
fn bindgen_test_layout_b() {
15-
assert_eq!(::std::mem::size_of::<b>() , 1usize , concat ! (
16-
"Size of: " , stringify ! ( b ) ));
17-
assert_eq! (::std::mem::align_of::<b>() , 1usize , concat ! (
18-
"Alignment of " , stringify ! ( b ) ));
19-
}
20-
impl Clone for b {
21-
fn clone(&self) -> Self { *self }
22-
}
23-
impl Default for b {
24-
fn default() -> Self { unsafe { ::std::mem::zeroed() } }
25-
}
268
#[repr(C)]
279
#[derive(Debug, Default, Copy)]
2810
pub struct A {
@@ -75,6 +57,24 @@ impl Clone for g {
7557
impl Default for g {
7658
fn default() -> Self { unsafe { ::std::mem::zeroed() } }
7759
}
60+
#[repr(C)]
61+
#[derive(Debug, Copy)]
62+
pub struct b {
63+
pub _base: g,
64+
}
65+
#[test]
66+
fn bindgen_test_layout_b() {
67+
assert_eq!(::std::mem::size_of::<b>() , 1usize , concat ! (
68+
"Size of: " , stringify ! ( b ) ));
69+
assert_eq! (::std::mem::align_of::<b>() , 1usize , concat ! (
70+
"Alignment of " , stringify ! ( b ) ));
71+
}
72+
impl Clone for b {
73+
fn clone(&self) -> Self { *self }
74+
}
75+
impl Default for b {
76+
fn default() -> Self { unsafe { ::std::mem::zeroed() } }
77+
}
7878
extern "C" {
7979
#[link_name = "_Z25Servo_Element_GetSnapshotv"]
8080
pub fn Servo_Element_GetSnapshot() -> A;
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
/* automatically generated by rust-bindgen */
2+
3+
4+
#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)]
5+
6+
7+
#[allow(non_snake_case, non_camel_case_types, non_upper_case_globals)]
8+
pub mod root {
9+
#[allow(unused_imports)]
10+
use self::super::root;
11+
pub mod Halide {
12+
#[allow(unused_imports)]
13+
use self::super::super::root;
14+
#[repr(C)]
15+
#[derive(Debug, Default, Copy)]
16+
pub struct Type {
17+
pub _address: u8,
18+
}
19+
extern "C" {
20+
#[link_name = "_ZN6Halide4Type1bE"]
21+
pub static mut Type_b: root::a;
22+
}
23+
#[test]
24+
fn bindgen_test_layout_Type() {
25+
assert_eq!(::std::mem::size_of::<Type>() , 1usize , concat ! (
26+
"Size of: " , stringify ! ( Type ) ));
27+
assert_eq! (::std::mem::align_of::<Type>() , 1usize , concat ! (
28+
"Alignment of " , stringify ! ( Type ) ));
29+
}
30+
impl Clone for Type {
31+
fn clone(&self) -> Self { *self }
32+
}
33+
}
34+
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
35+
pub enum a { }
36+
}

tests/expectations/tests/objc_class.rs

+4-4
Original file line numberDiff line numberDiff line change
@@ -9,13 +9,13 @@
99
extern crate objc;
1010
#[allow(non_camel_case_types)]
1111
pub type id = *mut objc::runtime::Object;
12+
extern "C" {
13+
#[link_name = "fooVar"]
14+
pub static mut fooVar: *mut id;
15+
}
1216
pub trait Foo {
1317
unsafe fn method(self);
1418
}
1519
impl Foo for id {
1620
unsafe fn method(self) { msg_send!(self , method) }
1721
}
18-
extern "C" {
19-
#[link_name = "fooVar"]
20-
pub static mut fooVar: *mut id;
21-
}

tests/expectations/tests/opaque-tracing.rs

+4-4
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,10 @@
44
#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)]
55

66

7+
extern "C" {
8+
#[link_name = "_Z3fooP9Container"]
9+
pub fn foo(c: *mut Container);
10+
}
711
#[repr(C)]
812
#[derive(Debug, Default, Copy, Hash, PartialEq, Eq)]
913
pub struct Container {
@@ -19,7 +23,3 @@ fn bindgen_test_layout_Container() {
1923
impl Clone for Container {
2024
fn clone(&self) -> Self { *self }
2125
}
22-
extern "C" {
23-
#[link_name = "_Z3fooP9Container"]
24-
pub fn foo(c: *mut Container);
25-
}

0 commit comments

Comments
 (0)