diff --git a/src/librustc/lib/llvm.rs b/src/librustc/lib/llvm.rs index d248627907a..559db3f9b84 100644 --- a/src/librustc/lib/llvm.rs +++ b/src/librustc/lib/llvm.rs @@ -2045,6 +2045,14 @@ pub mod llvm { AlwaysPreserve: bool, Flags: c_uint, ArgNo: c_uint) -> DIVariable; + + #[fast_ffi] + pub unsafe fn LLVMDIBuilderCreateArrayType( + Builder: DIBuilderRef, + Size: c_ulonglong, + AlignInBits: c_ulonglong, + Ty: DIType, + Subscripts: DIArray) -> DIType; #[fast_ffi] pub unsafe fn LLVMDIBuilderCreateVectorType( diff --git a/src/librustc/middle/trans/debuginfo.rs b/src/librustc/middle/trans/debuginfo.rs index bbdfefaaa59..07aedf4b2c9 100644 --- a/src/librustc/middle/trans/debuginfo.rs +++ b/src/librustc/middle/trans/debuginfo.rs @@ -24,6 +24,7 @@ use util::ppaux::ty_to_str; use core::hashmap::HashMap; use core::libc; use core::libc::c_uint; +use core::cmp; use core::ptr; use core::str::as_c_str; use core::sys; @@ -204,8 +205,7 @@ fn create_block(bcx: block) -> DILexicalBlock { fn size_and_align_of(cx: @CrateContext, t: ty::t) -> (uint, uint) { let llty = type_of::type_of(cx, t); - (machine::llsize_of_real(cx, llty), - machine::llalign_of_pref(cx, llty)) + (machine::llsize_of_real(cx, llty), machine::llalign_of_min(cx, llty)) } fn create_basic_type(cx: @CrateContext, t: ty::t, span: span) -> DIType{ @@ -277,6 +277,7 @@ struct StructContext { impl StructContext { fn create(cx: @CrateContext, file: DIFile, name: ~str, line: uint) -> ~StructContext { + debug!("StructContext::create: %s", name); let scx = ~StructContext { cx: cx, file: file, @@ -284,39 +285,48 @@ impl StructContext { line: line, members: ~[], total_size: 0, - align: 64 //XXX different alignment per arch? + align: 1 }; return scx; } 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); let mem_t = do as_c_str(name) |name| { unsafe { llvm::LLVMDIBuilderCreateMemberType(dbg_cx(self.cx).builder, ptr::null(), name, self.file, line as c_uint, - size * 8 as u64, align * 8 as u64, self.total_size as u64, + size * 8 as u64, align * 8 as u64, offset * 8 as u64, 0, ty) }}; - // XXX What about member alignment??? self.members.push(mem_t); - self.total_size += size * 8; + self.total_size = offset + size; + // struct alignment is the max alignment of its' members + self.align = cmp::max(self.align, align); } fn finalize(&self) -> DICompositeType { + debug!("StructContext(%s)::finalize: total_size=%u, align=%u", self.name, self.total_size, self.align); let dcx = dbg_cx(self.cx); let members_md = create_DIArray(dcx.builder, self.members); let struct_md = do as_c_str(self.name) |name| { unsafe { llvm::LLVMDIBuilderCreateStructType( - dcx.builder, ptr::null(), name, + dcx.builder, self.file, name, self.file, self.line as c_uint, - self.total_size as u64, self.align as u64, 0, ptr::null(), + self.total_size * 8 as u64, self.align * 8 as u64, 0, ptr::null(), members_md, 0, ptr::null()) }}; return struct_md; } } +#[inline(always)] +fn roundup(x: uint, a: uint) -> uint { + ((x + (a - 1)) / a) * a +} + fn create_struct(cx: @CrateContext, t: ty::t, fields: ~[ty::field], span: span) -> DICompositeType { let loc = span_start(cx, span); let file_md = create_file(cx, loc.file.name); @@ -390,12 +400,12 @@ fn create_fixed_vec(cx: @CrateContext, vec_t: ty::t, elem_t: ty::t, let (size, align) = size_and_align_of(cx, elem_t); let subrange = unsafe { - llvm::LLVMDIBuilderGetOrCreateSubrange(dcx.builder, 0_i64, (len-1) as i64) }; + llvm::LLVMDIBuilderGetOrCreateSubrange(dcx.builder, 0_i64, len as i64) }; let subscripts = create_DIArray(dcx.builder, [subrange]); return unsafe { - llvm::LLVMDIBuilderCreateVectorType(dcx.builder, - size * len as u64, align as u64, elem_ty_md, subscripts) + llvm::LLVMDIBuilderCreateArrayType(dcx.builder, + size * len * 8 as u64, align * 8 as u64, elem_ty_md, subscripts) }; } @@ -418,8 +428,8 @@ fn create_boxed_vec(cx: @CrateContext, vec_t: ty::t, elem_t: ty::t, let name = fmt!("[%s]", ty_to_str(cx.tcx, elem_t)); let subscripts = create_DIArray(dcx.builder, [subrange]); - let data_ptr = unsafe { llvm::LLVMDIBuilderCreateVectorType(dcx.builder, - arr_size as u64, arr_align as u64, elem_ty_md, subscripts) }; + let data_ptr = unsafe { llvm::LLVMDIBuilderCreateArrayType(dcx.builder, + arr_size * 8 as u64, arr_align * 8 as u64, elem_ty_md, subscripts) }; 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(); diff --git a/src/rustllvm/RustWrapper.cpp b/src/rustllvm/RustWrapper.cpp index b7a67f984f7..6537e232f8b 100644 --- a/src/rustllvm/RustWrapper.cpp +++ b/src/rustllvm/RustWrapper.cpp @@ -725,6 +725,17 @@ extern "C" LLVMValueRef LLVMDIBuilderCreateLocalVariable( unwrapDI(Ty), AlwaysPreserve, Flags, ArgNo)); } +extern "C" LLVMValueRef LLVMDIBuilderCreateArrayType( + DIBuilderRef Builder, + uint64_t Size, + uint64_t AlignInBits, + LLVMValueRef Ty, + LLVMValueRef Subscripts) { + return wrap(Builder->createArrayType(Size, AlignInBits, + unwrapDI(Ty), + unwrapDI(Subscripts))); +} + extern "C" LLVMValueRef LLVMDIBuilderCreateVectorType( DIBuilderRef Builder, uint64_t Size, diff --git a/src/rustllvm/rustllvm.def.in b/src/rustllvm/rustllvm.def.in index d1ed69feb04..2a3f7de9bf5 100644 --- a/src/rustllvm/rustllvm.def.in +++ b/src/rustllvm/rustllvm.def.in @@ -601,6 +601,7 @@ LLVMDIBuilderCreatePointerType LLVMDIBuilderCreateMemberType LLVMDIBuilderCreateStructType LLVMDIBuilderGetOrCreateSubrange +LLVMDIBuilderCreateArrayType LLVMDIBuilderCreateVectorType LLVMDIBuilderCreateSubroutineType LLVMDIBuilderGetOrCreateArray diff --git a/src/test/debug-info/basic-types.rs b/src/test/debug-info/basic-types.rs index 20da6b557f1..616740c850c 100644 --- a/src/test/debug-info/basic-types.rs +++ b/src/test/debug-info/basic-types.rs @@ -8,7 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -// xfail-test +// 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 @@ -17,8 +17,9 @@ // its numerical value. // compile-flags:-Z extra-debug-info -// debugger:break 67 +// debugger:break _zzz // debugger:run +// debugger:finish // debugger:print b // check:$1 = false // debugger:print i @@ -66,5 +67,7 @@ fn main() { let f: float = 1.5; let f32: f32 = 2.5; let f64: f64 = 3.5; - let _z = (); + _zzz(); } + +fn _zzz() {()} diff --git a/src/test/debug-info/box.rs b/src/test/debug-info/box.rs index 54aa0c12578..3e5483ad75b 100644 --- a/src/test/debug-info/box.rs +++ b/src/test/debug-info/box.rs @@ -8,12 +8,13 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -// xfail-test +// 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 29 +// debugger:break _zzz // debugger:run +// debugger:finish // debugger:print a->boxed // check:$1 = 1 // debugger:print b->boxed @@ -28,5 +29,7 @@ fn main() { let b = ~(2, 3.5); let c = @4; let d = @false; - let _z = 0; + _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 index 16ba6cda590..ddfac9cbeea 100644 --- a/src/test/debug-info/struct.rs +++ b/src/test/debug-info/struct.rs @@ -8,12 +8,13 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -// xfail-test +// 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 29 +// debugger:break _zzz // debugger:run +// debugger:finish // debugger:print pair // check:$1 = {x = 1, y = 2} // debugger:print pair.x @@ -28,5 +29,7 @@ struct Pair { fn main() { let pair = Pair { x: 1, y: 2 }; - let _z = (); + _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 index 35e2977f562..a50996871ce 100644 --- a/src/test/debug-info/tuple.rs +++ b/src/test/debug-info/tuple.rs @@ -8,16 +8,19 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -// xfail-test +// 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 20 +// debugger:break _zzz // debugger:run +// debugger:finish // debugger:print t // check:$1 = {4, 5.5, true} fn main() { let t = (4, 5.5, true); - let _z = (); + _zzz(); } + +fn _zzz() {()} \ No newline at end of file diff --git a/src/test/debug-info/vec.rs b/src/test/debug-info/vec.rs index 3876f1c46d4..c87849ac4b6 100644 --- a/src/test/debug-info/vec.rs +++ b/src/test/debug-info/vec.rs @@ -8,12 +8,13 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -// xfail-test +// 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 29 +// debugger:break _zzz // debugger:run +// debugger:finish // debugger:print a // check:$1 = {1, 2, 3} // debugger:print b.vec[0] @@ -28,5 +29,7 @@ fn main() { let b = &[4, 5, 6]; let c = @[7, 8, 9]; let d = ~[10, 11, 12]; - let _z = 0; + _zzz(); } + +fn _zzz() {()} \ No newline at end of file