From fda193de247c592b7b5b0081df9cf95aeb7d3ce3 Mon Sep 17 00:00:00 2001 From: Michael Woerister Date: Wed, 19 Jun 2013 16:26:35 +0200 Subject: [PATCH 01/18] Extended test cases for struct debug information. Added test cases for different kinds of padding (simple-struct.rs) Added test cases for nested structs (struct-in-struct.rs) --- src/test/debug-info/simple-struct.rs | 84 +++++++++++++ src/test/debug-info/struct-in-struct.rs | 153 ++++++++++++++++++++++++ src/test/debug-info/struct.rs | 35 ------ 3 files changed, 237 insertions(+), 35 deletions(-) create mode 100644 src/test/debug-info/simple-struct.rs create mode 100644 src/test/debug-info/struct-in-struct.rs delete mode 100644 src/test/debug-info/struct.rs diff --git a/src/test/debug-info/simple-struct.rs b/src/test/debug-info/simple-struct.rs new file mode 100644 index 0000000000000..64cfe4a4e23aa --- /dev/null +++ b/src/test/debug-info/simple-struct.rs @@ -0,0 +1,84 @@ +// 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. + +// xfail-win32 Broken because of LLVM bug: http://llvm.org/bugs/show_bug.cgi?id=16249 + +// compile-flags:-Z extra-debug-info +// debugger:set print pretty off +// debugger:break zzz +// debugger:run +// debugger:finish + +// debugger:print noPadding16 +// check:$1 = {x = 10000, y = -10001} + +// debugger:print noPadding32 +// check:$2 = {x = -10002, y = -10003.5, z = 10004} + +// debugger:print noPadding64 +// check:$3 = {x = -10005.5, y = 10006, z = 10007} + +// debugger:print noPadding163264 +// check:$4 = {a = -10008, b = 10009, c = 10010, d = 10011} + +// debugger:print internalPadding +// check:$5 = {x = 10012, y = -10013} + +// debugger:print paddingAtEnd +// check:$6 = {x = -10014, y = 10015} + + +struct NoPadding16 { + x: u16, + y: i16 +} + +struct NoPadding32 { + x: i32, + y: f32, + z: u32 +} + +struct NoPadding64 { + x: f64, + y: i64, + z: u64 +} + +struct NoPadding163264 { + a: i16, + b: u16, + c: i32, + d: u64 +} + +struct InternalPadding { + x: u16, + y: i64 +} + +struct PaddingAtEnd { + x: i64, + y: u16 +} + +fn main() { + let noPadding16 = NoPadding16 { x: 10000, y: -10001 }; + let noPadding32 = NoPadding32 { x: -10002, y: -10003.5, z: 10004 }; + let noPadding64 = NoPadding64 { x: -10005.5, y: 10006, z: 10007 }; + let noPadding163264 = NoPadding163264 { a: -10008, b: 10009, c: 10010, d: 10011 }; + + let internalPadding = InternalPadding { x: 10012, y: -10013 }; + let paddingAtEnd = PaddingAtEnd { x: -10014, y: 10015 }; + + zzz(); +} + +fn zzz() {()} \ No newline at end of file diff --git a/src/test/debug-info/struct-in-struct.rs b/src/test/debug-info/struct-in-struct.rs new file mode 100644 index 0000000000000..a74eb727dc0f1 --- /dev/null +++ b/src/test/debug-info/struct-in-struct.rs @@ -0,0 +1,153 @@ +// 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. + +// xfail-win32 Broken because of LLVM bug: http://llvm.org/bugs/show_bug.cgi?id=16249 + +// compile-flags:-Z extra-debug-info +// debugger:set print pretty off +// debugger:break zzz +// debugger:run +// debugger:finish + +// debugger:print three_simple_structs +// check:$1 = {x = {x = 1}, y = {x = 2}, z = {x = 3}} + +// debugger:print internal_padding_parent +// check:$2 = {x = {x = 4, y = 5}, y = {x = 6, y = 7}, z = {x = 8, y = 9}} + +// debugger:print padding_at_end_parent +// check:$3 = {x = {x = 10, y = 11}, y = {x = 12, y = 13}, z = {x = 14, y = 15}} + + +struct Simple { + x: i32 +} + +struct InternalPadding { + x: i32, + y: i64 +} + +struct PaddingAtEnd { + x: i64, + y: i32 +} + +struct ThreeSimpleStructs { + x: Simple, + y: Simple, + z: Simple +} + +struct InternalPaddingParent { + x: InternalPadding, + y: InternalPadding, + z: InternalPadding +} + +struct PaddingAtEndParent { + x: PaddingAtEnd, + y: PaddingAtEnd, + z: PaddingAtEnd +} + +struct Mixed { + x: PaddingAtEnd, + y: InternalPadding, + z: Simple, + w: i16 +} + +struct Bag { + x: Simple +} + +struct BagInBag { + x: Bag +} + +struct ThatsJustOverkill { + x: BagInBag +} + +struct Tree { + x: Simple, + y: InternalPaddingParent, + z: BagInBag +} + +fn main() { + + let three_simple_structs = ThreeSimpleStructs { + x: Simple { x: 1 }, + y: Simple { x: 2 }, + z: Simple { x: 3 } + }; + + let internal_padding_parent = InternalPaddingParent { + x: InternalPadding { x: 4, y: 5 }, + y: InternalPadding { x: 6, y: 7 }, + z: InternalPadding { x: 8, y: 9 } + }; + + let padding_at_end_parent = PaddingAtEndParent { + x: PaddingAtEnd { x: 10, y: 11 }, + y: PaddingAtEnd { x: 12, y: 13 }, + z: PaddingAtEnd { x: 14, y: 15 } + }; + + let mixed = Mixed { + x: PaddingAtEnd { x: 16, y: 17 }, + y: InternalPadding { x: 18, y: 19 }, + z: Simple { x: 20 }, + w: 21 + }; + + let bag = Bag { x: Simple { x: 22 } }; + let bag_in_bag = BagInBag + { + x: Bag + { + x: Simple { x: 23 } + } + }; + + let tjo = ThatsJustOverkill + { + x: BagInBag + { + x: Bag + { + x: Simple { x: 24 } + } + } + }; + + let tree = Tree { + x: Simple { x: 25 }, + y: InternalPaddingParent + { + x: InternalPadding { x: 26, y: 27 }, + y: InternalPadding { x: 28, y: 29 }, + z: InternalPadding { x: 30, y: 31 } + }, + z: BagInBag + { + x: Bag + { + x: Simple { x: 32 } + } + } + }; + + zzz(); +} + +fn zzz() {()} \ No newline at end of file diff --git a/src/test/debug-info/struct.rs b/src/test/debug-info/struct.rs deleted file mode 100644 index ddfac9cbeea8f..0000000000000 --- a/src/test/debug-info/struct.rs +++ /dev/null @@ -1,35 +0,0 @@ -// 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. - -// xfail-win32 Broken because of LLVM bug: http://llvm.org/bugs/show_bug.cgi?id=16249 - -// compile-flags:-Z extra-debug-info -// debugger:set print pretty off -// debugger:break _zzz -// debugger:run -// debugger:finish -// debugger:print pair -// check:$1 = {x = 1, y = 2} -// debugger:print pair.x -// check:$2 = 1 -// debugger:print pair.y -// check:$3 = 2 - -struct Pair { - x: int, - y: int -} - -fn main() { - let pair = Pair { x: 1, y: 2 }; - _zzz(); -} - -fn _zzz() {()} \ No newline at end of file From 7bb189e56c3ee7d5496e0938f2ec7ed7c3048258 Mon Sep 17 00:00:00 2001 From: Michael Woerister Date: Wed, 19 Jun 2013 16:30:35 +0200 Subject: [PATCH 02/18] Fixed debug information bug regarding struct padding. --- src/librustc/middle/trans/debuginfo.rs | 92 ++++++++++++++++++++++---- 1 file changed, 80 insertions(+), 12 deletions(-) diff --git a/src/librustc/middle/trans/debuginfo.rs b/src/librustc/middle/trans/debuginfo.rs index dae3d58d2be54..5281dcb919360 100644 --- a/src/librustc/middle/trans/debuginfo.rs +++ b/src/librustc/middle/trans/debuginfo.rs @@ -56,7 +56,7 @@ use util::ppaux::ty_to_str; use core::hashmap::HashMap; use core::libc; -use core::libc::c_uint; +use core::libc::{c_uint, c_ulonglong}; use core::cmp; use core::ptr; use core::str::as_c_str; @@ -337,6 +337,9 @@ fn create_DIArray(builder: DIBuilderRef, arr: &[DIDescriptor]) -> DIArray { fn create_compile_unit(cx: @mut CrateContext) { let dcx = dbg_cx(cx); let crate_name: &str = dcx.crate_file; + + debug!("create_compile_unit: %?", crate_name); + let work_dir = cx.sess.working_dir.to_str(); let producer = fmt!("rustc version %s", env!("CFG_VERSION")); @@ -507,14 +510,23 @@ impl StructContext { } fn add_member(&mut self, name: &str, line: uint, size: uint, align: uint, ty: DIType) { - debug!("StructContext(%s)::add_member: %s, size=%u, align=%u", - self.name, name, size, align); let offset = roundup(self.total_size, align); + + debug!("StructContext(%s)::add_member: %s, size=%u, align=%u, offset=%u", + self.name, name, size, align, offset); + let mem_t = do as_c_str(name) |name| { unsafe { llvm::LLVMDIBuilderCreateMemberType( - self.builder, ptr::null(), name, self.file, line as c_uint, - size * 8 as u64, align * 8 as u64, offset * 8 as u64, - 0, ty) + self.builder, + self.file, + name, + self.file, + line as c_uint, + (size * 8) as c_ulonglong, + (align * 8) as c_ulonglong, + (offset * 8) as c_ulonglong, + 0, + ty) }}; self.members.push(mem_t); self.total_size = offset + size; @@ -522,25 +534,67 @@ impl StructContext { self.align = cmp::max(self.align, align); } + fn get_total_size_with_alignment(&self) -> uint { + roundup(self.total_size, self.align) + } + + //fn verify_against_struct_or_tuple_type(&self, t: ty::t, ccx: &mut CrateContext) { + // let repr = adt::represent_type(ccx, t); + + // match *repr { + // Univariant(*) => + // { + // let size_with_alignment = self.get_total_size_with_alignment(); + + // if st.size != size_with_alignment { + // ccx.sess.bug("StructContext(%s)::verify_against_struct_or_tuple_type: invalid type size. Expected = %u, actual = %u", + // st.size, size_with_alignment); + // } + + // if st.align != self.align { + // ccx.sess.bug("StructContext(%s)::verify_against_struct_or_tuple_type: invalid type alignment. Expected = %u, actual = %u", + // st.align, self.align); + // } + // }, + // _ => ccx.sess.bug(fmt!("StructContext(%s)::verify_against_struct_or_tuple_type: called with invalid type %?", + // self.name, t)) + // } + //} + fn finalize(&self) -> DICompositeType { debug!("StructContext(%s)::finalize: total_size=%u, align=%u", self.name, self.total_size, self.align); let members_md = create_DIArray(self.builder, self.members); + // The size of the struct/tuple must be rounded to the next multiple of its alignment. + // Otherwise gdb has trouble reading the struct correct when it is embedded into another + // data structure. This is also the value `sizeof` in C would give. + let total_size_with_alignment = self.get_total_size_with_alignment(); + let struct_md = do as_c_str(self.name) |name| { unsafe { llvm::LLVMDIBuilderCreateStructType( - self.builder, self.file, name, - self.file, self.line as c_uint, - self.total_size * 8 as u64, self.align * 8 as u64, 0, ptr::null(), - members_md, 0, ptr::null()) + self.builder, + self.file, + name, + self.file, + self.line as c_uint, + (total_size_with_alignment * 8) as c_ulonglong, + (self.align * 8) as c_ulonglong, + 0, + ptr::null(), + members_md, + 0, + ptr::null()) }}; return struct_md; } } -fn create_struct(cx: @mut CrateContext, t: ty::t, fields: ~[ty::field], span: span) +fn create_struct(cx: @mut CrateContext, struct_type: ty::t, fields: ~[ty::field], span: span) -> DICompositeType { + debug!("create_struct: %?", ty::get(struct_type)); + let loc = span_start(cx, span); let file_md = create_file(cx, loc.file.name); @@ -565,8 +619,10 @@ fn voidptr(cx: @mut CrateContext) -> (DIDerivedType, uint, uint) { return (vp, size, align); } -fn create_tuple(cx: @mut CrateContext, _t: ty::t, elements: &[ty::t], span: span) +fn create_tuple(cx: @mut CrateContext, tuple_type: ty::t, elements: &[ty::t], span: span) -> DICompositeType { + debug!("create_tuple: %?", ty::get(tuple_type)); + let loc = span_start(cx, span); let file_md = create_file(cx, loc.file.name); @@ -582,6 +638,8 @@ fn create_tuple(cx: @mut CrateContext, _t: ty::t, elements: &[ty::t], span: span 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(); @@ -604,6 +662,8 @@ fn create_boxed_type(cx: @mut CrateContext, contents: ty::t, 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)); + let elem_ty_md = create_ty(cx, elem_t, span); let (size, align) = size_and_align_of(cx, elem_t); @@ -620,6 +680,8 @@ fn create_fixed_vec(cx: @mut CrateContext, _vec_t: ty::t, elem_t: ty::t, fn create_boxed_vec(cx: @mut CrateContext, vec_t: ty::t, elem_t: ty::t, vec_ty_span: span) -> DICompositeType { + 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 elem_ty_md = create_ty(cx, elem_t, vec_ty_span); @@ -663,6 +725,8 @@ fn create_boxed_vec(cx: @mut CrateContext, vec_t: ty::t, elem_t: ty::t, 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)); + 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); @@ -679,6 +743,8 @@ fn create_vec_slice(cx: @mut CrateContext, vec_t: ty::t, elem_t: ty::t, span: sp fn create_fn_ty(cx: @mut CrateContext, _fn_ty: ty::t, inputs: ~[ty::t], output: ty::t, span: span) -> DICompositeType { + debug!("create_fn_ty: %?", ty::get(_fn_ty)); + let loc = span_start(cx, span); let file_md = create_file(cx, loc.file.name); let (vp, _, _) = voidptr(cx); @@ -694,6 +760,8 @@ fn create_fn_ty(cx: @mut CrateContext, _fn_ty: ty::t, inputs: ~[ty::t], output: } fn create_unimpl_ty(cx: @mut CrateContext, t: ty::t) -> DIType { + debug!("create_unimpl_ty: %?", ty::get(t)); + let name = ty_to_str(cx.tcx, t); let md = do as_c_str(fmt!("NYI<%s>", name)) |name| { unsafe { llvm::LLVMDIBuilderCreateBasicType( From 36aa04b9aba097ad8f86a873066dda1b417c14e5 Mon Sep 17 00:00:00 2001 From: Michael Woerister Date: Thu, 20 Jun 2013 12:45:18 +0200 Subject: [PATCH 03/18] debuginfo: Added test cases for tuples. --- src/test/debug-info/simple-tuple.rs | 51 +++++++++++++++++++++++++++ src/test/debug-info/tuple-in-tuple.rs | 50 ++++++++++++++++++++++++++ src/test/debug-info/tuple.rs | 26 -------------- 3 files changed, 101 insertions(+), 26 deletions(-) create mode 100644 src/test/debug-info/simple-tuple.rs create mode 100644 src/test/debug-info/tuple-in-tuple.rs delete mode 100644 src/test/debug-info/tuple.rs diff --git a/src/test/debug-info/simple-tuple.rs b/src/test/debug-info/simple-tuple.rs new file mode 100644 index 0000000000000..6193e58969f1d --- /dev/null +++ b/src/test/debug-info/simple-tuple.rs @@ -0,0 +1,51 @@ +// 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. + +// xfail-win32 Broken because of LLVM bug: http://llvm.org/bugs/show_bug.cgi?id=16249 + +// compile-flags:-Z extra-debug-info +// debugger:set print pretty off +// debugger:break zzz +// debugger:run +// debugger:finish + +// debugger:print noPadding8 +// check:$1 = {-100 '\234', 100 'd'} +// debugger:print noPadding16 +// check:$2 = {0, 1, 2} +// debugger:print noPadding32 +// check:$3 = {3, 4.5, 5} +// debugger:print noPadding64 +// check:$4 = {6, 7.5, 8} + +// debugger:print internalPadding1 +// check:$5 = {9, 10} +// debugger:print internalPadding2 +// check:$6 = {11, 12, 13, 14} + +// debugger:print paddingAtEnd +// check:$7 = {15, 16} + + +fn main() { + let noPadding8 : (i8, u8) = (-100, 100); + let noPadding16 : (i16, i16, u16) = (0, 1, 2); + let noPadding32 : (i32, f32, u32) = (3, 4.5, 5); + let noPadding64 : (i64, f64, u64) = (6, 7.5, 8); + + let internalPadding1 : (i16, i32) = (9, 10); + let internalPadding2 : (i16, i32, u32, u64) = (11, 12, 13, 14); + + let paddingAtEnd : (i32, i16) = (15, 16); + + zzz(); +} + +fn zzz() {()} \ No newline at end of file diff --git a/src/test/debug-info/tuple-in-tuple.rs b/src/test/debug-info/tuple-in-tuple.rs new file mode 100644 index 0000000000000..f500ecef132bd --- /dev/null +++ b/src/test/debug-info/tuple-in-tuple.rs @@ -0,0 +1,50 @@ +// 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. + +// xfail-win32 Broken because of LLVM bug: http://llvm.org/bugs/show_bug.cgi?id=16249 + +// compile-flags:-Z extra-debug-info +// debugger:set print pretty off +// debugger:break zzz +// debugger:run +// debugger:finish + +// debugger:print noPadding1 +// check:$1 = {{0, 1}, 2, 3} +// debugger:print noPadding2 +// check:$2 = {4, {5, 6}, 7} +// debugger:print noPadding3 +// check:$3 = {8, 9, {10, 11}} + +// debugger:print internalPadding1 +// check:$4 = {12, {13, 14}} +// debugger:print internalPadding2 +// check:$5 = {15, {16, 17}} + +// debugger:print paddingAtEnd1 +// check:$6 = {18, {19, 20}} +// debugger:print paddingAtEnd2 +// check:$7 = {{21, 22}, 23} + +fn main() { + let noPadding1 : ((u32, u32), u32, u32) = ((0, 1), 2, 3); + let noPadding2 : (u32, (u32, u32), u32) = (4, (5, 6), 7); + let noPadding3 : (u32, u32, (u32, u32)) = (8, 9, (10, 11)); + + let internalPadding1 : (i16, (i32, i32)) = (12, (13, 14)); + let internalPadding2 : (i16, (i16, i32)) = (15, (16, 17)); + + let paddingAtEnd1 : (i32, (i32, i16)) = (18, (19, 20)); + let paddingAtEnd2 : ((i32, i16), i32) = ((21, 22), 23); + + zzz(); +} + +fn zzz() {()} \ No newline at end of file diff --git a/src/test/debug-info/tuple.rs b/src/test/debug-info/tuple.rs deleted file mode 100644 index a50996871cee9..0000000000000 --- a/src/test/debug-info/tuple.rs +++ /dev/null @@ -1,26 +0,0 @@ -// 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. - -// xfail-win32 Broken because of LLVM bug: http://llvm.org/bugs/show_bug.cgi?id=16249 - -// compile-flags:-Z extra-debug-info -// debugger:set print pretty off -// debugger:break _zzz -// debugger:run -// debugger:finish -// debugger:print t -// check:$1 = {4, 5.5, true} - -fn main() { - let t = (4, 5.5, true); - _zzz(); -} - -fn _zzz() {()} \ No newline at end of file From 5f97a6e951bfd45743c9153fc78743462472351b Mon Sep 17 00:00:00 2001 From: Michael Woerister Date: Thu, 20 Jun 2013 15:25:30 +0200 Subject: [PATCH 04/18] debuginfo: Added test cases for tuples contained in structs. --- src/test/debug-info/tuple-in-struct.rs | 151 +++++++++++++++++++++++++ 1 file changed, 151 insertions(+) create mode 100644 src/test/debug-info/tuple-in-struct.rs diff --git a/src/test/debug-info/tuple-in-struct.rs b/src/test/debug-info/tuple-in-struct.rs new file mode 100644 index 0000000000000..1ad4d7c069ec3 --- /dev/null +++ b/src/test/debug-info/tuple-in-struct.rs @@ -0,0 +1,151 @@ +// 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. + +// xfail-win32 Broken because of LLVM bug: http://llvm.org/bugs/show_bug.cgi?id=16249 + +// compile-flags:-Z extra-debug-info +// debugger:set print pretty off +// debugger:break zzz +// debugger:run +// debugger:finish + +// debugger:print noPadding1 +// check:$1 = {x = {0, 1}, y = 2, z = {3, 4, 5}} +// debugger:print noPadding2 +// check:$2 = {x = {6, 7}, y = {{8, 9}, 10}} + +// debugger:print tupleInternalPadding +// check:$3 = {x = {11, 12}, y = {13, 14}} +// debugger:print structInternalPadding +// check:$4 = {x = {15, 16}, y = {17, 18}} +// debugger:print bothInternallyPadded +// check:$5 = {x = {19, 20, 21}, y = {22, 23}} + +// debugger:print singleTuple +// check:$6 = {x = {24, 25, 26}} + +// debugger:print tuplePaddedAtEnd +// check:$7 = {x = {27, 28}, y = {29, 30}} +// debugger:print structPaddedAtEnd +// check:$8 = {x = {31, 32}, y = {33, 34}} +// debugger:print bothPaddedAtEnd +// check:$9 = {x = {35, 36, 37}, y = {38, 39}} + +// debugger:print mixedPadding +// check:$10 = {x = {{40, 41, 42}, {43, 44}}, y = {45, 46, 47, 48}} + +struct NoPadding1 { + x: (i32, i32), + y: i32, + z: (i32, i32, i32) +} + +struct NoPadding2 { + x: (i32, i32), + y: ((i32, i32), i32) +} + +struct TupleInternalPadding { + x: (i16, i32), + y: (i32, i64) +} + +struct StructInternalPadding { + x: (i16, i16), + y: (i64, i64) +} + +struct BothInternallyPadded { + x: (i16, i32, i32), + y: (i32, i64) +} + +struct SingleTuple { + x: (i16, i32, i64) +} + +struct TuplePaddedAtEnd { + x: (i32, i16), + y: (i64, i32) +} + +struct StructPaddedAtEnd { + x: (i64, i64), + y: (i16, i16) +} + +struct BothPaddedAtEnd { + x: (i32, i32, i16), + y: (i64, i32) +} + +// Data-layout (padding signified by dots, one column = 2 bytes): +// [a.bbc...ddddee..ffffg.hhi...] +struct MixedPadding { + x: ((i16, i32, i16), (i64, i32)), + y: (i64, i16, i32, i16) +} + + +fn main() { + let noPadding1 = NoPadding1 { + x: (0, 1), + y: 2, + z: (3, 4, 5) + }; + + let noPadding2 = NoPadding2 { + x: (6, 7), + y: ((8, 9), 10) + }; + + let tupleInternalPadding = TupleInternalPadding { + x: (11, 12), + y: (13, 14) + }; + + let structInternalPadding = StructInternalPadding { + x: (15, 16), + y: (17, 18) + }; + + let bothInternallyPadded = BothInternallyPadded { + x: (19, 20, 21), + y: (22, 23) + }; + + let singleTuple = SingleTuple { + x: (24, 25, 26) + }; + + let tuplePaddedAtEnd = TuplePaddedAtEnd { + x: (27, 28), + y: (29, 30) + }; + + let structPaddedAtEnd = StructPaddedAtEnd { + x: (31, 32), + y: (33, 34) + }; + + let bothPaddedAtEnd = BothPaddedAtEnd { + x: (35, 36, 37), + y: (38, 39) + }; + + let mixedPadding = MixedPadding { + x: ((40, 41, 42), (43, 44)), + y: (45, 46, 47, 48) + }; + + zzz(); +} + +fn zzz() {()} \ No newline at end of file From 4d8f2fd8714b983aa8ae5d697c90998424930f5b Mon Sep 17 00:00:00 2001 From: Michael Woerister Date: Thu, 20 Jun 2013 16:00:59 +0200 Subject: [PATCH 05/18] debuginfo: Many little formatting improvements. --- src/librustc/middle/trans/debuginfo.rs | 177 +++++++++++++++++-------- 1 file changed, 121 insertions(+), 56 deletions(-) diff --git a/src/librustc/middle/trans/debuginfo.rs b/src/librustc/middle/trans/debuginfo.rs index 5281dcb919360..0a1f2d1fe2411 100644 --- a/src/librustc/middle/trans/debuginfo.rs +++ b/src/librustc/middle/trans/debuginfo.rs @@ -211,9 +211,17 @@ pub fn create_arg(bcx: block, arg: ast::arg, span: span) -> Option { let ident = path.idents.last(); let name: &str = cx.sess.str_of(*ident); let mdnode = do as_c_str(name) |name| { unsafe { - llvm::LLVMDIBuilderCreateLocalVariable(DIB(cx), - ArgVariableTag as u32, context, name, - filemd, loc.line as c_uint, tymd, false, 0, 0) + llvm::LLVMDIBuilderCreateLocalVariable( + DIB(cx), + ArgVariableTag as u32, + context, + name, + filemd, + loc.line as c_uint, + tymd, + false, + 0, + 0) // XXX need to pass in a real argument number }}; @@ -290,16 +298,17 @@ pub fn create_function(fcx: fn_ctxt) -> DISubprogram { let ret_ty_md = if cx.sess.opts.extra_debuginfo { match ret_ty.node { ast::ty_nil => ptr::null(), - _ => create_ty(cx, ty::node_id_to_type(cx.tcx, id), - ret_ty.span) + _ => create_ty(cx, ty::node_id_to_type(cx.tcx, id), ret_ty.span) } } else { ptr::null() }; let fn_ty = unsafe { - llvm::LLVMDIBuilderCreateSubroutineType(DIB(cx), - file_md, create_DIArray(DIB(cx), [ret_ty_md])) + llvm::LLVMDIBuilderCreateSubroutineType( + DIB(cx), + file_md, + create_DIArray(DIB(cx), [ret_ty_md])) }; let fn_md = @@ -308,13 +317,19 @@ pub fn create_function(fcx: fn_ctxt) -> DISubprogram { llvm::LLVMDIBuilderCreateFunction( DIB(cx), file_md, - name, linkage, - file_md, loc.line as c_uint, - fn_ty, false, true, + name, + linkage, + file_md, + loc.line as c_uint, + fn_ty, + false, + true, loc.line as c_uint, FlagPrototyped as c_uint, cx.sess.opts.optimize != session::No, - fcx.llfn, ptr::null(), ptr::null()) + fcx.llfn, + ptr::null(), + ptr::null()) }}}; dbg_cx(cx).created_functions.insert(id, fn_md); @@ -463,8 +478,11 @@ fn create_basic_type(cx: @mut CrateContext, t: ty::t, _span: span) -> DIType { let (size, align) = size_and_align_of(cx, t); let ty_md = do as_c_str(name) |name| { unsafe { llvm::LLVMDIBuilderCreateBasicType( - DIB(cx), name, - size * 8 as u64, align * 8 as u64, encoding as c_uint) + DIB(cx), + name, + bytes_to_bits(size), + bytes_to_bits(align), + encoding as c_uint) }}; // One could think that this call is not necessary, as the create_ty() function will insert the @@ -478,8 +496,12 @@ fn create_pointer_type(cx: @mut CrateContext, t: ty::t, _span: span, pointee: DI let (size, align) = size_and_align_of(cx, t); let name = ty_to_str(cx.tcx, t); let ptr_md = do as_c_str(name) |name| { unsafe { - llvm::LLVMDIBuilderCreatePointerType(DIB(cx), - pointee, size * 8 as u64, align * 8 as u64, name) + llvm::LLVMDIBuilderCreatePointerType( + DIB(cx), + pointee, + bytes_to_bits(size), + bytes_to_bits(align), + name) }}; return ptr_md; } @@ -514,18 +536,18 @@ impl StructContext { debug!("StructContext(%s)::add_member: %s, size=%u, align=%u, offset=%u", self.name, name, size, align, offset); - + let mem_t = do as_c_str(name) |name| { unsafe { llvm::LLVMDIBuilderCreateMemberType( - self.builder, + self.builder, + self.file, + name, self.file, - name, - self.file, line as c_uint, - (size * 8) as c_ulonglong, - (align * 8) as c_ulonglong, - (offset * 8) as c_ulonglong, - 0, + bytes_to_bits(size), + bytes_to_bits(align), + bytes_to_bits(offset), + 0, ty) }}; self.members.push(mem_t); @@ -542,10 +564,10 @@ impl StructContext { // let repr = adt::represent_type(ccx, t); // match *repr { - // Univariant(*) => + // Univariant(*) => // { // let size_with_alignment = self.get_total_size_with_alignment(); - + // if st.size != size_with_alignment { // ccx.sess.bug("StructContext(%s)::verify_against_struct_or_tuple_type: invalid type size. Expected = %u, actual = %u", // st.size, size_with_alignment); @@ -556,7 +578,7 @@ impl StructContext { // st.align, self.align); // } // }, - // _ => ccx.sess.bug(fmt!("StructContext(%s)::verify_against_struct_or_tuple_type: called with invalid type %?", + // _ => ccx.sess.bug(fmt!("StructContext(%s)::verify_against_struct_or_tuple_type: called with invalid type %?", // self.name, t)) // } //} @@ -567,24 +589,24 @@ impl StructContext { let members_md = create_DIArray(self.builder, self.members); // The size of the struct/tuple must be rounded to the next multiple of its alignment. - // Otherwise gdb has trouble reading the struct correct when it is embedded into another + // Otherwise gdb has trouble reading the struct correctly when it is embedded into another // data structure. This is also the value `sizeof` in C would give. - let total_size_with_alignment = self.get_total_size_with_alignment(); + let actual_total_size = self.get_total_size_with_alignment(); let struct_md = do as_c_str(self.name) |name| { unsafe { llvm::LLVMDIBuilderCreateStructType( self.builder, - self.file, + self.file, name, - self.file, + self.file, self.line as c_uint, - (total_size_with_alignment * 8) as c_ulonglong, - (self.align * 8) as c_ulonglong, + bytes_to_bits(actual_total_size), + bytes_to_bits(self.align), 0, ptr::null(), - members_md, - 0, + members_md, + 0, ptr::null()) }}; return struct_md; @@ -613,8 +635,12 @@ fn voidptr(cx: @mut CrateContext) -> (DIDerivedType, uint, uint) { let size = sys::size_of::(); let align = sys::min_align_of::(); let vp = do as_c_str("*void") |name| { unsafe { - llvm::LLVMDIBuilderCreatePointerType(DIB(cx), ptr::null(), - size*8 as u64, align*8 as u64, name) + llvm::LLVMDIBuilderCreatePointerType( + DIB(cx), + ptr::null(), + bytes_to_bits(size), + bytes_to_bits(align), + name) }}; return (vp, size, align); } @@ -673,8 +699,12 @@ fn create_fixed_vec(cx: @mut CrateContext, _vec_t: ty::t, elem_t: ty::t, let subscripts = create_DIArray(DIB(cx), [subrange]); return unsafe { - llvm::LLVMDIBuilderCreateArrayType(DIB(cx), - size * len * 8 as u64, align * 8 as u64, elem_ty_md, subscripts) + llvm::LLVMDIBuilderCreateArrayType( + DIB(cx), + bytes_to_bits(size * len), + bytes_to_bits(align), + elem_ty_md, + subscripts) }; } @@ -688,10 +718,21 @@ fn create_boxed_vec(cx: @mut CrateContext, vec_t: ty::t, elem_t: ty::t, let mut vec_scx = StructContext::new(cx, ty_to_str(cx.tcx, vec_t), file_md, 0); let size_t_type = create_basic_type(cx, ty::mk_uint(), vec_ty_span); - vec_scx.add_member("fill", 0, sys::size_of::(), - sys::min_align_of::(), size_t_type); - vec_scx.add_member("alloc", 0, sys::size_of::(), - sys::min_align_of::(), size_t_type); + + vec_scx.add_member( + "fill", + 0, + sys::size_of::(), + sys::min_align_of::(), + size_t_type); + + vec_scx.add_member( + "alloc", + 0, + sys::size_of::(), + sys::min_align_of::(), + size_t_type); + let subrange = unsafe { llvm::LLVMDIBuilderGetOrCreateSubrange(DIB(cx), 0_i64, 0_i64) }; @@ -700,18 +741,32 @@ fn create_boxed_vec(cx: @mut CrateContext, vec_t: ty::t, elem_t: ty::t, let subscripts = create_DIArray(DIB(cx), [subrange]); let data_ptr = unsafe { - llvm::LLVMDIBuilderCreateArrayType(DIB(cx), - arr_size * 8 as u64, arr_align * 8 as u64, elem_ty_md, subscripts) + llvm::LLVMDIBuilderCreateArrayType( + DIB(cx), + bytes_to_bits(arr_size), + bytes_to_bits(arr_align), + elem_ty_md, + subscripts) }; - vec_scx.add_member("data", 0, 0, // clang says the size should be 0 - sys::min_align_of::(), data_ptr); + vec_scx.add_member( + "data", + 0, + 0, // clang says the size should be 0 + sys::min_align_of::(), data_ptr); + let vec_md = vec_scx.finalize(); let mut box_scx = StructContext::new(cx, fmt!("box<%s>", name), file_md, 0); let int_t = ty::mk_int(); let refcount_type = create_basic_type(cx, int_t, vec_ty_span); - box_scx.add_member("refcnt", 0, sys::size_of::(), - sys::min_align_of::(), refcount_type); + + box_scx.add_member( + "refcnt", + 0, + sys::size_of::(), + sys::min_align_of::(), + refcount_type); + let (vp, vpsize, vpalign) = voidptr(cx); box_scx.add_member("tydesc", 0, vpsize, vpalign, vp); box_scx.add_member("prev", 0, vpsize, vpalign, vp); @@ -736,8 +791,7 @@ fn create_vec_slice(cx: @mut CrateContext, vec_t: ty::t, elem_t: ty::t, span: sp 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); + scx.add_member("length", 0, sys::size_of::(), sys::min_align_of::(), uint_type); return scx.finalize(); } @@ -754,7 +808,9 @@ fn create_fn_ty(cx: @mut CrateContext, _fn_ty: ty::t, inputs: ~[ty::t], output: let members = ~[output_ptr_md, vp] + inputs_vals; return unsafe { - llvm::LLVMDIBuilderCreateSubroutineType(DIB(cx), file_md, + llvm::LLVMDIBuilderCreateSubroutineType( + DIB(cx), + file_md, create_DIArray(DIB(cx), members)) }; } @@ -765,8 +821,11 @@ fn create_unimpl_ty(cx: @mut CrateContext, t: ty::t) -> DIType { let name = ty_to_str(cx.tcx, t); let md = do as_c_str(fmt!("NYI<%s>", name)) |name| { unsafe { llvm::LLVMDIBuilderCreateBasicType( - DIB(cx), name, - 0_u64, 8_u64, DW_ATE_unsigned as c_uint) + DIB(cx), + name, + 0_u64, + 8_u64, + DW_ATE_unsigned as c_uint) }}; return md; } @@ -867,8 +926,10 @@ fn set_debug_location(cx: @mut CrateContext, scope: DIScope, line: uint, col: ui let elems = ~[C_i32(line as i32), C_i32(col as i32), scope, ptr::null()]; unsafe { let dbg_loc = llvm::LLVMMDNodeInContext( - dbg_cx(cx).llcontext, vec::raw::to_ptr(elems), - elems.len() as libc::c_uint); + dbg_cx(cx).llcontext, + vec::raw::to_ptr(elems), + elems.len() as c_uint); + llvm::LLVMSetCurrentDebugLocation(cx.builder.B, dbg_loc); } } @@ -887,7 +948,7 @@ fn roundup(x: uint, a: uint) -> uint { /// Return codemap::Loc corresponding to the beginning of the span fn span_start(cx: &CrateContext, span: span) -> codemap::Loc { - return cx.sess.codemap.lookup_char_pos(span.lo); + cx.sess.codemap.lookup_char_pos(span.lo) } fn size_and_align_of(cx: @mut CrateContext, t: ty::t) -> (uint, uint) { @@ -895,6 +956,10 @@ fn size_and_align_of(cx: @mut CrateContext, t: ty::t) -> (uint, uint) { (machine::llsize_of_real(cx, llty), machine::llalign_of_min(cx, llty)) } +fn bytes_to_bits(bytes: uint) -> c_ulonglong { + (bytes * 8) as c_ulonglong +} + #[inline] fn dbg_cx<'a>(cx: &'a mut CrateContext) -> &'a mut DebugContext { cx.dbg_cx.get_mut_ref() From 1dc8e76d3a32fbb304b152f815d394577fe008c6 Mon Sep 17 00:00:00 2001 From: Michael Woerister Date: Thu, 20 Jun 2013 16:45:47 +0200 Subject: [PATCH 06/18] debuginfo: Made test cases use correct naming convention for variables. --- src/test/debug-info/simple-struct.rs | 28 ++++++++--------- src/test/debug-info/struct-in-struct.rs | 32 ++++++++++---------- src/test/debug-info/tuple-in-struct.rs | 40 ++++++++++++------------- src/test/debug-info/tuple-in-tuple.rs | 28 ++++++++--------- 4 files changed, 64 insertions(+), 64 deletions(-) diff --git a/src/test/debug-info/simple-struct.rs b/src/test/debug-info/simple-struct.rs index 64cfe4a4e23aa..49e7bc255c10f 100644 --- a/src/test/debug-info/simple-struct.rs +++ b/src/test/debug-info/simple-struct.rs @@ -16,22 +16,22 @@ // debugger:run // debugger:finish -// debugger:print noPadding16 +// debugger:print no_padding16 // check:$1 = {x = 10000, y = -10001} -// debugger:print noPadding32 +// debugger:print no_padding32 // check:$2 = {x = -10002, y = -10003.5, z = 10004} -// debugger:print noPadding64 +// debugger:print no_padding64 // check:$3 = {x = -10005.5, y = 10006, z = 10007} -// debugger:print noPadding163264 +// debugger:print no_padding163264 // check:$4 = {a = -10008, b = 10009, c = 10010, d = 10011} -// debugger:print internalPadding +// debugger:print internal_padding // check:$5 = {x = 10012, y = -10013} -// debugger:print paddingAtEnd +// debugger:print padding_at_end // check:$6 = {x = -10014, y = 10015} @@ -39,7 +39,7 @@ struct NoPadding16 { x: u16, y: i16 } - + struct NoPadding32 { x: i32, y: f32, @@ -70,13 +70,13 @@ struct PaddingAtEnd { } fn main() { - let noPadding16 = NoPadding16 { x: 10000, y: -10001 }; - let noPadding32 = NoPadding32 { x: -10002, y: -10003.5, z: 10004 }; - let noPadding64 = NoPadding64 { x: -10005.5, y: 10006, z: 10007 }; - let noPadding163264 = NoPadding163264 { a: -10008, b: 10009, c: 10010, d: 10011 }; - - let internalPadding = InternalPadding { x: 10012, y: -10013 }; - let paddingAtEnd = PaddingAtEnd { x: -10014, y: 10015 }; + let no_padding16 = NoPadding16 { x: 10000, y: -10001 }; + let no_padding32 = NoPadding32 { x: -10002, y: -10003.5, z: 10004 }; + let no_padding64 = NoPadding64 { x: -10005.5, y: 10006, z: 10007 }; + let no_padding163264 = NoPadding163264 { a: -10008, b: 10009, c: 10010, d: 10011 }; + + let internal_padding = InternalPadding { x: 10012, y: -10013 }; + let padding_at_end = PaddingAtEnd { x: -10014, y: 10015 }; zzz(); } diff --git a/src/test/debug-info/struct-in-struct.rs b/src/test/debug-info/struct-in-struct.rs index a74eb727dc0f1..cfd8c24caa21a 100644 --- a/src/test/debug-info/struct-in-struct.rs +++ b/src/test/debug-info/struct-in-struct.rs @@ -55,7 +55,7 @@ struct InternalPaddingParent { struct PaddingAtEndParent { x: PaddingAtEnd, y: PaddingAtEnd, - z: PaddingAtEnd + z: PaddingAtEnd } struct Mixed { @@ -84,7 +84,7 @@ struct Tree { } fn main() { - + let three_simple_structs = ThreeSimpleStructs { x: Simple { x: 1 }, y: Simple { x: 2 }, @@ -100,7 +100,7 @@ fn main() { let padding_at_end_parent = PaddingAtEndParent { x: PaddingAtEnd { x: 10, y: 11 }, y: PaddingAtEnd { x: 12, y: 13 }, - z: PaddingAtEnd { x: 14, y: 15 } + z: PaddingAtEnd { x: 14, y: 15 } }; let mixed = Mixed { @@ -111,22 +111,22 @@ fn main() { }; let bag = Bag { x: Simple { x: 22 } }; - let bag_in_bag = BagInBag + let bag_in_bag = BagInBag { - x: Bag + x: Bag { - x: Simple { x: 23 } - } + x: Simple { x: 23 } + } }; - let tjo = ThatsJustOverkill + let tjo = ThatsJustOverkill { - x: BagInBag + x: BagInBag { - x: Bag + x: Bag { - x: Simple { x: 24 } - } + x: Simple { x: 24 } + } } }; @@ -138,12 +138,12 @@ fn main() { y: InternalPadding { x: 28, y: 29 }, z: InternalPadding { x: 30, y: 31 } }, - z: BagInBag + z: BagInBag { - x: Bag + x: Bag { - x: Simple { x: 32 } - } + x: Simple { x: 32 } + } } }; diff --git a/src/test/debug-info/tuple-in-struct.rs b/src/test/debug-info/tuple-in-struct.rs index 1ad4d7c069ec3..369c9fd28ccdf 100644 --- a/src/test/debug-info/tuple-in-struct.rs +++ b/src/test/debug-info/tuple-in-struct.rs @@ -16,29 +16,29 @@ // debugger:run // debugger:finish -// debugger:print noPadding1 +// debugger:print no_padding1 // check:$1 = {x = {0, 1}, y = 2, z = {3, 4, 5}} -// debugger:print noPadding2 +// debugger:print no_padding2 // check:$2 = {x = {6, 7}, y = {{8, 9}, 10}} -// debugger:print tupleInternalPadding +// debugger:print tuple_internal_padding // check:$3 = {x = {11, 12}, y = {13, 14}} -// debugger:print structInternalPadding +// debugger:print struct_internal_padding // check:$4 = {x = {15, 16}, y = {17, 18}} -// debugger:print bothInternallyPadded +// debugger:print both_internally_padded // check:$5 = {x = {19, 20, 21}, y = {22, 23}} -// debugger:print singleTuple +// debugger:print single_tuple // check:$6 = {x = {24, 25, 26}} -// debugger:print tuplePaddedAtEnd +// debugger:print tuple_padded_at_end // check:$7 = {x = {27, 28}, y = {29, 30}} -// debugger:print structPaddedAtEnd +// debugger:print struct_padded_at_end // check:$8 = {x = {31, 32}, y = {33, 34}} -// debugger:print bothPaddedAtEnd +// debugger:print both_padded_at_end // check:$9 = {x = {35, 36, 37}, y = {38, 39}} -// debugger:print mixedPadding +// debugger:print mixed_padding // check:$10 = {x = {{40, 41, 42}, {43, 44}}, y = {45, 46, 47, 48}} struct NoPadding1 { @@ -95,52 +95,52 @@ struct MixedPadding { fn main() { - let noPadding1 = NoPadding1 { + let no_padding1 = NoPadding1 { x: (0, 1), y: 2, z: (3, 4, 5) }; - let noPadding2 = NoPadding2 { + let no_padding2 = NoPadding2 { x: (6, 7), y: ((8, 9), 10) }; - let tupleInternalPadding = TupleInternalPadding { + let tuple_internal_padding = TupleInternalPadding { x: (11, 12), y: (13, 14) }; - let structInternalPadding = StructInternalPadding { + let struct_internal_padding = StructInternalPadding { x: (15, 16), y: (17, 18) }; - let bothInternallyPadded = BothInternallyPadded { + let both_internally_padded = BothInternallyPadded { x: (19, 20, 21), y: (22, 23) }; - let singleTuple = SingleTuple { + let single_tuple = SingleTuple { x: (24, 25, 26) }; - let tuplePaddedAtEnd = TuplePaddedAtEnd { + let tuple_padded_at_end = TuplePaddedAtEnd { x: (27, 28), y: (29, 30) }; - let structPaddedAtEnd = StructPaddedAtEnd { + let struct_padded_at_end = StructPaddedAtEnd { x: (31, 32), y: (33, 34) }; - let bothPaddedAtEnd = BothPaddedAtEnd { + let both_padded_at_end = BothPaddedAtEnd { x: (35, 36, 37), y: (38, 39) }; - let mixedPadding = MixedPadding { + let mixed_padding = MixedPadding { x: ((40, 41, 42), (43, 44)), y: (45, 46, 47, 48) }; diff --git a/src/test/debug-info/tuple-in-tuple.rs b/src/test/debug-info/tuple-in-tuple.rs index f500ecef132bd..13f8719694e5f 100644 --- a/src/test/debug-info/tuple-in-tuple.rs +++ b/src/test/debug-info/tuple-in-tuple.rs @@ -16,33 +16,33 @@ // debugger:run // debugger:finish -// debugger:print noPadding1 +// debugger:print no_padding1 // check:$1 = {{0, 1}, 2, 3} -// debugger:print noPadding2 +// debugger:print no_padding2 // check:$2 = {4, {5, 6}, 7} -// debugger:print noPadding3 +// debugger:print no_padding3 // check:$3 = {8, 9, {10, 11}} -// debugger:print internalPadding1 +// debugger:print internal_padding1 // check:$4 = {12, {13, 14}} -// debugger:print internalPadding2 +// debugger:print internal_padding2 // check:$5 = {15, {16, 17}} -// debugger:print paddingAtEnd1 +// debugger:print padding_at_end1 // check:$6 = {18, {19, 20}} -// debugger:print paddingAtEnd2 +// debugger:print padding_at_end2 // check:$7 = {{21, 22}, 23} fn main() { - let noPadding1 : ((u32, u32), u32, u32) = ((0, 1), 2, 3); - let noPadding2 : (u32, (u32, u32), u32) = (4, (5, 6), 7); - let noPadding3 : (u32, u32, (u32, u32)) = (8, 9, (10, 11)); + let no_padding1 : ((u32, u32), u32, u32) = ((0, 1), 2, 3); + let no_padding2 : (u32, (u32, u32), u32) = (4, (5, 6), 7); + let no_padding3 : (u32, u32, (u32, u32)) = (8, 9, (10, 11)); - let internalPadding1 : (i16, (i32, i32)) = (12, (13, 14)); - let internalPadding2 : (i16, (i16, i32)) = (15, (16, 17)); + let internal_padding1 : (i16, (i32, i32)) = (12, (13, 14)); + let internal_padding2 : (i16, (i16, i32)) = (15, (16, 17)); - let paddingAtEnd1 : (i32, (i32, i16)) = (18, (19, 20)); - let paddingAtEnd2 : ((i32, i16), i32) = ((21, 22), 23); + let padding_at_end1 : (i32, (i32, i16)) = (18, (19, 20)); + let padding_at_end2 : ((i32, i16), i32) = ((21, 22), 23); zzz(); } From 0b5fef3b267510dc9abd890f80b076f11543a919 Mon Sep 17 00:00:00 2001 From: Michael Woerister Date: Fri, 21 Jun 2013 11:19:33 +0200 Subject: [PATCH 07/18] debuginfo: Added test case for local variable scopes. --- src/test/debug-info/variable-scope.rs | 49 +++++++++++++++++++++++++++ 1 file changed, 49 insertions(+) create mode 100644 src/test/debug-info/variable-scope.rs diff --git a/src/test/debug-info/variable-scope.rs b/src/test/debug-info/variable-scope.rs new file mode 100644 index 0000000000000..a9177ac196647 --- /dev/null +++ b/src/test/debug-info/variable-scope.rs @@ -0,0 +1,49 @@ +// 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. + +// xfail-test + +// compile-flags:-Z extra-debug-info +// debugger:break zzz +// debugger:run +// debugger:finish +// debugger:print x +// check:$1 = false +// debugger:print y +// check:$2 = true + +// debugger:run +// debugger:finish +// debugger:print x +// check:$3 = 10 + +// debugger:run +// debugger:finish +// debugger:print x +// check:$4 = false +// debugger:print y +// check:$5 = 11 + +fn main() { + let x = false; + let y = true; + + zzz(); + + { + let x = 10; + zzz(); + } + + let y = 11; + zzz(); +} + +fn zzz() {()} From 168eba9201011e34a70febc8395d5e0808585600 Mon Sep 17 00:00:00 2001 From: Michael Woerister Date: Fri, 21 Jun 2013 12:09:30 +0200 Subject: [PATCH 08/18] debuginfo: Added test case for structs with destructor. --- src/test/debug-info/struct-with-destructor.rs | 77 +++++++++++++++++++ 1 file changed, 77 insertions(+) create mode 100644 src/test/debug-info/struct-with-destructor.rs diff --git a/src/test/debug-info/struct-with-destructor.rs b/src/test/debug-info/struct-with-destructor.rs new file mode 100644 index 0000000000000..b5ae4bbe8fbaf --- /dev/null +++ b/src/test/debug-info/struct-with-destructor.rs @@ -0,0 +1,77 @@ +// 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. + +// xfail-test + +// compile-flags:-Z extra-debug-info +// debugger:break zzz +// debugger:run +// debugger:finish +// debugger:print simple +// check:$1 = {x = 10, y = 20} + +// debugger:print noDestructor +// check:$2 = {a = {x = 10, y = 20}, guard = -1} + +// debugger:print withDestructor +// check:$3 = {a = {x = 10, y = 20}, guard = -1} + +struct NoDestructor { + x : i32, + y : i64 +} + +struct WithDestructor { + x : i32, + y : i64 +} + +impl Drop for WithDestructor { + fn finalize(&self) {} +} + +struct NoDestructorGuarded +{ + a: NoDestructor, + guard: i64 +} + +struct WithDestructorGuarded +{ + a: WithDestructor, + guard: i64 +} + + +// The compiler adds a 'destructed' boolean field to structs implementing Drop. This field is used +// at runtime to prevent finalize() to be executed more than once (see middle::trans::adt). +// This field must be incorporated by the debug info generation. Otherwise the debugger assumes a +// wrong size/layout for the struct. +fn main() { + + let simple = WithDestructor { x: 10, y: 20 }; + + let noDestructor = NoDestructorGuarded { + a: NoDestructor { x: 10, y: 20 }, + guard: -1 + }; + + // If the destructor flag field is not incorporated into the debug info for 'WithDestructor' + // then the debugger will have an invalid offset for the field 'guard' and thus should not be + // able to read its value correctly. + let withDestructor = WithDestructorGuarded { + a: WithDestructor { x: 10, y: 20 }, + guard: -1 + }; + + zzz(); +} + +fn zzz() {()} From 46d28c874ccb342e6b8f7fa45f7927bcde2f396e Mon Sep 17 00:00:00 2001 From: Michael Woerister Date: Mon, 24 Jun 2013 15:55:33 +0200 Subject: [PATCH 09/18] debuginfo: Replaced many instances of @ with &. --- src/librustc/middle/trans/debuginfo.rs | 45 +++++++++++++------------- 1 file changed, 23 insertions(+), 22 deletions(-) diff --git a/src/librustc/middle/trans/debuginfo.rs b/src/librustc/middle/trans/debuginfo.rs index 0a1f2d1fe2411..a0ba0667f4b4e 100644 --- a/src/librustc/middle/trans/debuginfo.rs +++ b/src/librustc/middle/trans/debuginfo.rs @@ -370,7 +370,7 @@ fn create_compile_unit(cx: @mut CrateContext) { }}}}}}; } -fn create_file(cx: @mut CrateContext, full_path: &str) -> DIFile { +fn 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 => () @@ -440,7 +440,7 @@ fn create_block(bcx: block) -> DILexicalBlock { -fn create_basic_type(cx: @mut CrateContext, t: ty::t, _span: span) -> DIType { +fn create_basic_type(cx: &mut CrateContext, t: ty::t, _span: span) -> DIType { let ty_id = ty::type_id(t); match dbg_cx(cx).created_types.find(&ty_id) { Some(ty_md) => return *ty_md, @@ -492,7 +492,7 @@ fn create_basic_type(cx: @mut CrateContext, t: ty::t, _span: span) -> DIType { return ty_md; } -fn create_pointer_type(cx: @mut CrateContext, t: ty::t, _span: span, pointee: DIType) -> DIType { +fn create_pointer_type(cx: &mut CrateContext, t: ty::t, _span: span, pointee: DIType) -> DIType { let (size, align) = size_and_align_of(cx, t); let name = ty_to_str(cx.tcx, t); let ptr_md = do as_c_str(name) |name| { unsafe { @@ -517,9 +517,9 @@ struct StructContext { } impl StructContext { - fn new(cx: &CrateContext, name: ~str, file: DIFile, line: uint) -> ~StructContext { + fn new(cx: &CrateContext, name: ~str, file: DIFile, line: uint) -> StructContext { debug!("StructContext::create: %s", name); - let scx = ~StructContext { + return StructContext { builder: DIB(cx), file: file, name: name, @@ -528,7 +528,6 @@ impl StructContext { total_size: 0, align: 1 }; - return scx; } fn add_member(&mut self, name: &str, line: uint, size: uint, align: uint, ty: DIType) { @@ -569,17 +568,19 @@ impl StructContext { // let size_with_alignment = self.get_total_size_with_alignment(); // if st.size != size_with_alignment { - // ccx.sess.bug("StructContext(%s)::verify_against_struct_or_tuple_type: invalid type size. Expected = %u, actual = %u", + // ccx.sess.bug("StructContext(%s)::verify_against_struct_or_tuple_type: + // invalid type size. Expected = %u, actual = %u", // st.size, size_with_alignment); // } // if st.align != self.align { - // ccx.sess.bug("StructContext(%s)::verify_against_struct_or_tuple_type: invalid type alignment. Expected = %u, actual = %u", + // ccx.sess.bug("StructContext(%s)::verify_against_struct_or_tuple_type: + // invalid type alignment. Expected = %u, actual = %u", // st.align, self.align); // } // }, - // _ => ccx.sess.bug(fmt!("StructContext(%s)::verify_against_struct_or_tuple_type: called with invalid type %?", - // self.name, t)) + // _ => ccx.sess.bug(fmt!("StructContext(%s)::verify_against_struct_or_tuple_type: + // called with invalid type %?", self.name, t)) // } //} @@ -613,14 +614,14 @@ impl StructContext { } } -fn create_struct(cx: @mut CrateContext, struct_type: ty::t, fields: ~[ty::field], span: span) +fn create_struct(cx: &mut CrateContext, struct_type: ty::t, fields: ~[ty::field], span: span) -> DICompositeType { debug!("create_struct: %?", ty::get(struct_type)); let loc = span_start(cx, span); let file_md = create_file(cx, loc.file.name); - let mut scx = StructContext::new(cx, ty_to_str(cx.tcx, t), file_md, loc.line); + let mut scx = StructContext::new(cx, ty_to_str(cx.tcx, struct_type), file_md, loc.line); for fields.iter().advance |field| { let field_t = field.mt.ty; let ty_md = create_ty(cx, field_t, span); @@ -631,7 +632,7 @@ fn create_struct(cx: @mut CrateContext, struct_type: ty::t, fields: ~[ty::field] } // returns (void* type as a ValueRef, size in bytes, align in bytes) -fn voidptr(cx: @mut CrateContext) -> (DIDerivedType, uint, uint) { +fn voidptr(cx: &mut CrateContext) -> (DIDerivedType, uint, uint) { let size = sys::size_of::(); let align = sys::min_align_of::(); let vp = do as_c_str("*void") |name| { unsafe { @@ -645,7 +646,7 @@ fn voidptr(cx: @mut CrateContext) -> (DIDerivedType, uint, uint) { return (vp, size, align); } -fn create_tuple(cx: @mut CrateContext, tuple_type: ty::t, elements: &[ty::t], span: span) +fn create_tuple(cx: &mut CrateContext, tuple_type: ty::t, elements: &[ty::t], span: span) -> DICompositeType { debug!("create_tuple: %?", ty::get(tuple_type)); @@ -662,7 +663,7 @@ fn create_tuple(cx: @mut CrateContext, tuple_type: ty::t, elements: &[ty::t], sp return scx.finalize(); } -fn create_boxed_type(cx: @mut CrateContext, contents: ty::t, +fn create_boxed_type(cx: &mut CrateContext, contents: ty::t, span: span, boxed: DIType) -> DICompositeType { debug!("create_boxed_type: %?", ty::get(contents)); @@ -686,7 +687,7 @@ fn create_boxed_type(cx: @mut CrateContext, contents: ty::t, return scx.finalize(); } -fn create_fixed_vec(cx: @mut CrateContext, _vec_t: ty::t, elem_t: ty::t, +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)); @@ -708,7 +709,7 @@ fn create_fixed_vec(cx: @mut CrateContext, _vec_t: ty::t, elem_t: ty::t, }; } -fn create_boxed_vec(cx: @mut CrateContext, vec_t: ty::t, elem_t: ty::t, +fn create_boxed_vec(cx: &mut CrateContext, vec_t: ty::t, elem_t: ty::t, vec_ty_span: span) -> DICompositeType { debug!("create_boxed_vec: %?", ty::get(vec_t)); @@ -778,7 +779,7 @@ 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) +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)); @@ -795,7 +796,7 @@ fn create_vec_slice(cx: @mut CrateContext, vec_t: ty::t, elem_t: ty::t, span: sp return scx.finalize(); } -fn create_fn_ty(cx: @mut CrateContext, _fn_ty: ty::t, inputs: ~[ty::t], output: ty::t, +fn create_fn_ty(cx: &mut CrateContext, _fn_ty: ty::t, inputs: ~[ty::t], output: ty::t, span: span) -> DICompositeType { debug!("create_fn_ty: %?", ty::get(_fn_ty)); @@ -815,7 +816,7 @@ fn create_fn_ty(cx: @mut CrateContext, _fn_ty: ty::t, inputs: ~[ty::t], output: }; } -fn create_unimpl_ty(cx: @mut CrateContext, t: ty::t) -> DIType { +fn create_unimpl_ty(cx: &mut CrateContext, t: ty::t) -> DIType { debug!("create_unimpl_ty: %?", ty::get(t)); let name = ty_to_str(cx.tcx, t); @@ -830,7 +831,7 @@ fn create_unimpl_ty(cx: @mut CrateContext, t: ty::t) -> DIType { return md; } -fn create_ty(cx: @mut CrateContext, t: ty::t, span: span) -> DIType { +fn create_ty(cx: &mut CrateContext, t: ty::t, span: span) -> DIType { let ty_id = ty::type_id(t); match dbg_cx(cx).created_types.find(&ty_id) { Some(ty_md) => return *ty_md, @@ -951,7 +952,7 @@ fn span_start(cx: &CrateContext, span: span) -> codemap::Loc { cx.sess.codemap.lookup_char_pos(span.lo) } -fn size_and_align_of(cx: @mut CrateContext, t: ty::t) -> (uint, uint) { +fn size_and_align_of(cx: &mut CrateContext, t: ty::t) -> (uint, uint) { let llty = type_of::type_of(cx, t); (machine::llsize_of_real(cx, llty), machine::llalign_of_min(cx, llty)) } From 6af78610e745f68b8eb3e107bdb1e4b2288c617c Mon Sep 17 00:00:00 2001 From: Michael Woerister Date: Mon, 24 Jun 2013 17:17:19 +0200 Subject: [PATCH 10/18] debuginfo: Added support for region pointers. --- src/librustc/middle/trans/debuginfo.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/librustc/middle/trans/debuginfo.rs b/src/librustc/middle/trans/debuginfo.rs index a0ba0667f4b4e..b1434bb798a96 100644 --- a/src/librustc/middle/trans/debuginfo.rs +++ b/src/librustc/middle/trans/debuginfo.rs @@ -886,9 +886,9 @@ fn create_ty(cx: &mut CrateContext, t: ty::t, span: span) -> DIType { let pointee = create_ty(cx, mt.ty, span); create_pointer_type(cx, t, span, pointee) }, - ty::ty_rptr(ref _region, ref _mt) => { - cx.sess.span_note(span, "debuginfo for rptr NYI"); - create_unimpl_ty(cx, t) + ty::ty_rptr(_, ref mt) => { + let pointee = create_ty(cx, mt.ty, span); + create_pointer_type(cx, t, span, pointee) }, ty::ty_bare_fn(ref barefnty) => { let inputs = barefnty.sig.inputs.map(|a| *a); From 751f0fba6fe9df4003cd18e95c8438e2cf742f9a Mon Sep 17 00:00:00 2001 From: Michael Woerister Date: Mon, 24 Jun 2013 17:18:10 +0200 Subject: [PATCH 11/18] debuginfo: Added test case for region pointers pointing to stack values with basic type. --- src/test/debug-info/reference-to-basic.rs | 116 ++++++++++++++++++++++ 1 file changed, 116 insertions(+) create mode 100644 src/test/debug-info/reference-to-basic.rs diff --git a/src/test/debug-info/reference-to-basic.rs b/src/test/debug-info/reference-to-basic.rs new file mode 100644 index 0000000000000..dfd0fbf865557 --- /dev/null +++ b/src/test/debug-info/reference-to-basic.rs @@ -0,0 +1,116 @@ +// 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. + +// xfail-win32 Broken because of LLVM bug: http://llvm.org/bugs/show_bug.cgi?id=16249 + +// Caveats - gdb prints any 8-bit value (meaning rust i8 and u8 values) +// as its numerical value along with its associated ASCII char, there +// doesn't seem to be any way around this. Also, gdb doesn't know +// about UTF-32 character encoding and will print a rust char as only +// its numerical value. + +// compile-flags:-Z extra-debug-info +// debugger:break zzz +// debugger:run +// debugger:finish +// debugger:print *bool_ref +// check:$1 = true + +// debugger:print *int_ref +// check:$2 = -1 + +// debugger:print *char_ref +// check:$3 = 97 + +// debugger:print *i8_ref +// check:$4 = 68 'D' + +// debugger:print *i16_ref +// check:$5 = -16 + +// debugger:print *i32_ref +// check:$6 = -32 + +// debugger:print *i64_ref +// check:$7 = -64 + +// debugger:print *uint_ref +// check:$8 = 1 + +// debugger:print *u8_ref +// check:$9 = 100 'd' + +// debugger:print *u16_ref +// check:$10 = 16 + +// debugger:print *u32_ref +// check:$11 = 32 + +// debugger:print *u64_ref +// check:$12 = 64 + +// debugger:print *float_ref +// check:$13 = 1.5 + +// debugger:print *f32_ref +// check:$14 = 2.5 + +// debugger:print *f64_ref +// check:$15 = 3.5 + +fn main() { + let bool_val: bool = true; + let bool_ref : &bool = &bool_val; + + let int_val: int = -1; + let int_ref : &int = &int_val; + + let char_val: char = 'a'; + let char_ref : &char = &char_val; + + let i8_val: i8 = 68; + let i8_ref : &i8 = &i8_val; + + let i16_val: i16 = -16; + let i16_ref : &i16 = &i16_val; + + let i32_val: i32 = -32; + let i32_ref : &i32 = &i32_val; + + let uint_val: i64 = -64; + let i64_ref : &i64 = &uint_val; + + let uint_val: uint = 1; + let uint_ref : &uint = &uint_val; + + let u8_val: u8 = 100; + let u8_ref : &u8 = &u8_val; + + let u16_val: u16 = 16; + let u16_ref : &u16 = &u16_val; + + let u32_val: u32 = 32; + let u32_ref : &u32 = &u32_val; + + let u64_val: u64 = 64; + let u64_ref : &u64 = &u64_val; + + let float_val: float = 1.5; + let float_ref : &float = &float_val; + + let f32_val: f32 = 2.5; + let f32_ref : &f32 = &f32_val; + + let f64_val: f64 = 3.5; + let f64_ref : &f64 = &f64_val; + zzz(); +} + +fn zzz() {()} \ No newline at end of file From fb3e17b93a7a9824459ca9a7fb0d8a638016f6fa Mon Sep 17 00:00:00 2001 From: Michael Woerister Date: Mon, 24 Jun 2013 17:47:21 +0200 Subject: [PATCH 12/18] debuginfo: Added test cases for region pointers into heap boxes for basic types. --- .../debug-info/reference-to-managed-basic.rs | 115 ++++++++++++++++++ .../debug-info/reference-to-unique-basic.rs | 115 ++++++++++++++++++ 2 files changed, 230 insertions(+) create mode 100644 src/test/debug-info/reference-to-managed-basic.rs create mode 100644 src/test/debug-info/reference-to-unique-basic.rs diff --git a/src/test/debug-info/reference-to-managed-basic.rs b/src/test/debug-info/reference-to-managed-basic.rs new file mode 100644 index 0000000000000..b93b2cee2d273 --- /dev/null +++ b/src/test/debug-info/reference-to-managed-basic.rs @@ -0,0 +1,115 @@ +// 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. + +// xfail-win32 Broken because of LLVM bug: http://llvm.org/bugs/show_bug.cgi?id=16249 + +// Gdb doesn't know +// about UTF-32 character encoding and will print a rust char as only +// its numerical value. + +// compile-flags:-Z extra-debug-info +// debugger:break zzz +// debugger:run +// debugger:finish +// debugger:print *bool_ref +// check:$1 = true + +// debugger:print *int_ref +// check:$2 = -1 + +// debugger:print *char_ref +// check:$3 = 97 + +// debugger:print/d *i8_ref +// check:$4 = 68 + +// debugger:print *i16_ref +// check:$5 = -16 + +// debugger:print *i32_ref +// check:$6 = -32 + +// debugger:print *i64_ref +// check:$7 = -64 + +// debugger:print *uint_ref +// check:$8 = 1 + +// debugger:print/d *u8_ref +// check:$9 = 100 + +// debugger:print *u16_ref +// check:$10 = 16 + +// debugger:print *u32_ref +// check:$11 = 32 + +// debugger:print *u64_ref +// check:$12 = 64 + +// debugger:print *float_ref +// check:$13 = 1.5 + +// debugger:print *f32_ref +// check:$14 = 2.5 + +// debugger:print *f64_ref +// check:$15 = 3.5 + + +fn main() { + let bool_box: @bool = @true; + let bool_ref : &bool = bool_box; + + let int_box: @int = @-1; + let int_ref : &int = int_box; + + let char_box: @char = @'a'; + let char_ref : &char = char_box; + + let i8_box: @i8 = @68; + let i8_ref : &i8 = i8_box; + + let i16_box: @i16 = @-16; + let i16_ref : &i16 = i16_box; + + let i32_box: @i32 = @-32; + let i32_ref : &i32 = i32_box; + + let i64_box: @i64 = @-64; + let i64_ref : &i64 = i64_box; + + let uint_box: @uint = @1; + let uint_ref : &uint = uint_box; + + let u8_box: @u8 = @100; + let u8_ref : &u8 = u8_box; + + let u16_box: @u16 = @16; + let u16_ref : &u16 = u16_box; + + let u32_box: @u32 = @32; + let u32_ref : &u32 = u32_box; + + let u64_box: @u64 = @64; + let u64_ref : &u64 = u64_box; + + let float_box: @float = @1.5; + let float_ref : &float = float_box; + + let f32_box: @f32 = @2.5; + let f32_ref : &f32 = f32_box; + + let f64_box: @f64 = @3.5; + let f64_ref : &f64 = f64_box; + zzz(); +} + +fn zzz() {()} \ No newline at end of file diff --git a/src/test/debug-info/reference-to-unique-basic.rs b/src/test/debug-info/reference-to-unique-basic.rs new file mode 100644 index 0000000000000..ce5b50459f660 --- /dev/null +++ b/src/test/debug-info/reference-to-unique-basic.rs @@ -0,0 +1,115 @@ +// 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. + +// xfail-win32 Broken because of LLVM bug: http://llvm.org/bugs/show_bug.cgi?id=16249 + +// Gdb doesn't know +// about UTF-32 character encoding and will print a rust char as only +// its numerical value. + +// compile-flags:-Z extra-debug-info +// debugger:break zzz +// debugger:run +// debugger:finish +// debugger:print *bool_ref +// check:$1 = true + +// debugger:print *int_ref +// check:$2 = -1 + +// debugger:print *char_ref +// check:$3 = 97 + +// debugger:print/d *i8_ref +// check:$4 = 68 + +// debugger:print *i16_ref +// check:$5 = -16 + +// debugger:print *i32_ref +// check:$6 = -32 + +// debugger:print *i64_ref +// check:$7 = -64 + +// debugger:print *uint_ref +// check:$8 = 1 + +// debugger:print/d *u8_ref +// check:$9 = 100 + +// debugger:print *u16_ref +// check:$10 = 16 + +// debugger:print *u32_ref +// check:$11 = 32 + +// debugger:print *u64_ref +// check:$12 = 64 + +// debugger:print *float_ref +// check:$13 = 1.5 + +// debugger:print *f32_ref +// check:$14 = 2.5 + +// debugger:print *f64_ref +// check:$15 = 3.5 + + +fn main() { + let bool_box: ~bool = ~true; + let bool_ref : &bool = bool_box; + + let int_box: ~int = ~-1; + let int_ref : &int = int_box; + + let char_box: ~char = ~'a'; + let char_ref : &char = char_box; + + let i8_box: ~i8 = ~68; + let i8_ref : &i8 = i8_box; + + let i16_box: ~i16 = ~-16; + let i16_ref : &i16 = i16_box; + + let i32_box: ~i32 = ~-32; + let i32_ref : &i32 = i32_box; + + let i64_box: ~i64 = ~-64; + let i64_ref : &i64 = i64_box; + + let uint_box: ~uint = ~1; + let uint_ref : &uint = uint_box; + + let u8_box: ~u8 = ~100; + let u8_ref : &u8 = u8_box; + + let u16_box: ~u16 = ~16; + let u16_ref : &u16 = u16_box; + + let u32_box: ~u32 = ~32; + let u32_ref : &u32 = u32_box; + + let u64_box: ~u64 = ~64; + let u64_ref : &u64 = u64_box; + + let float_box: ~float = ~1.5; + let float_ref : &float = float_box; + + let f32_box: ~f32 = ~2.5; + let f32_ref : &f32 = f32_box; + + let f64_box: ~f64 = ~3.5; + let f64_ref : &f64 = f64_box; + zzz(); +} + +fn zzz() {()} \ No newline at end of file From 6a3094159fc50c062e55e76379b402b4a5d5270d Mon Sep 17 00:00:00 2001 From: Michael Woerister Date: Mon, 24 Jun 2013 17:52:22 +0200 Subject: [PATCH 13/18] debuginfo: Fixed some instances of gdb wrongly printing u8/i8 values as chars. --- src/test/debug-info/basic-types.rs | 8 ++++---- src/test/debug-info/simple-tuple.rs | 4 ++-- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/test/debug-info/basic-types.rs b/src/test/debug-info/basic-types.rs index 616740c850c54..7125ebe8d564c 100644 --- a/src/test/debug-info/basic-types.rs +++ b/src/test/debug-info/basic-types.rs @@ -26,8 +26,8 @@ // check:$2 = -1 // debugger:print c // check:$3 = 97 -// debugger:print i8 -// check:$4 = 68 'D' +// debugger:print/d i8 +// check:$4 = 68 // debugger:print i16 // check:$5 = -16 // debugger:print i32 @@ -36,8 +36,8 @@ // check:$7 = -64 // debugger:print u // check:$8 = 1 -// debugger:print u8 -// check:$9 = 100 'd' +// debugger:print/d u8 +// check:$9 = 100 // debugger:print u16 // check:$10 = 16 // debugger:print u32 diff --git a/src/test/debug-info/simple-tuple.rs b/src/test/debug-info/simple-tuple.rs index 6193e58969f1d..84c736fab6b01 100644 --- a/src/test/debug-info/simple-tuple.rs +++ b/src/test/debug-info/simple-tuple.rs @@ -16,8 +16,8 @@ // debugger:run // debugger:finish -// debugger:print noPadding8 -// check:$1 = {-100 '\234', 100 'd'} +// debugger:print/d noPadding8 +// check:$1 = {-100, 100} // debugger:print noPadding16 // check:$2 = {0, 1, 2} // debugger:print noPadding32 From 9102ad035c2e61066d6fb85c2be80afc5860e043 Mon Sep 17 00:00:00 2001 From: Michael Woerister Date: Tue, 25 Jun 2013 21:53:15 +0200 Subject: [PATCH 14/18] debuginfo: Added more tests for region pointers (tuples, structs). --- src/test/debug-info/reference-to-struct.rs | 78 ++++++++++++++++++++++ src/test/debug-info/reference-to-tuple.rs | 47 +++++++++++++ 2 files changed, 125 insertions(+) create mode 100644 src/test/debug-info/reference-to-struct.rs create mode 100644 src/test/debug-info/reference-to-tuple.rs diff --git a/src/test/debug-info/reference-to-struct.rs b/src/test/debug-info/reference-to-struct.rs new file mode 100644 index 0000000000000..f00872c00b0e4 --- /dev/null +++ b/src/test/debug-info/reference-to-struct.rs @@ -0,0 +1,78 @@ +// 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. + +// xfail-win32 Broken because of LLVM bug: http://llvm.org/bugs/show_bug.cgi?id=16249 + +// GDB doesn't know about UTF-32 character encoding and will print a rust char as only its numerical +// value. + +// compile-flags:-Z extra-debug-info +// debugger:break zzz +// debugger:run +// debugger:finish + +// debugger:print *stack_val_ref +// check:$1 = {x = 10, y = 23.5} + +// debugger:print *stack_val_interior_ref_1 +// check:$2 = 10 + +// debugger:print *stack_val_interior_ref_2 +// check:$3 = 23.5 + +// debugger:print *ref_to_unnamed +// check:$4 = {x = 11, y = 24.5} + +// debugger:print *managed_val_ref +// check:$5 = {x = 12, y = 25.5} + +// debugger:print *managed_val_interior_ref_1 +// check:$6 = 12 + +// debugger:print *managed_val_interior_ref_2 +// check:$7 = 25.5 + +// debugger:print *unique_val_ref +// check:$8 = {x = 13, y = 26.5} + +// debugger:print *unique_val_interior_ref_1 +// check:$9 = 13 + +// debugger:print *unique_val_interior_ref_2 +// check:$10 = 26.5 + + + +struct SomeStruct { + x: int, + y: f64 +} + +fn main() { + let stack_val: SomeStruct = SomeStruct { x: 10, y: 23.5 }; + let stack_val_ref : &SomeStruct = &stack_val; + let stack_val_interior_ref_1 : &int = &stack_val.x; + let stack_val_interior_ref_2 : &f64 = &stack_val.y; + let ref_to_unnamed : &SomeStruct = &SomeStruct { x: 11, y: 24.5 }; + + let managed_val = @SomeStruct { x: 12, y: 25.5 }; + let managed_val_ref : &SomeStruct = managed_val; + let managed_val_interior_ref_1 : &int = &managed_val.x; + let managed_val_interior_ref_2 : &f64 = &managed_val.y; + + let unique_val = ~SomeStruct { x: 13, y: 26.5 }; + let unique_val_ref : &SomeStruct = unique_val; + let unique_val_interior_ref_1 : &int = &unique_val.x; + let unique_val_interior_ref_2 : &f64 = &unique_val.y; + + zzz(); +} + +fn zzz() {()} \ No newline at end of file diff --git a/src/test/debug-info/reference-to-tuple.rs b/src/test/debug-info/reference-to-tuple.rs new file mode 100644 index 0000000000000..86d02185bdae7 --- /dev/null +++ b/src/test/debug-info/reference-to-tuple.rs @@ -0,0 +1,47 @@ +// 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. + +// xfail-win32 Broken because of LLVM bug: http://llvm.org/bugs/show_bug.cgi?id=16249 + +// GDB doesn't know about UTF-32 character encoding and will print a rust char as only its numerical +// value. + +// compile-flags:-Z extra-debug-info +// debugger:break zzz +// debugger:run +// debugger:finish + +// debugger:print *stack_val_ref +// check:$1 = {-14, -19} + +// debugger:print *ref_to_unnamed +// check:$2 = {-15, -20} + +// debugger:print *managed_val_ref +// check:$3 = {-16, -21} + +// debugger:print *unique_val_ref +// check:$4 = {-17, -22} + +fn main() { + let stack_val: (i16, f32) = (-14, -19f32); + let stack_val_ref : &(i16, f32) = &stack_val; + let ref_to_unnamed : &(i16, f32) = &(-15, -20f32); + + let managed_val : @(i16, f32) = @(-16, -21f32); + let managed_val_ref : &(i16, f32) = managed_val; + + let unique_val: ~(i16, f32) = ~(-17, -22f32); + let unique_val_ref : &(i16, f32) = unique_val; + + zzz(); +} + +fn zzz() {()} \ No newline at end of file From 074e0fa2a95d9cc723c9c952cf6dc5e7daed574d Mon Sep 17 00:00:00 2001 From: Michael Woerister Date: Tue, 25 Jun 2013 21:54:03 +0200 Subject: [PATCH 15/18] debuginfo: Added test case for local variables declared with destructuring. --- src/test/debug-info/destructured-local.rs | 33 +++++++++++++++++++++++ 1 file changed, 33 insertions(+) create mode 100644 src/test/debug-info/destructured-local.rs diff --git a/src/test/debug-info/destructured-local.rs b/src/test/debug-info/destructured-local.rs new file mode 100644 index 0000000000000..bf53d95b588d0 --- /dev/null +++ b/src/test/debug-info/destructured-local.rs @@ -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 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// xfail-test + +// GDB doesn't know about UTF-32 character encoding and will print a rust char as only its numerical +// value. + +// compile-flags:-Z extra-debug-info +// debugger:break zzz +// debugger:run +// debugger:finish + +// debugger:print a +// check:$1 = 9898 + +// debugger:print b +// check:$2 = false + +fn main() { + let (a, b) : (int, bool) = (9898, false); + + zzz(); +} + +fn zzz() {()} \ No newline at end of file From 4fb471ab7828e31c29054b76217c42917c4206c5 Mon Sep 17 00:00:00 2001 From: Michael Woerister Date: Tue, 25 Jun 2013 21:55:02 +0200 Subject: [PATCH 16/18] debuginfo: Added test case for function arguments. --- src/test/debug-info/function-arguments.rs | 51 +++++++++++++++++++++++ 1 file changed, 51 insertions(+) create mode 100644 src/test/debug-info/function-arguments.rs diff --git a/src/test/debug-info/function-arguments.rs b/src/test/debug-info/function-arguments.rs new file mode 100644 index 0000000000000..f5563cda259e9 --- /dev/null +++ b/src/test/debug-info/function-arguments.rs @@ -0,0 +1,51 @@ +// 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. + +// xfail-test + +// GDB doesn't know about UTF-32 character encoding and will print a rust char as only its numerical +// value. + +// compile-flags:-Z extra-debug-info +// debugger:break zzz +// debugger:run +// debugger:finish + +// debugger:print x +// check:$1 = 111102 +// debugger:print y +// check:$2 = true + +// debugger:continue +// debugger:finish + +// debugger:print a +// check:$3 = 2000 +// debugger:print b +// check:$4 = 3000 + +fn main() { + + fun(111102, true); + nested(2000, 3000); + + fn nested(a: i32, b: i64) -> (i32, i64) { + zzz() + (a, b) + } +} + +fn fun(x: int, y: bool) -> (int, bool) { + zzz(); + + (x, y) +} + +fn zzz() {()} \ No newline at end of file From 42dbae7f2a7dbdc414646e706eeffacdf7d4b338 Mon Sep 17 00:00:00 2001 From: Michael Woerister Date: Wed, 26 Jun 2013 22:17:45 +0200 Subject: [PATCH 17/18] debuginfo: Formatting cleanup. --- src/test/debug-info/struct-in-struct.rs | 24 +++++++------------ src/test/debug-info/struct-with-destructor.rs | 6 ++--- src/test/debug-info/variable-scope.rs | 4 ++-- 3 files changed, 12 insertions(+), 22 deletions(-) diff --git a/src/test/debug-info/struct-in-struct.rs b/src/test/debug-info/struct-in-struct.rs index cfd8c24caa21a..04c5eec610b73 100644 --- a/src/test/debug-info/struct-in-struct.rs +++ b/src/test/debug-info/struct-in-struct.rs @@ -111,20 +111,15 @@ fn main() { }; let bag = Bag { x: Simple { x: 22 } }; - let bag_in_bag = BagInBag - { - x: Bag - { + let bag_in_bag = BagInBag { + x: Bag { x: Simple { x: 23 } } }; - let tjo = ThatsJustOverkill - { - x: BagInBag - { - x: Bag - { + let tjo = ThatsJustOverkill { + x: BagInBag { + x: Bag { x: Simple { x: 24 } } } @@ -132,16 +127,13 @@ fn main() { let tree = Tree { x: Simple { x: 25 }, - y: InternalPaddingParent - { + y: InternalPaddingParent { x: InternalPadding { x: 26, y: 27 }, y: InternalPadding { x: 28, y: 29 }, z: InternalPadding { x: 30, y: 31 } }, - z: BagInBag - { - x: Bag - { + z: BagInBag { + x: Bag { x: Simple { x: 32 } } } diff --git a/src/test/debug-info/struct-with-destructor.rs b/src/test/debug-info/struct-with-destructor.rs index b5ae4bbe8fbaf..c023e3c2ccbda 100644 --- a/src/test/debug-info/struct-with-destructor.rs +++ b/src/test/debug-info/struct-with-destructor.rs @@ -37,14 +37,12 @@ impl Drop for WithDestructor { fn finalize(&self) {} } -struct NoDestructorGuarded -{ +struct NoDestructorGuarded { a: NoDestructor, guard: i64 } -struct WithDestructorGuarded -{ +struct WithDestructorGuarded { a: WithDestructor, guard: i64 } diff --git a/src/test/debug-info/variable-scope.rs b/src/test/debug-info/variable-scope.rs index a9177ac196647..dd3a1671b7858 100644 --- a/src/test/debug-info/variable-scope.rs +++ b/src/test/debug-info/variable-scope.rs @@ -19,12 +19,12 @@ // debugger:print y // check:$2 = true -// debugger:run +// debugger:continue // debugger:finish // debugger:print x // check:$3 = 10 -// debugger:run +// debugger:continue // debugger:finish // debugger:print x // check:$4 = false From 2f5e33d02f0103a40de2493f824627effaedc6e0 Mon Sep 17 00:00:00 2001 From: Michael Woerister Date: Thu, 27 Jun 2013 19:27:06 +0200 Subject: [PATCH 18/18] debuginfo: Some corrections after review. --- src/librustc/middle/trans/debuginfo.rs | 25 ------------------- .../debug-info/reference-to-managed-basic.rs | 3 +-- src/test/debug-info/struct-with-destructor.rs | 17 +++++++++++-- 3 files changed, 16 insertions(+), 29 deletions(-) diff --git a/src/librustc/middle/trans/debuginfo.rs b/src/librustc/middle/trans/debuginfo.rs index b1434bb798a96..a42f20ea39ca3 100644 --- a/src/librustc/middle/trans/debuginfo.rs +++ b/src/librustc/middle/trans/debuginfo.rs @@ -559,31 +559,6 @@ impl StructContext { roundup(self.total_size, self.align) } - //fn verify_against_struct_or_tuple_type(&self, t: ty::t, ccx: &mut CrateContext) { - // let repr = adt::represent_type(ccx, t); - - // match *repr { - // Univariant(*) => - // { - // let size_with_alignment = self.get_total_size_with_alignment(); - - // if st.size != size_with_alignment { - // ccx.sess.bug("StructContext(%s)::verify_against_struct_or_tuple_type: - // invalid type size. Expected = %u, actual = %u", - // st.size, size_with_alignment); - // } - - // if st.align != self.align { - // ccx.sess.bug("StructContext(%s)::verify_against_struct_or_tuple_type: - // invalid type alignment. Expected = %u, actual = %u", - // st.align, self.align); - // } - // }, - // _ => ccx.sess.bug(fmt!("StructContext(%s)::verify_against_struct_or_tuple_type: - // called with invalid type %?", self.name, t)) - // } - //} - fn finalize(&self) -> DICompositeType { debug!("StructContext(%s)::finalize: total_size=%u, align=%u", self.name, self.total_size, self.align); diff --git a/src/test/debug-info/reference-to-managed-basic.rs b/src/test/debug-info/reference-to-managed-basic.rs index b93b2cee2d273..e3951c94b6f86 100644 --- a/src/test/debug-info/reference-to-managed-basic.rs +++ b/src/test/debug-info/reference-to-managed-basic.rs @@ -10,8 +10,7 @@ // xfail-win32 Broken because of LLVM bug: http://llvm.org/bugs/show_bug.cgi?id=16249 -// Gdb doesn't know -// about UTF-32 character encoding and will print a rust char as only +// Gdb doesn't know about UTF-32 character encoding and will print a rust char as only // its numerical value. // compile-flags:-Z extra-debug-info diff --git a/src/test/debug-info/struct-with-destructor.rs b/src/test/debug-info/struct-with-destructor.rs index c023e3c2ccbda..f8281bba49e9f 100644 --- a/src/test/debug-info/struct-with-destructor.rs +++ b/src/test/debug-info/struct-with-destructor.rs @@ -49,7 +49,7 @@ struct WithDestructorGuarded { // The compiler adds a 'destructed' boolean field to structs implementing Drop. This field is used -// at runtime to prevent finalize() to be executed more than once (see middle::trans::adt). +// at runtime to prevent drop() to be executed more than once (see middle::trans::adt). // This field must be incorporated by the debug info generation. Otherwise the debugger assumes a // wrong size/layout for the struct. fn main() { @@ -63,7 +63,20 @@ fn main() { // If the destructor flag field is not incorporated into the debug info for 'WithDestructor' // then the debugger will have an invalid offset for the field 'guard' and thus should not be - // able to read its value correctly. + // able to read its value correctly (dots are padding bytes, D is the boolean destructor flag): + // + // NoDestructorGuarded = 0000....00000000FFFFFFFF + // <--------------><------> + // NoDestructor guard + // + // + // withDestructorGuarded = 0000....00000000D.......FFFFFFFF + // <--------------><------> // How debug info says it is + // WithDestructor guard + // + // <----------------------><------> // How it actually is + // WithDestructor guard + // let withDestructor = WithDestructorGuarded { a: WithDestructor { x: 10, y: 20 }, guard: -1