]> git.lizzy.rs Git - rust.git/commitdiff
debuginfo: Added test cases for structs, tuples, enums, etc passed by value.
authorMichael Woerister <michaelwoerister@gmail>
Thu, 29 Aug 2013 09:44:11 +0000 (11:44 +0200)
committerMichael Woerister <michaelwoerister@gmail>
Wed, 4 Sep 2013 16:38:46 +0000 (18:38 +0200)
Also updated documentation comments in debuginfo and renamed DebugContext to CrateDebugContext.

src/librustc/middle/trans/context.rs
src/librustc/middle/trans/debuginfo.rs
src/rustllvm/rustllvm.def.in
src/test/debug-info/by-value-non-immediate-argument.rs [new file with mode: 0644]
src/test/debug-info/by-value-struct-argument.rs [deleted file]
src/test/debug-info/var-captured-in-managed-closure.rs
src/test/debug-info/var-captured-in-nested-closure.rs [new file with mode: 0644]
src/test/debug-info/var-captured-in-sendable-closure.rs
src/test/debug-info/var-captured-in-stack-closure.rs

index e7781e93d8ceca933e0c1a6a7fcb0fa24f44f3c1..59159f61f485f1db385bc3eacd45347f53ae31af 100644 (file)
@@ -111,7 +111,7 @@ pub struct CrateContext {
      // decl_gc_metadata knows whether to link to the module metadata, which
      // is not emitted by LLVM's GC pass when no functions use GC.
      uses_gc: bool,
-     dbg_cx: Option<debuginfo::DebugContext>,
+     dbg_cx: Option<debuginfo::CrateDebugContext>,
      do_not_commit_warning_issued: bool
 }
 
@@ -161,7 +161,7 @@ pub fn new(sess: session::Session,
 
             let crate_map = decl_crate_map(sess, link_meta, llmod);
             let dbg_cx = if sess.opts.debuginfo {
-                Some(debuginfo::DebugContext::new(llmod, name.to_owned()))
+                Some(debuginfo::CrateDebugContext::new(llmod, name.to_owned()))
             } else {
                 None
             };
index 70eb54313ca637afbfe57164aeb4db69aad094a8..1a39e0aa1a0f6e5eb0c4ce1bac51669daff9c4ff 100644 (file)
@@ -27,7 +27,7 @@
 
 The public API of the module is a set of functions that will insert the correct metadata into the
 LLVM IR when called with the right parameters. The module is thus driven from an outside client with
-functions like `debuginfo::local_var_metadata(bcx: block, local: &ast::local)`.
+functions like `debuginfo::create_local_var_metadata(bcx: block, local: &ast::local)`.
 
 Internally the module will try to reuse already created metadata by utilizing a cache. The way to
 get a shared metadata node when needed is thus to just call the corresponding function in this
@@ -37,9 +37,8 @@
 
 The function will take care of probing the cache for an existing node for that exact file path.
 
-All private state used by the module is stored within a DebugContext struct, which in turn is
-contained in the CrateContext.
-
+All private state used by the module is stored within either the CrateDebugContext struct (owned by
+the CrateContext) or the FunctionDebugContext (owned by the FunctionContext).
 
 This file consists of three conceptual sections:
 1. The public interface of the module
@@ -92,7 +91,7 @@
 //=-------------------------------------------------------------------------------------------------
 
 /// A context object for maintaining all state needed by the debuginfo module.
-pub struct DebugContext {
+pub struct CrateDebugContext {
     priv crate_file: ~str,
     priv llcontext: ContextRef,
     priv builder: DIBuilderRef,
@@ -101,13 +100,13 @@ pub struct DebugContext {
     priv created_types: HashMap<uint, DIType>,
 }
 
-impl DebugContext {
-    pub fn new(llmod: ModuleRef, crate: ~str) -> DebugContext {
-        debug!("DebugContext::new");
+impl CrateDebugContext {
+    pub fn new(llmod: ModuleRef, crate: ~str) -> CrateDebugContext {
+        debug!("CrateDebugContext::new");
         let builder = unsafe { llvm::LLVMDIBuilderCreate(llmod) };
         // DIBuilder inherits context from the module, so we'd better use the same one
         let llcontext = unsafe { llvm::LLVMGetModuleContext(llmod) };
-        return DebugContext {
+        return CrateDebugContext {
             crate_file: crate,
             llcontext: llcontext,
             builder: builder,
@@ -165,9 +164,9 @@ struct FunctionDebugContextData {
 }
 
 enum VariableAccess {
-    // The value given is a pointer to data
+    // The value given is a pointer to the data (T*)
     DirectVariable,
-    // The value given has to be dereferenced once to get the pointer to data
+    // The value given has to be dereferenced once to get the pointer to data (T**)
     IndirectVariable
 }
 
@@ -224,9 +223,9 @@ pub fn create_local_var_metadata(bcx: @mut Block,
     }
 }
 
-/// Creates debug information for a local variable introduced in the head of a match-statement arm.
+/// Creates debug information for a variable captured in a closure.
 ///
-// /// Adds the created metadata nodes directly to the crate's IR.
+/// Adds the created metadata nodes directly to the crate's IR.
 pub fn create_captured_var_metadata(bcx: @mut Block,
                                     node_id: ast::NodeId,
                                     llptr: ValueRef,
@@ -321,7 +320,8 @@ pub fn create_self_argument_metadata(bcx: @mut Block,
             _) => {
             explicit_self.span
         }
-        _ => bcx.ccx().sess.bug(fmt!("create_self_argument_metadata: unexpected sort of node: %?", fnitem))
+        _ => bcx.ccx().sess.bug(
+                fmt!("create_self_argument_metadata: unexpected sort of node: %?", fnitem))
     };
 
     let scope_metadata = bcx.fcx.debug_context.get_ref(bcx.ccx(), span).fn_metadata;
@@ -361,14 +361,10 @@ pub fn create_argument_metadata(bcx: @mut Block,
     let fcx = bcx.fcx;
     let cx = fcx.ccx;
 
-    let pattern = arg.pat;
-    let filename = span_start(cx, pattern.span).file.name;
-
     let def_map = cx.tcx.def_map;
-    let file_metadata = file_metadata(cx, filename);
     let scope_metadata = bcx.fcx.debug_context.get_ref(cx, arg.pat.span).fn_metadata;
 
-    do pat_util::pat_bindings(def_map, pattern) |_, node_id, span, path_ref| {
+    do pat_util::pat_bindings(def_map, arg.pat) |_, node_id, span, path_ref| {
 
         let llptr = match bcx.fcx.llargs.find_copy(&node_id) {
             Some(v) => v,
@@ -429,13 +425,24 @@ pub fn set_source_location(fcx: &FunctionContext,
     }
 }
 
+/// Enables emitting source locations for the given functions.
+///
+/// Since we don't want source locations to be emitted for the function prelude, they are disabled
+/// when beginning to translate a new function. This functions switches source location emitting on
+/// and must therefore be called before the first real statement/expression of the function is
+/// translated.
 pub fn start_emitting_source_locations(fcx: &mut FunctionContext) {
     match fcx.debug_context {
         FunctionDebugContext(~ref mut data) => data.source_locations_enabled = true,
-        _ => { /* safe to ignore */}
+        _ => { /* safe to ignore */ }
     }
 }
 
+/// Creates the function-specific debug context.
+///
+/// Returns the FunctionDebugContext for the function which holds state needed for debug info
+/// creation. The function may also return another variant of the FunctionDebugContext enum which
+/// indicates why no debuginfo should be created for the function.
 pub fn create_function_debug_context(cx: &mut CrateContext,
                                      fn_ast_id: ast::NodeId,
                                      param_substs: Option<@param_substs>,
@@ -1663,7 +1670,7 @@ fn bytes_to_bits(bytes: uint) -> c_ulonglong {
 }
 
 #[inline]
-fn dbg_cx<'a>(cx: &'a mut CrateContext) -> &'a mut DebugContext {
+fn dbg_cx<'a>(cx: &'a mut CrateContext) -> &'a mut CrateDebugContext {
     cx.dbg_cx.get_mut_ref()
 }
 
index e2cec6a04f346001e6a03dbbddca691e59a6ef6a..79cfe8b28519a4dc43193b586da67156ae4cdc54 100644 (file)
@@ -608,6 +608,9 @@ LLVMDIBuilderCreateEnumerator
 LLVMDIBuilderCreateEnumerationType
 LLVMDIBuilderCreateUnionType
 LLVMDIBuilderCreateTemplateTypeParameter
+LLVMDIBuilderCreateOpDeref
+LLVMDIBuilderCreateOpPlus
+LLVMDIBuilderCreateComplexVariable
 LLVMSetUnnamedAddr
 LLVMRustAddPass
 LLVMRustAddAnalysisPasses
diff --git a/src/test/debug-info/by-value-non-immediate-argument.rs b/src/test/debug-info/by-value-non-immediate-argument.rs
new file mode 100644 (file)
index 0000000..da9c79a
--- /dev/null
@@ -0,0 +1,99 @@
+// 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 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// compile-flags:-Z extra-debug-info
+// debugger:break zzz
+// debugger:run
+
+// debugger:finish
+// debugger:print s
+// check:$1 = {a = 1, b = 2.5}
+// debugger:continue
+
+// debugger:finish
+// debugger:print x
+// check:$2 = {a = 3, b = 4.5}
+// debugger:print y
+// check:$3 = 5
+// debugger:print z
+// check:$4 = 6.5
+// debugger:continue
+
+// debugger:finish
+// debugger:print a
+// check:$5 = {7, 8, 9.5, 10.5}
+// debugger:continue
+
+// debugger:finish
+// debugger:print a
+// check:$6 = {11.5, 12.5, 13, 14}
+// debugger:continue
+
+// debugger:finish
+// debugger:print x
+// check:$7 = {{Case1, x = 0, y = 8970181431921507452}, {Case1, 0, 2088533116, 2088533116}}
+// debugger:continue
+
+#[deriving(Clone)]
+struct Struct {
+    a: int,
+    b: float
+}
+
+#[deriving(Clone)]
+struct StructStruct {
+    a: Struct,
+    b: Struct
+}
+
+fn fun(s: Struct) {
+    zzz();
+}
+
+fn fun_fun(StructStruct { a: x, b: Struct { a: y, b: z } }: StructStruct) {
+    zzz();
+}
+
+fn tup(a: (int, uint, float, float)) {
+    zzz();
+}
+
+struct Newtype(float, float, int, uint);
+
+fn new_type(a: Newtype) {
+    zzz();
+}
+
+// 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 Enum {
+    Case1 { x: i64, y: i64 },
+    Case2 (i64, i32, i32),
+}
+
+fn by_val_enum(x: Enum) {
+    zzz();
+}
+
+fn main() {
+    fun(Struct { a: 1, b: 2.5 });
+    fun_fun(StructStruct { a: Struct { a: 3, b: 4.5 }, b: Struct { a: 5, b: 6.5 } });
+    tup((7, 8, 9.5, 10.5));
+    new_type(Newtype(11.5, 12.5, 13, 14));
+
+    // 0b0111110001111100011111000111110001111100011111000111110001111100 = 8970181431921507452
+    // 0b01111100011111000111110001111100 = 2088533116
+    // 0b0111110001111100 = 31868
+    // 0b01111100 = 124
+    by_val_enum(Case1 { x: 0, y: 8970181431921507452 });
+}
+
+fn zzz() {()}
diff --git a/src/test/debug-info/by-value-struct-argument.rs b/src/test/debug-info/by-value-struct-argument.rs
deleted file mode 100644 (file)
index 73bd805..0000000
+++ /dev/null
@@ -1,34 +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 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-// compile-flags:-Z extra-debug-info
-// debugger:break zzz
-// debugger:run
-
-// debugger:finish
-// debugger:print s
-// check:$1 = {a = 1, b = 2.5}
-// debugger:continue
-
-#[deriving(Clone)]
-struct Struct {
-    a: int,
-    b: float
-}
-
-fn fun(s: Struct) {
-    zzz();
-}
-
-fn main() {
-    fun(Struct { a: 1, b: 2.5 });
-}
-
-fn zzz() {()}
index 37f5fef471b6dfd987eb5b0916e8f2acaadc761c..002bfbd2242ae9089f41c316e999873eab4a89cf 100644 (file)
@@ -8,8 +8,6 @@
 // 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
diff --git a/src/test/debug-info/var-captured-in-nested-closure.rs b/src/test/debug-info/var-captured-in-nested-closure.rs
new file mode 100644 (file)
index 0000000..60ad2a3
--- /dev/null
@@ -0,0 +1,74 @@
+// 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 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// compile-flags:-Z extra-debug-info
+// debugger:break zzz
+// debugger:run
+// debugger:finish
+
+// debugger:print variable
+// check:$1 = 1
+// debugger:print constant
+// check:$2 = 2
+// debugger:print a_struct
+// check:$3 = {a = -3, b = 4.5, c = 5}
+// debugger:print *struct_ref
+// check:$4 = {a = -3, b = 4.5, c = 5}
+// debugger:print *owned
+// check:$5 = 6
+// debugger:print managed->val
+// check:$6 = 7
+// debugger:print closure_local
+// check:$7 = 8
+// debugger:continue
+
+#[allow(unused_variable)];
+
+struct Struct {
+    a: int,
+    b: float,
+    c: uint
+}
+
+fn main() {
+    let mut variable = 1;
+    let constant = 2;
+
+    let a_struct = Struct {
+        a: -3,
+        b: 4.5,
+        c: 5
+    };
+
+    let struct_ref = &a_struct;
+    let owned = ~6;
+    let managed = @7;
+
+    let closure = || {
+        let closure_local = 8;
+
+        let nested_closure = || {
+            zzz();
+            variable = constant + a_struct.a + struct_ref.a + *owned + *managed + closure_local;
+        };
+
+        // breaking here will yield a wrong value for 'constant'. In particular, GDB will
+        // read the value of the register that supposedly contains the pointer to 'constant'
+        // and try derefence it. The register, however, already contains the actual value, and
+        // not a pointer to it. -mw
+        // zzz();
+
+        nested_closure();
+    };
+
+    closure();
+}
+
+fn zzz() {()}
index c4568bd592fa610538fe8883786ff553cd3f2fab..01839ea783533b8765d29eb9df358f888c6881ca 100644 (file)
@@ -8,8 +8,6 @@
 // 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
index 6694d5111a83560467aa81e57d360a8748c7768c..3ce7d6fd89bddbc40cc584019443839c5c1e7afb 100644 (file)
@@ -8,8 +8,6 @@
 // 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