From 3c08be9b48f5a4413a35728a0c392df3b0bed785 Mon Sep 17 00:00:00 2001 From: Brian Leibig Date: Fri, 29 Mar 2013 17:14:08 -0400 Subject: [PATCH 1/7] Add debug info for boxes --- src/librustc/middle/trans/debuginfo.rs | 40 +++++++++++++++++--------- 1 file changed, 27 insertions(+), 13 deletions(-) diff --git a/src/librustc/middle/trans/debuginfo.rs b/src/librustc/middle/trans/debuginfo.rs index 8c40142335e38..cf8ecacfb8b37 100644 --- a/src/librustc/middle/trans/debuginfo.rs +++ b/src/librustc/middle/trans/debuginfo.rs @@ -542,13 +542,23 @@ fn create_tuple(cx: @CrateContext, t: ty::t, elements: &[ty::t], span: span) return mdval; } -fn create_boxed_type(cx: @CrateContext, outer: ty::t, _inner: ty::t, +// returns (void* type as a ValueRef, size in bytes, align in bytes) +fn voidptr() -> (ValueRef, int, int) { + let null = ptr::null(); + let size = sys::size_of::() as int; + let align = sys::min_align_of::() as int; + let vp = create_derived_type(PointerTypeTag, null, ~"", 0, + size, align, 0, null); + return (vp, size, align); +} + +fn create_boxed_type(cx: @CrateContext, contents: ty::t, span: span, boxed: @Metadata) -> @Metadata { //let tg = StructureTypeTag; /*let cache = cx.llmetadata; match cached_metadata::<@Metadata>( - cache, tg, {|md| ty::hash_ty(outer) == ty::hash_ty(md.data.hash)}) { + cache, tg, {|md| ty::hash_ty(contents) == ty::hash_ty(md.data.hash)}) { option::Some(md) { return md; } option::None {} }*/ @@ -557,18 +567,23 @@ fn create_boxed_type(cx: @CrateContext, outer: ty::t, _inner: ty::t, //let cu_node = create_compile_unit_metadata(cx, fname); let uint_t = ty::mk_uint(cx.tcx); let refcount_type = create_basic_type(cx, uint_t, span); - let scx = create_structure(file_node, - @/*bad*/ copy ty_to_str(cx.tcx, outer), 0); + let name = ty_to_str(cx.tcx, contents); + let scx = create_structure(file_node, @fmt!("box<%s>", name), 0); add_member(scx, ~"refcnt", 0, sys::size_of::() as int, sys::min_align_of::() as int, refcount_type.node); - add_member(scx, ~"boxed", 0, 8, //XXX member_size_and_align(??) - 8, //XXX just a guess - boxed.node); + // the tydesc and other pointers should be irrelevant to the + // debugger, so treat them as void* types + let (vp, vpsize, vpalign) = voidptr(); + add_member(scx, ~"tydesc", 0, vpsize, vpalign, vp); + add_member(scx, ~"prev", 0, vpsize, vpalign, vp); + add_member(scx, ~"next", 0, vpsize, vpalign, vp); + let (size, align) = size_and_align_of(cx, contents); + add_member(scx, ~"boxed", 0, size, align, boxed.node); let llnode = finish_structure(scx); let mdval = @Metadata { node: llnode, data: TyDescMetadata { - hash: ty::type_id(outer) + hash: ty::type_id(contents) } }; //update_cache(cache, tg, tydesc_metadata(mdval)); @@ -655,11 +670,10 @@ fn create_ty(cx: @CrateContext, t: ty::t, span: span) ty::ty_enum(_did, ref _substs) => { cx.sess.span_bug(span, ~"debuginfo for enum NYI") } - ty::ty_box(ref _mt) => { - cx.sess.span_bug(span, ~"debuginfo for box NYI") - }, - ty::ty_uniq(ref _mt) => { - cx.sess.span_bug(span, ~"debuginfo for uniq NYI") + ty::ty_box(ref mt) | ty::ty_uniq(ref mt) => { + let boxed = create_ty(cx, mt.ty, span); + let box_md = create_boxed_type(cx, mt.ty, span, boxed); + create_pointer_type(cx, t, span, box_md) }, ty::ty_evec(ref _mt, ref _vstore) => { cx.sess.span_bug(span, ~"debuginfo for evec NYI") From 917d5ab34eabab8e2f39e1c0815d67b583e3d422 Mon Sep 17 00:00:00 2001 From: Brian Leibig Date: Tue, 2 Apr 2013 16:08:34 -0400 Subject: [PATCH 2/7] Add debug info for vectors --- src/librustc/middle/trans/debuginfo.rs | 117 +++++++++++++++++++++---- 1 file changed, 102 insertions(+), 15 deletions(-) diff --git a/src/librustc/middle/trans/debuginfo.rs b/src/librustc/middle/trans/debuginfo.rs index cf8ecacfb8b37..8daf37260ac26 100644 --- a/src/librustc/middle/trans/debuginfo.rs +++ b/src/librustc/middle/trans/debuginfo.rs @@ -565,8 +565,8 @@ fn create_boxed_type(cx: @CrateContext, contents: ty::t, let fname = filename_from_span(cx, span); let file_node = create_file(cx, fname); //let cu_node = create_compile_unit_metadata(cx, fname); - let uint_t = ty::mk_uint(cx.tcx); - let refcount_type = create_basic_type(cx, uint_t, span); + let int_t = ty::mk_int(cx.tcx); + let refcount_type = create_basic_type(cx, int_t, span); let name = ty_to_str(cx.tcx, contents); let scx = create_structure(file_node, @fmt!("box<%s>", name), 0); add_member(scx, ~"refcnt", 0, sys::size_of::() as int, @@ -621,33 +621,97 @@ fn create_composite_type(type_tag: int, name: &str, file: ValueRef, return llmdnode(lldata); } -fn create_vec(cx: @CrateContext, vec_t: ty::t, elem_t: ty::t, - vec_ty_span: codemap::span) -> @Metadata { +fn create_fixed_vec(cx: @CrateContext, vec_t: ty::t, elem_t: ty::t, + len: int, span: span) -> @Metadata { + let t_md = create_ty(cx, elem_t, span); + let fname = filename_from_span(cx, span); + let file_node = create_file(cx, fname); + let (size, align) = size_and_align_of(cx, elem_t); + let subrange = llmdnode(~[lltag(SubrangeTag), lli64(0), lli64(len - 1)]); + let name = fmt!("[%s]", ty_to_str(cx.tcx, elem_t)); + let array = create_composite_type(ArrayTypeTag, name, file_node.node, 0, + size * len, align, 0, Some(t_md.node), + Some(~[subrange])); + @Metadata { + node: array, + data: TyDescMetadata { + hash: ty::type_id(vec_t) + } + } +} + +fn create_boxed_vec(cx: @CrateContext, vec_t: ty::t, elem_t: ty::t, + vec_ty_span: codemap::span) + -> @Metadata { let fname = filename_from_span(cx, vec_ty_span); let file_node = create_file(cx, fname); let elem_ty_md = create_ty(cx, elem_t, vec_ty_span); - let scx = create_structure(file_node, + let vec_scx = create_structure(file_node, @/*bad*/ copy ty_to_str(cx.tcx, vec_t), 0); let size_t_type = create_basic_type(cx, ty::mk_uint(cx.tcx), vec_ty_span); - add_member(scx, ~"fill", 0, sys::size_of::() as int, + add_member(vec_scx, ~"fill", 0, sys::size_of::() as int, sys::min_align_of::() as int, size_t_type.node); - add_member(scx, ~"alloc", 0, sys::size_of::() as int, + add_member(vec_scx, ~"alloc", 0, sys::size_of::() as int, sys::min_align_of::() as int, size_t_type.node); let subrange = llmdnode(~[lltag(SubrangeTag), lli64(0), lli64(0)]); let (arr_size, arr_align) = size_and_align_of(cx, elem_t); - let data_ptr = create_composite_type(ArrayTypeTag, ~"", file_node.node, 0, + let name = fmt!("[%s]", ty_to_str(cx.tcx, elem_t)); + let data_ptr = create_composite_type(ArrayTypeTag, name, file_node.node, 0, arr_size, arr_align, 0, Some(elem_ty_md.node), Some(~[subrange])); - add_member(scx, ~"data", 0, 0, // clang says the size should be 0 + add_member(vec_scx, ~"data", 0, 0, // clang says the size should be 0 sys::min_align_of::() as int, data_ptr); + let llnode = finish_structure(vec_scx); + let vec_md = @Metadata { + node: llnode, + data: TyDescMetadata { + hash: ty::type_id(vec_t) + } + }; + + let box_scx = create_structure(file_node, @fmt!("box<%s>", name), 0); + let int_t = ty::mk_int(cx.tcx); + let refcount_type = create_basic_type(cx, int_t, vec_ty_span); + add_member(box_scx, ~"refcnt", 0, sys::size_of::() as int, + sys::min_align_of::() as int, refcount_type.node); + let (vp, vpsize, vpalign) = voidptr(); + add_member(box_scx, ~"tydesc", 0, vpsize, vpalign, vp); + add_member(box_scx, ~"prev", 0, vpsize, vpalign, vp); + add_member(box_scx, ~"next", 0, vpsize, vpalign, vp); + let size = 2 * sys::size_of::() as int; + let align = sys::min_align_of::() as int; + add_member(box_scx, ~"boxed", 0, size, align, vec_md.node); + let llnode = finish_structure(box_scx); + let mdval = @Metadata { + node: llnode, + data: TyDescMetadata { + hash: ty::type_id(elem_t) + } + }; + return mdval; +} + +fn create_vec_slice(cx: @CrateContext, vec_t: ty::t, elem_t: ty::t, span: span) + -> @Metadata { + let fname = filename_from_span(cx, span); + let file_node = create_file(cx, fname); + let elem_ty_md = create_ty(cx, elem_t, span); + let uint_type = create_basic_type(cx, ty::mk_uint(cx.tcx), span); + let elem_ptr = create_pointer_type(cx, elem_t, span, elem_ty_md); + let scx = create_structure(file_node, @ty_to_str(cx.tcx, vec_t), 0); + let (_, ptr_size, ptr_align) = voidptr(); + add_member(scx, ~"vec", 0, ptr_size, ptr_align, elem_ptr.node); + add_member(scx, ~"length", 0, sys::size_of::() as int, + sys::min_align_of::() as int, uint_type.node); let llnode = finish_structure(scx); - @Metadata { + let mdval = @Metadata { node: llnode, data: TyDescMetadata { hash: ty::type_id(vec_t) } - } + }; + return mdval; } fn create_ty(cx: @CrateContext, t: ty::t, span: span) @@ -664,8 +728,20 @@ fn create_ty(cx: @CrateContext, t: ty::t, span: span) match sty { ty::ty_nil | ty::ty_bot | ty::ty_bool | ty::ty_int(_) | ty::ty_uint(_) | ty::ty_float(_) => create_basic_type(cx, t, span), - ty::ty_estr(_vstore) => { - cx.sess.span_bug(span, ~"debuginfo for estr NYI") + ty::ty_estr(ref vstore) => { + let i8_t = ty::mk_i8(cx.tcx); + match *vstore { + ty::vstore_fixed(len) => { + create_fixed_vec(cx, t, i8_t, len as int + 1, span) + }, + ty::vstore_uniq | ty::vstore_box => { + let box_md = create_boxed_vec(cx, t, i8_t, span); + create_pointer_type(cx, t, span, box_md) + } + ty::vstore_slice(_region) => { + create_vec_slice(cx, t, i8_t, span) + } + } }, ty::ty_enum(_did, ref _substs) => { cx.sess.span_bug(span, ~"debuginfo for enum NYI") @@ -675,8 +751,19 @@ fn create_ty(cx: @CrateContext, t: ty::t, span: span) let box_md = create_boxed_type(cx, mt.ty, span, boxed); create_pointer_type(cx, t, span, box_md) }, - ty::ty_evec(ref _mt, ref _vstore) => { - cx.sess.span_bug(span, ~"debuginfo for evec NYI") + ty::ty_evec(ref mt, ref vstore) => { + match *vstore { + ty::vstore_fixed(len) => { + create_fixed_vec(cx, t, mt.ty, len as int, span) + }, + ty::vstore_uniq | ty::vstore_box => { + let box_md = create_boxed_vec(cx, t, mt.ty, span); + create_pointer_type(cx, t, span, box_md) + }, + ty::vstore_slice(_region) => { + create_vec_slice(cx, t, mt.ty, span) + } + } }, ty::ty_ptr(ref mt) => { let pointee = create_ty(cx, mt.ty, span); From cf22d749eb9717e1e5befa727db5a9f7c47e8f48 Mon Sep 17 00:00:00 2001 From: Brian Leibig Date: Mon, 8 Apr 2013 23:08:10 -0400 Subject: [PATCH 3/7] Add debug info for bare_fn type --- src/librustc/middle/trans/debuginfo.rs | 29 +++++++++++++++++++++++--- 1 file changed, 26 insertions(+), 3 deletions(-) diff --git a/src/librustc/middle/trans/debuginfo.rs b/src/librustc/middle/trans/debuginfo.rs index 8daf37260ac26..c573529fbc23c 100644 --- a/src/librustc/middle/trans/debuginfo.rs +++ b/src/librustc/middle/trans/debuginfo.rs @@ -420,7 +420,8 @@ fn create_pointer_type(cx: @CrateContext, t: ty::t, span: span, let fname = filename_from_span(cx, span); let file_node = create_file(cx, fname); //let cu_node = create_compile_unit(cx, fname); - let llnode = create_derived_type(tg, file_node.node, ~"", 0, size * 8, + let name = ty_to_str(cx.tcx, t); + let llnode = create_derived_type(tg, file_node.node, name, 0, size * 8, align * 8, 0, pointee.node); let mdval = @Metadata { node: llnode, @@ -714,6 +715,26 @@ fn create_vec_slice(cx: @CrateContext, vec_t: ty::t, elem_t: ty::t, span: span) return mdval; } +fn create_fn_ty(cx: @CrateContext, fn_ty: ty::t, inputs: ~[ty::t], output: ty::t, + span: span) -> @Metadata { + let fname = filename_from_span(cx, span); + let file_node = create_file(cx, fname); + let (vp, _, _) = voidptr(); + let output_md = create_ty(cx, output, span); + let output_ptr_md = create_pointer_type(cx, output, span, output_md); + let inputs_vals = do inputs.map |arg| { create_ty(cx, *arg, span).node }; + let members = ~[output_ptr_md.node, vp] + inputs_vals; + let llnode = create_composite_type(SubroutineTag, ~"", file_node.node, + 0, 0, 0, 0, None, Some(members)); + let mdval = @Metadata { + node: llnode, + data: TyDescMetadata { + hash: ty::type_id(fn_ty) + } + }; + return mdval; +} + fn create_ty(cx: @CrateContext, t: ty::t, span: span) -> @Metadata { debug!("create_ty: %?", ty::get(t)); @@ -772,8 +793,10 @@ fn create_ty(cx: @CrateContext, t: ty::t, span: span) ty::ty_rptr(ref _region, ref _mt) => { cx.sess.span_bug(span, ~"debuginfo for rptr NYI") }, - ty::ty_bare_fn(ref _barefnty) => { - cx.sess.span_bug(span, ~"debuginfo for bare_fn NYI") + ty::ty_bare_fn(ref barefnty) => { + let inputs = do barefnty.sig.inputs.map |a| { a.ty }; + let output = barefnty.sig.output; + create_fn_ty(cx, t, inputs, output, span) }, ty::ty_closure(ref _closurety) => { cx.sess.span_bug(span, ~"debuginfo for closure NYI") From 10d930d51ea6a00349c08b53ecf6ffb1ee514219 Mon Sep 17 00:00:00 2001 From: Brian Leibig Date: Mon, 8 Apr 2013 23:13:00 -0400 Subject: [PATCH 4/7] Prevent debug info generation of zero-span nodes If a node has a (0, 0) span, it was not in the source, so debug symbols should not be generated for it. --- src/librustc/middle/trans/base.rs | 15 ++++++++++++--- src/librustc/middle/trans/debuginfo.rs | 2 +- 2 files changed, 13 insertions(+), 4 deletions(-) diff --git a/src/librustc/middle/trans/base.rs b/src/librustc/middle/trans/base.rs index 4faff086098b0..b8a14cb329b04 100644 --- a/src/librustc/middle/trans/base.rs +++ b/src/librustc/middle/trans/base.rs @@ -131,6 +131,13 @@ impl get_insn_ctxt for fn_ctxt { } } +fn fcx_has_nonzero_span(fcx: fn_ctxt) -> bool { + match fcx.span { + None => true, + Some(span) => *span.lo != 0 || *span.hi != 0 + } +} + pub fn log_fn_time(ccx: @CrateContext, +name: ~str, start: time::Timespec, end: time::Timespec) { let elapsed = 1000 * ((end.sec - start.sec) as int) + @@ -1158,7 +1165,8 @@ pub fn trans_stmt(cx: block, s: ast::stmt) -> block { ast::decl_local(ref locals) => { for locals.each |local| { bcx = init_local(bcx, *local); - if cx.sess().opts.extra_debuginfo { + if cx.sess().opts.extra_debuginfo + && fcx_has_nonzero_span(bcx.fcx) { debuginfo::create_local_var(bcx, *local); } } @@ -1738,7 +1746,7 @@ pub fn copy_args_to_allocas(fcx: fn_ctxt, fcx.llargs.insert(arg_id, local_mem(llarg)); - if fcx.ccx.sess.opts.extra_debuginfo { + if fcx.ccx.sess.opts.extra_debuginfo && fcx_has_nonzero_span(fcx) { debuginfo::create_arg(bcx, args[arg_n], args[arg_n].ty.span); } } @@ -1861,7 +1869,8 @@ pub fn trans_fn(ccx: @CrateContext, trans_closure(ccx, path, decl, body, llfndecl, ty_self, param_substs, id, impl_id, |fcx| { - if ccx.sess.opts.extra_debuginfo { + if ccx.sess.opts.extra_debuginfo + && fcx_has_nonzero_span(fcx) { debuginfo::create_function(fcx); } }, diff --git a/src/librustc/middle/trans/debuginfo.rs b/src/librustc/middle/trans/debuginfo.rs index c573529fbc23c..31f89deff5d7f 100644 --- a/src/librustc/middle/trans/debuginfo.rs +++ b/src/librustc/middle/trans/debuginfo.rs @@ -946,7 +946,7 @@ pub fn create_arg(bcx: block, arg: ast::arg, sp: span) } pub fn update_source_pos(cx: block, s: span) { - if !cx.sess().opts.debuginfo { + if !cx.sess().opts.debuginfo || (*s.lo == 0 && *s.hi == 0) { return; } let cm = cx.sess().codemap; From 3e5b98fc741624ae63c600cfb8882f21dd229e67 Mon Sep 17 00:00:00 2001 From: Brian Leibig Date: Tue, 9 Apr 2013 15:53:15 -0400 Subject: [PATCH 5/7] Add debug info test for boxes --- src/test/debug-info/box.rs | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) create mode 100644 src/test/debug-info/box.rs diff --git a/src/test/debug-info/box.rs b/src/test/debug-info/box.rs new file mode 100644 index 0000000000000..f77ec3f947a05 --- /dev/null +++ b/src/test/debug-info/box.rs @@ -0,0 +1,30 @@ +// 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 29 +// debugger:run +// debugger:print a->boxed +// check:$1 = 1 +// debugger:print b->boxed +// check:$2 = {2, 3.5} +// debugger:print c->boxed +// check:$3 = 4 +// debugger:print d->boxed +// check:$4 = false + +fn main() { + let a = ~1; + let b = ~(2, 3.5); + let c = @4; + let d = @false; + let _z = 0; +} From a34921ae890a27c99a6880588564a3fae5c45a41 Mon Sep 17 00:00:00 2001 From: Brian Leibig Date: Tue, 9 Apr 2013 16:27:47 -0400 Subject: [PATCH 6/7] Add debug info test for vectors --- src/test/debug-info/vec.rs | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) create mode 100644 src/test/debug-info/vec.rs diff --git a/src/test/debug-info/vec.rs b/src/test/debug-info/vec.rs new file mode 100644 index 0000000000000..861af3bdbc21d --- /dev/null +++ b/src/test/debug-info/vec.rs @@ -0,0 +1,30 @@ +// 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 29 +// debugger:run +// 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]; + let _z = 0; +} From d2718e6324270831b36e14638d8522b702a3534a Mon Sep 17 00:00:00 2001 From: Brian Leibig Date: Thu, 18 Apr 2013 18:05:33 -0400 Subject: [PATCH 7/7] xfail box and vec debug info tests --- src/test/debug-info/box.rs | 2 ++ src/test/debug-info/vec.rs | 2 ++ 2 files changed, 4 insertions(+) diff --git a/src/test/debug-info/box.rs b/src/test/debug-info/box.rs index f77ec3f947a05..54aa0c12578b9 100644 --- a/src/test/debug-info/box.rs +++ b/src/test/debug-info/box.rs @@ -8,6 +8,8 @@ // 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 29 diff --git a/src/test/debug-info/vec.rs b/src/test/debug-info/vec.rs index 861af3bdbc21d..3876f1c46d487 100644 --- a/src/test/debug-info/vec.rs +++ b/src/test/debug-info/vec.rs @@ -8,6 +8,8 @@ // 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 29