debuginfo: Basic support for trait objects.
This commit is contained in:
parent
4ecb0a372d
commit
bf37de9fc6
4 changed files with 96 additions and 16 deletions
|
@ -60,7 +60,7 @@ use middle::trans::adt;
|
|||
use middle::trans;
|
||||
use middle::ty;
|
||||
use middle::pat_util;
|
||||
use util::ppaux::ty_to_str;
|
||||
use util::ppaux;
|
||||
|
||||
use std::c_str::ToCStr;
|
||||
use std::hashmap::HashMap;
|
||||
|
@ -742,7 +742,7 @@ pub fn create_function_debug_context(cx: &mut CrateContext,
|
|||
codemap::dummy_sp());
|
||||
|
||||
// Add self type name to <...> clause of function name
|
||||
let actual_self_type_name = ty_to_str(cx.tcx, actual_self_type);
|
||||
let actual_self_type_name = ppaux::ty_to_str(cx.tcx, actual_self_type);
|
||||
name_to_append_suffix_to.push_str(actual_self_type_name);
|
||||
if generics.is_type_parameterized() {
|
||||
name_to_append_suffix_to.push_str(",");
|
||||
|
@ -779,7 +779,7 @@ pub fn create_function_debug_context(cx: &mut CrateContext,
|
|||
let actual_type_metadata = type_metadata(cx, actual_type, codemap::dummy_sp());
|
||||
|
||||
// Add actual type name to <...> clause of function name
|
||||
let actual_type_name = ty_to_str(cx.tcx, actual_type);
|
||||
let actual_type_name = ppaux::ty_to_str(cx.tcx, actual_type);
|
||||
name_to_append_suffix_to.push_str(actual_type_name);
|
||||
|
||||
if index != generics.ty_params.len() - 1 {
|
||||
|
@ -1039,7 +1039,7 @@ fn pointer_type_metadata(cx: &mut CrateContext,
|
|||
-> DIType {
|
||||
let pointer_llvm_type = type_of::type_of(cx, pointer_type);
|
||||
let (pointer_size, pointer_align) = size_and_align_of(cx, pointer_llvm_type);
|
||||
let name = ty_to_str(cx.tcx, pointer_type);
|
||||
let name = ppaux::ty_to_str(cx.tcx, pointer_type);
|
||||
let ptr_metadata = do name.with_c_str |name| {
|
||||
unsafe {
|
||||
llvm::LLVMDIBuilderCreatePointerType(
|
||||
|
@ -1059,7 +1059,7 @@ fn struct_metadata(cx: &mut CrateContext,
|
|||
substs: &ty::substs,
|
||||
span: Span)
|
||||
-> DICompositeType {
|
||||
let struct_name = ty_to_str(cx.tcx, struct_type);
|
||||
let struct_name = ppaux::ty_to_str(cx.tcx, struct_type);
|
||||
debug!("struct_metadata: %s", struct_name);
|
||||
|
||||
let struct_llvm_type = type_of::type_of(cx, struct_type);
|
||||
|
@ -1098,7 +1098,7 @@ fn tuple_metadata(cx: &mut CrateContext,
|
|||
component_types: &[ty::t],
|
||||
span: Span)
|
||||
-> DICompositeType {
|
||||
let tuple_name = ty_to_str(cx.tcx, tuple_type);
|
||||
let tuple_name = ppaux::ty_to_str(cx.tcx, tuple_type);
|
||||
let tuple_llvm_type = type_of::type_of(cx, tuple_type);
|
||||
|
||||
let component_descriptions = do component_types.map |&component_type| {
|
||||
|
@ -1127,7 +1127,7 @@ fn enum_metadata(cx: &mut CrateContext,
|
|||
enum_def_id: ast::DefId,
|
||||
span: Span)
|
||||
-> DIType {
|
||||
let enum_name = ty_to_str(cx.tcx, enum_type);
|
||||
let enum_name = ppaux::ty_to_str(cx.tcx, enum_type);
|
||||
|
||||
let (containing_scope, definition_span) = get_namespace_and_span_for_item(cx,
|
||||
enum_def_id,
|
||||
|
@ -1502,7 +1502,7 @@ fn vec_metadata(cx: &mut CrateContext,
|
|||
let (element_size, element_align) = size_and_align_of(cx, element_llvm_type);
|
||||
|
||||
let vec_llvm_type = Type::vec(cx.sess.targ_cfg.arch, &element_llvm_type);
|
||||
let vec_type_name: &str = fmt!("[%s]", ty_to_str(cx.tcx, element_type));
|
||||
let vec_type_name: &str = fmt!("[%s]", ppaux::ty_to_str(cx.tcx, element_type));
|
||||
|
||||
let member_llvm_types = vec_llvm_type.field_types();
|
||||
|
||||
|
@ -1556,7 +1556,7 @@ fn boxed_vec_metadata(cx: &mut CrateContext,
|
|||
|
||||
let element_llvm_type = type_of::type_of(cx, element_type);
|
||||
let vec_llvm_type = Type::vec(cx.sess.targ_cfg.arch, &element_llvm_type);
|
||||
let vec_type_name: &str = fmt!("[%s]", ty_to_str(cx.tcx, element_type));
|
||||
let vec_type_name: &str = fmt!("[%s]", ppaux::ty_to_str(cx.tcx, element_type));
|
||||
let vec_metadata = vec_metadata(cx, element_type, span);
|
||||
|
||||
return boxed_type_metadata(
|
||||
|
@ -1576,7 +1576,7 @@ fn vec_slice_metadata(cx: &mut CrateContext,
|
|||
debug!("vec_slice_metadata: %?", ty::get(vec_type));
|
||||
|
||||
let slice_llvm_type = type_of::type_of(cx, vec_type);
|
||||
let slice_type_name = ty_to_str(cx.tcx, vec_type);
|
||||
let slice_type_name = ppaux::ty_to_str(cx.tcx, vec_type);
|
||||
|
||||
let member_llvm_types = slice_llvm_type.field_types();
|
||||
assert!(slice_layout_is_correct(cx, member_llvm_types, element_type));
|
||||
|
@ -1648,10 +1648,47 @@ fn subroutine_type_metadata(cx: &mut CrateContext,
|
|||
};
|
||||
}
|
||||
|
||||
fn trait_metadata(cx: &mut CrateContext,
|
||||
def_id: ast::DefId,
|
||||
trait_type: ty::t,
|
||||
substs: &ty::substs,
|
||||
trait_store: ty::TraitStore,
|
||||
mutability: ast::Mutability,
|
||||
builtinBounds: &ty::BuiltinBounds,
|
||||
usage_site_span: Span)
|
||||
-> DIType {
|
||||
// The implementation provided here is a stub. It makes sure that the trait type is
|
||||
// assigned the correct name, size, namespace, and source location. But it does not describe
|
||||
// the trait's methods.
|
||||
let path = ty::item_path(cx.tcx, def_id);
|
||||
let ident = path.last().ident();
|
||||
let name = ppaux::trait_store_to_str(cx.tcx, trait_store)
|
||||
+ ppaux::mutability_to_str(mutability)
|
||||
+ token::ident_to_str(&ident);
|
||||
// Add type and region parameters
|
||||
let name = ppaux::parameterized(cx.tcx, name, &substs.regions, substs.tps);
|
||||
|
||||
let (containing_scope,
|
||||
definition_span) = get_namespace_and_span_for_item(cx, def_id, usage_site_span);
|
||||
|
||||
let file_name = span_start(cx, definition_span).file.name;
|
||||
let file_metadata = file_metadata(cx, file_name);
|
||||
|
||||
let trait_llvm_type = type_of::type_of(cx, trait_type);
|
||||
|
||||
return composite_type_metadata(cx,
|
||||
trait_llvm_type,
|
||||
name,
|
||||
[],
|
||||
containing_scope,
|
||||
file_metadata,
|
||||
definition_span);
|
||||
}
|
||||
|
||||
fn unimplemented_type_metadata(cx: &mut CrateContext, t: ty::t) -> DIType {
|
||||
debug!("unimplemented_type_metadata: %?", ty::get(t));
|
||||
|
||||
let name = ty_to_str(cx.tcx, t);
|
||||
let name = ppaux::ty_to_str(cx.tcx, t);
|
||||
let metadata = do fmt!("NYI<%s>", name).with_c_str |name| {
|
||||
unsafe {
|
||||
llvm::LLVMDIBuilderCreateBasicType(
|
||||
|
@ -1681,7 +1718,7 @@ fn type_metadata(cx: &mut CrateContext,
|
|||
type_in_box: ty::t)
|
||||
-> DIType {
|
||||
|
||||
let content_type_name: &str = ty_to_str(cx.tcx, type_in_box);
|
||||
let content_type_name: &str = ppaux::ty_to_str(cx.tcx, type_in_box);
|
||||
let content_llvm_type = type_of::type_of(cx, type_in_box);
|
||||
let content_type_metadata = type_metadata(
|
||||
cx,
|
||||
|
@ -1773,9 +1810,8 @@ fn type_metadata(cx: &mut CrateContext,
|
|||
ty::ty_closure(ref closurety) => {
|
||||
subroutine_type_metadata(cx, &closurety.sig, usage_site_span)
|
||||
},
|
||||
ty::ty_trait(_did, ref _substs, ref _vstore, _, _bounds) => {
|
||||
cx.sess.span_note(usage_site_span, "debuginfo for trait NYI");
|
||||
unimplemented_type_metadata(cx, t)
|
||||
ty::ty_trait(def_id, ref substs, trait_store, mutability, ref bounds) => {
|
||||
trait_metadata(cx, def_id, t, substs, trait_store, mutability, bounds, usage_site_span)
|
||||
},
|
||||
ty::ty_struct(def_id, ref substs) => {
|
||||
struct_metadata(cx, t, def_id, substs, usage_site_span)
|
||||
|
|
|
@ -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)
|
||||
|
|
34
src/test/debug-info/trait-pointers.rs
Normal file
34
src/test/debug-info/trait-pointers.rs
Normal file
|
@ -0,0 +1,34 @@
|
|||
// 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 {}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
fn zzz() {()}
|
Loading…
Add table
Reference in a new issue