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.
This commit is contained in:
commit
29032cda8c
|
@ -2117,6 +2117,9 @@ pub mod llvm {
|
|||
LineNo: c_uint)
|
||||
-> ValueRef;
|
||||
|
||||
#[fast_ffi]
|
||||
pub fn LLVMDICompositeTypeSetTypeArray(CompositeType: ValueRef, TypeArray: ValueRef);
|
||||
|
||||
#[fast_ffi]
|
||||
pub fn LLVMIsAArgument(value_ref: ValueRef) -> ValueRef;
|
||||
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -235,7 +235,7 @@ pub fn region_to_str(cx: ctxt, prefix: &str, space: bool, region: Region) -> ~st
|
|||
}
|
||||
}
|
||||
|
||||
fn mutability_to_str(m: ast::Mutability) -> ~str {
|
||||
pub fn mutability_to_str(m: ast::Mutability) -> ~str {
|
||||
match m {
|
||||
ast::MutMutable => ~"mut ",
|
||||
ast::MutImmutable => ~"",
|
||||
|
|
|
@ -38,6 +38,16 @@ pub enum path_elt {
|
|||
path_pretty_name(Ident, u64),
|
||||
}
|
||||
|
||||
impl path_elt {
|
||||
pub fn ident(&self) -> Ident {
|
||||
match *self {
|
||||
path_mod(ident) |
|
||||
path_name(ident) |
|
||||
path_pretty_name(ident, _) => ident
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub type path = ~[path_elt];
|
||||
|
||||
pub fn path_to_str_with_sep(p: &[path_elt], sep: &str, itr: @ident_interner)
|
||||
|
|
|
@ -789,3 +789,10 @@ extern "C" LLVMValueRef LLVMDIBuilderCreateNameSpace(
|
|||
unwrapDI<DIFile>(File),
|
||||
LineNo));
|
||||
}
|
||||
|
||||
extern "C" void LLVMDICompositeTypeSetTypeArray(
|
||||
LLVMValueRef CompositeType,
|
||||
LLVMValueRef TypeArray)
|
||||
{
|
||||
unwrapDI<DICompositeType>(CompositeType).setTypeArray(unwrapDI<DIArray>(TypeArray));
|
||||
}
|
||||
|
|
|
@ -612,6 +612,7 @@ LLVMDIBuilderCreateOpDeref
|
|||
LLVMDIBuilderCreateOpPlus
|
||||
LLVMDIBuilderCreateComplexVariable
|
||||
LLVMDIBuilderCreateNameSpace
|
||||
LLVMDICompositeTypeSetTypeArray
|
||||
LLVMSetUnnamedAddr
|
||||
LLVMRustAddPass
|
||||
LLVMRustAddAnalysisPasses
|
||||
|
|
|
@ -0,0 +1,314 @@
|
|||
// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
|
||||
// file at the top-level directory of this distribution and at
|
||||
// http://rust-lang.org/COPYRIGHT.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
// compile-flags:-Z extra-debug-info
|
||||
// debugger:set print pretty off
|
||||
// debugger:rbreak zzz
|
||||
// debugger:run
|
||||
// debugger:finish
|
||||
|
||||
// debugger:print stack_unique.value
|
||||
// check:$1 = 0
|
||||
// debugger:print stack_unique.next.val->value
|
||||
// check:$2 = 1
|
||||
|
||||
// debugger:print unique_unique->value
|
||||
// check:$3 = 2
|
||||
// debugger:print unique_unique->next.val->value
|
||||
// check:$4 = 3
|
||||
|
||||
// debugger:print box_unique->val.value
|
||||
// check:$5 = 4
|
||||
// debugger:print box_unique->val.next.val->value
|
||||
// check:$6 = 5
|
||||
|
||||
// debugger:print vec_unique[0].value
|
||||
// check:$7 = 6.5
|
||||
// debugger:print vec_unique[0].next.val->value
|
||||
// check:$8 = 7.5
|
||||
|
||||
// debugger:print borrowed_unique->value
|
||||
// check:$9 = 8.5
|
||||
// debugger:print borrowed_unique->next.val->value
|
||||
// check:$10 = 9.5
|
||||
|
||||
// MANAGED
|
||||
// debugger:print stack_managed.value
|
||||
// check:$11 = 10
|
||||
// debugger:print stack_managed.next.val->val.value
|
||||
// check:$12 = 11
|
||||
|
||||
// debugger:print unique_managed->val.value
|
||||
// check:$13 = 12
|
||||
// debugger:print unique_managed->val.next.val->val.value
|
||||
// check:$14 = 13
|
||||
|
||||
// debugger:print box_managed->val.value
|
||||
// check:$15 = 14
|
||||
// debugger:print box_managed->val.next.val->val.value
|
||||
// check:$16 = 15
|
||||
|
||||
// debugger:print vec_managed[0].value
|
||||
// check:$17 = 16.5
|
||||
// debugger:print vec_managed[0].next.val->val.value
|
||||
// check:$18 = 17.5
|
||||
|
||||
// debugger:print borrowed_managed->value
|
||||
// check:$19 = 18.5
|
||||
// debugger:print borrowed_managed->next.val->val.value
|
||||
// check:$20 = 19.5
|
||||
|
||||
// LONG CYCLE
|
||||
// debugger:print long_cycle1.value
|
||||
// check:$21 = 20
|
||||
// debugger:print long_cycle1.next->value
|
||||
// check:$22 = 21
|
||||
// debugger:print long_cycle1.next->next->value
|
||||
// check:$23 = 22
|
||||
// debugger:print long_cycle1.next->next->next->value
|
||||
// check:$24 = 23
|
||||
|
||||
// debugger:print long_cycle2.value
|
||||
// check:$25 = 24
|
||||
// debugger:print long_cycle2.next->value
|
||||
// check:$26 = 25
|
||||
// debugger:print long_cycle2.next->next->value
|
||||
// check:$27 = 26
|
||||
|
||||
// debugger:print long_cycle3.value
|
||||
// check:$28 = 27
|
||||
// debugger:print long_cycle3.next->value
|
||||
// check:$29 = 28
|
||||
|
||||
// debugger:print long_cycle4.value
|
||||
// check:$30 = 29.5
|
||||
|
||||
// debugger:print (*****long_cycle_w_anonymous_types).value
|
||||
// check:$31 = 30
|
||||
|
||||
// debugger:print (*****((*****long_cycle_w_anonymous_types).next.val)).value
|
||||
// check:$32 = 31
|
||||
|
||||
// debugger:continue
|
||||
|
||||
#[allow(unused_variable)];
|
||||
|
||||
enum Opt<T> {
|
||||
Empty,
|
||||
Val { val: T }
|
||||
}
|
||||
|
||||
struct UniqueNode<T> {
|
||||
next: Opt<~UniqueNode<T>>,
|
||||
value: T
|
||||
}
|
||||
|
||||
struct ManagedNode<T> {
|
||||
next: Opt<@ManagedNode<T>>,
|
||||
value: T
|
||||
}
|
||||
|
||||
struct LongCycle1<T> {
|
||||
next: ~LongCycle2<T>,
|
||||
value: T,
|
||||
}
|
||||
|
||||
struct LongCycle2<T> {
|
||||
next: ~LongCycle3<T>,
|
||||
value: T,
|
||||
}
|
||||
|
||||
struct LongCycle3<T> {
|
||||
next: ~LongCycle4<T>,
|
||||
value: T,
|
||||
}
|
||||
|
||||
struct LongCycle4<T> {
|
||||
next: Option<~LongCycle1<T>>,
|
||||
value: T,
|
||||
}
|
||||
|
||||
struct LongCycleWithAnonymousTypes {
|
||||
next: Opt<~~~~~LongCycleWithAnonymousTypes>,
|
||||
value: uint,
|
||||
}
|
||||
|
||||
// This test case makes sure that recursive structs are properly described. The Node structs are
|
||||
// generic so that we can have a new type (that newly needs to be described) for the different
|
||||
// cases. The potential problem with recursive types is that the DI generation algorithm gets
|
||||
// trapped in an endless loop. To make sure, we actually test this in the different cases, we have
|
||||
// to operate on a new type each time, otherwise we would just hit the DI cache for all but the
|
||||
// first case.
|
||||
|
||||
// The different cases below (stack_*, unique_*, box_*, etc) are set up so that the type description
|
||||
// algorithm will enter the type reference cycle that is created by a recursive definition from a
|
||||
// different context each time.
|
||||
|
||||
// The "long cycle" cases are constructed to span a longer, indirect recursion cycle between types.
|
||||
// The different locals will cause the DI algorithm to enter the type reference cycle at different
|
||||
// points.
|
||||
|
||||
fn main() {
|
||||
let stack_unique: UniqueNode<u16> = UniqueNode {
|
||||
next: Val {
|
||||
val: ~UniqueNode {
|
||||
next: Empty,
|
||||
value: 1_u16,
|
||||
}
|
||||
},
|
||||
value: 0_u16,
|
||||
};
|
||||
|
||||
let unique_unique: ~UniqueNode<u32> = ~UniqueNode {
|
||||
next: Val {
|
||||
val: ~UniqueNode {
|
||||
next: Empty,
|
||||
value: 3,
|
||||
}
|
||||
},
|
||||
value: 2,
|
||||
};
|
||||
|
||||
let box_unique: @UniqueNode<u64> = @UniqueNode {
|
||||
next: Val {
|
||||
val: ~UniqueNode {
|
||||
next: Empty,
|
||||
value: 5,
|
||||
}
|
||||
},
|
||||
value: 4,
|
||||
};
|
||||
|
||||
let vec_unique: [UniqueNode<f32>, ..1] = [UniqueNode {
|
||||
next: Val {
|
||||
val: ~UniqueNode {
|
||||
next: Empty,
|
||||
value: 7.5,
|
||||
}
|
||||
},
|
||||
value: 6.5,
|
||||
}];
|
||||
|
||||
let borrowed_unique: &UniqueNode<f64> = &UniqueNode {
|
||||
next: Val {
|
||||
val: ~UniqueNode {
|
||||
next: Empty,
|
||||
value: 9.5,
|
||||
}
|
||||
},
|
||||
value: 8.5,
|
||||
};
|
||||
|
||||
let stack_managed: ManagedNode<u16> = ManagedNode {
|
||||
next: Val {
|
||||
val: @ManagedNode {
|
||||
next: Empty,
|
||||
value: 11,
|
||||
}
|
||||
},
|
||||
value: 10,
|
||||
};
|
||||
|
||||
let unique_managed: ~ManagedNode<u32> = ~ManagedNode {
|
||||
next: Val {
|
||||
val: @ManagedNode {
|
||||
next: Empty,
|
||||
value: 13,
|
||||
}
|
||||
},
|
||||
value: 12,
|
||||
};
|
||||
|
||||
let box_managed: @ManagedNode<u64> = @ManagedNode {
|
||||
next: Val {
|
||||
val: @ManagedNode {
|
||||
next: Empty,
|
||||
value: 15,
|
||||
}
|
||||
},
|
||||
value: 14,
|
||||
};
|
||||
|
||||
let vec_managed: [ManagedNode<f32>, ..1] = [ManagedNode {
|
||||
next: Val {
|
||||
val: @ManagedNode {
|
||||
next: Empty,
|
||||
value: 17.5,
|
||||
}
|
||||
},
|
||||
value: 16.5,
|
||||
}];
|
||||
|
||||
let borrowed_managed: &ManagedNode<f64> = &ManagedNode {
|
||||
next: Val {
|
||||
val: @ManagedNode {
|
||||
next: Empty,
|
||||
value: 19.5,
|
||||
}
|
||||
},
|
||||
value: 18.5,
|
||||
};
|
||||
|
||||
// LONG CYCLE
|
||||
let long_cycle1: LongCycle1<u16> = LongCycle1 {
|
||||
next: ~LongCycle2 {
|
||||
next: ~LongCycle3 {
|
||||
next: ~LongCycle4 {
|
||||
next: None,
|
||||
value: 23,
|
||||
},
|
||||
value: 22,
|
||||
},
|
||||
value: 21
|
||||
},
|
||||
value: 20
|
||||
};
|
||||
|
||||
let long_cycle2: LongCycle2<u32> = LongCycle2 {
|
||||
next: ~LongCycle3 {
|
||||
next: ~LongCycle4 {
|
||||
next: None,
|
||||
value: 26,
|
||||
},
|
||||
value: 25,
|
||||
},
|
||||
value: 24
|
||||
};
|
||||
|
||||
let long_cycle3: LongCycle3<u64> = LongCycle3 {
|
||||
next: ~LongCycle4 {
|
||||
next: None,
|
||||
value: 28,
|
||||
},
|
||||
value: 27,
|
||||
};
|
||||
|
||||
let long_cycle4: LongCycle4<f32> = LongCycle4 {
|
||||
next: None,
|
||||
value: 29.5,
|
||||
};
|
||||
|
||||
// It's important that LongCycleWithAnonymousTypes is encountered only at the end of the
|
||||
// `~` chain.
|
||||
let long_cycle_w_anonymous_types = ~~~~~LongCycleWithAnonymousTypes {
|
||||
next: Val {
|
||||
val: ~~~~~LongCycleWithAnonymousTypes {
|
||||
next: Empty,
|
||||
value: 31,
|
||||
}
|
||||
},
|
||||
value: 30
|
||||
};
|
||||
|
||||
zzz();
|
||||
}
|
||||
|
||||
fn zzz() {()}
|
||||
|
|
@ -0,0 +1,33 @@
|
|||
// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
|
||||
// file at the top-level directory of this distribution and at
|
||||
// http://rust-lang.org/COPYRIGHT.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
// compile-flags:-Z extra-debug-info
|
||||
// debugger:run
|
||||
|
||||
#[allow(unused_variable)];
|
||||
|
||||
trait Trait {
|
||||
fn method(&self) -> int { 0 }
|
||||
}
|
||||
|
||||
struct Struct {
|
||||
a: int,
|
||||
b: float
|
||||
}
|
||||
|
||||
impl Trait for Struct {}
|
||||
|
||||
// There is no real test here yet. Just make sure that it compiles without crashing.
|
||||
fn main() {
|
||||
let stack_struct = Struct { a:0, b: 1.0 };
|
||||
let reference: &Trait = &stack_struct as &Trait;
|
||||
let managed: @Trait = @Struct { a:2, b: 3.0 } as @Trait;
|
||||
let unique: ~Trait = ~Struct { a:2, b: 3.0 } as ~Trait;
|
||||
}
|
Loading…
Reference in New Issue