From 36ea75683105447cb9f8338cd2a70493f4eb2c70 Mon Sep 17 00:00:00 2001 From: Michael Woerister Date: Fri, 28 Jun 2013 11:56:35 +0200 Subject: [PATCH] debuginfo: Refactored vec slice code to use the new infrastructure. Added test cases for vec slices. --- src/librustc/middle/trans/debuginfo.rs | 118 +++++++++++++------------ src/test/debug-info/vec-slices.rs | 70 +++++++++++++++ src/test/debug-info/vec.rs | 18 +--- 3 files changed, 134 insertions(+), 72 deletions(-) create mode 100644 src/test/debug-info/vec-slices.rs diff --git a/src/librustc/middle/trans/debuginfo.rs b/src/librustc/middle/trans/debuginfo.rs index 74d8825d6d4..6cb9ed4ec38 100644 --- a/src/librustc/middle/trans/debuginfo.rs +++ b/src/librustc/middle/trans/debuginfo.rs @@ -149,7 +149,7 @@ pub fn create_local_var(bcx: block, local: @ast::local) -> DIVariable { let loc = span_start(cx, local.span); let ty = node_id_type(bcx, local.node.id); let tymd = create_ty(cx, ty, local.node.ty.span); - let filemd = create_file(cx, loc.file.name); + let filemd = get_or_create_file(cx, loc.file.name); let context = match bcx.parent { None => create_function(bcx.fcx), Some(_) => create_block(bcx) @@ -203,7 +203,7 @@ pub fn create_arg(bcx: block, arg: &ast::arg, span: span) -> Option let ty = node_id_type(bcx, arg.id); let tymd = create_ty(cx, ty, arg.ty.span); - let filemd = create_file(cx, loc.file.name); + let filemd = get_or_create_file(cx, loc.file.name); let context = create_function(fcx); match arg.pat.node { @@ -297,7 +297,7 @@ pub fn create_function(fcx: fn_ctxt) -> DISubprogram { debug!("create_function: %s, %s", cx.sess.str_of(ident), cx.sess.codemap.span_to_str(span)); let loc = span_start(cx, span); - let file_md = create_file(cx, loc.file.name); + let file_md = get_or_create_file(cx, loc.file.name); let ret_ty_md = if cx.sess.opts.extra_debuginfo { match ret_ty.node { @@ -374,13 +374,13 @@ fn create_compile_unit(cx: @mut CrateContext) { }}}}}}; } -fn create_file(cx: &mut CrateContext, full_path: &str) -> DIFile { +fn get_or_create_file(cx: &mut CrateContext, full_path: &str) -> DIFile { match dbg_cx(cx).created_files.find_equiv(&full_path) { Some(file_md) => return *file_md, None => () } - debug!("create_file: %s", full_path); + debug!("get_or_create_file: %s", full_path); let work_dir = cx.sess.working_dir.to_str(); let file_name = @@ -428,7 +428,7 @@ fn create_block(bcx: block) -> DILexicalBlock { }; let cx = bcx.ccx(); let loc = span_start(cx, span); - let file_md = create_file(cx, loc.file.name); + let file_md = get_or_create_file(cx, loc.file.name); let block_md = unsafe { llvm::LLVMDIBuilderCreateLexicalBlock( @@ -639,6 +639,9 @@ fn create_tuple(cx: &mut CrateContext, span); } +/// Creates debug information for a composite type, that is, anything that results in a LLVM struct. +/// +/// Examples of Rust types to use this are: structs, tuples, boxes, and enums. fn create_composite_type(cx: &mut CrateContext, composite_llvm_type: Type, composite_type_name: &str, @@ -649,7 +652,7 @@ fn create_composite_type(cx: &mut CrateContext, -> DICompositeType { let loc = span_start(cx, span); - let file_metadata = create_file(cx, loc.file.name); + let file_metadata = get_or_create_file(cx, loc.file.name); let composite_size = machine::llsize_of_alloc(cx, composite_llvm_type); let composite_align = machine::llalign_of_min(cx, composite_llvm_type); @@ -763,47 +766,21 @@ fn create_boxed_type(cx: &mut CrateContext, member_types_metadata, span); + // Unfortunately, we cannot assert anything but the correct types here---and not whether the + // 'next' and 'prev' pointers are in the order. fn box_layout_is_as_expected(cx: &CrateContext, - member_types: &[Type], - content_type: Type) + member_llvm_types: &[Type], + content_llvm_type: Type) -> bool { - return member_types[0] == cx.int_type - && member_types[1] == cx.tydesc_type.ptr_to() - && member_types[2] == Type::i8().ptr_to() - && member_types[3] == Type::i8().ptr_to() - && member_types[4] == content_type; + member_llvm_types.len() == 5 && + member_llvm_types[0] == cx.int_type && + member_llvm_types[1] == cx.tydesc_type.ptr_to() && + member_llvm_types[2] == Type::i8().ptr_to() && + member_llvm_types[3] == Type::i8().ptr_to() && + member_llvm_types[4] == content_llvm_type } } -// fn create_boxed_type(cx: &mut CrateContext, -// contents: ty::t, -// span: span, -// boxed: DIType) -// -> DICompositeType { - -// debug!("create_boxed_type: %?", ty::get(contents)); - -// let loc = span_start(cx, span); -// let file_md = create_file(cx, loc.file.name); -// let int_t = ty::mk_int(); -// let refcount_type = create_basic_type(cx, int_t, span); -// let name = ty_to_str(cx.tcx, contents); - -// let mut scx = StructContext::new(cx, fmt!("box<%s>", name), file_md, 0); -// scx.add_member("refcnt", 0, sys::size_of::(), -// sys::min_align_of::(), refcount_type); -// // the tydesc and other pointers should be irrelevant to the -// // debugger, so treat them as void* types -// let (vp, vpsize, vpalign) = voidptr(cx); -// scx.add_member("tydesc", 0, vpsize, vpalign, vp); -// scx.add_member("prev", 0, vpsize, vpalign, vp); -// scx.add_member("next", 0, vpsize, vpalign, vp); -// let (size, align) = size_and_align_of(cx, contents); -// scx.add_member("val", 0, size, align, boxed); -// return scx.finalize(); -// } - - fn create_fixed_vec(cx: &mut CrateContext, _vec_t: ty::t, elem_t: ty::t, len: uint, span: span) -> DIType { debug!("create_fixed_vec: %?", ty::get(_vec_t)); @@ -831,7 +808,7 @@ fn create_boxed_vec(cx: &mut CrateContext, vec_t: ty::t, elem_t: ty::t, debug!("create_boxed_vec: %?", ty::get(vec_t)); let loc = span_start(cx, vec_ty_span); - let file_md = create_file(cx, loc.file.name); + let file_md = get_or_create_file(cx, loc.file.name); let elem_ty_md = create_ty(cx, elem_t, vec_ty_span); let mut vec_scx = StructContext::new(cx, ty_to_str(cx.tcx, vec_t), file_md, 0); @@ -896,21 +873,46 @@ fn create_boxed_vec(cx: &mut CrateContext, vec_t: ty::t, elem_t: ty::t, return mdval; } -fn create_vec_slice(cx: &mut CrateContext, vec_t: ty::t, elem_t: ty::t, span: span) - -> DICompositeType { - debug!("create_vec_slice: %?", ty::get(vec_t)); +fn create_vec_slice(cx: &mut CrateContext, + vec_type: ty::t, + element_type: ty::t, + span: span) + -> DICompositeType { - let loc = span_start(cx, span); - let file_md = create_file(cx, loc.file.name); - let elem_ty_md = create_ty(cx, elem_t, span); - let uint_type = create_basic_type(cx, ty::mk_uint(), span); - let elem_ptr = create_pointer_type(cx, elem_t, span, elem_ty_md); + debug!("create_vec_slice: %?", ty::get(vec_type)); - let mut scx = StructContext::new(cx, ty_to_str(cx.tcx, vec_t), file_md, 0); - let (_, ptr_size, ptr_align) = voidptr(cx); - scx.add_member("vec", 0, ptr_size, ptr_align, elem_ptr); - scx.add_member("length", 0, sys::size_of::(), sys::min_align_of::(), uint_type); - return scx.finalize(); + let slice_llvm_type = type_of::type_of(cx, vec_type); + let slice_type_name = ty_to_str(cx.tcx, vec_type); + + let member_llvm_types = slice_llvm_type.field_types(); + let member_names = &[~"data_ptr", ~"size_in_bytes"]; + + assert!(slice_layout_is_as_expected(cx, member_llvm_types, element_type)); + + let data_ptr_type = ty::mk_ptr(cx.tcx, ty::mt { ty: element_type, mutbl: ast::m_const }); + + let member_type_metadata = &[ + create_ty(cx, data_ptr_type, span), + create_ty(cx, ty::mk_uint(), span) + ]; + + return create_composite_type( + cx, + slice_llvm_type, + slice_type_name, + member_llvm_types, + member_names, + member_type_metadata, + span); + + fn slice_layout_is_as_expected(cx: &mut CrateContext, + member_llvm_types: &[Type], + element_type: ty::t) + -> bool { + member_llvm_types.len() == 2 && + member_llvm_types[0] == type_of::type_of(cx, element_type).ptr_to() && + member_llvm_types[1] == cx.int_type + } } fn create_fn_ty(cx: &mut CrateContext, _fn_ty: ty::t, inputs: ~[ty::t], output: ty::t, @@ -918,7 +920,7 @@ fn create_fn_ty(cx: &mut CrateContext, _fn_ty: ty::t, inputs: ~[ty::t], output: debug!("create_fn_ty: %?", ty::get(_fn_ty)); let loc = span_start(cx, span); - let file_md = create_file(cx, loc.file.name); + let file_md = get_or_create_file(cx, loc.file.name); let (vp, _, _) = voidptr(cx); let output_md = create_ty(cx, output, span); let output_ptr_md = create_pointer_type(cx, output, span, output_md); diff --git a/src/test/debug-info/vec-slices.rs b/src/test/debug-info/vec-slices.rs new file mode 100644 index 00000000000..a7e47f992fc --- /dev/null +++ b/src/test/debug-info/vec-slices.rs @@ -0,0 +1,70 @@ +// 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 or the MIT license +// , 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:break zzz +// debugger:run +// debugger:finish +// debugger:print empty.size_in_bytes +// check:$1 = 0 + +// debugger:print singleton.size_in_bytes +// check:$2 = 8 +// debugger:print *((int64_t[1]*)(singleton.data_ptr)) +// check:$3 = {1} + +// debugger:print multiple.size_in_bytes +// check:$4 = 32 +// debugger:print *((int64_t[4]*)(multiple.data_ptr)) +// check:$5 = {2, 3, 4, 5} + +// debugger:print slice_of_slice.size_in_bytes +// check:$6 = 16 +// debugger:print *((int64_t[2]*)(slice_of_slice.data_ptr)) +// check:$7 = {3, 4} + +// debugger:print padded_tuple.size_in_bytes +// check:$8 = 16 +// debugger:print padded_tuple.data_ptr[0] +// check:$9 = {6, 7} +// debugger:print padded_tuple.data_ptr[1] +// check:$10 = {8, 9} + +// debugger:print padded_struct.size_in_bytes +// check:$11 = 24 +// debugger:print padded_struct.data_ptr[0] +// check:$12 = {x = 10, y = 11, z = 12} +// debugger:print padded_struct.data_ptr[1] +// check:$13 = {x = 13, y = 14, z = 15} + +struct AStruct { + x: i16, + y: i32, + z: i16 +} + +fn main() { + let empty : &[i64] = &[]; + let singleton : &[i64] = &[1]; + let multiple : &[i64] = &[2, 3, 4, 5]; + let slice_of_slice = multiple.slice(1,3); + + let padded_tuple : &[(i32, i16)] = &[(6, 7), (8, 9)]; + + let padded_struct : &[AStruct] = &[ + AStruct { x: 10, y: 11, z: 12 }, + AStruct { x: 13, y: 14, z: 15 } + ]; + + zzz(); +} + +fn zzz() {()} diff --git a/src/test/debug-info/vec.rs b/src/test/debug-info/vec.rs index f198a53729e..a9aca58fad7 100644 --- a/src/test/debug-info/vec.rs +++ b/src/test/debug-info/vec.rs @@ -8,28 +8,18 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -// xfail-test - // compile-flags:-Z extra-debug-info // debugger:set print pretty off -// debugger:break _zzz +// debugger:break zzz // debugger:run // debugger:finish // debugger:print a // check:$1 = {1, 2, 3} -// debugger:print b.vec[0] -// check:$2 = 4 -// debugger:print c->boxed.data[1] -// check:$3 = 8 -// debugger:print d->boxed.data[2] -// check:$4 = 12 fn main() { let a = [1, 2, 3]; - let b = &[4, 5, 6]; - let c = @[7, 8, 9]; - let d = ~[10, 11, 12]; - _zzz(); + + zzz(); } -fn _zzz() {()} +fn zzz() {()}