Skip to content

Commit 29032cd

Browse files
committed
auto merge of #9168 : michaelwoerister/rust/traits, r=jdm
This pull request finally adds support for recursive type definitions and provides a stub implementation for object pointers.
2 parents c8c3c3b + 2ffe083 commit 29032cd

File tree

8 files changed

+891
-283
lines changed

8 files changed

+891
-283
lines changed

src/librustc/lib/llvm.rs

+3
Original file line numberDiff line numberDiff line change
@@ -2117,6 +2117,9 @@ pub mod llvm {
21172117
LineNo: c_uint)
21182118
-> ValueRef;
21192119

2120+
#[fast_ffi]
2121+
pub fn LLVMDICompositeTypeSetTypeArray(CompositeType: ValueRef, TypeArray: ValueRef);
2122+
21202123
#[fast_ffi]
21212124
pub fn LLVMIsAArgument(value_ref: ValueRef) -> ValueRef;
21222125

src/librustc/middle/trans/debuginfo.rs

+522-282
Large diffs are not rendered by default.

src/librustc/util/ppaux.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -235,7 +235,7 @@ pub fn region_to_str(cx: ctxt, prefix: &str, space: bool, region: Region) -> ~st
235235
}
236236
}
237237

238-
fn mutability_to_str(m: ast::Mutability) -> ~str {
238+
pub fn mutability_to_str(m: ast::Mutability) -> ~str {
239239
match m {
240240
ast::MutMutable => ~"mut ",
241241
ast::MutImmutable => ~"",

src/libsyntax/ast_map.rs

+10
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,16 @@ pub enum path_elt {
3838
path_pretty_name(Ident, u64),
3939
}
4040

41+
impl path_elt {
42+
pub fn ident(&self) -> Ident {
43+
match *self {
44+
path_mod(ident) |
45+
path_name(ident) |
46+
path_pretty_name(ident, _) => ident
47+
}
48+
}
49+
}
50+
4151
pub type path = ~[path_elt];
4252

4353
pub fn path_to_str_with_sep(p: &[path_elt], sep: &str, itr: @ident_interner)

src/rustllvm/RustWrapper.cpp

+7
Original file line numberDiff line numberDiff line change
@@ -789,3 +789,10 @@ extern "C" LLVMValueRef LLVMDIBuilderCreateNameSpace(
789789
unwrapDI<DIFile>(File),
790790
LineNo));
791791
}
792+
793+
extern "C" void LLVMDICompositeTypeSetTypeArray(
794+
LLVMValueRef CompositeType,
795+
LLVMValueRef TypeArray)
796+
{
797+
unwrapDI<DICompositeType>(CompositeType).setTypeArray(unwrapDI<DIArray>(TypeArray));
798+
}

src/rustllvm/rustllvm.def.in

+1
Original file line numberDiff line numberDiff line change
@@ -612,6 +612,7 @@ LLVMDIBuilderCreateOpDeref
612612
LLVMDIBuilderCreateOpPlus
613613
LLVMDIBuilderCreateComplexVariable
614614
LLVMDIBuilderCreateNameSpace
615+
LLVMDICompositeTypeSetTypeArray
615616
LLVMSetUnnamedAddr
616617
LLVMRustAddPass
617618
LLVMRustAddAnalysisPasses
+314
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,314 @@
1+
// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
2+
// file at the top-level directory of this distribution and at
3+
// http://rust-lang.org/COPYRIGHT.
4+
//
5+
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6+
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7+
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8+
// option. This file may not be copied, modified, or distributed
9+
// except according to those terms.
10+
11+
// compile-flags:-Z extra-debug-info
12+
// debugger:set print pretty off
13+
// debugger:rbreak zzz
14+
// debugger:run
15+
// debugger:finish
16+
17+
// debugger:print stack_unique.value
18+
// check:$1 = 0
19+
// debugger:print stack_unique.next.val->value
20+
// check:$2 = 1
21+
22+
// debugger:print unique_unique->value
23+
// check:$3 = 2
24+
// debugger:print unique_unique->next.val->value
25+
// check:$4 = 3
26+
27+
// debugger:print box_unique->val.value
28+
// check:$5 = 4
29+
// debugger:print box_unique->val.next.val->value
30+
// check:$6 = 5
31+
32+
// debugger:print vec_unique[0].value
33+
// check:$7 = 6.5
34+
// debugger:print vec_unique[0].next.val->value
35+
// check:$8 = 7.5
36+
37+
// debugger:print borrowed_unique->value
38+
// check:$9 = 8.5
39+
// debugger:print borrowed_unique->next.val->value
40+
// check:$10 = 9.5
41+
42+
// MANAGED
43+
// debugger:print stack_managed.value
44+
// check:$11 = 10
45+
// debugger:print stack_managed.next.val->val.value
46+
// check:$12 = 11
47+
48+
// debugger:print unique_managed->val.value
49+
// check:$13 = 12
50+
// debugger:print unique_managed->val.next.val->val.value
51+
// check:$14 = 13
52+
53+
// debugger:print box_managed->val.value
54+
// check:$15 = 14
55+
// debugger:print box_managed->val.next.val->val.value
56+
// check:$16 = 15
57+
58+
// debugger:print vec_managed[0].value
59+
// check:$17 = 16.5
60+
// debugger:print vec_managed[0].next.val->val.value
61+
// check:$18 = 17.5
62+
63+
// debugger:print borrowed_managed->value
64+
// check:$19 = 18.5
65+
// debugger:print borrowed_managed->next.val->val.value
66+
// check:$20 = 19.5
67+
68+
// LONG CYCLE
69+
// debugger:print long_cycle1.value
70+
// check:$21 = 20
71+
// debugger:print long_cycle1.next->value
72+
// check:$22 = 21
73+
// debugger:print long_cycle1.next->next->value
74+
// check:$23 = 22
75+
// debugger:print long_cycle1.next->next->next->value
76+
// check:$24 = 23
77+
78+
// debugger:print long_cycle2.value
79+
// check:$25 = 24
80+
// debugger:print long_cycle2.next->value
81+
// check:$26 = 25
82+
// debugger:print long_cycle2.next->next->value
83+
// check:$27 = 26
84+
85+
// debugger:print long_cycle3.value
86+
// check:$28 = 27
87+
// debugger:print long_cycle3.next->value
88+
// check:$29 = 28
89+
90+
// debugger:print long_cycle4.value
91+
// check:$30 = 29.5
92+
93+
// debugger:print (*****long_cycle_w_anonymous_types).value
94+
// check:$31 = 30
95+
96+
// debugger:print (*****((*****long_cycle_w_anonymous_types).next.val)).value
97+
// check:$32 = 31
98+
99+
// debugger:continue
100+
101+
#[allow(unused_variable)];
102+
103+
enum Opt<T> {
104+
Empty,
105+
Val { val: T }
106+
}
107+
108+
struct UniqueNode<T> {
109+
next: Opt<~UniqueNode<T>>,
110+
value: T
111+
}
112+
113+
struct ManagedNode<T> {
114+
next: Opt<@ManagedNode<T>>,
115+
value: T
116+
}
117+
118+
struct LongCycle1<T> {
119+
next: ~LongCycle2<T>,
120+
value: T,
121+
}
122+
123+
struct LongCycle2<T> {
124+
next: ~LongCycle3<T>,
125+
value: T,
126+
}
127+
128+
struct LongCycle3<T> {
129+
next: ~LongCycle4<T>,
130+
value: T,
131+
}
132+
133+
struct LongCycle4<T> {
134+
next: Option<~LongCycle1<T>>,
135+
value: T,
136+
}
137+
138+
struct LongCycleWithAnonymousTypes {
139+
next: Opt<~~~~~LongCycleWithAnonymousTypes>,
140+
value: uint,
141+
}
142+
143+
// This test case makes sure that recursive structs are properly described. The Node structs are
144+
// generic so that we can have a new type (that newly needs to be described) for the different
145+
// cases. The potential problem with recursive types is that the DI generation algorithm gets
146+
// trapped in an endless loop. To make sure, we actually test this in the different cases, we have
147+
// to operate on a new type each time, otherwise we would just hit the DI cache for all but the
148+
// first case.
149+
150+
// The different cases below (stack_*, unique_*, box_*, etc) are set up so that the type description
151+
// algorithm will enter the type reference cycle that is created by a recursive definition from a
152+
// different context each time.
153+
154+
// The "long cycle" cases are constructed to span a longer, indirect recursion cycle between types.
155+
// The different locals will cause the DI algorithm to enter the type reference cycle at different
156+
// points.
157+
158+
fn main() {
159+
let stack_unique: UniqueNode<u16> = UniqueNode {
160+
next: Val {
161+
val: ~UniqueNode {
162+
next: Empty,
163+
value: 1_u16,
164+
}
165+
},
166+
value: 0_u16,
167+
};
168+
169+
let unique_unique: ~UniqueNode<u32> = ~UniqueNode {
170+
next: Val {
171+
val: ~UniqueNode {
172+
next: Empty,
173+
value: 3,
174+
}
175+
},
176+
value: 2,
177+
};
178+
179+
let box_unique: @UniqueNode<u64> = @UniqueNode {
180+
next: Val {
181+
val: ~UniqueNode {
182+
next: Empty,
183+
value: 5,
184+
}
185+
},
186+
value: 4,
187+
};
188+
189+
let vec_unique: [UniqueNode<f32>, ..1] = [UniqueNode {
190+
next: Val {
191+
val: ~UniqueNode {
192+
next: Empty,
193+
value: 7.5,
194+
}
195+
},
196+
value: 6.5,
197+
}];
198+
199+
let borrowed_unique: &UniqueNode<f64> = &UniqueNode {
200+
next: Val {
201+
val: ~UniqueNode {
202+
next: Empty,
203+
value: 9.5,
204+
}
205+
},
206+
value: 8.5,
207+
};
208+
209+
let stack_managed: ManagedNode<u16> = ManagedNode {
210+
next: Val {
211+
val: @ManagedNode {
212+
next: Empty,
213+
value: 11,
214+
}
215+
},
216+
value: 10,
217+
};
218+
219+
let unique_managed: ~ManagedNode<u32> = ~ManagedNode {
220+
next: Val {
221+
val: @ManagedNode {
222+
next: Empty,
223+
value: 13,
224+
}
225+
},
226+
value: 12,
227+
};
228+
229+
let box_managed: @ManagedNode<u64> = @ManagedNode {
230+
next: Val {
231+
val: @ManagedNode {
232+
next: Empty,
233+
value: 15,
234+
}
235+
},
236+
value: 14,
237+
};
238+
239+
let vec_managed: [ManagedNode<f32>, ..1] = [ManagedNode {
240+
next: Val {
241+
val: @ManagedNode {
242+
next: Empty,
243+
value: 17.5,
244+
}
245+
},
246+
value: 16.5,
247+
}];
248+
249+
let borrowed_managed: &ManagedNode<f64> = &ManagedNode {
250+
next: Val {
251+
val: @ManagedNode {
252+
next: Empty,
253+
value: 19.5,
254+
}
255+
},
256+
value: 18.5,
257+
};
258+
259+
// LONG CYCLE
260+
let long_cycle1: LongCycle1<u16> = LongCycle1 {
261+
next: ~LongCycle2 {
262+
next: ~LongCycle3 {
263+
next: ~LongCycle4 {
264+
next: None,
265+
value: 23,
266+
},
267+
value: 22,
268+
},
269+
value: 21
270+
},
271+
value: 20
272+
};
273+
274+
let long_cycle2: LongCycle2<u32> = LongCycle2 {
275+
next: ~LongCycle3 {
276+
next: ~LongCycle4 {
277+
next: None,
278+
value: 26,
279+
},
280+
value: 25,
281+
},
282+
value: 24
283+
};
284+
285+
let long_cycle3: LongCycle3<u64> = LongCycle3 {
286+
next: ~LongCycle4 {
287+
next: None,
288+
value: 28,
289+
},
290+
value: 27,
291+
};
292+
293+
let long_cycle4: LongCycle4<f32> = LongCycle4 {
294+
next: None,
295+
value: 29.5,
296+
};
297+
298+
// It's important that LongCycleWithAnonymousTypes is encountered only at the end of the
299+
// `~` chain.
300+
let long_cycle_w_anonymous_types = ~~~~~LongCycleWithAnonymousTypes {
301+
next: Val {
302+
val: ~~~~~LongCycleWithAnonymousTypes {
303+
next: Empty,
304+
value: 31,
305+
}
306+
},
307+
value: 30
308+
};
309+
310+
zzz();
311+
}
312+
313+
fn zzz() {()}
314+

0 commit comments

Comments
 (0)