Skip to content

Commit bf37de9

Browse files
debuginfo: Basic support for trait objects.
1 parent 4ecb0a3 commit bf37de9

File tree

4 files changed

+96
-16
lines changed

4 files changed

+96
-16
lines changed

src/librustc/middle/trans/debuginfo.rs

Lines changed: 51 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@ use middle::trans::adt;
6060
use middle::trans;
6161
use middle::ty;
6262
use middle::pat_util;
63-
use util::ppaux::ty_to_str;
63+
use util::ppaux;
6464

6565
use std::c_str::ToCStr;
6666
use std::hashmap::HashMap;
@@ -742,7 +742,7 @@ pub fn create_function_debug_context(cx: &mut CrateContext,
742742
codemap::dummy_sp());
743743

744744
// Add self type name to <...> clause of function name
745-
let actual_self_type_name = ty_to_str(cx.tcx, actual_self_type);
745+
let actual_self_type_name = ppaux::ty_to_str(cx.tcx, actual_self_type);
746746
name_to_append_suffix_to.push_str(actual_self_type_name);
747747
if generics.is_type_parameterized() {
748748
name_to_append_suffix_to.push_str(",");
@@ -779,7 +779,7 @@ pub fn create_function_debug_context(cx: &mut CrateContext,
779779
let actual_type_metadata = type_metadata(cx, actual_type, codemap::dummy_sp());
780780

781781
// Add actual type name to <...> clause of function name
782-
let actual_type_name = ty_to_str(cx.tcx, actual_type);
782+
let actual_type_name = ppaux::ty_to_str(cx.tcx, actual_type);
783783
name_to_append_suffix_to.push_str(actual_type_name);
784784

785785
if index != generics.ty_params.len() - 1 {
@@ -1039,7 +1039,7 @@ fn pointer_type_metadata(cx: &mut CrateContext,
10391039
-> DIType {
10401040
let pointer_llvm_type = type_of::type_of(cx, pointer_type);
10411041
let (pointer_size, pointer_align) = size_and_align_of(cx, pointer_llvm_type);
1042-
let name = ty_to_str(cx.tcx, pointer_type);
1042+
let name = ppaux::ty_to_str(cx.tcx, pointer_type);
10431043
let ptr_metadata = do name.with_c_str |name| {
10441044
unsafe {
10451045
llvm::LLVMDIBuilderCreatePointerType(
@@ -1059,7 +1059,7 @@ fn struct_metadata(cx: &mut CrateContext,
10591059
substs: &ty::substs,
10601060
span: Span)
10611061
-> DICompositeType {
1062-
let struct_name = ty_to_str(cx.tcx, struct_type);
1062+
let struct_name = ppaux::ty_to_str(cx.tcx, struct_type);
10631063
debug!("struct_metadata: %s", struct_name);
10641064

10651065
let struct_llvm_type = type_of::type_of(cx, struct_type);
@@ -1098,7 +1098,7 @@ fn tuple_metadata(cx: &mut CrateContext,
10981098
component_types: &[ty::t],
10991099
span: Span)
11001100
-> DICompositeType {
1101-
let tuple_name = ty_to_str(cx.tcx, tuple_type);
1101+
let tuple_name = ppaux::ty_to_str(cx.tcx, tuple_type);
11021102
let tuple_llvm_type = type_of::type_of(cx, tuple_type);
11031103

11041104
let component_descriptions = do component_types.map |&component_type| {
@@ -1127,7 +1127,7 @@ fn enum_metadata(cx: &mut CrateContext,
11271127
enum_def_id: ast::DefId,
11281128
span: Span)
11291129
-> DIType {
1130-
let enum_name = ty_to_str(cx.tcx, enum_type);
1130+
let enum_name = ppaux::ty_to_str(cx.tcx, enum_type);
11311131

11321132
let (containing_scope, definition_span) = get_namespace_and_span_for_item(cx,
11331133
enum_def_id,
@@ -1502,7 +1502,7 @@ fn vec_metadata(cx: &mut CrateContext,
15021502
let (element_size, element_align) = size_and_align_of(cx, element_llvm_type);
15031503

15041504
let vec_llvm_type = Type::vec(cx.sess.targ_cfg.arch, &element_llvm_type);
1505-
let vec_type_name: &str = fmt!("[%s]", ty_to_str(cx.tcx, element_type));
1505+
let vec_type_name: &str = fmt!("[%s]", ppaux::ty_to_str(cx.tcx, element_type));
15061506

15071507
let member_llvm_types = vec_llvm_type.field_types();
15081508

@@ -1556,7 +1556,7 @@ fn boxed_vec_metadata(cx: &mut CrateContext,
15561556

15571557
let element_llvm_type = type_of::type_of(cx, element_type);
15581558
let vec_llvm_type = Type::vec(cx.sess.targ_cfg.arch, &element_llvm_type);
1559-
let vec_type_name: &str = fmt!("[%s]", ty_to_str(cx.tcx, element_type));
1559+
let vec_type_name: &str = fmt!("[%s]", ppaux::ty_to_str(cx.tcx, element_type));
15601560
let vec_metadata = vec_metadata(cx, element_type, span);
15611561

15621562
return boxed_type_metadata(
@@ -1576,7 +1576,7 @@ fn vec_slice_metadata(cx: &mut CrateContext,
15761576
debug!("vec_slice_metadata: %?", ty::get(vec_type));
15771577

15781578
let slice_llvm_type = type_of::type_of(cx, vec_type);
1579-
let slice_type_name = ty_to_str(cx.tcx, vec_type);
1579+
let slice_type_name = ppaux::ty_to_str(cx.tcx, vec_type);
15801580

15811581
let member_llvm_types = slice_llvm_type.field_types();
15821582
assert!(slice_layout_is_correct(cx, member_llvm_types, element_type));
@@ -1648,10 +1648,47 @@ fn subroutine_type_metadata(cx: &mut CrateContext,
16481648
};
16491649
}
16501650

1651+
fn trait_metadata(cx: &mut CrateContext,
1652+
def_id: ast::DefId,
1653+
trait_type: ty::t,
1654+
substs: &ty::substs,
1655+
trait_store: ty::TraitStore,
1656+
mutability: ast::Mutability,
1657+
builtinBounds: &ty::BuiltinBounds,
1658+
usage_site_span: Span)
1659+
-> DIType {
1660+
// The implementation provided here is a stub. It makes sure that the trait type is
1661+
// assigned the correct name, size, namespace, and source location. But it does not describe
1662+
// the trait's methods.
1663+
let path = ty::item_path(cx.tcx, def_id);
1664+
let ident = path.last().ident();
1665+
let name = ppaux::trait_store_to_str(cx.tcx, trait_store)
1666+
+ ppaux::mutability_to_str(mutability)
1667+
+ token::ident_to_str(&ident);
1668+
// Add type and region parameters
1669+
let name = ppaux::parameterized(cx.tcx, name, &substs.regions, substs.tps);
1670+
1671+
let (containing_scope,
1672+
definition_span) = get_namespace_and_span_for_item(cx, def_id, usage_site_span);
1673+
1674+
let file_name = span_start(cx, definition_span).file.name;
1675+
let file_metadata = file_metadata(cx, file_name);
1676+
1677+
let trait_llvm_type = type_of::type_of(cx, trait_type);
1678+
1679+
return composite_type_metadata(cx,
1680+
trait_llvm_type,
1681+
name,
1682+
[],
1683+
containing_scope,
1684+
file_metadata,
1685+
definition_span);
1686+
}
1687+
16511688
fn unimplemented_type_metadata(cx: &mut CrateContext, t: ty::t) -> DIType {
16521689
debug!("unimplemented_type_metadata: %?", ty::get(t));
16531690

1654-
let name = ty_to_str(cx.tcx, t);
1691+
let name = ppaux::ty_to_str(cx.tcx, t);
16551692
let metadata = do fmt!("NYI<%s>", name).with_c_str |name| {
16561693
unsafe {
16571694
llvm::LLVMDIBuilderCreateBasicType(
@@ -1681,7 +1718,7 @@ fn type_metadata(cx: &mut CrateContext,
16811718
type_in_box: ty::t)
16821719
-> DIType {
16831720

1684-
let content_type_name: &str = ty_to_str(cx.tcx, type_in_box);
1721+
let content_type_name: &str = ppaux::ty_to_str(cx.tcx, type_in_box);
16851722
let content_llvm_type = type_of::type_of(cx, type_in_box);
16861723
let content_type_metadata = type_metadata(
16871724
cx,
@@ -1773,9 +1810,8 @@ fn type_metadata(cx: &mut CrateContext,
17731810
ty::ty_closure(ref closurety) => {
17741811
subroutine_type_metadata(cx, &closurety.sig, usage_site_span)
17751812
},
1776-
ty::ty_trait(_did, ref _substs, ref _vstore, _, _bounds) => {
1777-
cx.sess.span_note(usage_site_span, "debuginfo for trait NYI");
1778-
unimplemented_type_metadata(cx, t)
1813+
ty::ty_trait(def_id, ref substs, trait_store, mutability, ref bounds) => {
1814+
trait_metadata(cx, def_id, t, substs, trait_store, mutability, bounds, usage_site_span)
17791815
},
17801816
ty::ty_struct(def_id, ref substs) => {
17811817
struct_metadata(cx, t, def_id, substs, usage_site_span)

src/librustc/util/ppaux.rs

Lines changed: 1 addition & 1 deletion
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

Lines changed: 10 additions & 0 deletions
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/test/debug-info/trait-pointers.rs

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
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:run
13+
14+
#[allow(unused_variable)];
15+
16+
trait Trait {
17+
fn method(&self) -> int { 0 }
18+
}
19+
20+
struct Struct {
21+
a: int,
22+
b: float
23+
}
24+
25+
impl Trait for Struct {}
26+
27+
fn main() {
28+
let stack_struct = Struct { a:0, b: 1.0 };
29+
let reference: &Trait = &stack_struct as &Trait;
30+
let managed: @Trait = @Struct { a:2, b: 3.0 } as @Trait;
31+
let unique: ~Trait = ~Struct { a:2, b: 3.0 } as ~Trait;
32+
}
33+
34+
fn zzz() {()}

0 commit comments

Comments
 (0)