Add argument metadata and aborted return value code.
This commit is contained in:
parent
0752252737
commit
6c26b892e4
|
@ -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;
|
||||
}
|
|
@ -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();
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue