From 5c9d7c2072ef93adf9912643d025e48ac832c3a6 Mon Sep 17 00:00:00 2001 From: Michael Woerister Date: Tue, 13 Aug 2013 16:31:42 +0200 Subject: [PATCH] debuginfo: Added test cases for generic structs and enums. Also, always set no_monomorphic_collapse flags if debuginfo is generated. --- src/librustc/driver/driver.rs | 8 ++ src/librustc/middle/trans/debuginfo.rs | 12 +-- .../debug-info/generic-struct-style-enum.rs | 77 ++++++++++++++++++ src/test/debug-info/generic-struct.rs | 42 ++++++++++ .../debug-info/generic-tuple-style-enum.rs | 78 +++++++++++++++++++ src/test/debug-info/struct-style-enum.rs | 2 +- 6 files changed, 213 insertions(+), 6 deletions(-) create mode 100644 src/test/debug-info/generic-struct-style-enum.rs create mode 100644 src/test/debug-info/generic-struct.rs create mode 100644 src/test/debug-info/generic-tuple-style-enum.rs diff --git a/src/librustc/driver/driver.rs b/src/librustc/driver/driver.rs index 89a8d33955d..5227d68774b 100644 --- a/src/librustc/driver/driver.rs +++ b/src/librustc/driver/driver.rs @@ -691,6 +691,14 @@ pub fn build_session_options(binary: @str, let extra_debuginfo = debugging_opts & session::extra_debug_info != 0; let debuginfo = debugging_opts & session::debug_info != 0 || extra_debuginfo; + + // If debugging info is generated, do not collapse monomorphized function instances. + // Functions with equivalent llvm code still need separate debugging descriptions because names + // might differ. + if debuginfo { + debugging_opts |= session::no_monomorphic_collapse; + } + let statik = debugging_opts & session::statik != 0; let addl_lib_search_paths = getopts::opt_strs(matches, "L").map(|s| Path(*s)); diff --git a/src/librustc/middle/trans/debuginfo.rs b/src/librustc/middle/trans/debuginfo.rs index a8600567c79..2bf79a1c757 100644 --- a/src/librustc/middle/trans/debuginfo.rs +++ b/src/librustc/middle/trans/debuginfo.rs @@ -256,9 +256,10 @@ pub fn create_argument_metadata(bcx: @mut Block, } } -/// Sets the current debug location at the beginning of the span +/// Sets the current debug location at the beginning of the span. /// -/// Maps to a call to llvm::LLVMSetCurrentDebugLocation(...) +/// Maps to a call to llvm::LLVMSetCurrentDebugLocation(...). The node_id parameter is used to +/// reliably find the correct visibility scope for the code position. pub fn update_source_pos(fcx: &FunctionContext, node_id: ast::NodeId, span: span) { @@ -357,6 +358,7 @@ pub fn create_function_metadata(fcx: &mut FunctionContext) -> DISubprogram { llvm::LLVMDIBuilderCreateSubroutineType(DIB(cx), file_metadata, fn_signature) }; + // get_template_parameters() will append a `<...>` clause to the function name if necessary. let mut function_name = cx.sess.str_of(ident).to_owned(); let template_parameters = get_template_parameters(fcx, generics, @@ -404,8 +406,8 @@ pub fn create_function_metadata(fcx: &mut FunctionContext) -> DISubprogram { } _ => cx.sess.span_bug(span, fmt!("debuginfo::create_function_metadata() - \ - FunctionContext::entry_bcx::node_info points to wrong type of ast_map entry. \ - Expected: ast_map::node_block, actual: %?", *entry_block)) + FunctionContext::entry_bcx::node_info points to wrong type of ast_map \ + entry. Expected: ast_map::node_block, actual: %?", *entry_block)) } fcx.debug_context = Some(fn_debug_context); @@ -508,7 +510,7 @@ pub fn create_function_metadata(fcx: &mut FunctionContext) -> DISubprogram { let actual_type_name = ty_to_str(cx.tcx, actual_type); name_to_append_suffix_to.push_str(actual_type_name); if index != generics.ty_params.len() - 1 { - name_to_append_suffix_to.push_str(", "); + name_to_append_suffix_to.push_str(","); } do cx.sess.str_of(ident).to_c_str().with_ref |name| { diff --git a/src/test/debug-info/generic-struct-style-enum.rs b/src/test/debug-info/generic-struct-style-enum.rs new file mode 100644 index 00000000000..77ac7895366 --- /dev/null +++ b/src/test/debug-info/generic-struct-style-enum.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-win32 Broken because of LLVM bug: http://llvm.org/bugs/show_bug.cgi?id=16249 + +// compile-flags:-Z extra-debug-info +// debugger:set print union on +// debugger:break zzz +// debugger:run +// debugger:finish + +// debugger:print case1 +// check:$1 = {{Case1, a = 0, b = 31868, c = 31868, d = 31868, e = 31868}, {Case1, a = 0, b = 2088533116, c = 2088533116}, {Case1, a = 0, b = 8970181431921507452}} + +// debugger:print case2 +// check:$2 = {{Case2, a = 0, b = 4369, c = 4369, d = 4369, e = 4369}, {Case2, a = 0, b = 286331153, c = 286331153}, {Case2, a = 0, b = 1229782938247303441}} + +// debugger:print case3 +// check:$3 = {{Case3, a = 0, b = 22873, c = 22873, d = 22873, e = 22873}, {Case3, a = 0, b = 1499027801, c = 1499027801}, {Case3, a = 0, b = 6438275382588823897}} + +// debugger:print univariant +// check:$4 = {a = -1} + +// NOTE: This is a copy of the non-generic test case. The `Txx` type parameters have to be +// substituted with something of size `xx` bits and the same alignment as an integer type of the +// same size. + +// The first element is to ensure proper alignment, irrespective of the machines word size. Since +// the size of the discriminant value is machine dependent, this has be taken into account when +// datatype layout should be predictable as in this case. +enum Regular { + Case1 { a: T64, b: T16, c: T16, d: T16, e: T16}, + Case2 { a: T64, b: T32, c: T32}, + Case3 { a: T64, b: T64 } +} + +enum Univariant { + TheOnlyCase { a: T } +} + +fn main() { + + // In order to avoid endianess trouble all of the following test values consist of a single + // repeated byte. This way each interpretation of the union should look the same, no matter if + // this is a big or little endian machine. + + // 0b0111110001111100011111000111110001111100011111000111110001111100 = 8970181431921507452 + // 0b01111100011111000111110001111100 = 2088533116 + // 0b0111110001111100 = 31868 + // 0b01111100 = 124 + let case1: Regular = Case1 { a: 0, b: 31868, c: 31868, d: 31868, e: 31868 }; + + // 0b0001000100010001000100010001000100010001000100010001000100010001 = 1229782938247303441 + // 0b00010001000100010001000100010001 = 286331153 + // 0b0001000100010001 = 4369 + // 0b00010001 = 17 + let case2: Regular = Case2 { a: 0, b: 286331153, c: 286331153 }; + + // 0b0101100101011001010110010101100101011001010110010101100101011001 = 6438275382588823897 + // 0b01011001010110010101100101011001 = 1499027801 + // 0b0101100101011001 = 22873 + // 0b01011001 = 89 + let case3: Regular = Case3 { a: 0, b: 6438275382588823897 }; + + let univariant = TheOnlyCase { a: -1 }; + + zzz(); +} + +fn zzz() {()} diff --git a/src/test/debug-info/generic-struct.rs b/src/test/debug-info/generic-struct.rs new file mode 100644 index 00000000000..0044def2707 --- /dev/null +++ b/src/test/debug-info/generic-struct.rs @@ -0,0 +1,42 @@ +// 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:break zzz +// debugger:run + +// debugger:finish +// debugger:print int_int +// check:$1 = {key = 0, value = 1} +// debugger:print int_float +// check:$2 = {key = 2, value = 3.5} +// debugger:print float_int +// check:$3 = {key = 4.5, value = 5} +// debugger:print float_int_float +// check:$4 = {key = 6.5, value = {key = 7, value = 8.5}} + +struct AGenericStruct { + key: TKey, + value: TValue +} + +fn main() { + + let int_int = AGenericStruct { key: 0, value: 1 }; + let int_float = AGenericStruct { key: 2, value: 3.5 }; + let float_int = AGenericStruct { key: 4.5, value: 5 }; + let float_int_float = AGenericStruct { key: 6.5, value: AGenericStruct { key: 7, value: 8.5 } }; + + zzz(); +} + +fn zzz() {()} diff --git a/src/test/debug-info/generic-tuple-style-enum.rs b/src/test/debug-info/generic-tuple-style-enum.rs new file mode 100644 index 00000000000..d6350e033f0 --- /dev/null +++ b/src/test/debug-info/generic-tuple-style-enum.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 + +// compile-flags:-Z extra-debug-info +// debugger:set print union on +// debugger:break zzz +// debugger:run +// debugger:finish + +// debugger:print case1 +// check:$1 = {{Case1, 0, 31868, 31868, 31868, 31868}, {Case1, 0, 2088533116, 2088533116}, {Case1, 0, 8970181431921507452}} + +// debugger:print case2 +// check:$2 = {{Case2, 0, 4369, 4369, 4369, 4369}, {Case2, 0, 286331153, 286331153}, {Case2, 0, 1229782938247303441}} + +// debugger:print case3 +// check:$3 = {{Case3, 0, 22873, 22873, 22873, 22873}, {Case3, 0, 1499027801, 1499027801}, {Case3, 0, 6438275382588823897}} + +// debugger:print univariant +// check:$4 = {-1} + + +// NOTE: This is a copy of the non-generic test case. The `Txx` type parameters have to be +// substituted with something of size `xx` bits and the same alignment as an integer type of the +// same size. + +// The first element is to ensure proper alignment, irrespective of the machines word size. Since +// the size of the discriminant value is machine dependent, this has be taken into account when +// datatype layout should be predictable as in this case. +enum Regular { + Case1(T64, T16, T16, T16, T16), + Case2(T64, T32, T32), + Case3(T64, T64) +} + +enum Univariant { + TheOnlyCase(T64) +} + +fn main() { + + // In order to avoid endianess trouble all of the following test values consist of a single + // repeated byte. This way each interpretation of the union should look the same, no matter if + // this is a big or little endian machine. + + // 0b0111110001111100011111000111110001111100011111000111110001111100 = 8970181431921507452 + // 0b01111100011111000111110001111100 = 2088533116 + // 0b0111110001111100 = 31868 + // 0b01111100 = 124 + let case1: Regular = Case1(0_u64, 31868_u16, 31868_u16, 31868_u16, 31868_u16); + + // 0b0001000100010001000100010001000100010001000100010001000100010001 = 1229782938247303441 + // 0b00010001000100010001000100010001 = 286331153 + // 0b0001000100010001 = 4369 + // 0b00010001 = 17 + let case2: Regular = Case2(0_i64, 286331153_i32, 286331153_i32); + + // 0b0101100101011001010110010101100101011001010110010101100101011001 = 6438275382588823897 + // 0b01011001010110010101100101011001 = 1499027801 + // 0b0101100101011001 = 22873 + // 0b01011001 = 89 + let case3: Regular = Case3(0_i64, 6438275382588823897_i64); + + let univariant = TheOnlyCase(-1_i64); + + zzz(); +} + +fn zzz() {()} diff --git a/src/test/debug-info/struct-style-enum.rs b/src/test/debug-info/struct-style-enum.rs index 61bbd2e215f..77d7746e2df 100644 --- a/src/test/debug-info/struct-style-enum.rs +++ b/src/test/debug-info/struct-style-enum.rs @@ -70,4 +70,4 @@ fn main() { zzz(); } -fn zzz() {()} \ No newline at end of file +fn zzz() {()}