about summary refs log tree commit diff
diff options
context:
space:
mode:
authorJosh Matthews <josh@joshmatthews.net>2011-12-06 00:05:22 -0500
committerJosh Matthews <josh@joshmatthews.net>2011-12-18 23:44:21 -0500
commit6c26b892e422b7ea8d4576f074dc2e9af52caed4 (patch)
tree759a76ffe609ffa06deb4a5e6509b24d1098100c
parent0752252737d530db5b81ebd3127c622f6ec92712 (diff)
downloadrust-6c26b892e422b7ea8d4576f074dc2e9af52caed4.tar.gz
rust-6c26b892e422b7ea8d4576f074dc2e9af52caed4.zip
Add argument metadata and aborted return value code.
-rw-r--r--src/comp/middle/debuginfo.rs117
-rw-r--r--src/comp/middle/trans.rs14
-rw-r--r--src/comp/middle/trans_build.rs8
3 files changed, 130 insertions, 9 deletions
diff --git a/src/comp/middle/debuginfo.rs b/src/comp/middle/debuginfo.rs
index 1b83353119d..be70c1b3f3d 100644
--- a/src/comp/middle/debuginfo.rs
+++ b/src/comp/middle/debuginfo.rs
@@ -4,10 +4,10 @@ import lib::llvm::llvm;
 import lib::llvm::llvm::ValueRef;
 import middle::trans_common::*;
 import middle::ty;
-import ast::ty;
 import syntax::{ast, codemap};
+import ast::ty;
 
-const LLVMDebugVersion: int = (9 << 16); //& 0xffff0000; // 0x80000 ?
+const LLVMDebugVersion: int = (9 << 16);
 
 const DW_LANG_RUST: int = 0x9000;
 const DW_VIRTUALITY_none: int = 0;
@@ -78,6 +78,8 @@ type subprogram_md = {name: str, file: str};
 type local_var_md = {id: ast::node_id};
 type tydesc_md = {hash: uint};
 type block_md = {start: codemap::loc, end: codemap::loc};
+type argument_md = {id: ast::node_id};
+type retval_md = {id: ast::node_id};
 
 type metadata_cache = hashmap<int, [debug_metadata]>;
 
@@ -88,9 +90,11 @@ tag debug_metadata {
     local_var_metadata(@metadata<local_var_md>);
     tydesc_metadata(@metadata<tydesc_md>);
     block_metadata(@metadata<block_md>);
+    argument_metadata(@metadata<argument_md>);
+    retval_metadata(@metadata<retval_md>);
 }
 
-fn cast_safely<T, U>(val: T) -> U unsafe {
+fn cast_safely<copy T, U>(val: T) -> U unsafe {
     let val2 = val;
     let val3 = unsafe::reinterpret_cast(val2);
     unsafe::leak(val2);
@@ -105,11 +109,13 @@ fn md_from_metadata<T>(val: debug_metadata) -> T unsafe {
       local_var_metadata(md) { cast_safely(md) }
       tydesc_metadata(md) { cast_safely(md) }
       block_metadata(md) { cast_safely(md) }
+      argument_metadata(md) { cast_safely(md) }
+      retval_metadata(md) { cast_safely(md) }
     }
 }
 
-fn cached_metadata<T>(cache: metadata_cache, mdtag: int,
-                      eq: block(md: T) -> bool) -> option::t<T> unsafe {
+fn cached_metadata<copy T>(cache: metadata_cache, mdtag: int,
+                           eq: block(md: T) -> bool) -> option::t<T> unsafe {
     if cache.contains_key(mdtag) {
         let items = cache.get(mdtag);
         for item in items {
@@ -270,7 +276,7 @@ fn function_metadata_from_block(bcx: @block_ctxt) -> @metadata<subprogram_md> {
     let fcx = bcx_fcx(bcx);
     let fn_node = cx.ast_map.get(fcx.id);
     let fn_item = alt fn_node { ast_map::node_item(item) { item } };
-    get_function_metadata(cx, fn_item, fcx.llfn)
+    get_function_metadata(fcx, fn_item, fcx.llfn)
 }
 
 fn filename_from_span(cx: @crate_ctxt, sp: codemap::span) -> str {
@@ -323,6 +329,98 @@ fn get_local_var_metadata(bcx: @block_ctxt, local: @ast::local)
     ret mdval;
 }
 
+//FIXME: consolidate with get_local_var_metadata
+/*fn get_retval_metadata(bcx: @block_ctxt)
+    -> @metadata<retval_md> unsafe {
+    let fcx = bcx_fcx(bcx);
+    let cx = fcx_ccx(fcx);
+    let cache = cx.llmetadata;
+    alt cached_metadata::<@metadata<retval_md>>(
+        cache, ReturnVariableTag, {|md| md.data.id == fcx.id}) {
+      option::some(md) { ret md; }
+      option::none. {}
+    }
+    let item = alt option::get(cx.ast_map.find(fcx.id)) {
+      ast_map::node_item(item) { item }
+    };
+    let loc = codemap::lookup_char_pos(cx.sess.get_codemap(),
+                                       fcx.sp.lo);
+    let ret_ty = alt item.node {
+      ast::item_fn(f, _) { f.decl.output }
+    };
+    let ty_node = alt ret_ty.node {
+      ast::ty_nil. { llnull() }
+      _ { get_ty_metadata(cx, ty::node_id_to_type(ccx_tcx(cx), item.id),
+                          ret_ty).node }
+    };
+    /*let ty_node = get_ty_metadata(cx, ty::node_id_to_type(ccx_tcx(cx), fcx.id),
+                                  ty).node;*/
+    //let ty = trans::node_id_type(cx, arg.id);
+    //let tymd = get_ty_metadata(cx, ty, arg.ty);
+    let filemd = get_file_metadata(cx, loc.filename);
+    let fn_node = cx.ast_map.get(fcx.id);
+    let fn_item = alt fn_node { ast_map::node_item(item) { item } };
+    let context = get_function_metadata(fcx, fn_item, fcx.llfn);
+    let lldata = [lltag(ReturnVariableTag),
+                  context.node, // context
+                  llstr("%0"), // name
+                  filemd.node,
+                  lli32(loc.line as int), // line
+                  ty_node,
+                  lli32(0) //XXX flags
+                 ];
+    let mdnode = llmdnode(lldata);
+    let mdval = @{node: mdnode, data: {id: fcx.id}};
+    update_cache(cache, ReturnVariableTag, retval_metadata(mdval));
+    let llptr = fcx.llretptr;
+    let declargs = [llmdnode([llptr]), mdnode];
+    trans_build::Call(bcx, cx.intrinsics.get("llvm.dbg.declare"),
+                      declargs);
+    ret mdval;
+}*/
+
+//FIXME: consolidate with get_local_var_metadata
+fn get_arg_metadata(bcx: @block_ctxt, arg: ast::arg)
+    -> @metadata<argument_md> unsafe {
+    let fcx = bcx_fcx(bcx);
+    let cx = fcx_ccx(fcx);
+    let cache = cx.llmetadata;
+    alt cached_metadata::<@metadata<argument_md>>(
+        cache, ArgVariableTag, {|md| md.data.id == arg.id}) {
+      option::some(md) { ret md; }
+      option::none. {}
+    }
+    let arg_n = alt cx.ast_map.get(arg.id) {
+      ast_map::node_arg(_, n) { n - 2u }
+    };
+    let loc = codemap::lookup_char_pos(cx.sess.get_codemap(),
+                                       fcx.sp.lo);
+    let ty = trans::node_id_type(cx, arg.id);
+    let tymd = get_ty_metadata(cx, ty, arg.ty);
+    let filemd = get_file_metadata(cx, loc.filename);
+    let fn_node = cx.ast_map.get(fcx.id);
+    let fn_item = alt fn_node { ast_map::node_item(item) { item } };
+    let context = get_function_metadata(fcx, fn_item, fcx.llfn);
+    let lldata = [lltag(ArgVariableTag),
+                  context.node, // context
+                  llstr(arg.ident), // name
+                  filemd.node,
+                  lli32(loc.line as int), // line
+                  tymd.node,
+                  lli32(0) //XXX flags
+                 ];
+    let mdnode = llmdnode(lldata);
+    let mdval = @{node: mdnode, data: {id: arg.id}};
+    update_cache(cache, ArgVariableTag, argument_metadata(mdval));
+    let llptr = alt fcx.llargs.get(arg.id) {
+      local_mem(v) | local_imm(v) { v }
+    };
+    let declargs = [llmdnode([llptr]), mdnode];
+    trans_build::Call(bcx, cx.intrinsics.get("llvm.dbg.declare"),
+                      declargs);
+    ret mdval;
+}
+
 fn update_source_pos(cx: @block_ctxt, s: codemap::span) -> @debug_source_pos {
     let dsp = @debug_source_pos(cx);
     if !bcx_ccx(cx).sess.get_opts().debuginfo {
@@ -384,8 +482,9 @@ fn add_line_info(cx: @block_ctxt, llinstr: ValueRef) {
     llvm::LLVMSetMetadata(llinstr, kind_id, dbgscope);
 }
 
-fn get_function_metadata(cx: @crate_ctxt, item: @ast::item,
+fn get_function_metadata(fcx: @fn_ctxt, item: @ast::item,
                          llfndecl: ValueRef) -> @metadata<subprogram_md> {
+    let cx = fcx_ccx(fcx);
     let cache = cx.llmetadata;
     alt cached_metadata::<@metadata<subprogram_md>>(
         cache, SubprogramTag, {|md| md.data.name == item.ident &&
@@ -448,5 +547,9 @@ fn get_function_metadata(cx: @crate_ctxt, item: @ast::item,
     let mdval = @{node: val, data: {name: item.ident,
                                     file: loc.filename}};
     update_cache(cache, SubprogramTag, subprogram_metadata(mdval));
+    /*alt ret_ty.node {
+      ast::ty_nil. {}
+      _ { let _ = get_retval_metadata(fcx, ret_ty); }
+    }*/
     ret mdval;
 }
\ No newline at end of file
diff --git a/src/comp/middle/trans.rs b/src/comp/middle/trans.rs
index 4c58cc5e26d..81f15d6b4de 100644
--- a/src/comp/middle/trans.rs
+++ b/src/comp/middle/trans.rs
@@ -4422,6 +4422,12 @@ fn create_llargs_for_fn_args(cx: @fn_ctxt, ty_self: self_arg,
 
 fn copy_args_to_allocas(fcx: @fn_ctxt, bcx: @block_ctxt, args: [ast::arg],
                         arg_tys: [ty::arg]) -> @block_ctxt {
+    if fcx_ccx(fcx).sess.get_opts().debuginfo {
+        llvm::LLVMAddAttribute(llvm::LLVMGetFirstParam(fcx.llfn),
+                               lib::llvm::LLVMStructRetAttribute as
+                                   lib::llvm::llvm::Attribute);
+        //let _ = debuginfo::get_retval_metadata(bcx);
+    }
     let arg_n: uint = 0u, bcx = bcx;
     for arg in arg_tys {
         let id = args[arg_n].id;
@@ -4441,6 +4447,9 @@ fn copy_args_to_allocas(fcx: @fn_ctxt, bcx: @block_ctxt, args: [ast::arg],
           }
           ast::by_ref. {}
         }
+        if fcx_ccx(fcx).sess.get_opts().debuginfo {
+            let _ = debuginfo::get_arg_metadata(bcx, args[arg_n]);
+        }
         arg_n += 1u;
     }
     ret bcx;
@@ -4574,12 +4583,13 @@ fn trans_fn(cx: @local_ctxt, sp: span, f: ast::_fn, llfndecl: ValueRef,
             id: ast::node_id) {
     let do_time = cx.ccx.sess.get_opts().stats;
     let start = do_time ? time::get_time() : {sec: 0u32, usec: 0u32};
-    trans_closure(cx, sp, f, llfndecl, ty_self, ty_params, id, {|_fcx|});
+    let fcx = option::none;
+    trans_closure(cx, sp, f, llfndecl, ty_self, ty_params, id, {|new_fcx| fcx = option::some(new_fcx);});
     if cx.ccx.sess.get_opts().debuginfo {
         let item = alt option::get(cx.ccx.ast_map.find(id)) {
             ast_map::node_item(item) { item }
         };
-        debuginfo::get_function_metadata(cx.ccx, item, llfndecl);
+        debuginfo::get_function_metadata(option::get(fcx), item, llfndecl);
     }
     if do_time {
         let end = time::get_time();
diff --git a/src/comp/middle/trans_build.rs b/src/comp/middle/trans_build.rs
index 600c1e27c73..2b45285a4ef 100644
--- a/src/comp/middle/trans_build.rs
+++ b/src/comp/middle/trans_build.rs
@@ -104,6 +104,14 @@ fn Invoke(cx: @block_ctxt, Fn: ValueRef, Args: [ValueRef],
         let instr = llvm::LLVMBuildInvoke(B(cx), Fn, vec::to_ptr(Args),
                                           vec::len(Args), Then, Catch,
                                           noname());
+        if bcx_ccx(cx).sess.get_opts().debuginfo {
+            /*llvm::LLVMAddAttribute(option::get(vec::last(llargs)),
+            lib::llvm::LLVMStructRetAttribute as
+            lib::llvm::llvm::Attribute);*/
+            llvm::LLVMAddInstrAttribute(instr, 1u,
+                                        lib::llvm::LLVMStructRetAttribute as
+                                            lib::llvm::llvm::Attribute);
+        }
         debuginfo::add_line_info(cx, instr);
     }
 }