From 10030a37d50f5c3ae681709598be201153e0b1e5 Mon Sep 17 00:00:00 2001 From: Josh Matthews Date: Thu, 10 Nov 2011 00:55:09 -0500 Subject: [PATCH 01/21] Generate basic debug info for files, functions and compile units. --- src/comp/lib/llvm.rs | 3 + src/comp/middle/debuginfo.rs | 192 ++++++++++++++++++++++++++++++++ src/comp/middle/trans.rs | 11 +- src/comp/middle/trans_common.rs | 3 +- src/comp/rustc.rc | 1 + src/rustllvm/RustWrapper.cpp | 14 +++ src/rustllvm/rustllvm.def.in | 1 + 7 files changed, 222 insertions(+), 3 deletions(-) create mode 100644 src/comp/middle/debuginfo.rs diff --git a/src/comp/lib/llvm.rs b/src/comp/lib/llvm.rs index 9ff014699abcc..b090fb74644a2 100644 --- a/src/comp/lib/llvm.rs +++ b/src/comp/lib/llvm.rs @@ -256,6 +256,7 @@ native mod llvm { /* Operations on Users */ fn LLVMGetOperand(Val: ValueRef, Index: uint) -> ValueRef; + fn LLVMSetOperand(Val: ValueRef, Index: uint, Op: ValueRef); /* Operations on constants of any type */ fn LLVMConstNull(Ty: TypeRef) -> ValueRef; @@ -275,6 +276,8 @@ native mod llvm { fn LLVMMDNodeInContext(C: ContextRef, Vals: *ValueRef, Count: uint) -> ValueRef; fn LLVMMDNode(Vals: *ValueRef, Count: uint) -> ValueRef; + fn LLVMAddNamedMetadataOperand(M: ModuleRef, Str: sbuf, SLen: uint, + Val: ValueRef); /* Operations on scalar constants */ fn LLVMConstInt(IntTy: TypeRef, N: ULongLong, SignExtend: Bool) -> diff --git a/src/comp/middle/debuginfo.rs b/src/comp/middle/debuginfo.rs new file mode 100644 index 0000000000000..72390a23383da --- /dev/null +++ b/src/comp/middle/debuginfo.rs @@ -0,0 +1,192 @@ +import std::{vec, str, map, option, unsafe}; +import std::vec::to_ptr; +import std::map::hashmap; +import lib::llvm::llvm; +import lib::llvm::llvm::{ModuleRef, ValueRef}; +import middle::trans_common::*; +import syntax::{ast, codemap}; + +const LLVMDebugVersion: int = 0x80000; + +const DW_LANG_RUST: int = 0x9000; +const DW_VIRTUALITY_none: int = 0; + +const CompileUnitTag: int = 17; +const FileDescriptorTag: int = 41; +const SubprogramTag: int = 46; + +fn as_buf(s: str) -> str::sbuf { + str::as_buf(s, {|sbuf| sbuf}) +} +fn llstr(s: str) -> ValueRef { + llvm::LLVMMDString(as_buf(s), str::byte_len(s)) +} + +fn lltag(lltag: int) -> ValueRef { + lli32(0x80000 + lltag) +} +fn lli32(val: int) -> ValueRef { + C_i32(val as i32) +} +fn lli1(bval: bool) -> ValueRef { + C_bool(bval) +} +fn llmdnode(elems: [ValueRef]) -> ValueRef unsafe { + llvm::LLVMMDNode(vec::unsafe::to_ptr(elems), + vec::len(elems)) +} +fn llunused() -> ValueRef { + lli32(0x0) +} + +fn update_cache(cache: metadata_cache, mdtag: int, val: debug_metadata) { + let existing = if cache.contains_key(mdtag) { + cache.get(mdtag) + } else { + [] + }; + cache.insert(mdtag, existing + [val]); +} + +//////////////// + +type metadata = {node: ValueRef, data: T}; + +type file_md = {path: str}; +type compile_unit_md = {path: str}; +type subprogram_md = {name: str, file: str}; + +type metadata_cache = hashmap; + +tag debug_metadata { + file_metadata(@metadata); + compile_unit_metadata(@metadata); + subprogram_metadata(@metadata); +} + +fn md_from_metadata(val: debug_metadata) -> T unsafe { + alt val { + file_metadata(md) { unsafe::reinterpret_cast(md) } + compile_unit_metadata(md) { unsafe::reinterpret_cast(md) } + subprogram_metadata(md) { unsafe::reinterpret_cast(md) } + } +} + +fn cached_metadata(cache: metadata_cache, mdtag: int, + eq: block(md: T) -> bool) -> option::t { + if cache.contains_key(mdtag) { + let items = cache.get(mdtag); + for item in items { + let md: T = md_from_metadata::(item); + if eq(md) { + ret option::some(md); + } + } + } + ret option::none; +} + +fn get_compile_unit_metadata(cx: @crate_ctxt, full_path: str) + -> @metadata { + let cache = cx.llmetadata; + alt cached_metadata::<@metadata>(cache, CompileUnitTag, + {|md| md.data.path == full_path}) { + option::some(md) { ret md; } + option::none. {} + } + let sep = str::rindex(full_path, '/' as u8) as uint; + let fname = str::slice(full_path, sep + 1u, + str::byte_len(full_path)); + let path = str::slice(full_path, 0u, sep + 1u); + let unit_metadata = [lltag(CompileUnitTag), + llunused(), + lli32(DW_LANG_RUST), + llstr(fname), + llstr(path), + llstr(#env["CFG_VERSION"]), + lli1(false), // main compile unit + lli1(cx.sess.get_opts().optimize != 0u), + llstr(""), // flags (???) + lli32(0) // runtime version (???) + // list of enum types + // list of retained values + // list of subprograms + // list of global variables + ]; + let unit_node = llmdnode(unit_metadata); + llvm::LLVMAddNamedMetadataOperand(cx.llmod, as_buf("llvm.dbg.cu"), + str::byte_len("llvm.dbg.cu"), + unit_node); + let mdval = @{node: unit_node, data: {path: full_path}}; + update_cache(cache, CompileUnitTag, compile_unit_metadata(mdval)); + ret mdval; +} + +// let kind_id = llvm::LLVMGetMDKindID(as_buf("dbg"), +// str::byte_len("dbg")); + + +fn get_file_metadata(cx: @crate_ctxt, full_path: str) -> @metadata { + let cache = cx.llmetadata; + alt cached_metadata::<@metadata>( + cache, FileDescriptorTag, {|md| md.data.path == full_path}) { + option::some(md) { ret md; } + option::none. {} + } + let sep = str::rindex(full_path, '/' as u8) as uint; + let fname = str::slice(full_path, sep + 1u, + str::byte_len(full_path)); + let path = str::slice(full_path, 0u, sep + 1u); + let unit_node = get_compile_unit_metadata(cx, path).node; + let file_md = [lltag(FileDescriptorTag), + llstr(fname), + llstr(path), + unit_node]; + let val = llmdnode(file_md); + let mdval = @{node: val, data: {path: full_path}}; + update_cache(cache, FileDescriptorTag, file_metadata(mdval)); + ret mdval; +} + +fn get_function_metadata(cx: @crate_ctxt, item: @ast::item, + llfndecl: ValueRef) -> @metadata { + let cache = cx.llmetadata; + alt cached_metadata::<@metadata>( + cache, SubprogramTag, {|md| md.data.name == item.ident && + /*sub.path == ??*/ true}) { + option::some(md) { ret md; } + option::none. {} + } + let loc = codemap::lookup_char_pos(cx.sess.get_codemap(), + item.span.lo); + let file_node = get_file_metadata(cx, loc.filename).node; + let fn_metadata = [lltag(SubprogramTag), + llunused(), + file_node, + llstr(item.ident), + llstr(item.ident), //XXX fully-qualified C++ name + llstr(item.ident), //XXX MIPS name????? + file_node, + lli32(loc.line as int), + C_null(T_ptr(T_nil())), // XXX reference to tydesc + lli1(false), //XXX static + lli1(true), // not extern + lli32(DW_VIRTUALITY_none), // virtual-ness + lli32(0i), //index into virt func + C_null(T_ptr(T_nil())), // base type with vtbl + lli1(false), // artificial + lli1(cx.sess.get_opts().optimize != 0u), + llfndecl + //list of template params + //func decl descriptor + //list of func vars + ]; + let val = llmdnode(fn_metadata); + llvm::LLVMAddNamedMetadataOperand(cx.llmod, as_buf("llvm.dbg.sp"), + str::byte_len("llvm.dbg.sp"), + val); + let mdval = @{node: val, data: {name: item.ident, + file: loc.filename}}; + update_cache(cache, SubprogramTag, subprogram_metadata(mdval)); + ret mdval; +} \ No newline at end of file diff --git a/src/comp/middle/trans.rs b/src/comp/middle/trans.rs index acec464e6f8e8..6985ef974e602 100644 --- a/src/comp/middle/trans.rs +++ b/src/comp/middle/trans.rs @@ -20,7 +20,7 @@ import std::map::{new_int_hash, new_str_hash}; import option::{some, none}; import driver::session; import front::attr; -import middle::{ty, gc, resolve}; +import middle::{ty, gc, resolve, debuginfo}; import middle::freevars::*; import back::{link, abi, upcall}; import syntax::{ast, ast_util}; @@ -4543,6 +4543,12 @@ fn trans_fn(cx: @local_ctxt, sp: span, f: ast::_fn, llfndecl: ValueRef, 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|}); + 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); + } if do_time { let end = time::get_time(); log_fn_time(cx.ccx, str::connect(cx.path, "::"), start, end); @@ -5659,7 +5665,8 @@ fn trans_crate(sess: session::session, crate: @ast::crate, tcx: ty::ctxt, builder: BuilderRef_res(llvm::LLVMCreateBuilder()), shape_cx: shape::mk_ctxt(llmod), gc_cx: gc::mk_ctxt(), - crate_map: crate_map}; + crate_map: crate_map, + llmetadata: map::new_int_hash()}; let cx = new_local_ctxt(ccx); collect_items(ccx, crate); collect_tag_ctors(ccx, crate); diff --git a/src/comp/middle/trans_common.rs b/src/comp/middle/trans_common.rs index 19f439235e421..a4f0a6dfe3dec 100644 --- a/src/comp/middle/trans_common.rs +++ b/src/comp/middle/trans_common.rs @@ -116,7 +116,8 @@ type crate_ctxt = builder: BuilderRef_res, shape_cx: shape::ctxt, gc_cx: gc::ctxt, - crate_map: ValueRef}; + crate_map: ValueRef, + llmetadata: debuginfo::metadata_cache}; type local_ctxt = {path: [str], diff --git a/src/comp/rustc.rc b/src/comp/rustc.rc index 51a01378fb3a9..9f88b369749a1 100644 --- a/src/comp/rustc.rc +++ b/src/comp/rustc.rc @@ -37,6 +37,7 @@ mod middle { mod freevars; mod shape; mod gc; + mod debuginfo; mod tstate { mod ck; diff --git a/src/rustllvm/RustWrapper.cpp b/src/rustllvm/RustWrapper.cpp index d50cc527dfd1a..ad7fec1586b40 100644 --- a/src/rustllvm/RustWrapper.cpp +++ b/src/rustllvm/RustWrapper.cpp @@ -165,3 +165,17 @@ extern "C" LLVMValueRef LLVMGetOrInsertFunction(LLVMModuleRef M, return wrap(unwrap(M)->getOrInsertFunction(Name, unwrap(FunctionTy))); } + +extern "C" LLVMTypeRef LLVMMetadataTypeInContext(LLVMContextRef C) { + return wrap(Type::getMetadataTy(*unwrap(C))); +} +extern "C" LLVMTypeRef LLVMMetadataType(void) { + return LLVMMetadataTypeInContext(LLVMGetGlobalContext()); +} + +extern "C" void LLVMAddNamedMetadataOperand(LLVMModuleRef M, const char *Str, + unsigned SLen, LLVMValueRef Val) +{ + NamedMDNode *N = unwrap(M)->getOrInsertNamedMetadata(StringRef(Str, SLen)); + N->addOperand(unwrap(Val)); +} diff --git a/src/rustllvm/rustllvm.def.in b/src/rustllvm/rustllvm.def.in index 381c5293eb73c..1a34f62f7a062 100644 --- a/src/rustllvm/rustllvm.def.in +++ b/src/rustllvm/rustllvm.def.in @@ -487,6 +487,7 @@ LLVMMDNode LLVMMDNodeInContext LLVMMDString LLVMMDStringInContext +LLVMAddNamedMetadataOperand LLVMModuleCreateWithName LLVMModuleCreateWithNameInContext LLVMMoveBasicBlockAfter From e383004985a5d725cec91cc48793284eedbcdbce Mon Sep 17 00:00:00 2001 From: Josh Matthews Date: Tue, 15 Nov 2011 21:11:22 -0500 Subject: [PATCH 02/21] Add debug info for local vars, basic fundamental types, and lexical blocks, along with source line information generation for individual instructions. --- src/comp/lib/llvm.rs | 2 + src/comp/middle/debuginfo.rs | 300 ++++++++++++++++++++++----- src/comp/middle/trans.rs | 41 +++- src/comp/middle/trans_build.rs | 355 +++++++++++++++++++++++--------- src/comp/middle/trans_common.rs | 9 +- src/rustllvm/rustllvm.def.in | 7 +- 6 files changed, 561 insertions(+), 153 deletions(-) diff --git a/src/comp/lib/llvm.rs b/src/comp/lib/llvm.rs index b090fb74644a2..c0fe027f39b4f 100644 --- a/src/comp/lib/llvm.rs +++ b/src/comp/lib/llvm.rs @@ -234,9 +234,11 @@ native mod llvm { /* Operations on other types */ fn LLVMVoidTypeInContext(C: ContextRef) -> TypeRef; fn LLVMLabelTypeInContext(C: ContextRef) -> TypeRef; + fn LLVMMetadataTypeInContext(C: ContextRef) -> TypeRef; fn LLVMVoidType() -> TypeRef; fn LLVMLabelType() -> TypeRef; + fn LLVMMetadataType() -> TypeRef; /* Operations on all values */ fn LLVMTypeOf(Val: ValueRef) -> TypeRef; diff --git a/src/comp/middle/debuginfo.rs b/src/comp/middle/debuginfo.rs index 72390a23383da..9379c42623c1b 100644 --- a/src/comp/middle/debuginfo.rs +++ b/src/comp/middle/debuginfo.rs @@ -1,12 +1,13 @@ -import std::{vec, str, map, option, unsafe}; -import std::vec::to_ptr; +import std::{vec, str, option, unsafe, fs}; import std::map::hashmap; import lib::llvm::llvm; -import lib::llvm::llvm::{ModuleRef, ValueRef}; +import lib::llvm::llvm::ValueRef; import middle::trans_common::*; +import middle::ty; +import ast::ty; import syntax::{ast, codemap}; -const LLVMDebugVersion: int = 0x80000; +const LLVMDebugVersion: int = (9 << 16); //& 0xffff0000; // 0x80000 ? const DW_LANG_RUST: int = 0x9000; const DW_VIRTUALITY_none: int = 0; @@ -14,6 +15,18 @@ const DW_VIRTUALITY_none: int = 0; const CompileUnitTag: int = 17; const FileDescriptorTag: int = 41; const SubprogramTag: int = 46; +const BasicTypeDescriptorTag: int = 36; +const AutoVariableTag: int = 256; +const ArgVariableTag: int = 257; +const ReturnVariableTag: int = 258; +const LexicalBlockTag: int = 11; + +const DW_ATE_boolean: int = 0x02; +const DW_ATE_float: int = 0x04; +const DW_ATE_signed: int = 0x05; +const DW_ATE_signed_char: int = 0x06; +const DW_ATE_unsigned: int = 0x07; +const DW_ATE_unsigned_char: int = 0x08; fn as_buf(s: str) -> str::sbuf { str::as_buf(s, {|sbuf| sbuf}) @@ -23,11 +36,14 @@ fn llstr(s: str) -> ValueRef { } fn lltag(lltag: int) -> ValueRef { - lli32(0x80000 + lltag) + lli32(LLVMDebugVersion | lltag) } fn lli32(val: int) -> ValueRef { C_i32(val as i32) } +fn lli64(val: int) -> ValueRef { + C_i64(val as i64) +} fn lli1(bval: bool) -> ValueRef { C_bool(bval) } @@ -38,6 +54,9 @@ fn llmdnode(elems: [ValueRef]) -> ValueRef unsafe { fn llunused() -> ValueRef { lli32(0x0) } +fn llnull() -> ValueRef { + C_null(T_ptr(T_nil())) +} fn update_cache(cache: metadata_cache, mdtag: int, val: debug_metadata) { let existing = if cache.contains_key(mdtag) { @@ -55,6 +74,9 @@ type metadata = {node: ValueRef, data: T}; type file_md = {path: str}; type compile_unit_md = {path: str}; 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 metadata_cache = hashmap; @@ -62,18 +84,31 @@ tag debug_metadata { file_metadata(@metadata); compile_unit_metadata(@metadata); subprogram_metadata(@metadata); + local_var_metadata(@metadata); + tydesc_metadata(@metadata); + block_metadata(@metadata); +} + +fn cast_safely(val: T) -> U unsafe { + let val2 = val; + let val3 = unsafe::reinterpret_cast(val2); + unsafe::leak(val2); + ret val3; } fn md_from_metadata(val: debug_metadata) -> T unsafe { alt val { - file_metadata(md) { unsafe::reinterpret_cast(md) } - compile_unit_metadata(md) { unsafe::reinterpret_cast(md) } - subprogram_metadata(md) { unsafe::reinterpret_cast(md) } + file_metadata(md) { cast_safely(md) } + compile_unit_metadata(md) { cast_safely(md) } + subprogram_metadata(md) { cast_safely(md) } + local_var_metadata(md) { cast_safely(md) } + tydesc_metadata(md) { cast_safely(md) } + block_metadata(md) { cast_safely(md) } } } fn cached_metadata(cache: metadata_cache, mdtag: int, - eq: block(md: T) -> bool) -> option::t { + eq: block(md: T) -> bool) -> option::t unsafe { if cache.contains_key(mdtag) { let items = cache.get(mdtag); for item in items { @@ -94,10 +129,8 @@ fn get_compile_unit_metadata(cx: @crate_ctxt, full_path: str) option::some(md) { ret md; } option::none. {} } - let sep = str::rindex(full_path, '/' as u8) as uint; - let fname = str::slice(full_path, sep + 1u, - str::byte_len(full_path)); - let path = str::slice(full_path, 0u, sep + 1u); + let fname = fs::basename(full_path); + let path = fs::dirname(full_path); let unit_metadata = [lltag(CompileUnitTag), llunused(), lli32(DW_LANG_RUST), @@ -122,22 +155,18 @@ fn get_compile_unit_metadata(cx: @crate_ctxt, full_path: str) ret mdval; } -// let kind_id = llvm::LLVMGetMDKindID(as_buf("dbg"), -// str::byte_len("dbg")); - - fn get_file_metadata(cx: @crate_ctxt, full_path: str) -> @metadata { let cache = cx.llmetadata; alt cached_metadata::<@metadata>( - cache, FileDescriptorTag, {|md| md.data.path == full_path}) { + cache, FileDescriptorTag, + {|md| + md.data.path == full_path}) { option::some(md) { ret md; } option::none. {} } - let sep = str::rindex(full_path, '/' as u8) as uint; - let fname = str::slice(full_path, sep + 1u, - str::byte_len(full_path)); - let path = str::slice(full_path, 0u, sep + 1u); - let unit_node = get_compile_unit_metadata(cx, path).node; + let fname = fs::basename(full_path); + let path = fs::dirname(full_path); + let unit_node = get_compile_unit_metadata(cx, full_path).node; let file_md = [lltag(FileDescriptorTag), llstr(fname), llstr(path), @@ -148,6 +177,162 @@ fn get_file_metadata(cx: @crate_ctxt, full_path: str) -> @metadata { ret mdval; } +fn get_block_metadata(cx: @block_ctxt) -> @metadata { + let cache = bcx_ccx(cx).llmetadata; + let start = codemap::lookup_char_pos(bcx_ccx(cx).sess.get_codemap(), + cx.sp.lo); + let fname = start.filename; + let end = codemap::lookup_char_pos(bcx_ccx(cx).sess.get_codemap(), + cx.sp.hi); + alt cached_metadata::<@metadata>( + cache, LexicalBlockTag, + {|md| start == md.data.start && end == md.data.end}) { + option::some(md) { ret md; } + option::none. {} + } + let parent = alt cx.parent { + trans_common::parent_none. { llnull() } + trans_common::parent_some(bcx) { + get_block_metadata(bcx).node + } + }; + let file_node = get_file_metadata(bcx_ccx(cx), fname); + let unique_id = alt cache.find(LexicalBlockTag) { + option::some(v) { vec::len(v) as int } + option::none. { 0 } + }; + let lldata = [lltag(LexicalBlockTag), + parent, + lli32(start.line as int), + lli32(start.col as int), + file_node.node, + lli32(unique_id) + ]; + let val = llmdnode(lldata); + let mdval = @{node: val, data: {start: start, end: end}}; + update_cache(cache, LexicalBlockTag, block_metadata(mdval)); + ret mdval; +} + +fn get_ty_metadata(cx: @crate_ctxt, t: ty::t, ty: @ast::ty) -> @metadata { + let cache = cx.llmetadata; + alt cached_metadata::<@metadata>( + cache, BasicTypeDescriptorTag, + {|md| ty::hash_ty(t) == ty::hash_ty(md.data.hash)}) { + option::some(md) { ret md; } + option::none. {} + } + let (name, size, flags) = alt ty.node { + ast::ty_bool. { ("bool", 1, DW_ATE_boolean) } + ast::ty_int. { ("int", 32, DW_ATE_signed) } //XXX machine-dependent? + ast::ty_uint. { ("uint", 32, DW_ATE_unsigned) } //XXX machine-dependent? + ast::ty_float. { ("float", 32, DW_ATE_float) } //XXX machine-dependent? + ast::ty_machine(m) { alt m { + ast::ty_i8. { ("i8", 1, DW_ATE_signed_char) } + ast::ty_i16. { ("i16", 16, DW_ATE_signed) } + ast::ty_i32. { ("i32", 32, DW_ATE_signed) } + ast::ty_i64. { ("i64", 64, DW_ATE_signed) } + ast::ty_u8. { ("u8", 8, DW_ATE_unsigned_char) } + ast::ty_u16. { ("u16", 16, DW_ATE_unsigned) } + ast::ty_u32. { ("u32", 32, DW_ATE_unsigned) } + ast::ty_u64. { ("u64", 64, DW_ATE_unsigned) } + ast::ty_f32. { ("f32", 32, DW_ATE_float) } + ast::ty_f64. { ("f64", 64, DW_ATE_float) } + } } + ast::ty_char. { ("char", 32, DW_ATE_unsigned) } + }; + let lldata = [lltag(BasicTypeDescriptorTag), + llunused(), //XXX scope context + llstr(name), + llnull(), //XXX basic types only + lli32(0), //XXX basic types only + lli64(size), + lli64(32), //XXX alignment? + lli64(0), //XXX offset? + lli32(flags)]; + let llnode = llmdnode(lldata); + let mdval = @{node: llnode, data: {hash: ty::hash_ty(t)}}; + update_cache(cache, BasicTypeDescriptorTag, tydesc_metadata(mdval)); + ret mdval; +} + +fn get_local_var_metadata(bcx: @block_ctxt, local: @ast::local) + -> @metadata unsafe { + let cx = bcx_ccx(bcx); + let cache = cx.llmetadata; + alt cached_metadata::<@metadata>( + cache, AutoVariableTag, {|md| md.data.id == local.node.id}) { + option::some(md) { ret md; } + option::none. {} + } + let name = alt local.node.pat.node { + ast::pat_bind(ident) { ident } + }; + let loc = codemap::lookup_char_pos(cx.sess.get_codemap(), + local.span.lo); + let ty = trans::node_id_type(cx, local.node.id); + let tymd = get_ty_metadata(cx, ty, local.node.ty); + let filemd = get_file_metadata(cx, loc.filename); + let blockmd = get_block_metadata(bcx); + let lldata = [lltag(AutoVariableTag), + blockmd.node, //XXX block context (maybe subprogram if possible?) + llstr(name), // name + filemd.node, + lli32(loc.line as int), // line + tymd.node, + lli32(0), //XXX flags + llnull() // inline loc reference + ]; + let mdnode = llmdnode(lldata); + let mdval = @{node: mdnode, data: {id: local.node.id}}; + update_cache(cache, AutoVariableTag, local_var_metadata(mdval)); + let llptr = alt bcx.fcx.lllocals.find(local.node.id) { + option::some(local_mem(v)) { v } + option::none. { + alt bcx.fcx.lllocals.get(local.node.pat.id) { + local_imm(v) { v } + } + } + }; + let declargs = [llmdnode([llptr]), mdnode]; + let instr = trans_build::Call(bcx, cx.intrinsics.get("llvm.dbg.declare"), + declargs); + llvm::LLVMAddNamedMetadataOperand(cx.llmod, as_buf("llvm.dbg.vars"), + str::byte_len("llvm.dbg.vars"), + mdnode); + ret mdval; +} + +fn update_source_pos(cx: @block_ctxt, s: T) { + if !bcx_ccx(cx).sess.get_opts().debuginfo { + ret; + } + cx.source_pos = option::some( + codemap::lookup_char_pos(bcx_ccx(cx).sess.get_codemap(), + s.span.lo)); //XXX maybe hi + +} + +fn reset_source_pos(cx: @block_ctxt) { + cx.source_pos = option::none; +} + +fn add_line_info(cx: @block_ctxt, llinstr: ValueRef) { + if !bcx_ccx(cx).sess.get_opts().debuginfo || + option::is_none(cx.source_pos) { + ret; + } + let loc = option::get(cx.source_pos); + let blockmd = get_block_metadata(cx); + let kind_id = llvm::LLVMGetMDKindID(as_buf("dbg"), str::byte_len("dbg")); + let scopedata = [lli32(loc.line as int), + lli32(loc.col as int), + blockmd.node, + llnull()]; + let dbgscope = llmdnode(scopedata); + llvm::LLVMSetMetadata(llinstr, kind_id, dbgscope); +} + fn get_function_metadata(cx: @crate_ctxt, item: @ast::item, llfndecl: ValueRef) -> @metadata { let cache = cx.llmetadata; @@ -159,34 +344,43 @@ fn get_function_metadata(cx: @crate_ctxt, item: @ast::item, } let loc = codemap::lookup_char_pos(cx.sess.get_codemap(), item.span.lo); - let file_node = get_file_metadata(cx, loc.filename).node; - let fn_metadata = [lltag(SubprogramTag), - llunused(), - file_node, - llstr(item.ident), - llstr(item.ident), //XXX fully-qualified C++ name - llstr(item.ident), //XXX MIPS name????? - file_node, - lli32(loc.line as int), - C_null(T_ptr(T_nil())), // XXX reference to tydesc - lli1(false), //XXX static - lli1(true), // not extern - lli32(DW_VIRTUALITY_none), // virtual-ness - lli32(0i), //index into virt func - C_null(T_ptr(T_nil())), // base type with vtbl - lli1(false), // artificial - lli1(cx.sess.get_opts().optimize != 0u), - llfndecl - //list of template params - //func decl descriptor - //list of func vars - ]; - let val = llmdnode(fn_metadata); - llvm::LLVMAddNamedMetadataOperand(cx.llmod, as_buf("llvm.dbg.sp"), - str::byte_len("llvm.dbg.sp"), - val); - let mdval = @{node: val, data: {name: item.ident, - file: loc.filename}}; - update_cache(cache, SubprogramTag, subprogram_metadata(mdval)); - ret mdval; + let file_node = get_file_metadata(cx, loc.filename).node; + let mangled = cx.item_symbols.get(item.id); + 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 fn_metadata = [lltag(SubprogramTag), + llunused(), + file_node, + llstr(item.ident), + llstr(item.ident), //XXX fully-qualified C++ name + llstr(mangled), //XXX MIPS name????? + file_node, + lli32(loc.line as int), + ty_node, + lli1(false), //XXX static (check export) + lli1(true), // not extern + lli32(DW_VIRTUALITY_none), // virtual-ness + lli32(0i), //index into virt func + llnull(), // base type with vtbl + lli1(false), // artificial + lli1(cx.sess.get_opts().optimize != 0u), + llfndecl + //list of template params + //func decl descriptor + //list of func vars + ]; + let val = llmdnode(fn_metadata); + llvm::LLVMAddNamedMetadataOperand(cx.llmod, as_buf("llvm.dbg.sp"), + str::byte_len("llvm.dbg.sp"), + val); + let mdval = @{node: val, data: {name: item.ident, + file: loc.filename}}; + update_cache(cache, SubprogramTag, subprogram_metadata(mdval)); + ret mdval; } \ No newline at end of file diff --git a/src/comp/middle/trans.rs b/src/comp/middle/trans.rs index 6985ef974e602..551ac18a1b200 100644 --- a/src/comp/middle/trans.rs +++ b/src/comp/middle/trans.rs @@ -3519,6 +3519,8 @@ fn trans_temp_expr(bcx: @block_ctxt, e: @ast::expr) -> result { // - exprs with non-immediate type never get dest=by_val fn trans_expr(bcx: @block_ctxt, e: @ast::expr, dest: dest) -> @block_ctxt { let tcx = bcx_tcx(bcx); + debuginfo::update_source_pos(bcx, e); + if expr_is_lval(bcx, e) { ret lval_to_dps(bcx, e, dest); } @@ -4012,6 +4014,8 @@ fn trans_stmt(cx: @block_ctxt, s: ast::stmt) -> @block_ctxt { } let bcx = cx; + debuginfo::update_source_pos(cx, s); + alt s.node { ast::stmt_expr(e, _) { bcx = trans_expr(cx, e, ignore); } ast::stmt_decl(d, _) { @@ -4023,6 +4027,9 @@ fn trans_stmt(cx: @block_ctxt, s: ast::stmt) -> @block_ctxt { } else { bcx = init_ref_local(bcx, local); } + if bcx_ccx(cx).sess.get_opts().debuginfo { + debuginfo::get_local_var_metadata(bcx, local); + } } } ast::decl_item(i) { trans_item(cx.fcx.lcx, *i); } @@ -4030,6 +4037,8 @@ fn trans_stmt(cx: @block_ctxt, s: ast::stmt) -> @block_ctxt { } _ { bcx_ccx(cx).sess.unimpl("stmt variant"); } } + + debuginfo::reset_source_pos(cx); ret bcx; } @@ -4053,7 +4062,8 @@ fn new_block_ctxt(cx: @fn_ctxt, parent: block_parent, kind: block_kind, mutable lpad_dirty: true, mutable lpad: option::none, sp: cx.sp, - fcx: cx}; + fcx: cx, + mutable source_pos: option::none}; alt parent { parent_some(cx) { if cx.unreachable { Unreachable(bcx); } @@ -4097,7 +4107,8 @@ fn new_raw_block_ctxt(fcx: @fn_ctxt, llbb: BasicBlockRef) -> @block_ctxt { mutable lpad_dirty: true, mutable lpad: option::none, sp: fcx.sp, - fcx: fcx}; + fcx: fcx, + mutable source_pos: option::none}; } @@ -4164,7 +4175,8 @@ fn llstaticallocas_block_ctxt(fcx: @fn_ctxt) -> @block_ctxt { mutable lpad_dirty: true, mutable lpad: option::none, sp: fcx.sp, - fcx: fcx}; + fcx: fcx, + mutable source_pos: option::none}; } fn llderivedtydescs_block_ctxt(fcx: @fn_ctxt) -> @block_ctxt { @@ -4177,7 +4189,8 @@ fn llderivedtydescs_block_ctxt(fcx: @fn_ctxt) -> @block_ctxt { mutable lpad_dirty: true, mutable lpad: option::none, sp: fcx.sp, - fcx: fcx}; + fcx: fcx, + mutable source_pos: option::none}; } @@ -4250,6 +4263,7 @@ fn trans_block(bcx: @block_ctxt, b: ast::blk) -> @block_ctxt { fn trans_block_dps(bcx: @block_ctxt, b: ast::blk, dest: dest) -> @block_ctxt { let bcx = bcx; + debuginfo::update_source_pos(bcx, b); block_locals(b) {|local| bcx = alloc_local(bcx, local); }; for s: @ast::stmt in b.node.stmts { bcx = trans_stmt(bcx, *s); @@ -4261,7 +4275,9 @@ fn trans_block_dps(bcx: @block_ctxt, b: ast::blk, dest: dest) } _ { assert dest == ignore || bcx.unreachable; } } - ret trans_block_cleanups(bcx, find_scope_cx(bcx)); + let rv = trans_block_cleanups(bcx, find_scope_cx(bcx)); + debuginfo::reset_source_pos(bcx); + ret rv; } fn new_local_ctxt(ccx: @crate_ctxt) -> @local_ctxt { @@ -5465,6 +5481,18 @@ fn declare_intrinsics(llmod: ModuleRef) -> hashmap { ret intrinsics; } +fn declare_dbg_intrinsics(llmod: ModuleRef, + intrinsics: hashmap) { + let declare = + decl_cdecl_fn(llmod, "llvm.dbg.declare", + T_fn([T_metadata(), T_metadata()], T_void())); + let value = + decl_cdecl_fn(llmod, "llvm.dbg.value", + T_fn([T_metadata(), T_i64(), T_metadata()], T_void())); + intrinsics.insert("llvm.dbg.declare", declare); + intrinsics.insert("llvm.dbg.value", value); +} + fn trap(bcx: @block_ctxt) { let v: [ValueRef] = []; alt bcx_ccx(bcx).intrinsics.find("llvm.trap") { @@ -5601,6 +5629,9 @@ fn trans_crate(sess: session::session, crate: @ast::crate, tcx: ty::ctxt, let td = mk_target_data(sess.get_targ_cfg().target_strs.data_layout); let tn = mk_type_names(); let intrinsics = declare_intrinsics(llmod); + if sess.get_opts().debuginfo { + declare_dbg_intrinsics(llmod, intrinsics); + } let int_type = T_int(targ_cfg); let float_type = T_float(targ_cfg); let task_type = T_task(targ_cfg); diff --git a/src/comp/middle/trans_build.rs b/src/comp/middle/trans_build.rs index 210626deffbe8..26c63290405d9 100644 --- a/src/comp/middle/trans_build.rs +++ b/src/comp/middle/trans_build.rs @@ -25,14 +25,16 @@ fn RetVoid(cx: @block_ctxt) { if cx.unreachable { ret; } assert (!cx.terminated); cx.terminated = true; - llvm::LLVMBuildRetVoid(B(cx)); + let instr = llvm::LLVMBuildRetVoid(B(cx)); + debuginfo::add_line_info(cx, instr); } fn Ret(cx: @block_ctxt, V: ValueRef) { if cx.unreachable { ret; } assert (!cx.terminated); cx.terminated = true; - llvm::LLVMBuildRet(B(cx), V); + let instr = llvm::LLVMBuildRet(B(cx), V); + debuginfo::add_line_info(cx, instr); } fn AggregateRet(cx: @block_ctxt, RetVals: [ValueRef]) { @@ -40,8 +42,9 @@ fn AggregateRet(cx: @block_ctxt, RetVals: [ValueRef]) { assert (!cx.terminated); cx.terminated = true; unsafe { - llvm::LLVMBuildAggregateRet(B(cx), vec::to_ptr(RetVals), - vec::len(RetVals)); + let instr = llvm::LLVMBuildAggregateRet(B(cx), vec::to_ptr(RetVals), + vec::len(RetVals)); + debuginfo::add_line_info(cx, instr); } } @@ -49,7 +52,8 @@ fn Br(cx: @block_ctxt, Dest: BasicBlockRef) { if cx.unreachable { ret; } assert (!cx.terminated); cx.terminated = true; - llvm::LLVMBuildBr(B(cx), Dest); + let instr = llvm::LLVMBuildBr(B(cx), Dest); + debuginfo::add_line_info(cx, instr); } fn CondBr(cx: @block_ctxt, If: ValueRef, Then: BasicBlockRef, @@ -57,7 +61,8 @@ fn CondBr(cx: @block_ctxt, If: ValueRef, Then: BasicBlockRef, if cx.unreachable { ret; } assert (!cx.terminated); cx.terminated = true; - llvm::LLVMBuildCondBr(B(cx), If, Then, Else); + let instr = llvm::LLVMBuildCondBr(B(cx), If, Then, Else); + debuginfo::add_line_info(cx, instr); } fn Switch(cx: @block_ctxt, V: ValueRef, Else: BasicBlockRef, NumCases: uint) @@ -65,7 +70,9 @@ fn Switch(cx: @block_ctxt, V: ValueRef, Else: BasicBlockRef, NumCases: uint) if cx.unreachable { ret _Undef(V); } assert !cx.terminated; cx.terminated = true; - ret llvm::LLVMBuildSwitch(B(cx), V, Else, NumCases); + let instr = llvm::LLVMBuildSwitch(B(cx), V, Else, NumCases); + debuginfo::add_line_info(cx, instr); + ret instr; } fn AddCase(S: ValueRef, OnVal: ValueRef, Dest: BasicBlockRef) { @@ -77,7 +84,8 @@ fn IndirectBr(cx: @block_ctxt, Addr: ValueRef, NumDests: uint) { if cx.unreachable { ret; } assert (!cx.terminated); cx.terminated = true; - llvm::LLVMBuildIndirectBr(B(cx), Addr, NumDests); + let instr = llvm::LLVMBuildIndirectBr(B(cx), Addr, NumDests); + debuginfo::add_line_info(cx, instr); } // This is a really awful way to get a zero-length c-string, but better (and a @@ -93,8 +101,10 @@ fn Invoke(cx: @block_ctxt, Fn: ValueRef, Args: [ValueRef], assert (!cx.terminated); cx.terminated = true; unsafe { - llvm::LLVMBuildInvoke(B(cx), Fn, vec::to_ptr(Args), - vec::len(Args), Then, Catch, noname()); + let instr = llvm::LLVMBuildInvoke(B(cx), Fn, vec::to_ptr(Args), + vec::len(Args), Then, Catch, + noname()); + debuginfo::add_line_info(cx, instr); } } @@ -107,6 +117,7 @@ fn FastInvoke(cx: @block_ctxt, Fn: ValueRef, Args: [ValueRef], let v = llvm::LLVMBuildInvoke(B(cx), Fn, vec::to_ptr(Args), vec::len(Args), Then, Catch, noname()); llvm::LLVMSetInstructionCallConv(v, lib::llvm::LLVMFastCallConv); + debuginfo::add_line_info(cx, v); } } @@ -123,183 +134,254 @@ fn _Undef(val: ValueRef) -> ValueRef { /* Arithmetic */ fn Add(cx: @block_ctxt, LHS: ValueRef, RHS: ValueRef) -> ValueRef { if cx.unreachable { ret _Undef(LHS); } - ret llvm::LLVMBuildAdd(B(cx), LHS, RHS, noname()); + let instr = llvm::LLVMBuildAdd(B(cx), LHS, RHS, noname()); + debuginfo::add_line_info(cx, instr); + ret instr; } fn NSWAdd(cx: @block_ctxt, LHS: ValueRef, RHS: ValueRef) -> ValueRef { if cx.unreachable { ret _Undef(LHS); } - ret llvm::LLVMBuildNSWAdd(B(cx), LHS, RHS, noname()); + let instr = llvm::LLVMBuildNSWAdd(B(cx), LHS, RHS, noname()); + debuginfo::add_line_info(cx, instr); + ret instr; } fn NUWAdd(cx: @block_ctxt, LHS: ValueRef, RHS: ValueRef) -> ValueRef { if cx.unreachable { ret _Undef(LHS); } - ret llvm::LLVMBuildNUWAdd(B(cx), LHS, RHS, noname()); + let instr = llvm::LLVMBuildNUWAdd(B(cx), LHS, RHS, noname()); + debuginfo::add_line_info(cx, instr); + ret instr; } fn FAdd(cx: @block_ctxt, LHS: ValueRef, RHS: ValueRef) -> ValueRef { if cx.unreachable { ret _Undef(LHS); } - ret llvm::LLVMBuildFAdd(B(cx), LHS, RHS, noname()); + let instr = llvm::LLVMBuildFAdd(B(cx), LHS, RHS, noname()); + debuginfo::add_line_info(cx, instr); + ret instr; } fn Sub(cx: @block_ctxt, LHS: ValueRef, RHS: ValueRef) -> ValueRef { if cx.unreachable { ret _Undef(LHS); } - ret llvm::LLVMBuildSub(B(cx), LHS, RHS, noname()); + let instr = llvm::LLVMBuildSub(B(cx), LHS, RHS, noname()); + debuginfo::add_line_info(cx, instr); + ret instr; } fn NSWSub(cx: @block_ctxt, LHS: ValueRef, RHS: ValueRef) -> ValueRef { if cx.unreachable { ret _Undef(LHS); } - ret llvm::LLVMBuildNSWSub(B(cx), LHS, RHS, noname()); + let instr = llvm::LLVMBuildNSWSub(B(cx), LHS, RHS, noname()); + debuginfo::add_line_info(cx, instr); + ret instr; } fn NUWSub(cx: @block_ctxt, LHS: ValueRef, RHS: ValueRef) -> ValueRef { if cx.unreachable { ret _Undef(LHS); } - ret llvm::LLVMBuildNUWSub(B(cx), LHS, RHS, noname()); + let instr = llvm::LLVMBuildNUWSub(B(cx), LHS, RHS, noname()); + debuginfo::add_line_info(cx, instr); + ret instr; } fn FSub(cx: @block_ctxt, LHS: ValueRef, RHS: ValueRef) -> ValueRef { if cx.unreachable { ret _Undef(LHS); } - ret llvm::LLVMBuildFSub(B(cx), LHS, RHS, noname()); + let instr = llvm::LLVMBuildFSub(B(cx), LHS, RHS, noname()); + debuginfo::add_line_info(cx, instr); + ret instr; } fn Mul(cx: @block_ctxt, LHS: ValueRef, RHS: ValueRef) -> ValueRef { if cx.unreachable { ret _Undef(LHS); } - ret llvm::LLVMBuildMul(B(cx), LHS, RHS, noname()); + let instr = llvm::LLVMBuildMul(B(cx), LHS, RHS, noname()); + debuginfo::add_line_info(cx, instr); + ret instr; } fn NSWMul(cx: @block_ctxt, LHS: ValueRef, RHS: ValueRef) -> ValueRef { if cx.unreachable { ret _Undef(LHS); } - ret llvm::LLVMBuildNSWMul(B(cx), LHS, RHS, noname()); + let instr = llvm::LLVMBuildNSWMul(B(cx), LHS, RHS, noname()); + debuginfo::add_line_info(cx, instr); + ret instr; } fn NUWMul(cx: @block_ctxt, LHS: ValueRef, RHS: ValueRef) -> ValueRef { if cx.unreachable { ret _Undef(LHS); } - ret llvm::LLVMBuildNUWMul(B(cx), LHS, RHS, noname()); + let instr = llvm::LLVMBuildNUWMul(B(cx), LHS, RHS, noname()); + debuginfo::add_line_info(cx, instr); + ret instr; } fn FMul(cx: @block_ctxt, LHS: ValueRef, RHS: ValueRef) -> ValueRef { if cx.unreachable { ret _Undef(LHS); } - ret llvm::LLVMBuildFMul(B(cx), LHS, RHS, noname()); + let instr = llvm::LLVMBuildFMul(B(cx), LHS, RHS, noname()); + debuginfo::add_line_info(cx, instr); + ret instr; } fn UDiv(cx: @block_ctxt, LHS: ValueRef, RHS: ValueRef) -> ValueRef { if cx.unreachable { ret _Undef(LHS); } - ret llvm::LLVMBuildUDiv(B(cx), LHS, RHS, noname()); + let instr = llvm::LLVMBuildUDiv(B(cx), LHS, RHS, noname()); + debuginfo::add_line_info(cx, instr); + ret instr; } fn SDiv(cx: @block_ctxt, LHS: ValueRef, RHS: ValueRef) -> ValueRef { if cx.unreachable { ret _Undef(LHS); } - ret llvm::LLVMBuildSDiv(B(cx), LHS, RHS, noname()); + let instr = llvm::LLVMBuildSDiv(B(cx), LHS, RHS, noname()); + debuginfo::add_line_info(cx, instr); + ret instr; } fn ExactSDiv(cx: @block_ctxt, LHS: ValueRef, RHS: ValueRef) -> ValueRef { if cx.unreachable { ret _Undef(LHS); } - ret llvm::LLVMBuildExactSDiv(B(cx), LHS, RHS, noname()); + let instr = llvm::LLVMBuildExactSDiv(B(cx), LHS, RHS, noname()); + debuginfo::add_line_info(cx, instr); + ret instr; } fn FDiv(cx: @block_ctxt, LHS: ValueRef, RHS: ValueRef) -> ValueRef { if cx.unreachable { ret _Undef(LHS); } - ret llvm::LLVMBuildFDiv(B(cx), LHS, RHS, noname()); + let instr = llvm::LLVMBuildFDiv(B(cx), LHS, RHS, noname()); + debuginfo::add_line_info(cx, instr); + ret instr; } fn URem(cx: @block_ctxt, LHS: ValueRef, RHS: ValueRef) -> ValueRef { if cx.unreachable { ret _Undef(LHS); } - ret llvm::LLVMBuildURem(B(cx), LHS, RHS, noname()); + let instr = llvm::LLVMBuildURem(B(cx), LHS, RHS, noname()); + debuginfo::add_line_info(cx, instr); + ret instr; } fn SRem(cx: @block_ctxt, LHS: ValueRef, RHS: ValueRef) -> ValueRef { if cx.unreachable { ret _Undef(LHS); } - ret llvm::LLVMBuildSRem(B(cx), LHS, RHS, noname()); + let instr = llvm::LLVMBuildSRem(B(cx), LHS, RHS, noname()); + debuginfo::add_line_info(cx, instr); + ret instr; } fn FRem(cx: @block_ctxt, LHS: ValueRef, RHS: ValueRef) -> ValueRef { if cx.unreachable { ret _Undef(LHS); } - ret llvm::LLVMBuildFRem(B(cx), LHS, RHS, noname()); + let instr = llvm::LLVMBuildFRem(B(cx), LHS, RHS, noname()); + debuginfo::add_line_info(cx, instr); + ret instr; } fn Shl(cx: @block_ctxt, LHS: ValueRef, RHS: ValueRef) -> ValueRef { if cx.unreachable { ret _Undef(LHS); } - ret llvm::LLVMBuildShl(B(cx), LHS, RHS, noname()); + let instr = llvm::LLVMBuildShl(B(cx), LHS, RHS, noname()); + debuginfo::add_line_info(cx, instr); + ret instr; } fn LShr(cx: @block_ctxt, LHS: ValueRef, RHS: ValueRef) -> ValueRef { if cx.unreachable { ret _Undef(LHS); } - ret llvm::LLVMBuildLShr(B(cx), LHS, RHS, noname()); + let instr = llvm::LLVMBuildLShr(B(cx), LHS, RHS, noname()); + debuginfo::add_line_info(cx, instr); + ret instr; } fn AShr(cx: @block_ctxt, LHS: ValueRef, RHS: ValueRef) -> ValueRef { if cx.unreachable { ret _Undef(LHS); } - ret llvm::LLVMBuildAShr(B(cx), LHS, RHS, noname()); + let instr = llvm::LLVMBuildAShr(B(cx), LHS, RHS, noname()); + debuginfo::add_line_info(cx, instr); + ret instr; } fn And(cx: @block_ctxt, LHS: ValueRef, RHS: ValueRef) -> ValueRef { if cx.unreachable { ret _Undef(LHS); } - ret llvm::LLVMBuildAnd(B(cx), LHS, RHS, noname()); + let instr = llvm::LLVMBuildAnd(B(cx), LHS, RHS, noname()); + debuginfo::add_line_info(cx, instr); + ret instr; } fn Or(cx: @block_ctxt, LHS: ValueRef, RHS: ValueRef) -> ValueRef { if cx.unreachable { ret _Undef(LHS); } - ret llvm::LLVMBuildOr(B(cx), LHS, RHS, noname()); + let instr = llvm::LLVMBuildOr(B(cx), LHS, RHS, noname()); + debuginfo::add_line_info(cx, instr); + ret instr; } fn Xor(cx: @block_ctxt, LHS: ValueRef, RHS: ValueRef) -> ValueRef { if cx.unreachable { ret _Undef(LHS); } - ret llvm::LLVMBuildXor(B(cx), LHS, RHS, noname()); + let instr = llvm::LLVMBuildXor(B(cx), LHS, RHS, noname()); + debuginfo::add_line_info(cx, instr); + ret instr; } fn BinOp(cx: @block_ctxt, Op: Opcode, LHS: ValueRef, RHS: ValueRef) -> ValueRef { if cx.unreachable { ret _Undef(LHS); } - ret llvm::LLVMBuildBinOp(B(cx), Op, LHS, RHS, noname()); + let instr = llvm::LLVMBuildBinOp(B(cx), Op, LHS, RHS, noname()); + debuginfo::add_line_info(cx, instr); + ret instr; } fn Neg(cx: @block_ctxt, V: ValueRef) -> ValueRef { if cx.unreachable { ret _Undef(V); } - ret llvm::LLVMBuildNeg(B(cx), V, noname()); + let instr = llvm::LLVMBuildNeg(B(cx), V, noname()); + debuginfo::add_line_info(cx, instr); + ret instr; } fn NSWNeg(cx: @block_ctxt, V: ValueRef) -> ValueRef { if cx.unreachable { ret _Undef(V); } - ret llvm::LLVMBuildNSWNeg(B(cx), V, noname()); + let instr = llvm::LLVMBuildNSWNeg(B(cx), V, noname()); + debuginfo::add_line_info(cx, instr); + ret instr; } fn NUWNeg(cx: @block_ctxt, V: ValueRef) -> ValueRef { if cx.unreachable { ret _Undef(V); } - ret llvm::LLVMBuildNUWNeg(B(cx), V, noname()); + let instr = llvm::LLVMBuildNUWNeg(B(cx), V, noname()); + debuginfo::add_line_info(cx, instr); + ret instr; } fn FNeg(cx: @block_ctxt, V: ValueRef) -> ValueRef { if cx.unreachable { ret _Undef(V); } - ret llvm::LLVMBuildFNeg(B(cx), V, noname()); + let instr = llvm::LLVMBuildFNeg(B(cx), V, noname()); + debuginfo::add_line_info(cx, instr); + ret instr; } fn Not(cx: @block_ctxt, V: ValueRef) -> ValueRef { if cx.unreachable { ret _Undef(V); } - ret llvm::LLVMBuildNot(B(cx), V, noname()); + let instr = llvm::LLVMBuildNot(B(cx), V, noname()); + debuginfo::add_line_info(cx, instr); + ret instr; } /* Memory */ fn Malloc(cx: @block_ctxt, Ty: TypeRef) -> ValueRef { if cx.unreachable { ret llvm::LLVMGetUndef(T_ptr(T_i8())); } - ret llvm::LLVMBuildMalloc(B(cx), Ty, noname()); + let instr = llvm::LLVMBuildMalloc(B(cx), Ty, noname()); + debuginfo::add_line_info(cx, instr); + ret instr; } fn ArrayMalloc(cx: @block_ctxt, Ty: TypeRef, Val: ValueRef) -> ValueRef { if cx.unreachable { ret llvm::LLVMGetUndef(T_ptr(T_i8())); } - ret llvm::LLVMBuildArrayMalloc(B(cx), Ty, Val, noname()); + let instr = llvm::LLVMBuildArrayMalloc(B(cx), Ty, Val, noname()); + debuginfo::add_line_info(cx, instr); + ret instr; } fn Alloca(cx: @block_ctxt, Ty: TypeRef) -> ValueRef { if cx.unreachable { ret llvm::LLVMGetUndef(T_ptr(Ty)); } - ret llvm::LLVMBuildAlloca(B(cx), Ty, noname()); + let instr = llvm::LLVMBuildAlloca(B(cx), Ty, noname()); + debuginfo::add_line_info(cx, instr); + ret instr; } fn ArrayAlloca(cx: @block_ctxt, Ty: TypeRef, Val: ValueRef) -> ValueRef { if cx.unreachable { ret llvm::LLVMGetUndef(T_ptr(Ty)); } - ret llvm::LLVMBuildArrayAlloca(B(cx), Ty, Val, noname()); + let instr = llvm::LLVMBuildArrayAlloca(B(cx), Ty, Val, noname()); + debuginfo::add_line_info(cx, instr); + ret instr; } fn Free(cx: @block_ctxt, PointerVal: ValueRef) { if cx.unreachable { ret; } - llvm::LLVMBuildFree(B(cx), PointerVal); + let instr = llvm::LLVMBuildFree(B(cx), PointerVal); + debuginfo::add_line_info(cx, instr); } fn Load(cx: @block_ctxt, PointerVal: ValueRef) -> ValueRef { @@ -310,19 +392,24 @@ fn Load(cx: @block_ctxt, PointerVal: ValueRef) -> ValueRef { llvm::LLVMGetElementType(ty) } else { ccx.int_type }; ret llvm::LLVMGetUndef(eltty); } - ret llvm::LLVMBuildLoad(B(cx), PointerVal, noname()); + let instr = llvm::LLVMBuildLoad(B(cx), PointerVal, noname()); + debuginfo::add_line_info(cx, instr); + ret instr; } fn Store(cx: @block_ctxt, Val: ValueRef, Ptr: ValueRef) { if cx.unreachable { ret; } - llvm::LLVMBuildStore(B(cx), Val, Ptr); + let instr = llvm::LLVMBuildStore(B(cx), Val, Ptr); + debuginfo::add_line_info(cx, instr); } fn GEP(cx: @block_ctxt, Pointer: ValueRef, Indices: [ValueRef]) -> ValueRef { if cx.unreachable { ret llvm::LLVMGetUndef(T_ptr(T_nil())); } unsafe { - ret llvm::LLVMBuildGEP(B(cx), Pointer, vec::to_ptr(Indices), - vec::len(Indices), noname()); + let instr = llvm::LLVMBuildGEP(B(cx), Pointer, vec::to_ptr(Indices), + vec::len(Indices), noname()); + debuginfo::add_line_info(cx, instr); + ret instr; } } @@ -338,142 +425,195 @@ fn InBoundsGEP(cx: @block_ctxt, Pointer: ValueRef, Indices: [ValueRef]) -> ValueRef { if cx.unreachable { ret llvm::LLVMGetUndef(T_ptr(T_nil())); } unsafe { - ret llvm::LLVMBuildInBoundsGEP(B(cx), Pointer, vec::to_ptr(Indices), - vec::len(Indices), noname()); + let v = llvm::LLVMBuildInBoundsGEP(B(cx), Pointer, + vec::to_ptr(Indices), + vec::len(Indices), noname()); + debuginfo::add_line_info(cx, v); + ret v; } } fn StructGEP(cx: @block_ctxt, Pointer: ValueRef, Idx: uint) -> ValueRef { if cx.unreachable { ret llvm::LLVMGetUndef(T_ptr(T_nil())); } - ret llvm::LLVMBuildStructGEP(B(cx), Pointer, Idx, noname()); + let instr = llvm::LLVMBuildStructGEP(B(cx), Pointer, Idx, noname()); + debuginfo::add_line_info(cx, instr); + ret instr; } fn GlobalString(cx: @block_ctxt, _Str: sbuf) -> ValueRef { if cx.unreachable { ret llvm::LLVMGetUndef(T_ptr(T_i8())); } - ret llvm::LLVMBuildGlobalString(B(cx), _Str, noname()); + let instr = llvm::LLVMBuildGlobalString(B(cx), _Str, noname()); + debuginfo::add_line_info(cx, instr); + ret instr; } fn GlobalStringPtr(cx: @block_ctxt, _Str: sbuf) -> ValueRef { if cx.unreachable { ret llvm::LLVMGetUndef(T_ptr(T_i8())); } - ret llvm::LLVMBuildGlobalStringPtr(B(cx), _Str, noname()); + let instr = llvm::LLVMBuildGlobalStringPtr(B(cx), _Str, noname()); + debuginfo::add_line_info(cx, instr); + ret instr; } /* Casts */ fn Trunc(cx: @block_ctxt, Val: ValueRef, DestTy: TypeRef) -> ValueRef { if cx.unreachable { ret llvm::LLVMGetUndef(DestTy); } - ret llvm::LLVMBuildTrunc(B(cx), Val, DestTy, noname()); + let instr = llvm::LLVMBuildTrunc(B(cx), Val, DestTy, noname()); + debuginfo::add_line_info(cx, instr); + ret instr; } fn ZExt(cx: @block_ctxt, Val: ValueRef, DestTy: TypeRef) -> ValueRef { if cx.unreachable { ret llvm::LLVMGetUndef(DestTy); } - ret llvm::LLVMBuildZExt(B(cx), Val, DestTy, noname()); + let instr = llvm::LLVMBuildZExt(B(cx), Val, DestTy, noname()); + debuginfo::add_line_info(cx, instr); + ret instr; } fn SExt(cx: @block_ctxt, Val: ValueRef, DestTy: TypeRef) -> ValueRef { if cx.unreachable { ret llvm::LLVMGetUndef(DestTy); } - ret llvm::LLVMBuildSExt(B(cx), Val, DestTy, noname()); + let instr = llvm::LLVMBuildSExt(B(cx), Val, DestTy, noname()); + debuginfo::add_line_info(cx, instr); + ret instr; } fn FPToUI(cx: @block_ctxt, Val: ValueRef, DestTy: TypeRef) -> ValueRef { if cx.unreachable { ret llvm::LLVMGetUndef(DestTy); } - ret llvm::LLVMBuildFPToUI(B(cx), Val, DestTy, noname()); + let instr = llvm::LLVMBuildFPToUI(B(cx), Val, DestTy, noname()); + debuginfo::add_line_info(cx, instr); + ret instr; } fn FPToSI(cx: @block_ctxt, Val: ValueRef, DestTy: TypeRef) -> ValueRef { if cx.unreachable { ret llvm::LLVMGetUndef(DestTy); } - ret llvm::LLVMBuildFPToSI(B(cx), Val, DestTy, noname()); + let instr = llvm::LLVMBuildFPToSI(B(cx), Val, DestTy, noname()); + debuginfo::add_line_info(cx, instr); + ret instr; } fn UIToFP(cx: @block_ctxt, Val: ValueRef, DestTy: TypeRef) -> ValueRef { if cx.unreachable { ret llvm::LLVMGetUndef(DestTy); } - ret llvm::LLVMBuildUIToFP(B(cx), Val, DestTy, noname()); + let instr = llvm::LLVMBuildUIToFP(B(cx), Val, DestTy, noname()); + debuginfo::add_line_info(cx, instr); + ret instr; } fn SIToFP(cx: @block_ctxt, Val: ValueRef, DestTy: TypeRef) -> ValueRef { if cx.unreachable { ret llvm::LLVMGetUndef(DestTy); } - ret llvm::LLVMBuildSIToFP(B(cx), Val, DestTy, noname()); + let instr = llvm::LLVMBuildSIToFP(B(cx), Val, DestTy, noname()); + debuginfo::add_line_info(cx, instr); + ret instr; } fn FPTrunc(cx: @block_ctxt, Val: ValueRef, DestTy: TypeRef) -> ValueRef { if cx.unreachable { ret llvm::LLVMGetUndef(DestTy); } - ret llvm::LLVMBuildFPTrunc(B(cx), Val, DestTy, noname()); + let instr = llvm::LLVMBuildFPTrunc(B(cx), Val, DestTy, noname()); + debuginfo::add_line_info(cx, instr); + ret instr; } fn FPExt(cx: @block_ctxt, Val: ValueRef, DestTy: TypeRef) -> ValueRef { if cx.unreachable { ret llvm::LLVMGetUndef(DestTy); } - ret llvm::LLVMBuildFPExt(B(cx), Val, DestTy, noname()); + let instr = llvm::LLVMBuildFPExt(B(cx), Val, DestTy, noname()); + debuginfo::add_line_info(cx, instr); + ret instr; } fn PtrToInt(cx: @block_ctxt, Val: ValueRef, DestTy: TypeRef) -> ValueRef { if cx.unreachable { ret llvm::LLVMGetUndef(DestTy); } - ret llvm::LLVMBuildPtrToInt(B(cx), Val, DestTy, noname()); + let instr = llvm::LLVMBuildPtrToInt(B(cx), Val, DestTy, noname()); + debuginfo::add_line_info(cx, instr); + ret instr; } fn IntToPtr(cx: @block_ctxt, Val: ValueRef, DestTy: TypeRef) -> ValueRef { if cx.unreachable { ret llvm::LLVMGetUndef(DestTy); } - ret llvm::LLVMBuildIntToPtr(B(cx), Val, DestTy, noname()); + let instr = llvm::LLVMBuildIntToPtr(B(cx), Val, DestTy, noname()); + debuginfo::add_line_info(cx, instr); + ret instr; } fn BitCast(cx: @block_ctxt, Val: ValueRef, DestTy: TypeRef) -> ValueRef { if cx.unreachable { ret llvm::LLVMGetUndef(DestTy); } - ret llvm::LLVMBuildBitCast(B(cx), Val, DestTy, noname()); + let instr = llvm::LLVMBuildBitCast(B(cx), Val, DestTy, noname()); + debuginfo::add_line_info(cx, instr); + ret instr; } fn ZExtOrBitCast(cx: @block_ctxt, Val: ValueRef, DestTy: TypeRef) -> ValueRef { if cx.unreachable { ret llvm::LLVMGetUndef(DestTy); } - ret llvm::LLVMBuildZExtOrBitCast(B(cx), Val, DestTy, noname()); + let instr = llvm::LLVMBuildZExtOrBitCast(B(cx), Val, DestTy, noname()); + debuginfo::add_line_info(cx, instr); + ret instr; } fn SExtOrBitCast(cx: @block_ctxt, Val: ValueRef, DestTy: TypeRef) -> ValueRef { if cx.unreachable { ret llvm::LLVMGetUndef(DestTy); } - ret llvm::LLVMBuildSExtOrBitCast(B(cx), Val, DestTy, noname()); + let instr = llvm::LLVMBuildSExtOrBitCast(B(cx), Val, DestTy, noname()); + debuginfo::add_line_info(cx, instr); + ret instr; } fn TruncOrBitCast(cx: @block_ctxt, Val: ValueRef, DestTy: TypeRef) -> ValueRef { if cx.unreachable { ret llvm::LLVMGetUndef(DestTy); } - ret llvm::LLVMBuildTruncOrBitCast(B(cx), Val, DestTy, noname()); + let instr = llvm::LLVMBuildTruncOrBitCast(B(cx), Val, DestTy, noname()); + debuginfo::add_line_info(cx, instr); + ret instr; } fn Cast(cx: @block_ctxt, Op: Opcode, Val: ValueRef, DestTy: TypeRef, _Name: sbuf) -> ValueRef { if cx.unreachable { ret llvm::LLVMGetUndef(DestTy); } - ret llvm::LLVMBuildCast(B(cx), Op, Val, DestTy, noname()); + let instr = llvm::LLVMBuildCast(B(cx), Op, Val, DestTy, noname()); + debuginfo::add_line_info(cx, instr); + ret instr; } fn PointerCast(cx: @block_ctxt, Val: ValueRef, DestTy: TypeRef) -> ValueRef { if cx.unreachable { ret llvm::LLVMGetUndef(DestTy); } - ret llvm::LLVMBuildPointerCast(B(cx), Val, DestTy, noname()); + let instr = llvm::LLVMBuildPointerCast(B(cx), Val, DestTy, noname()); + debuginfo::add_line_info(cx, instr); + ret instr; } fn IntCast(cx: @block_ctxt, Val: ValueRef, DestTy: TypeRef) -> ValueRef { if cx.unreachable { ret llvm::LLVMGetUndef(DestTy); } - ret llvm::LLVMBuildIntCast(B(cx), Val, DestTy, noname()); + let instr = llvm::LLVMBuildIntCast(B(cx), Val, DestTy, noname()); + debuginfo::add_line_info(cx, instr); + ret instr; } fn FPCast(cx: @block_ctxt, Val: ValueRef, DestTy: TypeRef) -> ValueRef { if cx.unreachable { ret llvm::LLVMGetUndef(DestTy); } - ret llvm::LLVMBuildFPCast(B(cx), Val, DestTy, noname()); + let instr = llvm::LLVMBuildFPCast(B(cx), Val, DestTy, noname()); + debuginfo::add_line_info(cx, instr); + ret instr; } /* Comparisons */ fn ICmp(cx: @block_ctxt, Op: uint, LHS: ValueRef, RHS: ValueRef) -> ValueRef { if cx.unreachable { ret llvm::LLVMGetUndef(T_i1()); } - ret llvm::LLVMBuildICmp(B(cx), Op, LHS, RHS, noname()); + let instr = llvm::LLVMBuildICmp(B(cx), Op, LHS, RHS, noname()); + debuginfo::add_line_info(cx, instr); + ret instr; } fn FCmp(cx: @block_ctxt, Op: uint, LHS: ValueRef, RHS: ValueRef) -> ValueRef { if cx.unreachable { ret llvm::LLVMGetUndef(T_i1()); } - ret llvm::LLVMBuildFCmp(B(cx), Op, LHS, RHS, noname()); + let instr = llvm::LLVMBuildFCmp(B(cx), Op, LHS, RHS, noname()); + debuginfo::add_line_info(cx, instr); + ret instr; } /* Miscellaneous instructions */ fn EmptyPhi(cx: @block_ctxt, Ty: TypeRef) -> ValueRef { if cx.unreachable { ret llvm::LLVMGetUndef(Ty); } - ret llvm::LLVMBuildPhi(B(cx), Ty, noname()); + let instr = llvm::LLVMBuildPhi(B(cx), Ty, noname()); + debuginfo::add_line_info(cx, instr); + ret instr; } fn Phi(cx: @block_ctxt, Ty: TypeRef, vals: [ValueRef], bbs: [BasicBlockRef]) @@ -528,8 +668,10 @@ fn add_comment(bcx: @block_ctxt, text: str) { fn Call(cx: @block_ctxt, Fn: ValueRef, Args: [ValueRef]) -> ValueRef { if cx.unreachable { ret _UndefReturn(cx, Fn); } unsafe { - ret llvm::LLVMBuildCall(B(cx), Fn, vec::to_ptr(Args), - vec::len(Args), noname()); + let instr = llvm::LLVMBuildCall(B(cx), Fn, vec::to_ptr(Args), + vec::len(Args), noname()); + debuginfo::add_line_info(cx, instr); + ret instr; } } @@ -539,6 +681,7 @@ fn FastCall(cx: @block_ctxt, Fn: ValueRef, Args: [ValueRef]) -> ValueRef { let v = llvm::LLVMBuildCall(B(cx), Fn, vec::to_ptr(Args), vec::len(Args), noname()); llvm::LLVMSetInstructionCallConv(v, lib::llvm::LLVMFastCallConv); + debuginfo::add_line_info(cx, v); ret v; } } @@ -550,6 +693,7 @@ fn CallWithConv(cx: @block_ctxt, Fn: ValueRef, Args: [ValueRef], Conv: uint) let v = llvm::LLVMBuildCall(B(cx), Fn, vec::to_ptr(Args), vec::len(Args), noname()); llvm::LLVMSetInstructionCallConv(v, Conv); + debuginfo::add_line_info(cx, v); ret v; } } @@ -557,57 +701,76 @@ fn CallWithConv(cx: @block_ctxt, Fn: ValueRef, Args: [ValueRef], Conv: uint) fn Select(cx: @block_ctxt, If: ValueRef, Then: ValueRef, Else: ValueRef) -> ValueRef { if cx.unreachable { ret _Undef(Then); } - ret llvm::LLVMBuildSelect(B(cx), If, Then, Else, noname()); + let instr = llvm::LLVMBuildSelect(B(cx), If, Then, Else, noname()); + debuginfo::add_line_info(cx, instr); + ret instr; } fn VAArg(cx: @block_ctxt, list: ValueRef, Ty: TypeRef) -> ValueRef { if cx.unreachable { ret llvm::LLVMGetUndef(Ty); } - ret llvm::LLVMBuildVAArg(B(cx), list, Ty, noname()); + let instr = llvm::LLVMBuildVAArg(B(cx), list, Ty, noname()); + debuginfo::add_line_info(cx, instr); + ret instr; } fn ExtractElement(cx: @block_ctxt, VecVal: ValueRef, Index: ValueRef) -> ValueRef { if cx.unreachable { ret llvm::LLVMGetUndef(T_nil()); } - ret llvm::LLVMBuildExtractElement(B(cx), VecVal, Index, noname()); + let instr = llvm::LLVMBuildExtractElement(B(cx), VecVal, Index, noname()); + debuginfo::add_line_info(cx, instr); + ret instr; } fn InsertElement(cx: @block_ctxt, VecVal: ValueRef, EltVal: ValueRef, Index: ValueRef) { if cx.unreachable { ret; } - llvm::LLVMBuildInsertElement(B(cx), VecVal, EltVal, Index, noname()); + let instr = llvm::LLVMBuildInsertElement(B(cx), VecVal, EltVal, Index, + noname()); + debuginfo::add_line_info(cx, instr); } fn ShuffleVector(cx: @block_ctxt, V1: ValueRef, V2: ValueRef, Mask: ValueRef) { if cx.unreachable { ret; } - llvm::LLVMBuildShuffleVector(B(cx), V1, V2, Mask, noname()); + let instr = llvm::LLVMBuildShuffleVector(B(cx), V1, V2, Mask, noname()); + debuginfo::add_line_info(cx, instr); } fn ExtractValue(cx: @block_ctxt, AggVal: ValueRef, Index: uint) -> ValueRef { if cx.unreachable { ret llvm::LLVMGetUndef(T_nil()); } - ret llvm::LLVMBuildExtractValue(B(cx), AggVal, Index, noname()); + let instr = llvm::LLVMBuildExtractValue(B(cx), AggVal, Index, noname()); + debuginfo::add_line_info(cx, instr); + ret instr; } fn InsertValue(cx: @block_ctxt, AggVal: ValueRef, EltVal: ValueRef, Index: uint) { if cx.unreachable { ret; } - llvm::LLVMBuildInsertValue(B(cx), AggVal, EltVal, Index, noname()); + let instr = llvm::LLVMBuildInsertValue(B(cx), AggVal, EltVal, Index, + noname()); + debuginfo::add_line_info(cx, instr); } fn IsNull(cx: @block_ctxt, Val: ValueRef) -> ValueRef { if cx.unreachable { ret llvm::LLVMGetUndef(T_i1()); } - ret llvm::LLVMBuildIsNull(B(cx), Val, noname()); + let instr = llvm::LLVMBuildIsNull(B(cx), Val, noname()); + debuginfo::add_line_info(cx, instr); + ret instr; } fn IsNotNull(cx: @block_ctxt, Val: ValueRef) -> ValueRef { if cx.unreachable { ret llvm::LLVMGetUndef(T_i1()); } - ret llvm::LLVMBuildIsNotNull(B(cx), Val, noname()); + let instr = llvm::LLVMBuildIsNotNull(B(cx), Val, noname()); + debuginfo::add_line_info(cx, instr); + ret instr; } fn PtrDiff(cx: @block_ctxt, LHS: ValueRef, RHS: ValueRef) -> ValueRef { let ccx = cx.fcx.lcx.ccx; if cx.unreachable { ret llvm::LLVMGetUndef(ccx.int_type); } - ret llvm::LLVMBuildPtrDiff(B(cx), LHS, RHS, noname()); + let instr = llvm::LLVMBuildPtrDiff(B(cx), LHS, RHS, noname()); + debuginfo::add_line_info(cx, instr); + ret instr; } fn Trap(cx: @block_ctxt) { @@ -622,15 +785,19 @@ fn Trap(cx: @block_ctxt) { assert (T as int != 0); let Args: [ValueRef] = []; unsafe { - llvm::LLVMBuildCall(b, T, vec::to_ptr(Args), - vec::len(Args), noname()); + let instr = llvm::LLVMBuildCall(b, T, vec::to_ptr(Args), + vec::len(Args), noname()); + debuginfo::add_line_info(cx, instr); } } fn LandingPad(cx: @block_ctxt, Ty: TypeRef, PersFn: ValueRef, NumClauses: uint) -> ValueRef { assert !cx.terminated && !cx.unreachable; - ret llvm::LLVMBuildLandingPad(B(cx), Ty, PersFn, NumClauses, noname()); + let instr = llvm::LLVMBuildLandingPad(B(cx), Ty, PersFn, NumClauses, + noname()); + debuginfo::add_line_info(cx, instr); + ret instr; } fn SetCleanup(_cx: @block_ctxt, LandingPad: ValueRef) { @@ -640,7 +807,9 @@ fn SetCleanup(_cx: @block_ctxt, LandingPad: ValueRef) { fn Resume(cx: @block_ctxt, Exn: ValueRef) -> ValueRef { assert (!cx.terminated); cx.terminated = true; - ret llvm::LLVMBuildResume(B(cx), Exn); + let instr = llvm::LLVMBuildResume(B(cx), Exn); + debuginfo::add_line_info(cx, instr); + ret instr; } // diff --git a/src/comp/middle/trans_common.rs b/src/comp/middle/trans_common.rs index a4f0a6dfe3dec..98c4b497ab53d 100644 --- a/src/comp/middle/trans_common.rs +++ b/src/comp/middle/trans_common.rs @@ -385,7 +385,8 @@ type block_ctxt = mutable lpad_dirty: bool, mutable lpad: option::t, sp: span, - fcx: @fn_ctxt}; + fcx: @fn_ctxt, + mutable source_pos: option::t}; // FIXME: we should be able to use option::t<@block_parent> here but // the infinite-tag check in rustboot gets upset. @@ -464,6 +465,8 @@ fn T_nil() -> TypeRef { ret llvm::LLVMInt1Type(); } +fn T_metadata() -> TypeRef { ret llvm::LLVMMetadataType(); } + fn T_i1() -> TypeRef { ret llvm::LLVMInt1Type(); } fn T_i8() -> TypeRef { ret llvm::LLVMInt8Type(); } @@ -801,6 +804,10 @@ fn C_i32(i: i32) -> ValueRef { ret C_integral(T_i32(), i as u64, True); } +fn C_i64(i: i64) -> ValueRef { + ret C_integral(T_i64(), i as uint, True); +} + fn C_int(cx: @crate_ctxt, i: int) -> ValueRef { ret C_integral(cx.int_type, i as u64, True); } diff --git a/src/rustllvm/rustllvm.def.in b/src/rustllvm/rustllvm.def.in index 1a34f62f7a062..8c5c2385c9b3b 100644 --- a/src/rustllvm/rustllvm.def.in +++ b/src/rustllvm/rustllvm.def.in @@ -60,6 +60,7 @@ LLVMAddLoopRotatePass LLVMAddLoopUnrollPass LLVMAddLoopUnswitchPass LLVMAddMemCpyOptPass +LLVMAddNamedMetadataOperand LLVMAddPromoteMemoryToRegisterPass LLVMAddPruneEHPass LLVMAddReassociatePass @@ -483,11 +484,15 @@ LLVMIsThreadLocal LLVMIsUndef LLVMLabelType LLVMLabelTypeInContext +LLVMLinkInInterpreter +LLVMLinkInJIT +LLVMLinkInMCJIT LLVMMDNode LLVMMDNodeInContext LLVMMDString LLVMMDStringInContext -LLVMAddNamedMetadataOperand +LLVMMetadataType +LLVMMetadataTypeInContext LLVMModuleCreateWithName LLVMModuleCreateWithNameInContext LLVMMoveBasicBlockAfter From fa6d871e11bc4f765062cff41fbce5d977e24ea5 Mon Sep 17 00:00:00 2001 From: Josh Matthews Date: Wed, 16 Nov 2011 12:37:27 -0500 Subject: [PATCH 03/21] Build fix. --- src/comp/middle/debuginfo.rs | 11 +++++++---- src/comp/middle/trans.rs | 6 +++--- 2 files changed, 10 insertions(+), 7 deletions(-) diff --git a/src/comp/middle/debuginfo.rs b/src/comp/middle/debuginfo.rs index 9379c42623c1b..885e42abc506a 100644 --- a/src/comp/middle/debuginfo.rs +++ b/src/comp/middle/debuginfo.rs @@ -253,6 +253,9 @@ fn get_ty_metadata(cx: @crate_ctxt, t: ty::t, ty: @ast::ty) -> @metadata(cx: @block_ctxt, s: T) { +fn update_source_pos(cx: @block_ctxt, s: codemap::span) { if !bcx_ccx(cx).sess.get_opts().debuginfo { ret; } cx.source_pos = option::some( codemap::lookup_char_pos(bcx_ccx(cx).sess.get_codemap(), - s.span.lo)); //XXX maybe hi + s.lo)); //XXX maybe hi } diff --git a/src/comp/middle/trans.rs b/src/comp/middle/trans.rs index 551ac18a1b200..66b58369d2521 100644 --- a/src/comp/middle/trans.rs +++ b/src/comp/middle/trans.rs @@ -3519,7 +3519,7 @@ fn trans_temp_expr(bcx: @block_ctxt, e: @ast::expr) -> result { // - exprs with non-immediate type never get dest=by_val fn trans_expr(bcx: @block_ctxt, e: @ast::expr, dest: dest) -> @block_ctxt { let tcx = bcx_tcx(bcx); - debuginfo::update_source_pos(bcx, e); + debuginfo::update_source_pos(bcx, e.span); if expr_is_lval(bcx, e) { ret lval_to_dps(bcx, e, dest); @@ -4014,7 +4014,7 @@ fn trans_stmt(cx: @block_ctxt, s: ast::stmt) -> @block_ctxt { } let bcx = cx; - debuginfo::update_source_pos(cx, s); + debuginfo::update_source_pos(cx, s.span); alt s.node { ast::stmt_expr(e, _) { bcx = trans_expr(cx, e, ignore); } @@ -4263,7 +4263,7 @@ fn trans_block(bcx: @block_ctxt, b: ast::blk) -> @block_ctxt { fn trans_block_dps(bcx: @block_ctxt, b: ast::blk, dest: dest) -> @block_ctxt { let bcx = bcx; - debuginfo::update_source_pos(bcx, b); + debuginfo::update_source_pos(bcx, b.span); block_locals(b) {|local| bcx = alloc_local(bcx, local); }; for s: @ast::stmt in b.node.stmts { bcx = trans_stmt(bcx, *s); From 544bcfece238d47ca600fd09cef1f282a7a9bb26 Mon Sep 17 00:00:00 2001 From: Josh Matthews Date: Wed, 16 Nov 2011 19:30:45 -0500 Subject: [PATCH 04/21] Fix LLVM assertions when lowering log statements. --- src/comp/middle/debuginfo.rs | 51 +++++++++++++++++++++++++------ src/comp/middle/trans.rs | 24 +++++++++------ src/comp/middle/trans_build.rs | 54 ++++++++++++++++----------------- src/comp/middle/trans_common.rs | 3 +- src/comp/middle/trans_vec.rs | 2 ++ 5 files changed, 87 insertions(+), 47 deletions(-) diff --git a/src/comp/middle/debuginfo.rs b/src/comp/middle/debuginfo.rs index 885e42abc506a..3f422b21d8510 100644 --- a/src/comp/middle/debuginfo.rs +++ b/src/comp/middle/debuginfo.rs @@ -306,34 +306,65 @@ fn get_local_var_metadata(bcx: @block_ctxt, local: @ast::local) ret mdval; } -fn update_source_pos(cx: @block_ctxt, s: codemap::span) { +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 { - ret; + ret dsp; + } + let cm = bcx_ccx(cx).sess.get_codemap(); + if vec::is_empty(cx.source_pos.pos) { + cx.source_pos.usable = true; + } + cx.source_pos.pos += [codemap::lookup_char_pos(cm, s.lo)]; //XXX maybe hi + ret dsp; +} + +fn invalidate_source_pos(cx: @block_ctxt) -> @invalidated_source_pos { + let isp = @invalidated_source_pos(cx); + if !bcx_ccx(cx).sess.get_opts().debuginfo { + ret isp; } - cx.source_pos = option::some( - codemap::lookup_char_pos(bcx_ccx(cx).sess.get_codemap(), - s.lo)); //XXX maybe hi + cx.source_pos.usable = false; + ret isp; +} +fn revalidate_source_pos(cx: @block_ctxt) { + if !bcx_ccx(cx).sess.get_opts().debuginfo { + ret; + } + cx.source_pos.usable = true; } fn reset_source_pos(cx: @block_ctxt) { - cx.source_pos = option::none; + if !bcx_ccx(cx).sess.get_opts().debuginfo { + ret; + } + vec::pop(cx.source_pos.pos); +} + +resource debug_source_pos(bcx: @block_ctxt) { + reset_source_pos(bcx); +} +resource invalidated_source_pos(bcx: @block_ctxt) { + revalidate_source_pos(bcx); } fn add_line_info(cx: @block_ctxt, llinstr: ValueRef) { if !bcx_ccx(cx).sess.get_opts().debuginfo || - option::is_none(cx.source_pos) { + !cx.source_pos.usable || + vec::is_empty(cx.source_pos.pos) { ret; } - let loc = option::get(cx.source_pos); + let loc = option::get(vec::last(cx.source_pos.pos)); let blockmd = get_block_metadata(cx); - let kind_id = llvm::LLVMGetMDKindID(as_buf("dbg"), str::byte_len("dbg")); + let kind_id = llvm::LLVMGetMDKindID(as_buf("dbg"), + str::byte_len("dbg")); let scopedata = [lli32(loc.line as int), lli32(loc.col as int), blockmd.node, llnull()]; let dbgscope = llmdnode(scopedata); - llvm::LLVMSetMetadata(llinstr, kind_id, dbgscope); + llvm::LLVMSetMetadata(llinstr, kind_id, dbgscope); } fn get_function_metadata(cx: @crate_ctxt, item: @ast::item, diff --git a/src/comp/middle/trans.rs b/src/comp/middle/trans.rs index 66b58369d2521..1e91949d51fb2 100644 --- a/src/comp/middle/trans.rs +++ b/src/comp/middle/trans.rs @@ -3519,7 +3519,7 @@ fn trans_temp_expr(bcx: @block_ctxt, e: @ast::expr) -> result { // - exprs with non-immediate type never get dest=by_val fn trans_expr(bcx: @block_ctxt, e: @ast::expr, dest: dest) -> @block_ctxt { let tcx = bcx_tcx(bcx); - debuginfo::update_source_pos(bcx, e.span); + let _s = debuginfo::update_source_pos(bcx, e.span); if expr_is_lval(bcx, e) { ret lval_to_dps(bcx, e, dest); @@ -4014,7 +4014,7 @@ fn trans_stmt(cx: @block_ctxt, s: ast::stmt) -> @block_ctxt { } let bcx = cx; - debuginfo::update_source_pos(cx, s.span); + let _s = debuginfo::update_source_pos(cx, s.span); alt s.node { ast::stmt_expr(e, _) { bcx = trans_expr(cx, e, ignore); } @@ -4038,7 +4038,7 @@ fn trans_stmt(cx: @block_ctxt, s: ast::stmt) -> @block_ctxt { _ { bcx_ccx(cx).sess.unimpl("stmt variant"); } } - debuginfo::reset_source_pos(cx); + //debuginfo::reset_source_pos(cx); ret bcx; } @@ -4063,7 +4063,8 @@ fn new_block_ctxt(cx: @fn_ctxt, parent: block_parent, kind: block_kind, mutable lpad: option::none, sp: cx.sp, fcx: cx, - mutable source_pos: option::none}; + source_pos: {mutable usable: false, + mutable pos: []}}; alt parent { parent_some(cx) { if cx.unreachable { Unreachable(bcx); } @@ -4108,7 +4109,8 @@ fn new_raw_block_ctxt(fcx: @fn_ctxt, llbb: BasicBlockRef) -> @block_ctxt { mutable lpad: option::none, sp: fcx.sp, fcx: fcx, - mutable source_pos: option::none}; + source_pos: {mutable usable: false, + mutable pos: []}}; } @@ -4176,7 +4178,8 @@ fn llstaticallocas_block_ctxt(fcx: @fn_ctxt) -> @block_ctxt { mutable lpad: option::none, sp: fcx.sp, fcx: fcx, - mutable source_pos: option::none}; + source_pos: {mutable usable: false, + mutable pos: []}}; } fn llderivedtydescs_block_ctxt(fcx: @fn_ctxt) -> @block_ctxt { @@ -4190,7 +4193,8 @@ fn llderivedtydescs_block_ctxt(fcx: @fn_ctxt) -> @block_ctxt { mutable lpad: option::none, sp: fcx.sp, fcx: fcx, - mutable source_pos: option::none}; + source_pos: {mutable usable: false, + mutable pos: []}}; } @@ -4263,20 +4267,22 @@ fn trans_block(bcx: @block_ctxt, b: ast::blk) -> @block_ctxt { fn trans_block_dps(bcx: @block_ctxt, b: ast::blk, dest: dest) -> @block_ctxt { let bcx = bcx; - debuginfo::update_source_pos(bcx, b.span); block_locals(b) {|local| bcx = alloc_local(bcx, local); }; for s: @ast::stmt in b.node.stmts { + let _s = debuginfo::update_source_pos(bcx, b.span); bcx = trans_stmt(bcx, *s); + //debuginfo::reset_source_pos(bcx); } alt b.node.expr { some(e) { let bt = ty::type_is_bot(bcx_tcx(bcx), ty::expr_ty(bcx_tcx(bcx), e)); + let _s = debuginfo::update_source_pos(bcx, e.span); bcx = trans_expr(bcx, e, bt ? ignore : dest); + //debuginfo::reset_source_pos(bcx); } _ { assert dest == ignore || bcx.unreachable; } } let rv = trans_block_cleanups(bcx, find_scope_cx(bcx)); - debuginfo::reset_source_pos(bcx); ret rv; } diff --git a/src/comp/middle/trans_build.rs b/src/comp/middle/trans_build.rs index 26c63290405d9..a4512be24f7fa 100644 --- a/src/comp/middle/trans_build.rs +++ b/src/comp/middle/trans_build.rs @@ -408,7 +408,7 @@ fn GEP(cx: @block_ctxt, Pointer: ValueRef, Indices: [ValueRef]) -> ValueRef { unsafe { let instr = llvm::LLVMBuildGEP(B(cx), Pointer, vec::to_ptr(Indices), vec::len(Indices), noname()); - debuginfo::add_line_info(cx, instr); + //debuginfo::add_line_info(cx, instr); ret instr; } } @@ -425,18 +425,18 @@ fn InBoundsGEP(cx: @block_ctxt, Pointer: ValueRef, Indices: [ValueRef]) -> ValueRef { if cx.unreachable { ret llvm::LLVMGetUndef(T_ptr(T_nil())); } unsafe { - let v = llvm::LLVMBuildInBoundsGEP(B(cx), Pointer, - vec::to_ptr(Indices), - vec::len(Indices), noname()); - debuginfo::add_line_info(cx, v); - ret v; + let instr = llvm::LLVMBuildInBoundsGEP(B(cx), Pointer, + vec::to_ptr(Indices), + vec::len(Indices), noname()); + //debuginfo::add_line_info(cx, instr); + ret instr; } } fn StructGEP(cx: @block_ctxt, Pointer: ValueRef, Idx: uint) -> ValueRef { if cx.unreachable { ret llvm::LLVMGetUndef(T_ptr(T_nil())); } let instr = llvm::LLVMBuildStructGEP(B(cx), Pointer, Idx, noname()); - debuginfo::add_line_info(cx, instr); + //debuginfo::add_line_info(cx, instr); ret instr; } @@ -458,84 +458,84 @@ fn GlobalStringPtr(cx: @block_ctxt, _Str: sbuf) -> ValueRef { fn Trunc(cx: @block_ctxt, Val: ValueRef, DestTy: TypeRef) -> ValueRef { if cx.unreachable { ret llvm::LLVMGetUndef(DestTy); } let instr = llvm::LLVMBuildTrunc(B(cx), Val, DestTy, noname()); - debuginfo::add_line_info(cx, instr); + //debuginfo::add_line_info(cx, instr); ret instr; } fn ZExt(cx: @block_ctxt, Val: ValueRef, DestTy: TypeRef) -> ValueRef { if cx.unreachable { ret llvm::LLVMGetUndef(DestTy); } let instr = llvm::LLVMBuildZExt(B(cx), Val, DestTy, noname()); - debuginfo::add_line_info(cx, instr); + //debuginfo::add_line_info(cx, instr); ret instr; } fn SExt(cx: @block_ctxt, Val: ValueRef, DestTy: TypeRef) -> ValueRef { if cx.unreachable { ret llvm::LLVMGetUndef(DestTy); } let instr = llvm::LLVMBuildSExt(B(cx), Val, DestTy, noname()); - debuginfo::add_line_info(cx, instr); + //debuginfo::add_line_info(cx, instr); ret instr; } fn FPToUI(cx: @block_ctxt, Val: ValueRef, DestTy: TypeRef) -> ValueRef { if cx.unreachable { ret llvm::LLVMGetUndef(DestTy); } let instr = llvm::LLVMBuildFPToUI(B(cx), Val, DestTy, noname()); - debuginfo::add_line_info(cx, instr); + //debuginfo::add_line_info(cx, instr); ret instr; } fn FPToSI(cx: @block_ctxt, Val: ValueRef, DestTy: TypeRef) -> ValueRef { if cx.unreachable { ret llvm::LLVMGetUndef(DestTy); } let instr = llvm::LLVMBuildFPToSI(B(cx), Val, DestTy, noname()); - debuginfo::add_line_info(cx, instr); + //debuginfo::add_line_info(cx, instr); ret instr; } fn UIToFP(cx: @block_ctxt, Val: ValueRef, DestTy: TypeRef) -> ValueRef { if cx.unreachable { ret llvm::LLVMGetUndef(DestTy); } let instr = llvm::LLVMBuildUIToFP(B(cx), Val, DestTy, noname()); - debuginfo::add_line_info(cx, instr); + //debuginfo::add_line_info(cx, instr); ret instr; } fn SIToFP(cx: @block_ctxt, Val: ValueRef, DestTy: TypeRef) -> ValueRef { if cx.unreachable { ret llvm::LLVMGetUndef(DestTy); } let instr = llvm::LLVMBuildSIToFP(B(cx), Val, DestTy, noname()); - debuginfo::add_line_info(cx, instr); + //debuginfo::add_line_info(cx, instr); ret instr; } fn FPTrunc(cx: @block_ctxt, Val: ValueRef, DestTy: TypeRef) -> ValueRef { if cx.unreachable { ret llvm::LLVMGetUndef(DestTy); } let instr = llvm::LLVMBuildFPTrunc(B(cx), Val, DestTy, noname()); - debuginfo::add_line_info(cx, instr); + //debuginfo::add_line_info(cx, instr); ret instr; } fn FPExt(cx: @block_ctxt, Val: ValueRef, DestTy: TypeRef) -> ValueRef { if cx.unreachable { ret llvm::LLVMGetUndef(DestTy); } let instr = llvm::LLVMBuildFPExt(B(cx), Val, DestTy, noname()); - debuginfo::add_line_info(cx, instr); + //debuginfo::add_line_info(cx, instr); ret instr; } fn PtrToInt(cx: @block_ctxt, Val: ValueRef, DestTy: TypeRef) -> ValueRef { if cx.unreachable { ret llvm::LLVMGetUndef(DestTy); } let instr = llvm::LLVMBuildPtrToInt(B(cx), Val, DestTy, noname()); - debuginfo::add_line_info(cx, instr); + //debuginfo::add_line_info(cx, instr); ret instr; } fn IntToPtr(cx: @block_ctxt, Val: ValueRef, DestTy: TypeRef) -> ValueRef { if cx.unreachable { ret llvm::LLVMGetUndef(DestTy); } let instr = llvm::LLVMBuildIntToPtr(B(cx), Val, DestTy, noname()); - debuginfo::add_line_info(cx, instr); + //debuginfo::add_line_info(cx, instr); ret instr; } fn BitCast(cx: @block_ctxt, Val: ValueRef, DestTy: TypeRef) -> ValueRef { if cx.unreachable { ret llvm::LLVMGetUndef(DestTy); } let instr = llvm::LLVMBuildBitCast(B(cx), Val, DestTy, noname()); - debuginfo::add_line_info(cx, instr); + //debuginfo::add_line_info(cx, instr); ret instr; } @@ -543,7 +543,7 @@ fn ZExtOrBitCast(cx: @block_ctxt, Val: ValueRef, DestTy: TypeRef) -> ValueRef { if cx.unreachable { ret llvm::LLVMGetUndef(DestTy); } let instr = llvm::LLVMBuildZExtOrBitCast(B(cx), Val, DestTy, noname()); - debuginfo::add_line_info(cx, instr); + //debuginfo::add_line_info(cx, instr); ret instr; } @@ -551,7 +551,7 @@ fn SExtOrBitCast(cx: @block_ctxt, Val: ValueRef, DestTy: TypeRef) -> ValueRef { if cx.unreachable { ret llvm::LLVMGetUndef(DestTy); } let instr = llvm::LLVMBuildSExtOrBitCast(B(cx), Val, DestTy, noname()); - debuginfo::add_line_info(cx, instr); + //debuginfo::add_line_info(cx, instr); ret instr; } @@ -559,7 +559,7 @@ fn TruncOrBitCast(cx: @block_ctxt, Val: ValueRef, DestTy: TypeRef) -> ValueRef { if cx.unreachable { ret llvm::LLVMGetUndef(DestTy); } let instr = llvm::LLVMBuildTruncOrBitCast(B(cx), Val, DestTy, noname()); - debuginfo::add_line_info(cx, instr); + //debuginfo::add_line_info(cx, instr); ret instr; } @@ -567,28 +567,28 @@ fn Cast(cx: @block_ctxt, Op: Opcode, Val: ValueRef, DestTy: TypeRef, _Name: sbuf) -> ValueRef { if cx.unreachable { ret llvm::LLVMGetUndef(DestTy); } let instr = llvm::LLVMBuildCast(B(cx), Op, Val, DestTy, noname()); - debuginfo::add_line_info(cx, instr); + //debuginfo::add_line_info(cx, instr); ret instr; } fn PointerCast(cx: @block_ctxt, Val: ValueRef, DestTy: TypeRef) -> ValueRef { if cx.unreachable { ret llvm::LLVMGetUndef(DestTy); } let instr = llvm::LLVMBuildPointerCast(B(cx), Val, DestTy, noname()); - debuginfo::add_line_info(cx, instr); + //debuginfo::add_line_info(cx, instr); ret instr; } fn IntCast(cx: @block_ctxt, Val: ValueRef, DestTy: TypeRef) -> ValueRef { if cx.unreachable { ret llvm::LLVMGetUndef(DestTy); } let instr = llvm::LLVMBuildIntCast(B(cx), Val, DestTy, noname()); - debuginfo::add_line_info(cx, instr); + //debuginfo::add_line_info(cx, instr); ret instr; } fn FPCast(cx: @block_ctxt, Val: ValueRef, DestTy: TypeRef) -> ValueRef { if cx.unreachable { ret llvm::LLVMGetUndef(DestTy); } let instr = llvm::LLVMBuildFPCast(B(cx), Val, DestTy, noname()); - debuginfo::add_line_info(cx, instr); + //debuginfo::add_line_info(cx, instr); ret instr; } @@ -670,7 +670,7 @@ fn Call(cx: @block_ctxt, Fn: ValueRef, Args: [ValueRef]) -> ValueRef { unsafe { let instr = llvm::LLVMBuildCall(B(cx), Fn, vec::to_ptr(Args), vec::len(Args), noname()); - debuginfo::add_line_info(cx, instr); + //debuginfo::add_line_info(cx, instr); ret instr; } } diff --git a/src/comp/middle/trans_common.rs b/src/comp/middle/trans_common.rs index 98c4b497ab53d..770b751cf82a0 100644 --- a/src/comp/middle/trans_common.rs +++ b/src/comp/middle/trans_common.rs @@ -386,7 +386,8 @@ type block_ctxt = mutable lpad: option::t, sp: span, fcx: @fn_ctxt, - mutable source_pos: option::t}; + source_pos: {mutable usable: bool, + mutable pos: [syntax::codemap::loc]}}; // FIXME: we should be able to use option::t<@block_parent> here but // the infinite-tag check in rustboot gets upset. diff --git a/src/comp/middle/trans_vec.rs b/src/comp/middle/trans_vec.rs index dba2b67410ec9..9c1d574aad683 100644 --- a/src/comp/middle/trans_vec.rs +++ b/src/comp/middle/trans_vec.rs @@ -27,6 +27,7 @@ fn pointer_add(bcx: @block_ctxt, ptr: ValueRef, bytes: ValueRef) -> ValueRef { } fn alloc_raw(bcx: @block_ctxt, fill: ValueRef, alloc: ValueRef) -> result { + let _s = debuginfo::invalidate_source_pos(bcx); let ccx = bcx_ccx(bcx); let llvecty = ccx.opaque_vec_type; let vecsize = Add(bcx, alloc, llsize_of(ccx, llvecty)); @@ -45,6 +46,7 @@ type alloc_result = llunitty: TypeRef}; fn alloc(bcx: @block_ctxt, vec_ty: ty::t, elts: uint) -> alloc_result { + let _s = debuginfo::invalidate_source_pos(bcx); let ccx = bcx_ccx(bcx); let unit_ty = ty::sequence_element_type(bcx_tcx(bcx), vec_ty); let llunitty = type_of_or_i8(bcx, unit_ty); From e95c56f8554bd4c13876e999d3372408ffd732e7 Mon Sep 17 00:00:00 2001 From: Josh Matthews Date: Fri, 18 Nov 2011 00:13:02 -0500 Subject: [PATCH 05/21] Fix up subprogram composite type nodes, and lexical block context nodes. --- src/comp/middle/debuginfo.rs | 43 ++++++++++++++++++++++++++++-------- 1 file changed, 34 insertions(+), 9 deletions(-) diff --git a/src/comp/middle/debuginfo.rs b/src/comp/middle/debuginfo.rs index 3f422b21d8510..e360e4b0ea460 100644 --- a/src/comp/middle/debuginfo.rs +++ b/src/comp/middle/debuginfo.rs @@ -15,6 +15,7 @@ const DW_VIRTUALITY_none: int = 0; const CompileUnitTag: int = 17; const FileDescriptorTag: int = 41; const SubprogramTag: int = 46; +const SubroutineTag: int = 21; const BasicTypeDescriptorTag: int = 36; const AutoVariableTag: int = 256; const ArgVariableTag: int = 257; @@ -54,8 +55,8 @@ fn llmdnode(elems: [ValueRef]) -> ValueRef unsafe { fn llunused() -> ValueRef { lli32(0x0) } -fn llnull() -> ValueRef { - C_null(T_ptr(T_nil())) +fn llnull() -> ValueRef unsafe { + unsafe::reinterpret_cast(std::ptr::null::()) } fn update_cache(cache: metadata_cache, mdtag: int, val: debug_metadata) { @@ -191,10 +192,8 @@ fn get_block_metadata(cx: @block_ctxt) -> @metadata { option::none. {} } let parent = alt cx.parent { - trans_common::parent_none. { llnull() } - trans_common::parent_some(bcx) { - get_block_metadata(bcx).node - } + trans_common::parent_none. { function_metadata_from_block(cx).node } + trans_common::parent_some(bcx) { get_block_metadata(cx).node } }; let file_node = get_file_metadata(bcx_ccx(cx), fname); let unique_id = alt cache.find(LexicalBlockTag) { @@ -259,6 +258,14 @@ fn get_ty_metadata(cx: @crate_ctxt, t: ty::t, ty: @ast::ty) -> @metadata @metadata { + let cx = bcx_ccx(bcx); + 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) +} + fn get_local_var_metadata(bcx: @block_ctxt, local: @ast::local) -> @metadata unsafe { let cx = bcx_ccx(bcx); @@ -276,9 +283,12 @@ fn get_local_var_metadata(bcx: @block_ctxt, local: @ast::local) let ty = trans::node_id_type(cx, local.node.id); let tymd = get_ty_metadata(cx, ty, local.node.ty); let filemd = get_file_metadata(cx, loc.filename); - let blockmd = get_block_metadata(bcx); + let context = alt bcx.parent { + trans_common::parent_none. { function_metadata_from_block(bcx).node } + trans_common::parent_some(_) { get_block_metadata(bcx).node } + }; let lldata = [lltag(AutoVariableTag), - blockmd.node, //XXX block context (maybe subprogram if possible?) + context, // context llstr(name), // name filemd.node, lli32(loc.line as int), // line @@ -388,6 +398,21 @@ fn get_function_metadata(cx: @crate_ctxt, item: @ast::item, _ { get_ty_metadata(cx, ty::node_id_to_type(ccx_tcx(cx), item.id), ret_ty).node } }; + let sub_type = llmdnode([ty_node]); + let sub_metadata = [lltag(SubroutineTag), + file_node, + llstr(""), + file_node, + lli32(0), + lli64(0), + lli64(0), + lli64(0), + lli32(0), + llnull(), + sub_type, + lli32(0), + llnull()]; + let sub_node = llmdnode(sub_metadata); let fn_metadata = [lltag(SubprogramTag), llunused(), file_node, @@ -396,7 +421,7 @@ fn get_function_metadata(cx: @crate_ctxt, item: @ast::item, llstr(mangled), //XXX MIPS name????? file_node, lli32(loc.line as int), - ty_node, + sub_node, lli1(false), //XXX static (check export) lli1(true), // not extern lli32(DW_VIRTUALITY_none), // virtual-ness From 0b303523bdb34c946326b72420f19f670cf884d6 Mon Sep 17 00:00:00 2001 From: Josh Matthews Date: Fri, 18 Nov 2011 02:55:01 -0500 Subject: [PATCH 06/21] Fix up local variable support so it actually works. --- src/comp/middle/debuginfo.rs | 22 +++++++++++++--------- src/comp/middle/trans.rs | 34 ++++++++++++++++++++++------------ src/comp/middle/trans_build.rs | 2 +- 3 files changed, 36 insertions(+), 22 deletions(-) diff --git a/src/comp/middle/debuginfo.rs b/src/comp/middle/debuginfo.rs index e360e4b0ea460..01408b2886ab1 100644 --- a/src/comp/middle/debuginfo.rs +++ b/src/comp/middle/debuginfo.rs @@ -221,7 +221,7 @@ fn get_ty_metadata(cx: @crate_ctxt, t: ty::t, ty: @ast::ty) -> @metadata @metadata @metadata { get_function_metadata(cx, fn_item, fcx.llfn) } +fn filename_from_span(cx: @crate_ctxt, sp: codemap::span) -> str { + codemap::lookup_char_pos(cx.sess.get_codemap(), sp.lo).filename +} + fn get_local_var_metadata(bcx: @block_ctxt, local: @ast::local) -> @metadata unsafe { let cx = bcx_ccx(bcx); @@ -293,8 +301,7 @@ fn get_local_var_metadata(bcx: @block_ctxt, local: @ast::local) filemd.node, lli32(loc.line as int), // line tymd.node, - lli32(0), //XXX flags - llnull() // inline loc reference + lli32(0) //XXX flags ]; let mdnode = llmdnode(lldata); let mdval = @{node: mdnode, data: {id: local.node.id}}; @@ -310,9 +317,6 @@ fn get_local_var_metadata(bcx: @block_ctxt, local: @ast::local) let declargs = [llmdnode([llptr]), mdnode]; trans_build::Call(bcx, cx.intrinsics.get("llvm.dbg.declare"), declargs); - llvm::LLVMAddNamedMetadataOperand(cx.llmod, as_buf("llvm.dbg.vars"), - str::byte_len("llvm.dbg.vars"), - mdnode); ret mdval; } diff --git a/src/comp/middle/trans.rs b/src/comp/middle/trans.rs index 1e91949d51fb2..4c58cc5e26d90 100644 --- a/src/comp/middle/trans.rs +++ b/src/comp/middle/trans.rs @@ -23,7 +23,7 @@ import front::attr; import middle::{ty, gc, resolve, debuginfo}; import middle::freevars::*; import back::{link, abi, upcall}; -import syntax::{ast, ast_util}; +import syntax::{ast, ast_util, codemap}; import syntax::visit; import syntax::codemap::span; import syntax::print::pprust::{expr_to_str, stmt_to_str}; @@ -4038,10 +4038,22 @@ fn trans_stmt(cx: @block_ctxt, s: ast::stmt) -> @block_ctxt { _ { bcx_ccx(cx).sess.unimpl("stmt variant"); } } - //debuginfo::reset_source_pos(cx); ret bcx; } +fn source_pos_from_block_parent(parent: block_parent) + -> (bool, [codemap::loc]) { + alt parent { + parent_none. { (false, []) } + parent_some(bcx) { (bcx.source_pos.usable, + alt vec::last(bcx.source_pos.pos) { + option::some(p) { [p] } + option::none. { [] } + }) + } + } +} + // You probably don't want to use this one. See the // next three functions instead. fn new_block_ctxt(cx: @fn_ctxt, parent: block_parent, kind: block_kind, @@ -4053,6 +4065,7 @@ fn new_block_ctxt(cx: @fn_ctxt, parent: block_parent, kind: block_kind, } let llbb: BasicBlockRef = str::as_buf(s, {|buf| llvm::LLVMAppendBasicBlock(cx.llfn, buf) }); + let (usable, pos) = source_pos_from_block_parent(parent); let bcx = @{llbb: llbb, mutable terminated: false, mutable unreachable: false, @@ -4063,8 +4076,7 @@ fn new_block_ctxt(cx: @fn_ctxt, parent: block_parent, kind: block_kind, mutable lpad: option::none, sp: cx.sp, fcx: cx, - source_pos: {mutable usable: false, - mutable pos: []}}; + source_pos: {mutable usable: usable, mutable pos: pos}}; alt parent { parent_some(cx) { if cx.unreachable { Unreachable(bcx); } @@ -4099,6 +4111,7 @@ fn new_sub_block_ctxt(bcx: @block_ctxt, n: str) -> @block_ctxt { } fn new_raw_block_ctxt(fcx: @fn_ctxt, llbb: BasicBlockRef) -> @block_ctxt { + let (usable, pos) = source_pos_from_block_parent(parent_none); ret @{llbb: llbb, mutable terminated: false, mutable unreachable: false, @@ -4109,8 +4122,7 @@ fn new_raw_block_ctxt(fcx: @fn_ctxt, llbb: BasicBlockRef) -> @block_ctxt { mutable lpad: option::none, sp: fcx.sp, fcx: fcx, - source_pos: {mutable usable: false, - mutable pos: []}}; + source_pos: {mutable usable: usable, mutable pos: pos}}; } @@ -4168,6 +4180,7 @@ fn block_locals(b: ast::blk, it: block(@ast::local)) { } fn llstaticallocas_block_ctxt(fcx: @fn_ctxt) -> @block_ctxt { + let (usable, pos) = source_pos_from_block_parent(parent_none); ret @{llbb: fcx.llstaticallocas, mutable terminated: false, mutable unreachable: false, @@ -4178,11 +4191,11 @@ fn llstaticallocas_block_ctxt(fcx: @fn_ctxt) -> @block_ctxt { mutable lpad: option::none, sp: fcx.sp, fcx: fcx, - source_pos: {mutable usable: false, - mutable pos: []}}; + source_pos: {mutable usable: usable, mutable pos: pos}}; } fn llderivedtydescs_block_ctxt(fcx: @fn_ctxt) -> @block_ctxt { + let (usable, pos) = source_pos_from_block_parent(parent_none); ret @{llbb: fcx.llderivedtydescs, mutable terminated: false, mutable unreachable: false, @@ -4193,8 +4206,7 @@ fn llderivedtydescs_block_ctxt(fcx: @fn_ctxt) -> @block_ctxt { mutable lpad: option::none, sp: fcx.sp, fcx: fcx, - source_pos: {mutable usable: false, - mutable pos: []}}; + source_pos: {mutable usable: usable, mutable pos: pos}}; } @@ -4271,14 +4283,12 @@ fn trans_block_dps(bcx: @block_ctxt, b: ast::blk, dest: dest) for s: @ast::stmt in b.node.stmts { let _s = debuginfo::update_source_pos(bcx, b.span); bcx = trans_stmt(bcx, *s); - //debuginfo::reset_source_pos(bcx); } alt b.node.expr { some(e) { let bt = ty::type_is_bot(bcx_tcx(bcx), ty::expr_ty(bcx_tcx(bcx), e)); let _s = debuginfo::update_source_pos(bcx, e.span); bcx = trans_expr(bcx, e, bt ? ignore : dest); - //debuginfo::reset_source_pos(bcx); } _ { assert dest == ignore || bcx.unreachable; } } diff --git a/src/comp/middle/trans_build.rs b/src/comp/middle/trans_build.rs index a4512be24f7fa..600c1e27c73dd 100644 --- a/src/comp/middle/trans_build.rs +++ b/src/comp/middle/trans_build.rs @@ -670,7 +670,7 @@ fn Call(cx: @block_ctxt, Fn: ValueRef, Args: [ValueRef]) -> ValueRef { unsafe { let instr = llvm::LLVMBuildCall(B(cx), Fn, vec::to_ptr(Args), vec::len(Args), noname()); - //debuginfo::add_line_info(cx, instr); + debuginfo::add_line_info(cx, instr); ret instr; } } From 1da4b3b987f4d6be09dafa23e63978a36f677b00 Mon Sep 17 00:00:00 2001 From: Josh Matthews Date: Fri, 18 Nov 2011 03:47:59 -0500 Subject: [PATCH 07/21] Fix build error after rebasing. --- src/comp/middle/trans_common.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/comp/middle/trans_common.rs b/src/comp/middle/trans_common.rs index 770b751cf82a0..b47a00f8a6858 100644 --- a/src/comp/middle/trans_common.rs +++ b/src/comp/middle/trans_common.rs @@ -806,7 +806,7 @@ fn C_i32(i: i32) -> ValueRef { } fn C_i64(i: i64) -> ValueRef { - ret C_integral(T_i64(), i as uint, True); + ret C_integral(T_i64(), i as u64, True); } fn C_int(cx: @crate_ctxt, i: int) -> ValueRef { From 0752252737d530db5b81ebd3127c622f6ec92712 Mon Sep 17 00:00:00 2001 From: Josh Matthews Date: Sat, 3 Dec 2011 16:07:28 -0500 Subject: [PATCH 08/21] Use proper size and alignment of types for debuginfo. --- src/comp/middle/debuginfo.rs | 43 +++++++++++++++++++----------------- 1 file changed, 23 insertions(+), 20 deletions(-) diff --git a/src/comp/middle/debuginfo.rs b/src/comp/middle/debuginfo.rs index 01408b2886ab1..1b83353119d93 100644 --- a/src/comp/middle/debuginfo.rs +++ b/src/comp/middle/debuginfo.rs @@ -1,4 +1,4 @@ -import std::{vec, str, option, unsafe, fs}; +import std::{vec, str, option, unsafe, fs, sys}; import std::map::hashmap; import lib::llvm::llvm; import lib::llvm::llvm::ValueRef; @@ -221,24 +221,27 @@ fn get_ty_metadata(cx: @crate_ctxt, t: ty::t, ty: @ast::ty) -> @metadata() -> (int, int) { + (sys::size_of::() as int, sys::align_of::() as int) + } + let (name, (size, align), encoding) = alt ty.node { + ast::ty_bool. {("bool", size_and_align_of::(), DW_ATE_boolean)} + ast::ty_int. {("int", size_and_align_of::(), DW_ATE_signed)} + ast::ty_uint. {("uint", size_and_align_of::(), DW_ATE_unsigned)} + ast::ty_float. {("float", size_and_align_of::(), DW_ATE_float)} ast::ty_machine(m) { alt m { - ast::ty_i8. { ("i8", 1, DW_ATE_signed_char) } - ast::ty_i16. { ("i16", 16, DW_ATE_signed) } - ast::ty_i32. { ("i32", 32, DW_ATE_signed) } - ast::ty_i64. { ("i64", 64, DW_ATE_signed) } - ast::ty_u8. { ("u8", 8, DW_ATE_unsigned_char) } - ast::ty_u16. { ("u16", 16, DW_ATE_unsigned) } - ast::ty_u32. { ("u32", 32, DW_ATE_unsigned) } - ast::ty_u64. { ("u64", 64, DW_ATE_unsigned) } - ast::ty_f32. { ("f32", 32, DW_ATE_float) } - ast::ty_f64. { ("f64", 64, DW_ATE_float) } + ast::ty_i8. {("i8", size_and_align_of::(), DW_ATE_signed_char)} + ast::ty_i16. {("i16", size_and_align_of::(), DW_ATE_signed)} + ast::ty_i32. {("i32", size_and_align_of::(), DW_ATE_signed)} + ast::ty_i64. {("i64", size_and_align_of::(), DW_ATE_signed)} + ast::ty_u8. {("u8", size_and_align_of::(), DW_ATE_unsigned_char)} + ast::ty_u16. {("u16", size_and_align_of::(), DW_ATE_unsigned)} + ast::ty_u32. {("u32", size_and_align_of::(), DW_ATE_unsigned)} + ast::ty_u64. {("u64", size_and_align_of::(), DW_ATE_unsigned)} + ast::ty_f32. {("f32", size_and_align_of::(), DW_ATE_float)} + ast::ty_f64. {("f64", size_and_align_of::(), DW_ATE_float)} } } - ast::ty_char. { ("char", 32, DW_ATE_unsigned) } + ast::ty_char. {("char", size_and_align_of::(), DW_ATE_unsigned)} }; let fname = filename_from_span(cx, ty.span); let file_node = get_file_metadata(cx, fname); @@ -247,9 +250,9 @@ fn get_ty_metadata(cx: @crate_ctxt, t: ty::t, ty: @ast::ty) -> @metadata Date: Tue, 6 Dec 2011 00:05:22 -0500 Subject: [PATCH 09/21] Add argument metadata and aborted return value code. --- src/comp/middle/debuginfo.rs | 117 +++++++++++++++++++++++++++++++-- src/comp/middle/trans.rs | 14 +++- src/comp/middle/trans_build.rs | 8 +++ 3 files changed, 130 insertions(+), 9 deletions(-) diff --git a/src/comp/middle/debuginfo.rs b/src/comp/middle/debuginfo.rs index 1b83353119d93..be70c1b3f3da4 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; @@ -88,9 +90,11 @@ tag debug_metadata { local_var_metadata(@metadata); tydesc_metadata(@metadata); block_metadata(@metadata); + argument_metadata(@metadata); + retval_metadata(@metadata); } -fn cast_safely(val: T) -> U unsafe { +fn cast_safely(val: T) -> U unsafe { let val2 = val; let val3 = unsafe::reinterpret_cast(val2); unsafe::leak(val2); @@ -105,11 +109,13 @@ fn md_from_metadata(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(cache: metadata_cache, mdtag: int, - eq: block(md: T) -> bool) -> option::t unsafe { +fn cached_metadata(cache: metadata_cache, mdtag: int, + eq: block(md: T) -> bool) -> option::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 { 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 unsafe { + let fcx = bcx_fcx(bcx); + let cx = fcx_ccx(fcx); + let cache = cx.llmetadata; + alt cached_metadata::<@metadata>( + 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 unsafe { + let fcx = bcx_fcx(bcx); + let cx = fcx_ccx(fcx); + let cache = cx.llmetadata; + alt cached_metadata::<@metadata>( + 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 { + let cx = fcx_ccx(fcx); let cache = cx.llmetadata; alt cached_metadata::<@metadata>( 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 4c58cc5e26d90..81f15d6b4de10 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 600c1e27c73dd..2b45285a4ef06 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); } } From 064d757ece8d4d846e68da0a8f826cc1f309a730 Mon Sep 17 00:00:00 2001 From: Josh Matthews Date: Tue, 6 Dec 2011 12:49:53 -0500 Subject: [PATCH 10/21] Handle inferred basic types when generating debug information for types. --- src/comp/middle/debuginfo.rs | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/src/comp/middle/debuginfo.rs b/src/comp/middle/debuginfo.rs index be70c1b3f3da4..e372fc86e8b7f 100644 --- a/src/comp/middle/debuginfo.rs +++ b/src/comp/middle/debuginfo.rs @@ -230,7 +230,20 @@ fn get_ty_metadata(cx: @crate_ctxt, t: ty::t, ty: @ast::ty) -> @metadata() -> (int, int) { (sys::size_of::() as int, sys::align_of::() as int) } - let (name, (size, align), encoding) = alt ty.node { + let ast_ty = alt ty.node { + ast::ty_infer. { + alt ty::struct(ccx_tcx(cx), t) { + ty::ty_bool. { ast::ty_bool } + ty::ty_int. { ast::ty_int } + ty::ty_uint. { ast::ty_uint } + ty::ty_float. { ast::ty_float } + ty::ty_machine(m) { ast::ty_machine(m) } + ty::ty_char. { ast::ty_char } + } + } + _ { ty.node } + }; + let (name, (size, align), encoding) = alt ast_ty { ast::ty_bool. {("bool", size_and_align_of::(), DW_ATE_boolean)} ast::ty_int. {("int", size_and_align_of::(), DW_ATE_signed)} ast::ty_uint. {("uint", size_and_align_of::(), DW_ATE_unsigned)} From e25f6d03eb037ed905297e28edccc2346efbbc99 Mon Sep 17 00:00:00 2001 From: Josh Matthews Date: Tue, 6 Dec 2011 19:06:40 -0500 Subject: [PATCH 11/21] Remove rebase error. --- src/rustllvm/rustllvm.def.in | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/rustllvm/rustllvm.def.in b/src/rustllvm/rustllvm.def.in index 8c5c2385c9b3b..8456f69e7f38b 100644 --- a/src/rustllvm/rustllvm.def.in +++ b/src/rustllvm/rustllvm.def.in @@ -484,9 +484,6 @@ LLVMIsThreadLocal LLVMIsUndef LLVMLabelType LLVMLabelTypeInContext -LLVMLinkInInterpreter -LLVMLinkInJIT -LLVMLinkInMCJIT LLVMMDNode LLVMMDNodeInContext LLVMMDString From 134585bb069a6f8c51aa5b60f42ed00217605df6 Mon Sep 17 00:00:00 2001 From: Josh Matthews Date: Wed, 7 Dec 2011 16:08:25 -0500 Subject: [PATCH 12/21] Add debug information for boxed and unique values. --- src/comp/middle/debuginfo.rs | 185 ++++++++++++++++++++++++++++++----- 1 file changed, 163 insertions(+), 22 deletions(-) diff --git a/src/comp/middle/debuginfo.rs b/src/comp/middle/debuginfo.rs index e372fc86e8b7f..75a374094dc16 100644 --- a/src/comp/middle/debuginfo.rs +++ b/src/comp/middle/debuginfo.rs @@ -1,4 +1,4 @@ -import std::{vec, str, option, unsafe, fs, sys}; +import std::{vec, str, option, unsafe, fs, sys, ctypes}; import std::map::hashmap; import lib::llvm::llvm; import lib::llvm::llvm::ValueRef; @@ -6,6 +6,7 @@ import middle::trans_common::*; import middle::ty; import syntax::{ast, codemap}; import ast::ty; +import util::ppaux::ty_to_str; const LLVMDebugVersion: int = (9 << 16); @@ -21,6 +22,9 @@ const AutoVariableTag: int = 256; const ArgVariableTag: int = 257; const ReturnVariableTag: int = 258; const LexicalBlockTag: int = 11; +const PointerTypeTag: int = 15; +const StructureTypeTag: int = 19; +const MemberTag: int = 13; const DW_ATE_boolean: int = 0x02; const DW_ATE_float: int = 0x04; @@ -219,31 +223,21 @@ fn get_block_metadata(cx: @block_ctxt) -> @metadata { ret mdval; } -fn get_ty_metadata(cx: @crate_ctxt, t: ty::t, ty: @ast::ty) -> @metadata { +fn size_and_align_of() -> (int, int) { + (sys::size_of::() as int, sys::align_of::() as int) +} + +fn get_basic_type_metadata(cx: @crate_ctxt, t: ty::t, ty: @ast::ty) + -> @metadata { let cache = cx.llmetadata; + let tg = BasicTypeDescriptorTag; alt cached_metadata::<@metadata>( - cache, BasicTypeDescriptorTag, + cache, tg, {|md| ty::hash_ty(t) == ty::hash_ty(md.data.hash)}) { option::some(md) { ret md; } option::none. {} } - fn size_and_align_of() -> (int, int) { - (sys::size_of::() as int, sys::align_of::() as int) - } - let ast_ty = alt ty.node { - ast::ty_infer. { - alt ty::struct(ccx_tcx(cx), t) { - ty::ty_bool. { ast::ty_bool } - ty::ty_int. { ast::ty_int } - ty::ty_uint. { ast::ty_uint } - ty::ty_float. { ast::ty_float } - ty::ty_machine(m) { ast::ty_machine(m) } - ty::ty_char. { ast::ty_char } - } - } - _ { ty.node } - }; - let (name, (size, align), encoding) = alt ast_ty { + let (name, (size, align), encoding) = alt ty.node { ast::ty_bool. {("bool", size_and_align_of::(), DW_ATE_boolean)} ast::ty_int. {("int", size_and_align_of::(), DW_ATE_signed)} ast::ty_uint. {("uint", size_and_align_of::(), DW_ATE_unsigned)} @@ -265,7 +259,7 @@ fn get_ty_metadata(cx: @crate_ctxt, t: ty::t, ty: @ast::ty) -> @metadata @metadata) + -> @metadata { + let tg = PointerTypeTag; + /*let cache = cx.llmetadata; + alt cached_metadata::<@metadata>( + cache, tg, {|md| ty::hash_ty(t) == ty::hash_ty(md.data.hash)}) { + option::some(md) { ret md; } + option::none. {} + }*/ + let (size, align) = size_and_align_of::(); + let fname = filename_from_span(cx, span); + let file_node = get_file_metadata(cx, fname); + //let cu_node = get_compile_unit_metadata(cx, fname); + let lldata = [lltag(tg), + file_node.node, + llstr(""), + file_node.node, + lli32(0), //XXX source line + lli64(size * 8), // size in bits + lli64(align * 8), // alignment in bits + lli64(0), //XXX offset? + lli32(0), + pointee.node]; + let llnode = llmdnode(lldata); + let mdval = @{node: llnode, data: {hash: ty::hash_ty(t)}}; + //update_cache(cache, tg, tydesc_metadata(mdval)); + llvm::LLVMAddNamedMetadataOperand(cx.llmod, as_buf("llvm.dbg.ty"), + str::byte_len("llvm.dbg.ty"), + llnode); + ret mdval; +} + +fn get_boxed_type_metadata(cx: @crate_ctxt, outer: ty::t, inner: ty::t, + span: codemap::span, boxed: @metadata) + -> @metadata { + let tg = StructureTypeTag; + /*let cache = cx.llmetadata; + alt cached_metadata::<@metadata>( + cache, tg, {|md| ty::hash_ty(outer) == ty::hash_ty(md.data.hash)}) { + option::some(md) { ret md; } + option::none. {} + }*/ + let (size, align) = size_and_align_of::<@int>(); + let fname = filename_from_span(cx, span); + let file_node = get_file_metadata(cx, fname); + //let cu_node = get_compile_unit_metadata(cx, fname); + let tcx = ccx_tcx(cx); + let uint_t = ty::mk_uint(tcx); + let uint_ty = @{node: ast::ty_uint, span: span}; + let refcount_type = get_basic_type_metadata(cx, uint_t, uint_ty); + /*let refcount_ptr_type = get_pointer_type_metadata(cx, + ty::mk_imm_uniq(tcx, uint_t), + span, refcount_type);*/ + /*let boxed_ptr_type = get_pointer_type_metadata(cx, ty::mk_imm_uniq(tcx, inner), + span, boxed);*/ + //let ptr_size = sys::size_of::() as int; + //let ptr_align = sys::align_of::() as int; + let size = sys::size_of::() as int * 8; + let total_size = size; + let refcount = [lltag(MemberTag), + file_node.node, + llstr("refcnt"), + file_node.node, + lli32(0), + lli64(size), + lli64(sys::align_of::() as int * 8), + lli64(0), + lli32(0), + refcount_type.node]; + let size = 64; //XXX size of inner + let boxed_member = [lltag(MemberTag), + file_node.node, + llstr("boxed"), + file_node.node, + lli32(0), + lli64(size), + lli64(64), //XXX align of inner + lli64(total_size), + lli32(0), + boxed.node]; + total_size += size; + let members = [llmdnode(refcount), llmdnode(boxed_member)]; + let lldata = [lltag(tg), + file_node.node, + llstr(ty_to_str(ccx_tcx(cx), outer)), + file_node.node, + lli32(0), //XXX source line + lli64(total_size), // size in bits + lli64(align * 8), // alignment in bits + lli64(0), //XXX offset? + lli32(0), //XXX flags + llnull(), // derived from + llmdnode(members), // members + lli32(0) // runtime language + ]; + let llnode = llmdnode(lldata); + let mdval = @{node: llnode, data: {hash: ty::hash_ty(outer)}}; + //update_cache(cache, tg, tydesc_metadata(mdval)); llvm::LLVMAddNamedMetadataOperand(cx.llmod, as_buf("llvm.dbg.ty"), str::byte_len("llvm.dbg.ty"), llnode); ret mdval; } +fn get_ty_metadata(cx: @crate_ctxt, t: ty::t, ty: @ast::ty) -> @metadata { + fn t_to_ty(cx: @crate_ctxt, t: ty::t, span: codemap::span) -> @ast::ty { + let ty = alt ty::struct(ccx_tcx(cx), t) { + ty::ty_nil. { ast::ty_nil } + ty::ty_bot. { ast::ty_bot } + ty::ty_bool. { ast::ty_bool } + ty::ty_int. { ast::ty_int } + ty::ty_float. { ast::ty_float } + ty::ty_uint. { ast::ty_uint } + ty::ty_machine(mt) { ast::ty_machine(mt) } + ty::ty_char. { ast::ty_char } + ty::ty_box(mt) { ast::ty_box({ty: t_to_ty(cx, mt.ty, span), + mut: mt.mut}) } + ty::ty_uniq(mt) { ast::ty_uniq({ty: t_to_ty(cx, mt.ty, span), + mut: mt.mut}) } + }; + ret @{node: ty, span: span}; + } + alt ty.node { + ast::ty_box(mt) { + let inner_t = alt ty::struct(ccx_tcx(cx), t) { + ty::ty_box(boxed) { boxed.ty } + }; + let md = get_ty_metadata(cx, inner_t, mt.ty); + let box = get_boxed_type_metadata(cx, t, inner_t, ty.span, md); + ret get_pointer_type_metadata(cx, t, ty.span, box); + } + ast::ty_uniq(mt) { + let inner_t = alt ty::struct(ccx_tcx(cx), t) { + ty::ty_uniq(boxed) { boxed.ty } + }; + let md = get_ty_metadata(cx, inner_t, mt.ty); + ret get_pointer_type_metadata(cx, t, ty.span, md); + } + ast::ty_infer. { + let inferred = t_to_ty(cx, t, ty.span); + ret get_ty_metadata(cx, t, inferred); + } + _ { ret get_basic_type_metadata(cx, t, ty); } + }; +} + fn function_metadata_from_block(bcx: @block_ctxt) -> @metadata { let cx = bcx_ccx(bcx); let fcx = bcx_fcx(bcx); From f43ed8f1bd249f4d758c2451a422a6d7395a52df Mon Sep 17 00:00:00 2001 From: Josh Matthews Date: Thu, 8 Dec 2011 07:03:00 -0500 Subject: [PATCH 13/21] Fix up ast types after literal changes. --- src/comp/middle/debuginfo.rs | 26 ++++++++++++++------------ 1 file changed, 14 insertions(+), 12 deletions(-) diff --git a/src/comp/middle/debuginfo.rs b/src/comp/middle/debuginfo.rs index 75a374094dc16..ee33d9dcd5f8d 100644 --- a/src/comp/middle/debuginfo.rs +++ b/src/comp/middle/debuginfo.rs @@ -239,22 +239,26 @@ fn get_basic_type_metadata(cx: @crate_ctxt, t: ty::t, ty: @ast::ty) } let (name, (size, align), encoding) = alt ty.node { ast::ty_bool. {("bool", size_and_align_of::(), DW_ATE_boolean)} - ast::ty_int. {("int", size_and_align_of::(), DW_ATE_signed)} - ast::ty_uint. {("uint", size_and_align_of::(), DW_ATE_unsigned)} - ast::ty_float. {("float", size_and_align_of::(), DW_ATE_float)} - ast::ty_machine(m) { alt m { + ast::ty_int(m) { alt m { + ast::ty_char. {("char", size_and_align_of::(), DW_ATE_unsigned)} + ast::ty_i. {("int", size_and_align_of::(), DW_ATE_signed)} ast::ty_i8. {("i8", size_and_align_of::(), DW_ATE_signed_char)} ast::ty_i16. {("i16", size_and_align_of::(), DW_ATE_signed)} ast::ty_i32. {("i32", size_and_align_of::(), DW_ATE_signed)} ast::ty_i64. {("i64", size_and_align_of::(), DW_ATE_signed)} + }} + ast::ty_uint(m) { alt m { + ast::ty_u. {("uint", size_and_align_of::(), DW_ATE_unsigned)} ast::ty_u8. {("u8", size_and_align_of::(), DW_ATE_unsigned_char)} ast::ty_u16. {("u16", size_and_align_of::(), DW_ATE_unsigned)} ast::ty_u32. {("u32", size_and_align_of::(), DW_ATE_unsigned)} ast::ty_u64. {("u64", size_and_align_of::(), DW_ATE_unsigned)} + }} + ast::ty_float(m) { alt m { + ast::ty_f. {("float", size_and_align_of::(), DW_ATE_float)} ast::ty_f32. {("f32", size_and_align_of::(), DW_ATE_float)} ast::ty_f64. {("f64", size_and_align_of::(), DW_ATE_float)} - } } - ast::ty_char. {("char", size_and_align_of::(), DW_ATE_unsigned)} + }} }; let fname = filename_from_span(cx, ty.span); let file_node = get_file_metadata(cx, fname); @@ -327,7 +331,7 @@ fn get_boxed_type_metadata(cx: @crate_ctxt, outer: ty::t, inner: ty::t, //let cu_node = get_compile_unit_metadata(cx, fname); let tcx = ccx_tcx(cx); let uint_t = ty::mk_uint(tcx); - let uint_ty = @{node: ast::ty_uint, span: span}; + let uint_ty = @{node: ast::ty_uint(ast::ty_u), span: span}; let refcount_type = get_basic_type_metadata(cx, uint_t, uint_ty); /*let refcount_ptr_type = get_pointer_type_metadata(cx, ty::mk_imm_uniq(tcx, uint_t), @@ -389,11 +393,9 @@ fn get_ty_metadata(cx: @crate_ctxt, t: ty::t, ty: @ast::ty) -> @metadata Date: Fri, 9 Dec 2011 11:32:23 -0500 Subject: [PATCH 14/21] Add record debug information. --- src/comp/middle/debuginfo.rs | 189 ++++++++++++++++++++++++++++---- src/comp/middle/trans.rs | 8 +- src/comp/middle/trans_common.rs | 2 +- 3 files changed, 177 insertions(+), 22 deletions(-) diff --git a/src/comp/middle/debuginfo.rs b/src/comp/middle/debuginfo.rs index ee33d9dcd5f8d..1e5cbadc44928 100644 --- a/src/comp/middle/debuginfo.rs +++ b/src/comp/middle/debuginfo.rs @@ -74,6 +74,15 @@ fn update_cache(cache: metadata_cache, mdtag: int, val: debug_metadata) { //////////////// +type debug_ctxt = { + llmetadata: metadata_cache, + //llmod: ValueRef, + //opt: bool, + names: trans_common::namegen +}; + +//////////////// + type metadata = {node: ValueRef, data: T}; type file_md = {path: str}; @@ -134,7 +143,7 @@ fn cached_metadata(cache: metadata_cache, mdtag: int, fn get_compile_unit_metadata(cx: @crate_ctxt, full_path: str) -> @metadata { - let cache = cx.llmetadata; + let cache = get_cache(cx); alt cached_metadata::<@metadata>(cache, CompileUnitTag, {|md| md.data.path == full_path}) { option::some(md) { ret md; } @@ -166,37 +175,45 @@ fn get_compile_unit_metadata(cx: @crate_ctxt, full_path: str) ret mdval; } +fn get_cache(cx: @crate_ctxt) -> metadata_cache { + option::get(cx.dbg_cx).llmetadata +} + fn get_file_metadata(cx: @crate_ctxt, full_path: str) -> @metadata { - let cache = cx.llmetadata; + let cache = get_cache(cx);; + let tg = FileDescriptorTag; alt cached_metadata::<@metadata>( - cache, FileDescriptorTag, - {|md| - md.data.path == full_path}) { - option::some(md) { ret md; } - option::none. {} + cache, tg, {|md| md.data.path == full_path}) { + option::some(md) { ret md; } + option::none. {} } let fname = fs::basename(full_path); let path = fs::dirname(full_path); let unit_node = get_compile_unit_metadata(cx, full_path).node; - let file_md = [lltag(FileDescriptorTag), + let file_md = [lltag(tg), llstr(fname), llstr(path), unit_node]; let val = llmdnode(file_md); let mdval = @{node: val, data: {path: full_path}}; - update_cache(cache, FileDescriptorTag, file_metadata(mdval)); + update_cache(cache, tg, file_metadata(mdval)); ret mdval; } +fn line_from_span(cm: codemap::codemap, sp: codemap::span) -> uint { + codemap::lookup_char_pos(cm, sp.lo).line +} + fn get_block_metadata(cx: @block_ctxt) -> @metadata { - let cache = bcx_ccx(cx).llmetadata; + let cache = get_cache(bcx_ccx(cx)); let start = codemap::lookup_char_pos(bcx_ccx(cx).sess.get_codemap(), cx.sp.lo); let fname = start.filename; let end = codemap::lookup_char_pos(bcx_ccx(cx).sess.get_codemap(), cx.sp.hi); + let tg = LexicalBlockTag; alt cached_metadata::<@metadata>( - cache, LexicalBlockTag, + cache, tg, {|md| start == md.data.start && end == md.data.end}) { option::some(md) { ret md; } option::none. {} @@ -210,7 +227,7 @@ fn get_block_metadata(cx: @block_ctxt) -> @metadata { option::some(v) { vec::len(v) as int } option::none. { 0 } }; - let lldata = [lltag(LexicalBlockTag), + let lldata = [lltag(tg), parent, lli32(start.line as int), lli32(start.col as int), @@ -219,7 +236,7 @@ fn get_block_metadata(cx: @block_ctxt) -> @metadata { ]; let val = llmdnode(lldata); let mdval = @{node: val, data: {start: start, end: end}}; - update_cache(cache, LexicalBlockTag, block_metadata(mdval)); + update_cache(cache, tg, block_metadata(mdval)); ret mdval; } @@ -229,7 +246,7 @@ fn size_and_align_of() -> (int, int) { fn get_basic_type_metadata(cx: @crate_ctxt, t: ty::t, ty: @ast::ty) -> @metadata { - let cache = cx.llmetadata; + let cache = get_cache(cx); let tg = BasicTypeDescriptorTag; alt cached_metadata::<@metadata>( cache, tg, @@ -315,6 +332,82 @@ fn get_pointer_type_metadata(cx: @crate_ctxt, t: ty::t, span: codemap::span, ret mdval; } +type struct_ctxt = { + file: ValueRef, + name: str, + line: int, + mutable members: [ValueRef], + mutable total_size: int, + align: int +}; + +fn finish_structure(cx: @struct_ctxt) -> ValueRef { + let lldata = [lltag(StructureTypeTag), + cx.file, + llstr(cx.name), // type name + cx.file, // source file definition + lli32(cx.line), // source line definition + lli64(cx.total_size), // size of members + lli64(cx.align), // align + lli64(0), // offset + lli32(0), // flags + llnull(), // derived from + llmdnode(cx.members), // members + lli32(0), // runtime language + llnull() + ]; + ret llmdnode(lldata); +} + +fn create_structure(file: @metadata, name: str, line: int) + -> @struct_ctxt { + let cx = @{file: file.node, + name: name, + line: line, + mutable members: [], + mutable total_size: 0, + align: 64 //XXX different alignment per arch? + }; + ret cx; +} + +fn add_member(cx: @struct_ctxt, name: str, line: int, size: int, align: int, + ty: ValueRef) { + let lldata = [lltag(MemberTag), + cx.file, + llstr(name), + cx.file, + lli32(line), + lli64(size * 8), + lli64(align * 8), + lli64(cx.total_size), + lli32(0), + ty]; + cx.total_size += size * 8; + cx.members += [llmdnode(lldata)]; +} + +fn get_record_metadata(cx: @crate_ctxt, t: ty::t, fields: [ast::ty_field], + span: codemap::span) -> @metadata { + let fname = filename_from_span(cx, span); + let file_node = get_file_metadata(cx, fname); + let scx = create_structure(file_node, + option::get(cx.dbg_cx).names.next("rec"), + line_from_span(cx.sess.get_codemap(), + span) as int); + for field in fields { + //let field_t = option::get(ccx_tcx(cx).ast_ty_to_ty_cache.get(field.node.mt.ty)); + let field_t = ty::get_field(ccx_tcx(cx), t, field.node.ident).mt.ty; + let ty_md = get_ty_metadata(cx, field_t, field.node.mt.ty); + let (size, align) = member_size_and_align(field.node.mt.ty); + add_member(scx, field.node.ident, + line_from_span(cx.sess.get_codemap(), field.span) as int, + size as int, align as int, ty_md.node); + } + let mdval = @{node: finish_structure(scx), data:{hash: t}}; + ret mdval; +} + fn get_boxed_type_metadata(cx: @crate_ctxt, outer: ty::t, inner: ty::t, span: codemap::span, boxed: @metadata) -> @metadata { @@ -352,7 +445,7 @@ fn get_boxed_type_metadata(cx: @crate_ctxt, outer: ty::t, inner: ty::t, lli64(0), lli32(0), refcount_type.node]; - let size = 64; //XXX size of inner + let size = 64; //XXX member_size_and_align(???) let boxed_member = [lltag(MemberTag), file_node.node, llstr("boxed"), @@ -379,7 +472,7 @@ fn get_boxed_type_metadata(cx: @crate_ctxt, outer: ty::t, inner: ty::t, lli32(0) // runtime language ]; let llnode = llmdnode(lldata); - let mdval = @{node: llnode, data: {hash: ty::hash_ty(outer)}}; + let mdval = @{node: llnode, data: {hash: outer}}; //update_cache(cache, tg, tydesc_metadata(mdval)); llvm::LLVMAddNamedMetadataOperand(cx.llmod, as_buf("llvm.dbg.ty"), str::byte_len("llvm.dbg.ty"), @@ -387,7 +480,49 @@ fn get_boxed_type_metadata(cx: @crate_ctxt, outer: ty::t, inner: ty::t, ret mdval; } +fn member_size_and_align(ty: @ast::ty) -> (int, int) { + alt ty.node { + ast::ty_bool. { size_and_align_of::() } + ast::ty_int(m) { alt m { + ast::ty_char. { size_and_align_of::() } + ast::ty_i. { size_and_align_of::() } + ast::ty_i8. { size_and_align_of::() } + ast::ty_i16. { size_and_align_of::() } + ast::ty_i32. { size_and_align_of::() } + }} + ast::ty_uint(m) { alt m { + ast::ty_u. { size_and_align_of::() } + ast::ty_u8. { size_and_align_of::() } + ast::ty_u16. { size_and_align_of::() } + ast::ty_u32. { size_and_align_of::() } + }} + ast::ty_float(m) { alt m { + ast::ty_f. { size_and_align_of::() } + ast::ty_f32. { size_and_align_of::() } + ast::ty_f64. { size_and_align_of::() } + }} + ast::ty_box(_) | ast::ty_uniq(_) { + size_and_align_of::() + } + ast::ty_rec(fields) { + let total_size = 0; + for field in fields { + let (size, _) = member_size_and_align(field.node.mt.ty); + total_size += size; + } + (total_size, 64) //XXX different align for other arches? + } + } +} + fn get_ty_metadata(cx: @crate_ctxt, t: ty::t, ty: @ast::ty) -> @metadata { + /*let cache = get_cache(cx); + alt cached_metadata::<@metadata>( + cache, tg, {|md| t == md.data.hash}) { + option::some(md) { ret md; } + option::none. {} + }*/ + fn t_to_ty(cx: @crate_ctxt, t: ty::t, span: codemap::span) -> @ast::ty { let ty = alt ty::struct(ccx_tcx(cx), t) { ty::ty_nil. { ast::ty_nil } @@ -400,9 +535,20 @@ fn get_ty_metadata(cx: @crate_ctxt, t: ty::t, ty: @ast::ty) -> @metadata @metadata str { fn get_local_var_metadata(bcx: @block_ctxt, local: @ast::local) -> @metadata unsafe { let cx = bcx_ccx(bcx); - let cache = cx.llmetadata; + let cache = get_cache(cx); alt cached_metadata::<@metadata>( cache, AutoVariableTag, {|md| md.data.id == local.node.id}) { option::some(md) { ret md; } @@ -540,7 +689,7 @@ fn get_arg_metadata(bcx: @block_ctxt, arg: ast::arg) -> @metadata unsafe { let fcx = bcx_fcx(bcx); let cx = fcx_ccx(fcx); - let cache = cx.llmetadata; + let cache = get_cache(cx); alt cached_metadata::<@metadata>( cache, ArgVariableTag, {|md| md.data.id == arg.id}) { option::some(md) { ret md; } @@ -641,7 +790,7 @@ fn add_line_info(cx: @block_ctxt, llinstr: ValueRef) { fn get_function_metadata(fcx: @fn_ctxt, item: @ast::item, llfndecl: ValueRef) -> @metadata { let cx = fcx_ccx(fcx); - let cache = cx.llmetadata; + let cache = get_cache(cx); alt cached_metadata::<@metadata>( cache, SubprogramTag, {|md| md.data.name == item.ident && /*sub.path == ??*/ true}) { @@ -708,4 +857,4 @@ fn get_function_metadata(fcx: @fn_ctxt, item: @ast::item, _ { 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 81f15d6b4de10..e92095f67e56c 100644 --- a/src/comp/middle/trans.rs +++ b/src/comp/middle/trans.rs @@ -5673,6 +5673,12 @@ fn trans_crate(sess: session::session, crate: @ast::crate, tcx: ty::ctxt, let sha1s = map::mk_hashmap::(hasher, eqer); let short_names = map::mk_hashmap::(hasher, eqer); let crate_map = decl_crate_map(sess, link_meta.name, llmod); + let dbg_cx = if sess.get_opts().debuginfo { + option::some(@{llmetadata: map::new_int_hash(), + names: namegen(0)}) + } else { + option::none + }; let ccx = @{sess: sess, llmod: llmod, @@ -5723,7 +5729,7 @@ fn trans_crate(sess: session::session, crate: @ast::crate, tcx: ty::ctxt, shape_cx: shape::mk_ctxt(llmod), gc_cx: gc::mk_ctxt(), crate_map: crate_map, - llmetadata: map::new_int_hash()}; + dbg_cx: dbg_cx}; let cx = new_local_ctxt(ccx); collect_items(ccx, crate); collect_tag_ctors(ccx, crate); diff --git a/src/comp/middle/trans_common.rs b/src/comp/middle/trans_common.rs index b47a00f8a6858..c7333ef74115a 100644 --- a/src/comp/middle/trans_common.rs +++ b/src/comp/middle/trans_common.rs @@ -117,7 +117,7 @@ type crate_ctxt = shape_cx: shape::ctxt, gc_cx: gc::ctxt, crate_map: ValueRef, - llmetadata: debuginfo::metadata_cache}; + dbg_cx: option::t<@debuginfo::debug_ctxt>}; type local_ctxt = {path: [str], From 61e8b44f2051e31e41c2ea45841c77c5ec7eec59 Mon Sep 17 00:00:00 2001 From: Josh Matthews Date: Sun, 11 Dec 2011 15:24:47 -0500 Subject: [PATCH 15/21] Add support for vectors. --- src/comp/middle/debuginfo.rs | 135 +++++++++++++++++++---------------- 1 file changed, 72 insertions(+), 63 deletions(-) diff --git a/src/comp/middle/debuginfo.rs b/src/comp/middle/debuginfo.rs index 1e5cbadc44928..3949e88f3c2f6 100644 --- a/src/comp/middle/debuginfo.rs +++ b/src/comp/middle/debuginfo.rs @@ -25,6 +25,8 @@ const LexicalBlockTag: int = 11; const PointerTypeTag: int = 15; const StructureTypeTag: int = 19; const MemberTag: int = 13; +const ArrayTypeTag: int = 1; +const SubrangeTag: int = 33; const DW_ATE_boolean: int = 0x02; const DW_ATE_float: int = 0x04; @@ -342,21 +344,9 @@ type struct_ctxt = { }; fn finish_structure(cx: @struct_ctxt) -> ValueRef { - let lldata = [lltag(StructureTypeTag), - cx.file, - llstr(cx.name), // type name - cx.file, // source file definition - lli32(cx.line), // source line definition - lli64(cx.total_size), // size of members - lli64(cx.align), // align - lli64(0), // offset - lli32(0), // flags - llnull(), // derived from - llmdnode(cx.members), // members - lli32(0), // runtime language - llnull() - ]; - ret llmdnode(lldata); + ret create_composite_type(StructureTypeTag, cx.name, cx.file, cx.line, + cx.total_size, cx.align, 0, option::none, + option::some(cx.members)); } fn create_structure(file: @metadata, name: str, line: int) @@ -396,7 +386,6 @@ fn get_record_metadata(cx: @crate_ctxt, t: ty::t, fields: [ast::ty_field], line_from_span(cx.sess.get_codemap(), span) as int); for field in fields { - //let field_t = option::get(ccx_tcx(cx).ast_ty_to_ty_cache.get(field.node.mt.ty)); let field_t = ty::get_field(ccx_tcx(cx), t, field.node.ident).mt.ty; let ty_md = get_ty_metadata(cx, field_t, field.node.mt.ty); let (size, align) = member_size_and_align(field.node.mt.ty); @@ -418,7 +407,6 @@ fn get_boxed_type_metadata(cx: @crate_ctxt, outer: ty::t, inner: ty::t, option::some(md) { ret md; } option::none. {} }*/ - let (size, align) = size_and_align_of::<@int>(); let fname = filename_from_span(cx, span); let file_node = get_file_metadata(cx, fname); //let cu_node = get_compile_unit_metadata(cx, fname); @@ -426,52 +414,13 @@ fn get_boxed_type_metadata(cx: @crate_ctxt, outer: ty::t, inner: ty::t, let uint_t = ty::mk_uint(tcx); let uint_ty = @{node: ast::ty_uint(ast::ty_u), span: span}; let refcount_type = get_basic_type_metadata(cx, uint_t, uint_ty); - /*let refcount_ptr_type = get_pointer_type_metadata(cx, - ty::mk_imm_uniq(tcx, uint_t), - span, refcount_type);*/ - /*let boxed_ptr_type = get_pointer_type_metadata(cx, ty::mk_imm_uniq(tcx, inner), - span, boxed);*/ - //let ptr_size = sys::size_of::() as int; - //let ptr_align = sys::align_of::() as int; - let size = sys::size_of::() as int * 8; - let total_size = size; - let refcount = [lltag(MemberTag), - file_node.node, - llstr("refcnt"), - file_node.node, - lli32(0), - lli64(size), - lli64(sys::align_of::() as int * 8), - lli64(0), - lli32(0), - refcount_type.node]; - let size = 64; //XXX member_size_and_align(???) - let boxed_member = [lltag(MemberTag), - file_node.node, - llstr("boxed"), - file_node.node, - lli32(0), - lli64(size), - lli64(64), //XXX align of inner - lli64(total_size), - lli32(0), - boxed.node]; - total_size += size; - let members = [llmdnode(refcount), llmdnode(boxed_member)]; - let lldata = [lltag(tg), - file_node.node, - llstr(ty_to_str(ccx_tcx(cx), outer)), - file_node.node, - lli32(0), //XXX source line - lli64(total_size), // size in bits - lli64(align * 8), // alignment in bits - lli64(0), //XXX offset? - lli32(0), //XXX flags - llnull(), // derived from - llmdnode(members), // members - lli32(0) // runtime language - ]; - let llnode = llmdnode(lldata); + let scx = create_structure(file_node, ty_to_str(ccx_tcx(cx), outer), 0); + add_member(scx, "refcnt", 0, sys::size_of::() as int, + sys::align_of::() as int, refcount_type.node); + add_member(scx, "boxed", 0, 8, //XXX member_size_and_align(??) + 8, //XXX just a guess + boxed.node); + let llnode = finish_structure(scx); let mdval = @{node: llnode, data: {hash: outer}}; //update_cache(cache, tg, tydesc_metadata(mdval)); llvm::LLVMAddNamedMetadataOperand(cx.llmod, as_buf("llvm.dbg.ty"), @@ -480,6 +429,56 @@ fn get_boxed_type_metadata(cx: @crate_ctxt, outer: ty::t, inner: ty::t, ret mdval; } +fn create_composite_type(type_tag: int, name: str, file: ValueRef, line: int, + size: int, align: int, offset: int, + derived: option::t, + members: option::t<[ValueRef]>) + -> ValueRef { + let lldata = [lltag(type_tag), + file, + llstr(name), // type name + file, // source file definition + lli32(line), // source line definition + lli64(size), // size of members + lli64(align), // align + lli64(offset), // offset + lli32(0), // flags + option::is_none(derived) ? llnull() : // derived from + option::get(derived), + option::is_none(members) ? llnull() : // members + llmdnode(option::get(members)), + lli32(0), // runtime language + llnull() + ]; + ret llmdnode(lldata); +} + +fn get_vec_metadata(cx: @crate_ctxt, vec_t: ty::t, elem_t: ty::t, vec_ty: @ast::ty) + -> @metadata { + let fname = filename_from_span(cx, vec_ty.span); + let file_node = get_file_metadata(cx, fname); + let elem_ty = alt vec_ty.node { ast::ty_vec(mt) { mt.ty } }; + let elem_ty_md = get_ty_metadata(cx, elem_t, elem_ty); + let tcx = ccx_tcx(cx); + let scx = create_structure(file_node, ty_to_str(tcx, vec_t), 0); + let uint_ty = @{node: ast::ty_uint(ast::ty_u), span: vec_ty.span}; + let size_t_type = get_basic_type_metadata(cx, ty::mk_uint(tcx), uint_ty); + add_member(scx, "fill", 0, sys::size_of::() as int, + sys::align_of::() as int, size_t_type.node); + add_member(scx, "alloc", 0, sys::size_of::() as int, + sys::align_of::() as int, size_t_type.node); + let subrange = llmdnode([lltag(SubrangeTag), lli64(0), lli64(0)]); + let (arr_size, arr_align) = member_size_and_align(elem_ty); + let data_ptr = create_composite_type(ArrayTypeTag, "", file_node.node, 0, + arr_size, arr_align, 0, + option::some(elem_ty_md.node), + option::some([subrange])); + add_member(scx, "data", 0, 0, // according to an equivalent clang dump, the size should be 0 + sys::align_of::() as int, data_ptr); + let llnode = finish_structure(scx); + ret @{node: llnode, data: {hash: vec_t}}; +} + fn member_size_and_align(ty: @ast::ty) -> (int, int) { alt ty.node { ast::ty_bool. { size_and_align_of::() } @@ -512,6 +511,9 @@ fn member_size_and_align(ty: @ast::ty) -> (int, int) { } (total_size, 64) //XXX different align for other arches? } + ast::ty_vec(_) { + size_and_align_of::() + } } } @@ -545,6 +547,8 @@ fn get_ty_metadata(cx: @crate_ctxt, t: ty::t, ty: @ast::ty) -> @metadata @metadata Date: Wed, 14 Dec 2011 15:14:06 -0500 Subject: [PATCH 16/21] Clean up some names and factor out some common code. --- src/comp/middle/debuginfo.rs | 371 +++++++++++++++-------------------- src/comp/middle/trans.rs | 7 +- 2 files changed, 164 insertions(+), 214 deletions(-) diff --git a/src/comp/middle/debuginfo.rs b/src/comp/middle/debuginfo.rs index 3949e88f3c2f6..2c249a64d4aa1 100644 --- a/src/comp/middle/debuginfo.rs +++ b/src/comp/middle/debuginfo.rs @@ -8,6 +8,15 @@ import syntax::{ast, codemap}; import ast::ty; import util::ppaux::ty_to_str; +export create_local_var; +export create_function; +export create_arg; +export add_line_info; +export update_source_pos; +export invalidate_source_pos; +export revalidate_source_pos; +export debug_ctxt; + const LLVMDebugVersion: int = (9 << 16); const DW_LANG_RUST: int = 0x9000; @@ -35,13 +44,11 @@ const DW_ATE_signed_char: int = 0x06; const DW_ATE_unsigned: int = 0x07; const DW_ATE_unsigned_char: int = 0x08; -fn as_buf(s: str) -> str::sbuf { - str::as_buf(s, {|sbuf| sbuf}) -} fn llstr(s: str) -> ValueRef { - llvm::LLVMMDString(as_buf(s), str::byte_len(s)) + str::as_buf(s, {|sbuf| + llvm::LLVMMDString(sbuf, str::byte_len(s)) + }) } - fn lltag(lltag: int) -> ValueRef { lli32(LLVMDebugVersion | lltag) } @@ -65,25 +72,27 @@ fn llnull() -> ValueRef unsafe { unsafe::reinterpret_cast(std::ptr::null::()) } -fn update_cache(cache: metadata_cache, mdtag: int, val: debug_metadata) { - let existing = if cache.contains_key(mdtag) { - cache.get(mdtag) - } else { - [] - }; - cache.insert(mdtag, existing + [val]); +fn add_named_metadata(cx: @crate_ctxt, name: str, val: ValueRef) { + str::as_buf(name, {|sbuf| + llvm::LLVMAddNamedMetadataOperand(cx.llmod, sbuf, str::byte_len(name), val) + }) } //////////////// type debug_ctxt = { llmetadata: metadata_cache, - //llmod: ValueRef, - //opt: bool, names: trans_common::namegen }; -//////////////// +fn update_cache(cache: metadata_cache, mdtag: int, val: debug_metadata) { + let existing = if cache.contains_key(mdtag) { + cache.get(mdtag) + } else { + [] + }; + cache.insert(mdtag, existing + [val]); +} type metadata = {node: ValueRef, data: T}; @@ -143,17 +152,19 @@ fn cached_metadata(cache: metadata_cache, mdtag: int, ret option::none; } -fn get_compile_unit_metadata(cx: @crate_ctxt, full_path: str) +fn create_compile_unit(cx: @crate_ctxt, full_path: str) -> @metadata { let cache = get_cache(cx); - alt cached_metadata::<@metadata>(cache, CompileUnitTag, + let tg = CompileUnitTag; + alt cached_metadata::<@metadata>(cache, tg, {|md| md.data.path == full_path}) { option::some(md) { ret md; } option::none. {} } + let fname = fs::basename(full_path); let path = fs::dirname(full_path); - let unit_metadata = [lltag(CompileUnitTag), + let unit_metadata = [lltag(tg), llunused(), lli32(DW_LANG_RUST), llstr(fname), @@ -169,11 +180,9 @@ fn get_compile_unit_metadata(cx: @crate_ctxt, full_path: str) // list of global variables ]; let unit_node = llmdnode(unit_metadata); - llvm::LLVMAddNamedMetadataOperand(cx.llmod, as_buf("llvm.dbg.cu"), - str::byte_len("llvm.dbg.cu"), - unit_node); + add_named_metadata(cx, "llvm.dbg.cu", unit_node); let mdval = @{node: unit_node, data: {path: full_path}}; - update_cache(cache, CompileUnitTag, compile_unit_metadata(mdval)); + update_cache(cache, tg, compile_unit_metadata(mdval)); ret mdval; } @@ -181,7 +190,7 @@ fn get_cache(cx: @crate_ctxt) -> metadata_cache { option::get(cx.dbg_cx).llmetadata } -fn get_file_metadata(cx: @crate_ctxt, full_path: str) -> @metadata { +fn create_file(cx: @crate_ctxt, full_path: str) -> @metadata { let cache = get_cache(cx);; let tg = FileDescriptorTag; alt cached_metadata::<@metadata>( @@ -189,9 +198,10 @@ fn get_file_metadata(cx: @crate_ctxt, full_path: str) -> @metadata { option::some(md) { ret md; } option::none. {} } + let fname = fs::basename(full_path); let path = fs::dirname(full_path); - let unit_node = get_compile_unit_metadata(cx, full_path).node; + let unit_node = create_compile_unit(cx, full_path).node; let file_md = [lltag(tg), llstr(fname), llstr(path), @@ -206,7 +216,7 @@ fn line_from_span(cm: codemap::codemap, sp: codemap::span) -> uint { codemap::lookup_char_pos(cm, sp.lo).line } -fn get_block_metadata(cx: @block_ctxt) -> @metadata { +fn create_block(cx: @block_ctxt) -> @metadata { let cache = get_cache(bcx_ccx(cx)); let start = codemap::lookup_char_pos(bcx_ccx(cx).sess.get_codemap(), cx.sp.lo); @@ -220,11 +230,12 @@ fn get_block_metadata(cx: @block_ctxt) -> @metadata { option::some(md) { ret md; } option::none. {} } + let parent = alt cx.parent { trans_common::parent_none. { function_metadata_from_block(cx).node } - trans_common::parent_some(bcx) { get_block_metadata(cx).node } + trans_common::parent_some(bcx) { create_block(cx).node } }; - let file_node = get_file_metadata(bcx_ccx(cx), fname); + let file_node = create_file(bcx_ccx(cx), fname); let unique_id = alt cache.find(LexicalBlockTag) { option::some(v) { vec::len(v) as int } option::none. { 0 } @@ -246,7 +257,7 @@ fn size_and_align_of() -> (int, int) { (sys::size_of::() as int, sys::align_of::() as int) } -fn get_basic_type_metadata(cx: @crate_ctxt, t: ty::t, ty: @ast::ty) +fn create_basic_type(cx: @crate_ctxt, t: ty::t, ty: @ast::ty) -> @metadata { let cache = get_cache(cx); let tg = BasicTypeDescriptorTag; @@ -256,6 +267,7 @@ fn get_basic_type_metadata(cx: @crate_ctxt, t: ty::t, ty: @ast::ty) option::some(md) { ret md; } option::none. {} } + let (name, (size, align), encoding) = alt ty.node { ast::ty_bool. {("bool", size_and_align_of::(), DW_ATE_boolean)} ast::ty_int(m) { alt m { @@ -279,9 +291,10 @@ fn get_basic_type_metadata(cx: @crate_ctxt, t: ty::t, ty: @ast::ty) ast::ty_f64. {("f64", size_and_align_of::(), DW_ATE_float)} }} }; + let fname = filename_from_span(cx, ty.span); - let file_node = get_file_metadata(cx, fname); - let cu_node = get_compile_unit_metadata(cx, fname); + let file_node = create_file(cx, fname); + let cu_node = create_compile_unit(cx, fname); let lldata = [lltag(tg), cu_node.node, llstr(name), @@ -295,14 +308,12 @@ fn get_basic_type_metadata(cx: @crate_ctxt, t: ty::t, ty: @ast::ty) let llnode = llmdnode(lldata); let mdval = @{node: llnode, data: {hash: ty::hash_ty(t)}}; update_cache(cache, tg, tydesc_metadata(mdval)); - llvm::LLVMAddNamedMetadataOperand(cx.llmod, as_buf("llvm.dbg.ty"), - str::byte_len("llvm.dbg.ty"), - llnode); + add_named_metadata(cx, "llvm.dbg.ty", llnode); ret mdval; } -fn get_pointer_type_metadata(cx: @crate_ctxt, t: ty::t, span: codemap::span, - pointee: @metadata) +fn create_pointer_type(cx: @crate_ctxt, t: ty::t, span: codemap::span, + pointee: @metadata) -> @metadata { let tg = PointerTypeTag; /*let cache = cx.llmetadata; @@ -313,24 +324,13 @@ fn get_pointer_type_metadata(cx: @crate_ctxt, t: ty::t, span: codemap::span, }*/ let (size, align) = size_and_align_of::(); let fname = filename_from_span(cx, span); - let file_node = get_file_metadata(cx, fname); - //let cu_node = get_compile_unit_metadata(cx, fname); - let lldata = [lltag(tg), - file_node.node, - llstr(""), - file_node.node, - lli32(0), //XXX source line - lli64(size * 8), // size in bits - lli64(align * 8), // alignment in bits - lli64(0), //XXX offset? - lli32(0), - pointee.node]; - let llnode = llmdnode(lldata); + let file_node = create_file(cx, fname); + //let cu_node = create_compile_unit(cx, fname); + let llnode = create_derived_type(tg, file_node.node, "", 0, size * 8, + align * 8, 0, pointee.node); let mdval = @{node: llnode, data: {hash: ty::hash_ty(t)}}; //update_cache(cache, tg, tydesc_metadata(mdval)); - llvm::LLVMAddNamedMetadataOperand(cx.llmod, as_buf("llvm.dbg.ty"), - str::byte_len("llvm.dbg.ty"), - llnode); + add_named_metadata(cx, "llvm.dbg.ty", llnode); ret mdval; } @@ -361,33 +361,40 @@ fn create_structure(file: @metadata, name: str, line: int) ret cx; } -fn add_member(cx: @struct_ctxt, name: str, line: int, size: int, align: int, - ty: ValueRef) { - let lldata = [lltag(MemberTag), - cx.file, +fn create_derived_type(type_tag: int, file: ValueRef, name: str, line: int, + size: int, align: int, offset: int, ty: ValueRef) + -> ValueRef { + let lldata = [lltag(type_tag), + file, llstr(name), - cx.file, + file, lli32(line), - lli64(size * 8), - lli64(align * 8), - lli64(cx.total_size), + lli64(size), + lli64(align), + lli64(offset), lli32(0), ty]; + ret llmdnode(lldata); +} + +fn add_member(cx: @struct_ctxt, name: str, line: int, size: int, align: int, + ty: ValueRef) { + cx.members += [create_derived_type(MemberTag, cx.file, name, line, size * 8, + align * 8, cx.total_size, ty)]; cx.total_size += size * 8; - cx.members += [llmdnode(lldata)]; } -fn get_record_metadata(cx: @crate_ctxt, t: ty::t, fields: [ast::ty_field], - span: codemap::span) -> @metadata { +fn create_record(cx: @crate_ctxt, t: ty::t, fields: [ast::ty_field], + span: codemap::span) -> @metadata { let fname = filename_from_span(cx, span); - let file_node = get_file_metadata(cx, fname); + let file_node = create_file(cx, fname); let scx = create_structure(file_node, option::get(cx.dbg_cx).names.next("rec"), line_from_span(cx.sess.get_codemap(), span) as int); for field in fields { let field_t = ty::get_field(ccx_tcx(cx), t, field.node.ident).mt.ty; - let ty_md = get_ty_metadata(cx, field_t, field.node.mt.ty); + let ty_md = create_ty(cx, field_t, field.node.mt.ty); let (size, align) = member_size_and_align(field.node.mt.ty); add_member(scx, field.node.ident, line_from_span(cx.sess.get_codemap(), field.span) as int, @@ -397,10 +404,10 @@ fn get_record_metadata(cx: @crate_ctxt, t: ty::t, fields: [ast::ty_field], ret mdval; } -fn get_boxed_type_metadata(cx: @crate_ctxt, outer: ty::t, inner: ty::t, - span: codemap::span, boxed: @metadata) +fn create_boxed_type(cx: @crate_ctxt, outer: ty::t, _inner: ty::t, + span: codemap::span, boxed: @metadata) -> @metadata { - let tg = StructureTypeTag; + //let tg = StructureTypeTag; /*let cache = cx.llmetadata; alt cached_metadata::<@metadata>( cache, tg, {|md| ty::hash_ty(outer) == ty::hash_ty(md.data.hash)}) { @@ -408,12 +415,12 @@ fn get_boxed_type_metadata(cx: @crate_ctxt, outer: ty::t, inner: ty::t, option::none. {} }*/ let fname = filename_from_span(cx, span); - let file_node = get_file_metadata(cx, fname); - //let cu_node = get_compile_unit_metadata(cx, fname); + let file_node = create_file(cx, fname); + //let cu_node = create_compile_unit_metadata(cx, fname); let tcx = ccx_tcx(cx); let uint_t = ty::mk_uint(tcx); let uint_ty = @{node: ast::ty_uint(ast::ty_u), span: span}; - let refcount_type = get_basic_type_metadata(cx, uint_t, uint_ty); + let refcount_type = create_basic_type(cx, uint_t, uint_ty); let scx = create_structure(file_node, ty_to_str(ccx_tcx(cx), outer), 0); add_member(scx, "refcnt", 0, sys::size_of::() as int, sys::align_of::() as int, refcount_type.node); @@ -423,9 +430,7 @@ fn get_boxed_type_metadata(cx: @crate_ctxt, outer: ty::t, inner: ty::t, let llnode = finish_structure(scx); let mdval = @{node: llnode, data: {hash: outer}}; //update_cache(cache, tg, tydesc_metadata(mdval)); - llvm::LLVMAddNamedMetadataOperand(cx.llmod, as_buf("llvm.dbg.ty"), - str::byte_len("llvm.dbg.ty"), - llnode); + add_named_metadata(cx, "llvm.dbg.ty", llnode); ret mdval; } @@ -453,16 +458,16 @@ fn create_composite_type(type_tag: int, name: str, file: ValueRef, line: int, ret llmdnode(lldata); } -fn get_vec_metadata(cx: @crate_ctxt, vec_t: ty::t, elem_t: ty::t, vec_ty: @ast::ty) +fn create_vec(cx: @crate_ctxt, vec_t: ty::t, elem_t: ty::t, vec_ty: @ast::ty) -> @metadata { let fname = filename_from_span(cx, vec_ty.span); - let file_node = get_file_metadata(cx, fname); + let file_node = create_file(cx, fname); let elem_ty = alt vec_ty.node { ast::ty_vec(mt) { mt.ty } }; - let elem_ty_md = get_ty_metadata(cx, elem_t, elem_ty); + let elem_ty_md = create_ty(cx, elem_t, elem_ty); let tcx = ccx_tcx(cx); let scx = create_structure(file_node, ty_to_str(tcx, vec_t), 0); let uint_ty = @{node: ast::ty_uint(ast::ty_u), span: vec_ty.span}; - let size_t_type = get_basic_type_metadata(cx, ty::mk_uint(tcx), uint_ty); + let size_t_type = create_basic_type(cx, ty::mk_uint(tcx), uint_ty); add_member(scx, "fill", 0, sys::size_of::() as int, sys::align_of::() as int, size_t_type.node); add_member(scx, "alloc", 0, sys::size_of::() as int, @@ -517,7 +522,7 @@ fn member_size_and_align(ty: @ast::ty) -> (int, int) { } } -fn get_ty_metadata(cx: @crate_ctxt, t: ty::t, ty: @ast::ty) -> @metadata { +fn create_ty(cx: @crate_ctxt, t: ty::t, ty: @ast::ty) -> @metadata { /*let cache = get_cache(cx); alt cached_metadata::<@metadata>( cache, tg, {|md| t == md.data.hash}) { @@ -558,30 +563,35 @@ fn get_ty_metadata(cx: @crate_ctxt, t: ty::t, ty: @ast::ty) -> @metadata @metadata { 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(fcx, fn_item, fcx.llfn) + ret create_function(fcx, fn_item, fcx.llfn); } fn filename_from_span(cx: @crate_ctxt, sp: codemap::span) -> str { codemap::lookup_char_pos(cx.sess.get_codemap(), sp.lo).filename } -fn get_local_var_metadata(bcx: @block_ctxt, local: @ast::local) +fn create_var(type_tag: int, context: ValueRef, name: str, file: ValueRef, + line: int, ret_ty: ValueRef) -> ValueRef { + let lldata = [lltag(type_tag), + context, + llstr(name), + file, + lli32(line), + ret_ty, + lli32(0) + ]; + ret llmdnode(lldata); +} + +fn create_local_var(bcx: @block_ctxt, local: @ast::local) -> @metadata unsafe { let cx = bcx_ccx(bcx); let cache = get_cache(cx); + let tg = AutoVariableTag; alt cached_metadata::<@metadata>( - cache, AutoVariableTag, {|md| md.data.id == local.node.id}) { + cache, tg, {|md| md.data.id == local.node.id}) { option::some(md) { ret md; } option::none. {} } + let name = alt local.node.pat.node { ast::pat_bind(ident) { ident } }; let loc = codemap::lookup_char_pos(cx.sess.get_codemap(), local.span.lo); let ty = trans::node_id_type(cx, local.node.id); - let tymd = get_ty_metadata(cx, ty, local.node.ty); - let filemd = get_file_metadata(cx, loc.filename); + let tymd = create_ty(cx, ty, local.node.ty); + let filemd = create_file(cx, loc.filename); let context = alt bcx.parent { trans_common::parent_none. { function_metadata_from_block(bcx).node } - trans_common::parent_some(_) { get_block_metadata(bcx).node } + trans_common::parent_some(_) { create_block(bcx).node } }; - let lldata = [lltag(AutoVariableTag), - context, // context - llstr(name), // name - filemd.node, - lli32(loc.line as int), // line - tymd.node, - lli32(0) //XXX flags - ]; - let mdnode = llmdnode(lldata); + let mdnode = create_var(tg, context, name, filemd.node, + loc.line as int, tymd.node); let mdval = @{node: mdnode, data: {id: local.node.id}}; update_cache(cache, AutoVariableTag, local_var_metadata(mdval)); + let llptr = alt bcx.fcx.lllocals.find(local.node.id) { option::some(local_mem(v)) { v } option::none. { @@ -643,89 +662,35 @@ 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 unsafe { - let fcx = bcx_fcx(bcx); - let cx = fcx_ccx(fcx); - let cache = cx.llmetadata; - alt cached_metadata::<@metadata>( - 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) +//FIXME: consolidate with create_local_var +fn create_arg(bcx: @block_ctxt, arg: ast::arg) -> @metadata unsafe { let fcx = bcx_fcx(bcx); let cx = fcx_ccx(fcx); let cache = get_cache(cx); + let tg = ArgVariableTag; alt cached_metadata::<@metadata>( 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) { + + /*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 tymd = create_ty(cx, ty, arg.ty); + let filemd = create_file(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 context = create_function(fcx, fn_item, fcx.llfn); + let mdnode = create_var(tg, context.node, arg.ident, filemd.node, + loc.line as int, tymd.node); let mdval = @{node: mdnode, data: {id: arg.id}}; - update_cache(cache, ArgVariableTag, argument_metadata(mdval)); + update_cache(cache, tg, argument_metadata(mdval)); + let llptr = alt fcx.llargs.get(arg.id) { local_mem(v) | local_imm(v) { v } }; @@ -785,54 +750,46 @@ fn add_line_info(cx: @block_ctxt, llinstr: ValueRef) { ret; } let loc = option::get(vec::last(cx.source_pos.pos)); - let blockmd = get_block_metadata(cx); - let kind_id = llvm::LLVMGetMDKindID(as_buf("dbg"), - str::byte_len("dbg")); - let scopedata = [lli32(loc.line as int), - lli32(loc.col as int), - blockmd.node, - llnull()]; - let dbgscope = llmdnode(scopedata); - llvm::LLVMSetMetadata(llinstr, kind_id, dbgscope); -} - -fn get_function_metadata(fcx: @fn_ctxt, item: @ast::item, - llfndecl: ValueRef) -> @metadata { + let blockmd = create_block(cx); + let kind = "dbg"; + str::as_buf(kind, {|sbuf| + let kind_id = llvm::LLVMGetMDKindID(sbuf, + str::byte_len(kind)); + let scopedata = [lli32(loc.line as int), + lli32(loc.col as int), + blockmd.node, + llnull()]; + let dbgscope = llmdnode(scopedata); + llvm::LLVMSetMetadata(llinstr, kind_id, dbgscope) + }); +} + +fn create_function(fcx: @fn_ctxt, item: @ast::item, llfndecl: ValueRef) + -> @metadata { let cx = fcx_ccx(fcx); let cache = get_cache(cx); alt cached_metadata::<@metadata>( cache, SubprogramTag, {|md| md.data.name == item.ident && - /*sub.path == ??*/ true}) { + /*md.data.path == ??*/ true}) { option::some(md) { ret md; } option::none. {} } + let loc = codemap::lookup_char_pos(cx.sess.get_codemap(), - item.span.lo); - let file_node = get_file_metadata(cx, loc.filename).node; + item.span.lo); + let file_node = create_file(cx, loc.filename).node; let mangled = cx.item_symbols.get(item.id); 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 } + _ { create_ty(cx, ty::node_id_to_type(ccx_tcx(cx), item.id), ret_ty).node } }; - let sub_type = llmdnode([ty_node]); - let sub_metadata = [lltag(SubroutineTag), - file_node, - llstr(""), - file_node, - lli32(0), - lli64(0), - lli64(0), - lli64(0), - lli32(0), - llnull(), - sub_type, - lli32(0), - llnull()]; - let sub_node = llmdnode(sub_metadata); + let sub_node = create_composite_type(SubroutineTag, "", file_node, 0, 0, + 0, 0, option::none, + option::some([ty_node])); + let fn_metadata = [lltag(SubprogramTag), llunused(), file_node, @@ -855,15 +812,9 @@ fn get_function_metadata(fcx: @fn_ctxt, item: @ast::item, //list of func vars ]; let val = llmdnode(fn_metadata); - llvm::LLVMAddNamedMetadataOperand(cx.llmod, as_buf("llvm.dbg.sp"), - str::byte_len("llvm.dbg.sp"), - val); + add_named_metadata(cx, "llvm.dbg.sp", val); 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; } diff --git a/src/comp/middle/trans.rs b/src/comp/middle/trans.rs index e92095f67e56c..563f4d64cd2a9 100644 --- a/src/comp/middle/trans.rs +++ b/src/comp/middle/trans.rs @@ -4028,7 +4028,7 @@ fn trans_stmt(cx: @block_ctxt, s: ast::stmt) -> @block_ctxt { bcx = init_ref_local(bcx, local); } if bcx_ccx(cx).sess.get_opts().debuginfo { - debuginfo::get_local_var_metadata(bcx, local); + debuginfo::create_local_var(bcx, local); } } } @@ -4426,7 +4426,6 @@ fn copy_args_to_allocas(fcx: @fn_ctxt, bcx: @block_ctxt, args: [ast::arg], 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 { @@ -4448,7 +4447,7 @@ 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]); + debuginfo::create_arg(bcx, args[arg_n]); } arg_n += 1u; } @@ -4589,7 +4588,7 @@ fn trans_fn(cx: @local_ctxt, sp: span, f: ast::_fn, llfndecl: ValueRef, let item = alt option::get(cx.ccx.ast_map.find(id)) { ast_map::node_item(item) { item } }; - debuginfo::get_function_metadata(option::get(fcx), item, llfndecl); + debuginfo::create_function(option::get(fcx), item, llfndecl); } if do_time { let end = time::get_time(); From c6f16ed2c418268f2acbb8728f265b3b960f8efd Mon Sep 17 00:00:00 2001 From: Josh Matthews Date: Wed, 14 Dec 2011 15:47:05 -0500 Subject: [PATCH 17/21] Hide extended, unfinished debug information behind --xg compiler flag. --- src/comp/driver/rustc.rs | 6 ++++-- src/comp/driver/session.rs | 1 + src/comp/middle/debuginfo.rs | 11 ++++++++--- src/comp/middle/trans.rs | 10 +++++----- 4 files changed, 18 insertions(+), 10 deletions(-) diff --git a/src/comp/driver/rustc.rs b/src/comp/driver/rustc.rs index 5bb7e60a6849c..35e450244ac8c 100644 --- a/src/comp/driver/rustc.rs +++ b/src/comp/driver/rustc.rs @@ -421,7 +421,8 @@ fn build_session_options(match: getopts::match) let libcore = !opt_present(match, "no-core"); let verify = !opt_present(match, "no-verify"); let save_temps = opt_present(match, "save-temps"); - let debuginfo = opt_present(match, "g"); + let extra_debuginfo = opt_present(match, "xg"); + let debuginfo = opt_present(match, "g") || extra_debuginfo; let stats = opt_present(match, "stats"); let time_passes = opt_present(match, "time-passes"); let time_llvm_passes = opt_present(match, "time-llvm-passes"); @@ -468,6 +469,7 @@ fn build_session_options(match: getopts::match) libcore: libcore, optimize: opt_level, debuginfo: debuginfo, + extra_debuginfo: extra_debuginfo, verify: verify, save_temps: save_temps, stats: stats, @@ -516,7 +518,7 @@ fn opts() -> [getopts::opt] { optflag("emit-llvm"), optflagopt("pretty"), optflag("ls"), optflag("parse-only"), optflag("no-trans"), optflag("O"), optopt("opt-level"), optmulti("L"), optflag("S"), - optopt("o"), optopt("out-dir"), + optopt("o"), optopt("out-dir"), optflag("xg"), optflag("c"), optflag("g"), optflag("save-temps"), optopt("sysroot"), optopt("target"), optflag("stats"), optflag("time-passes"), optflag("time-llvm-passes"), diff --git a/src/comp/driver/session.rs b/src/comp/driver/session.rs index 586dce38df969..6645d5d68946e 100644 --- a/src/comp/driver/session.rs +++ b/src/comp/driver/session.rs @@ -31,6 +31,7 @@ type options = libcore: bool, optimize: uint, debuginfo: bool, + extra_debuginfo: bool, verify: bool, save_temps: bool, stats: bool, diff --git a/src/comp/middle/debuginfo.rs b/src/comp/middle/debuginfo.rs index 2c249a64d4aa1..14cc13e217eff 100644 --- a/src/comp/middle/debuginfo.rs +++ b/src/comp/middle/debuginfo.rs @@ -782,9 +782,14 @@ fn create_function(fcx: @fn_ctxt, item: @ast::item, llfndecl: ValueRef) let ret_ty = alt item.node { ast::item_fn(f, _) { f.decl.output } }; - let ty_node = alt ret_ty.node { - ast::ty_nil. { llnull() } - _ { create_ty(cx, ty::node_id_to_type(ccx_tcx(cx), item.id), ret_ty).node } + let ty_node = if cx.sess.get_opts().extra_debuginfo { + alt ret_ty.node { + ast::ty_nil. { llnull() } + _ { create_ty(cx, ty::node_id_to_type(ccx_tcx(cx), item.id), + ret_ty).node } + } + } else { + llnull() }; let sub_node = create_composite_type(SubroutineTag, "", file_node, 0, 0, 0, 0, option::none, diff --git a/src/comp/middle/trans.rs b/src/comp/middle/trans.rs index 563f4d64cd2a9..b030a5d52c941 100644 --- a/src/comp/middle/trans.rs +++ b/src/comp/middle/trans.rs @@ -4027,7 +4027,7 @@ fn trans_stmt(cx: @block_ctxt, s: ast::stmt) -> @block_ctxt { } else { bcx = init_ref_local(bcx, local); } - if bcx_ccx(cx).sess.get_opts().debuginfo { + if bcx_ccx(cx).sess.get_opts().extra_debuginfo { debuginfo::create_local_var(bcx, local); } } @@ -4422,7 +4422,7 @@ 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 { + if fcx_ccx(fcx).sess.get_opts().extra_debuginfo { llvm::LLVMAddAttribute(llvm::LLVMGetFirstParam(fcx.llfn), lib::llvm::LLVMStructRetAttribute as lib::llvm::llvm::Attribute); @@ -4446,7 +4446,7 @@ 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 { + if fcx_ccx(fcx).sess.get_opts().extra_debuginfo { debuginfo::create_arg(bcx, args[arg_n]); } arg_n += 1u; @@ -4584,7 +4584,7 @@ fn trans_fn(cx: @local_ctxt, sp: span, f: ast::_fn, llfndecl: ValueRef, let start = do_time ? time::get_time() : {sec: 0u32, usec: 0u32}; 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 { + if cx.ccx.sess.get_opts().extra_debuginfo { let item = alt option::get(cx.ccx.ast_map.find(id)) { ast_map::node_item(item) { item } }; @@ -5654,7 +5654,7 @@ fn trans_crate(sess: session::session, crate: @ast::crate, tcx: ty::ctxt, let td = mk_target_data(sess.get_targ_cfg().target_strs.data_layout); let tn = mk_type_names(); let intrinsics = declare_intrinsics(llmod); - if sess.get_opts().debuginfo { + if sess.get_opts().extra_debuginfo { declare_dbg_intrinsics(llmod, intrinsics); } let int_type = T_int(targ_cfg); From df6052c4f88fbc9118411967d236576ae45d7dc5 Mon Sep 17 00:00:00 2001 From: Josh Matthews Date: Sun, 18 Dec 2011 23:32:38 -0500 Subject: [PATCH 18/21] Remove source line generation craziness. Ensure incorrect subprogram caches are not conflated. Generate ast_map entries for object members and resource constructors and destructors. --- src/comp/middle/ast_map.rs | 12 +- src/comp/middle/debuginfo.rs | 145 +++++-------- src/comp/middle/trans.rs | 42 +--- src/comp/middle/trans_build.rs | 357 +++++++++----------------------- src/comp/middle/trans_common.rs | 4 +- src/comp/middle/trans_vec.rs | 2 - 6 files changed, 172 insertions(+), 390 deletions(-) diff --git a/src/comp/middle/ast_map.rs b/src/comp/middle/ast_map.rs index 78e3da6b03037..63b7131d15d76 100644 --- a/src/comp/middle/ast_map.rs +++ b/src/comp/middle/ast_map.rs @@ -7,6 +7,7 @@ import syntax::{visit, codemap}; tag ast_node { node_item(@item); node_obj_ctor(@item); + node_obj_method(@method); node_native_item(@native_item); node_method(@method); node_expr(@expr); @@ -14,6 +15,7 @@ tag ast_node { // order they are introduced. node_arg(arg, uint); node_local(uint); + node_res_ctor(@item); } type map = std::map::hashmap; @@ -63,9 +65,17 @@ fn map_arm(cx: ctx, arm: arm) { fn map_item(cx: ctx, i: @item) { cx.map.insert(i.id, node_item(i)); alt i.node { - item_obj(_, _, ctor_id) { cx.map.insert(ctor_id, node_obj_ctor(i)); } + item_obj(ob, _, ctor_id) { + cx.map.insert(ctor_id, node_obj_ctor(i)); + for m in ob.methods { + cx.map.insert(m.node.id, node_obj_method(m)); + } + } item_impl(_, _, ms) { for m in ms { cx.map.insert(m.node.id, node_method(m)); } + item_res(_, dtor_id, _, ctor_id) { + cx.map.insert(ctor_id, node_res_ctor(i)); + cx.map.insert(dtor_id, node_item(i)); } _ { } } diff --git a/src/comp/middle/debuginfo.rs b/src/comp/middle/debuginfo.rs index 14cc13e217eff..12b26410c88cb 100644 --- a/src/comp/middle/debuginfo.rs +++ b/src/comp/middle/debuginfo.rs @@ -11,10 +11,7 @@ import util::ppaux::ty_to_str; export create_local_var; export create_function; export create_arg; -export add_line_info; export update_source_pos; -export invalidate_source_pos; -export revalidate_source_pos; export debug_ctxt; const LLVMDebugVersion: int = (9 << 16); @@ -98,7 +95,7 @@ type metadata = {node: ValueRef, data: T}; type file_md = {path: str}; type compile_unit_md = {path: str}; -type subprogram_md = {name: str, file: str}; +type subprogram_md = {path: str}; type local_var_md = {id: ast::node_id}; type tydesc_md = {hash: uint}; type block_md = {start: codemap::loc, end: codemap::loc}; @@ -232,7 +229,7 @@ fn create_block(cx: @block_ctxt) -> @metadata { } let parent = alt cx.parent { - trans_common::parent_none. { function_metadata_from_block(cx).node } + trans_common::parent_none. { create_function(cx.fcx).node } trans_common::parent_some(bcx) { create_block(cx).node } }; let file_node = create_file(bcx_ccx(cx), fname); @@ -595,14 +592,6 @@ fn create_ty(cx: @crate_ctxt, t: ty::t, ty: @ast::ty) -> @metadata { }; } -fn function_metadata_from_block(bcx: @block_ctxt) -> @metadata { - let cx = bcx_ccx(bcx); - 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 } }; - ret create_function(fcx, fn_item, fcx.llfn); -} - fn filename_from_span(cx: @crate_ctxt, sp: codemap::span) -> str { codemap::lookup_char_pos(cx.sess.get_codemap(), sp.lo).filename } @@ -640,7 +629,7 @@ fn create_local_var(bcx: @block_ctxt, local: @ast::local) let tymd = create_ty(cx, ty, local.node.ty); let filemd = create_file(cx, loc.filename); let context = alt bcx.parent { - trans_common::parent_none. { function_metadata_from_block(bcx).node } + trans_common::parent_none. { create_function(bcx.fcx).node } trans_common::parent_some(_) { create_block(bcx).node } }; let mdnode = create_var(tg, context, name, filemd.node, @@ -662,7 +651,6 @@ fn create_local_var(bcx: @block_ctxt, local: @ast::local) ret mdval; } -//FIXME: consolidate with create_local_var fn create_arg(bcx: @block_ctxt, arg: ast::arg) -> @metadata unsafe { let fcx = bcx_fcx(bcx); @@ -683,9 +671,7 @@ fn create_arg(bcx: @block_ctxt, arg: ast::arg) let ty = trans::node_id_type(cx, arg.id); let tymd = create_ty(cx, ty, arg.ty); let filemd = create_file(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 = create_function(fcx, fn_item, fcx.llfn); + let context = create_function(bcx.fcx); let mdnode = create_var(tg, context.node, arg.ident, filemd.node, loc.line as int, tymd.node); let mdval = @{node: mdnode, data: {id: arg.id}}; @@ -700,92 +686,76 @@ fn create_arg(bcx: @block_ctxt, arg: ast::arg) ret mdval; } -fn update_source_pos(cx: @block_ctxt, s: codemap::span) -> @debug_source_pos { - let dsp = @debug_source_pos(cx); +fn update_source_pos(cx: @block_ctxt, s: codemap::span) { if !bcx_ccx(cx).sess.get_opts().debuginfo { - ret dsp; + ret; } let cm = bcx_ccx(cx).sess.get_codemap(); - if vec::is_empty(cx.source_pos.pos) { - cx.source_pos.usable = true; - } - cx.source_pos.pos += [codemap::lookup_char_pos(cm, s.lo)]; //XXX maybe hi - ret dsp; + let blockmd = create_block(cx); + let loc = codemap::lookup_char_pos(cm, s.lo); + let scopedata = [lli32(loc.line as int), + lli32(loc.col as int), + blockmd.node, + llnull()]; + let dbgscope = llmdnode(scopedata); + llvm::LLVMSetCurrentDebugLocation(trans_build::B(cx), dbgscope); } -fn invalidate_source_pos(cx: @block_ctxt) -> @invalidated_source_pos { - let isp = @invalidated_source_pos(cx); - if !bcx_ccx(cx).sess.get_opts().debuginfo { - ret isp; - } - cx.source_pos.usable = false; - ret isp; -} +fn create_function(fcx: @fn_ctxt) -> @metadata { + let cx = fcx_ccx(fcx); + let dbg_cx = option::get(cx.dbg_cx); -fn revalidate_source_pos(cx: @block_ctxt) { - if !bcx_ccx(cx).sess.get_opts().debuginfo { - ret; - } - cx.source_pos.usable = true; -} + log "~~"; + log fcx.id; + log cx.sess.span_str(fcx.sp); -fn reset_source_pos(cx: @block_ctxt) { - if !bcx_ccx(cx).sess.get_opts().debuginfo { - ret; - } - vec::pop(cx.source_pos.pos); -} + let (ident, ret_ty, id) = alt cx.ast_map.get(fcx.id) { + ast_map::node_item(item) { + alt item.node { + ast::item_fn(f, _) | ast::item_res(f, _, _, _) { + (item.ident, f.decl.output, item.id) + } + } + } + ast_map::node_obj_method(method) { + (method.node.ident, method.node.meth.decl.output, method.node.id) + } + ast_map::node_res_ctor(item) { + alt item.node { ast::item_res(f, _, _, ctor_id) { + (item.ident, f.decl.output, ctor_id) + }} + } + ast_map::node_expr(expr) { + alt expr.node { + ast::expr_fn(f) { + (dbg_cx.names.next("fn"), f.decl.output, expr.id) + } + } + } + }; -resource debug_source_pos(bcx: @block_ctxt) { - reset_source_pos(bcx); -} -resource invalidated_source_pos(bcx: @block_ctxt) { - revalidate_source_pos(bcx); -} + log ident; + log id; + + let path = str::connect(fcx.lcx.path + [ident], "::"); -fn add_line_info(cx: @block_ctxt, llinstr: ValueRef) { - if !bcx_ccx(cx).sess.get_opts().debuginfo || - !cx.source_pos.usable || - vec::is_empty(cx.source_pos.pos) { - ret; - } - let loc = option::get(vec::last(cx.source_pos.pos)); - let blockmd = create_block(cx); - let kind = "dbg"; - str::as_buf(kind, {|sbuf| - let kind_id = llvm::LLVMGetMDKindID(sbuf, - str::byte_len(kind)); - let scopedata = [lli32(loc.line as int), - lli32(loc.col as int), - blockmd.node, - llnull()]; - let dbgscope = llmdnode(scopedata); - llvm::LLVMSetMetadata(llinstr, kind_id, dbgscope) - }); -} - -fn create_function(fcx: @fn_ctxt, item: @ast::item, llfndecl: ValueRef) - -> @metadata { - let cx = fcx_ccx(fcx); let cache = get_cache(cx); alt cached_metadata::<@metadata>( - cache, SubprogramTag, {|md| md.data.name == item.ident && + cache, SubprogramTag, {|md| md.data.path == path && /*md.data.path == ??*/ true}) { option::some(md) { ret md; } option::none. {} } let loc = codemap::lookup_char_pos(cx.sess.get_codemap(), - item.span.lo); + fcx.sp.lo); let file_node = create_file(cx, loc.filename).node; - let mangled = cx.item_symbols.get(item.id); - let ret_ty = alt item.node { - ast::item_fn(f, _) { f.decl.output } - }; + let key = cx.item_symbols.contains_key(fcx.id) ? fcx.id : id; + let mangled = cx.item_symbols.get(key); let ty_node = if cx.sess.get_opts().extra_debuginfo { alt ret_ty.node { ast::ty_nil. { llnull() } - _ { create_ty(cx, ty::node_id_to_type(ccx_tcx(cx), item.id), + _ { create_ty(cx, ty::node_id_to_type(ccx_tcx(cx), id), ret_ty).node } } } else { @@ -798,8 +768,8 @@ fn create_function(fcx: @fn_ctxt, item: @ast::item, llfndecl: ValueRef) let fn_metadata = [lltag(SubprogramTag), llunused(), file_node, - llstr(item.ident), - llstr(item.ident), //XXX fully-qualified C++ name + llstr(ident), + llstr(path), //XXX fully-qualified C++ name llstr(mangled), //XXX MIPS name????? file_node, lli32(loc.line as int), @@ -811,15 +781,14 @@ fn create_function(fcx: @fn_ctxt, item: @ast::item, llfndecl: ValueRef) llnull(), // base type with vtbl lli1(false), // artificial lli1(cx.sess.get_opts().optimize != 0u), - llfndecl + fcx.llfn //list of template params //func decl descriptor //list of func vars ]; let val = llmdnode(fn_metadata); add_named_metadata(cx, "llvm.dbg.sp", val); - let mdval = @{node: val, data: {name: item.ident, - file: loc.filename}}; + let mdval = @{node: val, data: {path: path}}; update_cache(cache, SubprogramTag, subprogram_metadata(mdval)); ret mdval; } diff --git a/src/comp/middle/trans.rs b/src/comp/middle/trans.rs index b030a5d52c941..7828390ee4fb6 100644 --- a/src/comp/middle/trans.rs +++ b/src/comp/middle/trans.rs @@ -3519,7 +3519,7 @@ fn trans_temp_expr(bcx: @block_ctxt, e: @ast::expr) -> result { // - exprs with non-immediate type never get dest=by_val fn trans_expr(bcx: @block_ctxt, e: @ast::expr, dest: dest) -> @block_ctxt { let tcx = bcx_tcx(bcx); - let _s = debuginfo::update_source_pos(bcx, e.span); + debuginfo::update_source_pos(bcx, e.span); if expr_is_lval(bcx, e) { ret lval_to_dps(bcx, e, dest); @@ -4014,7 +4014,7 @@ fn trans_stmt(cx: @block_ctxt, s: ast::stmt) -> @block_ctxt { } let bcx = cx; - let _s = debuginfo::update_source_pos(cx, s.span); + debuginfo::update_source_pos(cx, s.span); alt s.node { ast::stmt_expr(e, _) { bcx = trans_expr(cx, e, ignore); } @@ -4041,19 +4041,6 @@ fn trans_stmt(cx: @block_ctxt, s: ast::stmt) -> @block_ctxt { ret bcx; } -fn source_pos_from_block_parent(parent: block_parent) - -> (bool, [codemap::loc]) { - alt parent { - parent_none. { (false, []) } - parent_some(bcx) { (bcx.source_pos.usable, - alt vec::last(bcx.source_pos.pos) { - option::some(p) { [p] } - option::none. { [] } - }) - } - } -} - // You probably don't want to use this one. See the // next three functions instead. fn new_block_ctxt(cx: @fn_ctxt, parent: block_parent, kind: block_kind, @@ -4065,7 +4052,6 @@ fn new_block_ctxt(cx: @fn_ctxt, parent: block_parent, kind: block_kind, } let llbb: BasicBlockRef = str::as_buf(s, {|buf| llvm::LLVMAppendBasicBlock(cx.llfn, buf) }); - let (usable, pos) = source_pos_from_block_parent(parent); let bcx = @{llbb: llbb, mutable terminated: false, mutable unreachable: false, @@ -4075,8 +4061,7 @@ fn new_block_ctxt(cx: @fn_ctxt, parent: block_parent, kind: block_kind, mutable lpad_dirty: true, mutable lpad: option::none, sp: cx.sp, - fcx: cx, - source_pos: {mutable usable: usable, mutable pos: pos}}; + fcx: cx}; alt parent { parent_some(cx) { if cx.unreachable { Unreachable(bcx); } @@ -4111,7 +4096,6 @@ fn new_sub_block_ctxt(bcx: @block_ctxt, n: str) -> @block_ctxt { } fn new_raw_block_ctxt(fcx: @fn_ctxt, llbb: BasicBlockRef) -> @block_ctxt { - let (usable, pos) = source_pos_from_block_parent(parent_none); ret @{llbb: llbb, mutable terminated: false, mutable unreachable: false, @@ -4121,8 +4105,7 @@ fn new_raw_block_ctxt(fcx: @fn_ctxt, llbb: BasicBlockRef) -> @block_ctxt { mutable lpad_dirty: true, mutable lpad: option::none, sp: fcx.sp, - fcx: fcx, - source_pos: {mutable usable: usable, mutable pos: pos}}; + fcx: fcx}; } @@ -4180,7 +4163,6 @@ fn block_locals(b: ast::blk, it: block(@ast::local)) { } fn llstaticallocas_block_ctxt(fcx: @fn_ctxt) -> @block_ctxt { - let (usable, pos) = source_pos_from_block_parent(parent_none); ret @{llbb: fcx.llstaticallocas, mutable terminated: false, mutable unreachable: false, @@ -4190,12 +4172,10 @@ fn llstaticallocas_block_ctxt(fcx: @fn_ctxt) -> @block_ctxt { mutable lpad_dirty: true, mutable lpad: option::none, sp: fcx.sp, - fcx: fcx, - source_pos: {mutable usable: usable, mutable pos: pos}}; + fcx: fcx}; } fn llderivedtydescs_block_ctxt(fcx: @fn_ctxt) -> @block_ctxt { - let (usable, pos) = source_pos_from_block_parent(parent_none); ret @{llbb: fcx.llderivedtydescs, mutable terminated: false, mutable unreachable: false, @@ -4205,8 +4185,7 @@ fn llderivedtydescs_block_ctxt(fcx: @fn_ctxt) -> @block_ctxt { mutable lpad_dirty: true, mutable lpad: option::none, sp: fcx.sp, - fcx: fcx, - source_pos: {mutable usable: usable, mutable pos: pos}}; + fcx: fcx}; } @@ -4281,13 +4260,13 @@ fn trans_block_dps(bcx: @block_ctxt, b: ast::blk, dest: dest) let bcx = bcx; block_locals(b) {|local| bcx = alloc_local(bcx, local); }; for s: @ast::stmt in b.node.stmts { - let _s = debuginfo::update_source_pos(bcx, b.span); + debuginfo::update_source_pos(bcx, b.span); bcx = trans_stmt(bcx, *s); } alt b.node.expr { some(e) { let bt = ty::type_is_bot(bcx_tcx(bcx), ty::expr_ty(bcx_tcx(bcx), e)); - let _s = debuginfo::update_source_pos(bcx, e.span); + debuginfo::update_source_pos(bcx, e.span); bcx = trans_expr(bcx, e, bt ? ignore : dest); } _ { assert dest == ignore || bcx.unreachable; } @@ -4585,10 +4564,7 @@ fn trans_fn(cx: @local_ctxt, sp: span, f: ast::_fn, llfndecl: ValueRef, 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().extra_debuginfo { - let item = alt option::get(cx.ccx.ast_map.find(id)) { - ast_map::node_item(item) { item } - }; - debuginfo::create_function(option::get(fcx), item, llfndecl); + debuginfo::create_function(option::get(fcx)); } 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 2b45285a4ef06..af709ec5420e0 100644 --- a/src/comp/middle/trans_build.rs +++ b/src/comp/middle/trans_build.rs @@ -25,16 +25,14 @@ fn RetVoid(cx: @block_ctxt) { if cx.unreachable { ret; } assert (!cx.terminated); cx.terminated = true; - let instr = llvm::LLVMBuildRetVoid(B(cx)); - debuginfo::add_line_info(cx, instr); + llvm::LLVMBuildRetVoid(B(cx)); } fn Ret(cx: @block_ctxt, V: ValueRef) { if cx.unreachable { ret; } assert (!cx.terminated); cx.terminated = true; - let instr = llvm::LLVMBuildRet(B(cx), V); - debuginfo::add_line_info(cx, instr); + llvm::LLVMBuildRet(B(cx), V); } fn AggregateRet(cx: @block_ctxt, RetVals: [ValueRef]) { @@ -42,9 +40,8 @@ fn AggregateRet(cx: @block_ctxt, RetVals: [ValueRef]) { assert (!cx.terminated); cx.terminated = true; unsafe { - let instr = llvm::LLVMBuildAggregateRet(B(cx), vec::to_ptr(RetVals), - vec::len(RetVals)); - debuginfo::add_line_info(cx, instr); + llvm::LLVMBuildAggregateRet(B(cx), vec::to_ptr(RetVals), + vec::len(RetVals)); } } @@ -52,8 +49,7 @@ fn Br(cx: @block_ctxt, Dest: BasicBlockRef) { if cx.unreachable { ret; } assert (!cx.terminated); cx.terminated = true; - let instr = llvm::LLVMBuildBr(B(cx), Dest); - debuginfo::add_line_info(cx, instr); + llvm::LLVMBuildBr(B(cx), Dest); } fn CondBr(cx: @block_ctxt, If: ValueRef, Then: BasicBlockRef, @@ -61,8 +57,7 @@ fn CondBr(cx: @block_ctxt, If: ValueRef, Then: BasicBlockRef, if cx.unreachable { ret; } assert (!cx.terminated); cx.terminated = true; - let instr = llvm::LLVMBuildCondBr(B(cx), If, Then, Else); - debuginfo::add_line_info(cx, instr); + llvm::LLVMBuildCondBr(B(cx), If, Then, Else); } fn Switch(cx: @block_ctxt, V: ValueRef, Else: BasicBlockRef, NumCases: uint) @@ -70,9 +65,7 @@ fn Switch(cx: @block_ctxt, V: ValueRef, Else: BasicBlockRef, NumCases: uint) if cx.unreachable { ret _Undef(V); } assert !cx.terminated; cx.terminated = true; - let instr = llvm::LLVMBuildSwitch(B(cx), V, Else, NumCases); - debuginfo::add_line_info(cx, instr); - ret instr; + ret llvm::LLVMBuildSwitch(B(cx), V, Else, NumCases); } fn AddCase(S: ValueRef, OnVal: ValueRef, Dest: BasicBlockRef) { @@ -84,8 +77,7 @@ fn IndirectBr(cx: @block_ctxt, Addr: ValueRef, NumDests: uint) { if cx.unreachable { ret; } assert (!cx.terminated); cx.terminated = true; - let instr = llvm::LLVMBuildIndirectBr(B(cx), Addr, NumDests); - debuginfo::add_line_info(cx, instr); + llvm::LLVMBuildIndirectBr(B(cx), Addr, NumDests); } // This is a really awful way to get a zero-length c-string, but better (and a @@ -105,14 +97,10 @@ fn Invoke(cx: @block_ctxt, Fn: ValueRef, Args: [ValueRef], 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); } } @@ -125,7 +113,6 @@ fn FastInvoke(cx: @block_ctxt, Fn: ValueRef, Args: [ValueRef], let v = llvm::LLVMBuildInvoke(B(cx), Fn, vec::to_ptr(Args), vec::len(Args), Then, Catch, noname()); llvm::LLVMSetInstructionCallConv(v, lib::llvm::LLVMFastCallConv); - debuginfo::add_line_info(cx, v); } } @@ -142,254 +129,183 @@ fn _Undef(val: ValueRef) -> ValueRef { /* Arithmetic */ fn Add(cx: @block_ctxt, LHS: ValueRef, RHS: ValueRef) -> ValueRef { if cx.unreachable { ret _Undef(LHS); } - let instr = llvm::LLVMBuildAdd(B(cx), LHS, RHS, noname()); - debuginfo::add_line_info(cx, instr); - ret instr; + ret llvm::LLVMBuildAdd(B(cx), LHS, RHS, noname()); } fn NSWAdd(cx: @block_ctxt, LHS: ValueRef, RHS: ValueRef) -> ValueRef { if cx.unreachable { ret _Undef(LHS); } - let instr = llvm::LLVMBuildNSWAdd(B(cx), LHS, RHS, noname()); - debuginfo::add_line_info(cx, instr); - ret instr; + ret llvm::LLVMBuildNSWAdd(B(cx), LHS, RHS, noname()); } fn NUWAdd(cx: @block_ctxt, LHS: ValueRef, RHS: ValueRef) -> ValueRef { if cx.unreachable { ret _Undef(LHS); } - let instr = llvm::LLVMBuildNUWAdd(B(cx), LHS, RHS, noname()); - debuginfo::add_line_info(cx, instr); - ret instr; + ret llvm::LLVMBuildNUWAdd(B(cx), LHS, RHS, noname()); } fn FAdd(cx: @block_ctxt, LHS: ValueRef, RHS: ValueRef) -> ValueRef { if cx.unreachable { ret _Undef(LHS); } - let instr = llvm::LLVMBuildFAdd(B(cx), LHS, RHS, noname()); - debuginfo::add_line_info(cx, instr); - ret instr; + ret llvm::LLVMBuildFAdd(B(cx), LHS, RHS, noname()); } fn Sub(cx: @block_ctxt, LHS: ValueRef, RHS: ValueRef) -> ValueRef { if cx.unreachable { ret _Undef(LHS); } - let instr = llvm::LLVMBuildSub(B(cx), LHS, RHS, noname()); - debuginfo::add_line_info(cx, instr); - ret instr; + ret llvm::LLVMBuildSub(B(cx), LHS, RHS, noname()); } fn NSWSub(cx: @block_ctxt, LHS: ValueRef, RHS: ValueRef) -> ValueRef { if cx.unreachable { ret _Undef(LHS); } - let instr = llvm::LLVMBuildNSWSub(B(cx), LHS, RHS, noname()); - debuginfo::add_line_info(cx, instr); - ret instr; + ret llvm::LLVMBuildNSWSub(B(cx), LHS, RHS, noname()); } fn NUWSub(cx: @block_ctxt, LHS: ValueRef, RHS: ValueRef) -> ValueRef { if cx.unreachable { ret _Undef(LHS); } - let instr = llvm::LLVMBuildNUWSub(B(cx), LHS, RHS, noname()); - debuginfo::add_line_info(cx, instr); - ret instr; + ret llvm::LLVMBuildNUWSub(B(cx), LHS, RHS, noname()); } fn FSub(cx: @block_ctxt, LHS: ValueRef, RHS: ValueRef) -> ValueRef { if cx.unreachable { ret _Undef(LHS); } - let instr = llvm::LLVMBuildFSub(B(cx), LHS, RHS, noname()); - debuginfo::add_line_info(cx, instr); - ret instr; + ret llvm::LLVMBuildFSub(B(cx), LHS, RHS, noname()); } fn Mul(cx: @block_ctxt, LHS: ValueRef, RHS: ValueRef) -> ValueRef { if cx.unreachable { ret _Undef(LHS); } - let instr = llvm::LLVMBuildMul(B(cx), LHS, RHS, noname()); - debuginfo::add_line_info(cx, instr); - ret instr; + ret llvm::LLVMBuildMul(B(cx), LHS, RHS, noname()); } fn NSWMul(cx: @block_ctxt, LHS: ValueRef, RHS: ValueRef) -> ValueRef { if cx.unreachable { ret _Undef(LHS); } - let instr = llvm::LLVMBuildNSWMul(B(cx), LHS, RHS, noname()); - debuginfo::add_line_info(cx, instr); - ret instr; + ret llvm::LLVMBuildNSWMul(B(cx), LHS, RHS, noname()); } fn NUWMul(cx: @block_ctxt, LHS: ValueRef, RHS: ValueRef) -> ValueRef { if cx.unreachable { ret _Undef(LHS); } - let instr = llvm::LLVMBuildNUWMul(B(cx), LHS, RHS, noname()); - debuginfo::add_line_info(cx, instr); - ret instr; + ret llvm::LLVMBuildNUWMul(B(cx), LHS, RHS, noname()); } fn FMul(cx: @block_ctxt, LHS: ValueRef, RHS: ValueRef) -> ValueRef { if cx.unreachable { ret _Undef(LHS); } - let instr = llvm::LLVMBuildFMul(B(cx), LHS, RHS, noname()); - debuginfo::add_line_info(cx, instr); - ret instr; + ret llvm::LLVMBuildFMul(B(cx), LHS, RHS, noname()); } fn UDiv(cx: @block_ctxt, LHS: ValueRef, RHS: ValueRef) -> ValueRef { if cx.unreachable { ret _Undef(LHS); } - let instr = llvm::LLVMBuildUDiv(B(cx), LHS, RHS, noname()); - debuginfo::add_line_info(cx, instr); - ret instr; + ret llvm::LLVMBuildUDiv(B(cx), LHS, RHS, noname()); } fn SDiv(cx: @block_ctxt, LHS: ValueRef, RHS: ValueRef) -> ValueRef { if cx.unreachable { ret _Undef(LHS); } - let instr = llvm::LLVMBuildSDiv(B(cx), LHS, RHS, noname()); - debuginfo::add_line_info(cx, instr); - ret instr; + ret llvm::LLVMBuildSDiv(B(cx), LHS, RHS, noname()); } fn ExactSDiv(cx: @block_ctxt, LHS: ValueRef, RHS: ValueRef) -> ValueRef { if cx.unreachable { ret _Undef(LHS); } - let instr = llvm::LLVMBuildExactSDiv(B(cx), LHS, RHS, noname()); - debuginfo::add_line_info(cx, instr); - ret instr; + ret llvm::LLVMBuildExactSDiv(B(cx), LHS, RHS, noname()); } fn FDiv(cx: @block_ctxt, LHS: ValueRef, RHS: ValueRef) -> ValueRef { if cx.unreachable { ret _Undef(LHS); } - let instr = llvm::LLVMBuildFDiv(B(cx), LHS, RHS, noname()); - debuginfo::add_line_info(cx, instr); - ret instr; + ret llvm::LLVMBuildFDiv(B(cx), LHS, RHS, noname()); } fn URem(cx: @block_ctxt, LHS: ValueRef, RHS: ValueRef) -> ValueRef { if cx.unreachable { ret _Undef(LHS); } - let instr = llvm::LLVMBuildURem(B(cx), LHS, RHS, noname()); - debuginfo::add_line_info(cx, instr); - ret instr; + ret llvm::LLVMBuildURem(B(cx), LHS, RHS, noname()); } fn SRem(cx: @block_ctxt, LHS: ValueRef, RHS: ValueRef) -> ValueRef { if cx.unreachable { ret _Undef(LHS); } - let instr = llvm::LLVMBuildSRem(B(cx), LHS, RHS, noname()); - debuginfo::add_line_info(cx, instr); - ret instr; + ret llvm::LLVMBuildSRem(B(cx), LHS, RHS, noname()); } fn FRem(cx: @block_ctxt, LHS: ValueRef, RHS: ValueRef) -> ValueRef { if cx.unreachable { ret _Undef(LHS); } - let instr = llvm::LLVMBuildFRem(B(cx), LHS, RHS, noname()); - debuginfo::add_line_info(cx, instr); - ret instr; + ret llvm::LLVMBuildFRem(B(cx), LHS, RHS, noname()); } fn Shl(cx: @block_ctxt, LHS: ValueRef, RHS: ValueRef) -> ValueRef { if cx.unreachable { ret _Undef(LHS); } - let instr = llvm::LLVMBuildShl(B(cx), LHS, RHS, noname()); - debuginfo::add_line_info(cx, instr); - ret instr; + ret llvm::LLVMBuildShl(B(cx), LHS, RHS, noname()); } fn LShr(cx: @block_ctxt, LHS: ValueRef, RHS: ValueRef) -> ValueRef { if cx.unreachable { ret _Undef(LHS); } - let instr = llvm::LLVMBuildLShr(B(cx), LHS, RHS, noname()); - debuginfo::add_line_info(cx, instr); - ret instr; + ret llvm::LLVMBuildLShr(B(cx), LHS, RHS, noname()); } fn AShr(cx: @block_ctxt, LHS: ValueRef, RHS: ValueRef) -> ValueRef { if cx.unreachable { ret _Undef(LHS); } - let instr = llvm::LLVMBuildAShr(B(cx), LHS, RHS, noname()); - debuginfo::add_line_info(cx, instr); - ret instr; + ret llvm::LLVMBuildAShr(B(cx), LHS, RHS, noname()); } fn And(cx: @block_ctxt, LHS: ValueRef, RHS: ValueRef) -> ValueRef { if cx.unreachable { ret _Undef(LHS); } - let instr = llvm::LLVMBuildAnd(B(cx), LHS, RHS, noname()); - debuginfo::add_line_info(cx, instr); - ret instr; + ret llvm::LLVMBuildAnd(B(cx), LHS, RHS, noname()); } fn Or(cx: @block_ctxt, LHS: ValueRef, RHS: ValueRef) -> ValueRef { if cx.unreachable { ret _Undef(LHS); } - let instr = llvm::LLVMBuildOr(B(cx), LHS, RHS, noname()); - debuginfo::add_line_info(cx, instr); - ret instr; + ret llvm::LLVMBuildOr(B(cx), LHS, RHS, noname()); } fn Xor(cx: @block_ctxt, LHS: ValueRef, RHS: ValueRef) -> ValueRef { if cx.unreachable { ret _Undef(LHS); } - let instr = llvm::LLVMBuildXor(B(cx), LHS, RHS, noname()); - debuginfo::add_line_info(cx, instr); - ret instr; + ret llvm::LLVMBuildXor(B(cx), LHS, RHS, noname()); } fn BinOp(cx: @block_ctxt, Op: Opcode, LHS: ValueRef, RHS: ValueRef) -> ValueRef { if cx.unreachable { ret _Undef(LHS); } - let instr = llvm::LLVMBuildBinOp(B(cx), Op, LHS, RHS, noname()); - debuginfo::add_line_info(cx, instr); - ret instr; + ret llvm::LLVMBuildBinOp(B(cx), Op, LHS, RHS, noname()); } fn Neg(cx: @block_ctxt, V: ValueRef) -> ValueRef { if cx.unreachable { ret _Undef(V); } - let instr = llvm::LLVMBuildNeg(B(cx), V, noname()); - debuginfo::add_line_info(cx, instr); - ret instr; + ret llvm::LLVMBuildNeg(B(cx), V, noname()); } fn NSWNeg(cx: @block_ctxt, V: ValueRef) -> ValueRef { if cx.unreachable { ret _Undef(V); } - let instr = llvm::LLVMBuildNSWNeg(B(cx), V, noname()); - debuginfo::add_line_info(cx, instr); - ret instr; + ret llvm::LLVMBuildNSWNeg(B(cx), V, noname()); } fn NUWNeg(cx: @block_ctxt, V: ValueRef) -> ValueRef { if cx.unreachable { ret _Undef(V); } - let instr = llvm::LLVMBuildNUWNeg(B(cx), V, noname()); - debuginfo::add_line_info(cx, instr); - ret instr; + ret llvm::LLVMBuildNUWNeg(B(cx), V, noname()); } fn FNeg(cx: @block_ctxt, V: ValueRef) -> ValueRef { if cx.unreachable { ret _Undef(V); } - let instr = llvm::LLVMBuildFNeg(B(cx), V, noname()); - debuginfo::add_line_info(cx, instr); - ret instr; + ret llvm::LLVMBuildFNeg(B(cx), V, noname()); } fn Not(cx: @block_ctxt, V: ValueRef) -> ValueRef { if cx.unreachable { ret _Undef(V); } - let instr = llvm::LLVMBuildNot(B(cx), V, noname()); - debuginfo::add_line_info(cx, instr); - ret instr; + ret llvm::LLVMBuildNot(B(cx), V, noname()); } /* Memory */ fn Malloc(cx: @block_ctxt, Ty: TypeRef) -> ValueRef { if cx.unreachable { ret llvm::LLVMGetUndef(T_ptr(T_i8())); } - let instr = llvm::LLVMBuildMalloc(B(cx), Ty, noname()); - debuginfo::add_line_info(cx, instr); - ret instr; + ret llvm::LLVMBuildMalloc(B(cx), Ty, noname()); } fn ArrayMalloc(cx: @block_ctxt, Ty: TypeRef, Val: ValueRef) -> ValueRef { if cx.unreachable { ret llvm::LLVMGetUndef(T_ptr(T_i8())); } - let instr = llvm::LLVMBuildArrayMalloc(B(cx), Ty, Val, noname()); - debuginfo::add_line_info(cx, instr); - ret instr; + ret llvm::LLVMBuildArrayMalloc(B(cx), Ty, Val, noname()); } fn Alloca(cx: @block_ctxt, Ty: TypeRef) -> ValueRef { if cx.unreachable { ret llvm::LLVMGetUndef(T_ptr(Ty)); } - let instr = llvm::LLVMBuildAlloca(B(cx), Ty, noname()); - debuginfo::add_line_info(cx, instr); - ret instr; + ret llvm::LLVMBuildAlloca(B(cx), Ty, noname()); } fn ArrayAlloca(cx: @block_ctxt, Ty: TypeRef, Val: ValueRef) -> ValueRef { if cx.unreachable { ret llvm::LLVMGetUndef(T_ptr(Ty)); } - let instr = llvm::LLVMBuildArrayAlloca(B(cx), Ty, Val, noname()); - debuginfo::add_line_info(cx, instr); - ret instr; + ret llvm::LLVMBuildArrayAlloca(B(cx), Ty, Val, noname()); } fn Free(cx: @block_ctxt, PointerVal: ValueRef) { if cx.unreachable { ret; } - let instr = llvm::LLVMBuildFree(B(cx), PointerVal); - debuginfo::add_line_info(cx, instr); + llvm::LLVMBuildFree(B(cx), PointerVal); } fn Load(cx: @block_ctxt, PointerVal: ValueRef) -> ValueRef { @@ -400,24 +316,19 @@ fn Load(cx: @block_ctxt, PointerVal: ValueRef) -> ValueRef { llvm::LLVMGetElementType(ty) } else { ccx.int_type }; ret llvm::LLVMGetUndef(eltty); } - let instr = llvm::LLVMBuildLoad(B(cx), PointerVal, noname()); - debuginfo::add_line_info(cx, instr); - ret instr; + ret llvm::LLVMBuildLoad(B(cx), PointerVal, noname()); } fn Store(cx: @block_ctxt, Val: ValueRef, Ptr: ValueRef) { if cx.unreachable { ret; } - let instr = llvm::LLVMBuildStore(B(cx), Val, Ptr); - debuginfo::add_line_info(cx, instr); + llvm::LLVMBuildStore(B(cx), Val, Ptr); } fn GEP(cx: @block_ctxt, Pointer: ValueRef, Indices: [ValueRef]) -> ValueRef { if cx.unreachable { ret llvm::LLVMGetUndef(T_ptr(T_nil())); } unsafe { - let instr = llvm::LLVMBuildGEP(B(cx), Pointer, vec::to_ptr(Indices), - vec::len(Indices), noname()); - //debuginfo::add_line_info(cx, instr); - ret instr; + ret llvm::LLVMBuildGEP(B(cx), Pointer, vec::to_ptr(Indices), + vec::len(Indices), noname()); } } @@ -433,195 +344,143 @@ fn InBoundsGEP(cx: @block_ctxt, Pointer: ValueRef, Indices: [ValueRef]) -> ValueRef { if cx.unreachable { ret llvm::LLVMGetUndef(T_ptr(T_nil())); } unsafe { - let instr = llvm::LLVMBuildInBoundsGEP(B(cx), Pointer, - vec::to_ptr(Indices), - vec::len(Indices), noname()); - //debuginfo::add_line_info(cx, instr); - ret instr; + ret llvm::LLVMBuildInBoundsGEP(B(cx), Pointer, + vec::to_ptr(Indices), + vec::len(Indices), noname()); } } fn StructGEP(cx: @block_ctxt, Pointer: ValueRef, Idx: uint) -> ValueRef { if cx.unreachable { ret llvm::LLVMGetUndef(T_ptr(T_nil())); } - let instr = llvm::LLVMBuildStructGEP(B(cx), Pointer, Idx, noname()); - //debuginfo::add_line_info(cx, instr); - ret instr; + ret llvm::LLVMBuildStructGEP(B(cx), Pointer, Idx, noname()); } fn GlobalString(cx: @block_ctxt, _Str: sbuf) -> ValueRef { if cx.unreachable { ret llvm::LLVMGetUndef(T_ptr(T_i8())); } - let instr = llvm::LLVMBuildGlobalString(B(cx), _Str, noname()); - debuginfo::add_line_info(cx, instr); - ret instr; + ret llvm::LLVMBuildGlobalString(B(cx), _Str, noname()); } fn GlobalStringPtr(cx: @block_ctxt, _Str: sbuf) -> ValueRef { if cx.unreachable { ret llvm::LLVMGetUndef(T_ptr(T_i8())); } - let instr = llvm::LLVMBuildGlobalStringPtr(B(cx), _Str, noname()); - debuginfo::add_line_info(cx, instr); - ret instr; + ret llvm::LLVMBuildGlobalStringPtr(B(cx), _Str, noname()); } /* Casts */ fn Trunc(cx: @block_ctxt, Val: ValueRef, DestTy: TypeRef) -> ValueRef { if cx.unreachable { ret llvm::LLVMGetUndef(DestTy); } - let instr = llvm::LLVMBuildTrunc(B(cx), Val, DestTy, noname()); - //debuginfo::add_line_info(cx, instr); - ret instr; + ret llvm::LLVMBuildTrunc(B(cx), Val, DestTy, noname()); } fn ZExt(cx: @block_ctxt, Val: ValueRef, DestTy: TypeRef) -> ValueRef { if cx.unreachable { ret llvm::LLVMGetUndef(DestTy); } - let instr = llvm::LLVMBuildZExt(B(cx), Val, DestTy, noname()); - //debuginfo::add_line_info(cx, instr); - ret instr; + ret llvm::LLVMBuildZExt(B(cx), Val, DestTy, noname()); } fn SExt(cx: @block_ctxt, Val: ValueRef, DestTy: TypeRef) -> ValueRef { if cx.unreachable { ret llvm::LLVMGetUndef(DestTy); } - let instr = llvm::LLVMBuildSExt(B(cx), Val, DestTy, noname()); - //debuginfo::add_line_info(cx, instr); - ret instr; + ret llvm::LLVMBuildSExt(B(cx), Val, DestTy, noname()); } fn FPToUI(cx: @block_ctxt, Val: ValueRef, DestTy: TypeRef) -> ValueRef { if cx.unreachable { ret llvm::LLVMGetUndef(DestTy); } - let instr = llvm::LLVMBuildFPToUI(B(cx), Val, DestTy, noname()); - //debuginfo::add_line_info(cx, instr); - ret instr; + ret llvm::LLVMBuildFPToUI(B(cx), Val, DestTy, noname()); } fn FPToSI(cx: @block_ctxt, Val: ValueRef, DestTy: TypeRef) -> ValueRef { if cx.unreachable { ret llvm::LLVMGetUndef(DestTy); } - let instr = llvm::LLVMBuildFPToSI(B(cx), Val, DestTy, noname()); - //debuginfo::add_line_info(cx, instr); - ret instr; + ret llvm::LLVMBuildFPToSI(B(cx), Val, DestTy, noname()); } fn UIToFP(cx: @block_ctxt, Val: ValueRef, DestTy: TypeRef) -> ValueRef { if cx.unreachable { ret llvm::LLVMGetUndef(DestTy); } - let instr = llvm::LLVMBuildUIToFP(B(cx), Val, DestTy, noname()); - //debuginfo::add_line_info(cx, instr); - ret instr; + ret llvm::LLVMBuildUIToFP(B(cx), Val, DestTy, noname()); } fn SIToFP(cx: @block_ctxt, Val: ValueRef, DestTy: TypeRef) -> ValueRef { if cx.unreachable { ret llvm::LLVMGetUndef(DestTy); } - let instr = llvm::LLVMBuildSIToFP(B(cx), Val, DestTy, noname()); - //debuginfo::add_line_info(cx, instr); - ret instr; + ret llvm::LLVMBuildSIToFP(B(cx), Val, DestTy, noname()); } fn FPTrunc(cx: @block_ctxt, Val: ValueRef, DestTy: TypeRef) -> ValueRef { if cx.unreachable { ret llvm::LLVMGetUndef(DestTy); } - let instr = llvm::LLVMBuildFPTrunc(B(cx), Val, DestTy, noname()); - //debuginfo::add_line_info(cx, instr); - ret instr; + ret llvm::LLVMBuildFPTrunc(B(cx), Val, DestTy, noname()); } fn FPExt(cx: @block_ctxt, Val: ValueRef, DestTy: TypeRef) -> ValueRef { if cx.unreachable { ret llvm::LLVMGetUndef(DestTy); } - let instr = llvm::LLVMBuildFPExt(B(cx), Val, DestTy, noname()); - //debuginfo::add_line_info(cx, instr); - ret instr; + ret llvm::LLVMBuildFPExt(B(cx), Val, DestTy, noname()); } fn PtrToInt(cx: @block_ctxt, Val: ValueRef, DestTy: TypeRef) -> ValueRef { if cx.unreachable { ret llvm::LLVMGetUndef(DestTy); } - let instr = llvm::LLVMBuildPtrToInt(B(cx), Val, DestTy, noname()); - //debuginfo::add_line_info(cx, instr); - ret instr; + ret llvm::LLVMBuildPtrToInt(B(cx), Val, DestTy, noname()); } fn IntToPtr(cx: @block_ctxt, Val: ValueRef, DestTy: TypeRef) -> ValueRef { if cx.unreachable { ret llvm::LLVMGetUndef(DestTy); } - let instr = llvm::LLVMBuildIntToPtr(B(cx), Val, DestTy, noname()); - //debuginfo::add_line_info(cx, instr); - ret instr; + ret llvm::LLVMBuildIntToPtr(B(cx), Val, DestTy, noname()); } fn BitCast(cx: @block_ctxt, Val: ValueRef, DestTy: TypeRef) -> ValueRef { if cx.unreachable { ret llvm::LLVMGetUndef(DestTy); } - let instr = llvm::LLVMBuildBitCast(B(cx), Val, DestTy, noname()); - //debuginfo::add_line_info(cx, instr); - ret instr; + ret llvm::LLVMBuildBitCast(B(cx), Val, DestTy, noname()); } fn ZExtOrBitCast(cx: @block_ctxt, Val: ValueRef, DestTy: TypeRef) -> ValueRef { if cx.unreachable { ret llvm::LLVMGetUndef(DestTy); } - let instr = llvm::LLVMBuildZExtOrBitCast(B(cx), Val, DestTy, noname()); - //debuginfo::add_line_info(cx, instr); - ret instr; + ret llvm::LLVMBuildZExtOrBitCast(B(cx), Val, DestTy, noname()); } fn SExtOrBitCast(cx: @block_ctxt, Val: ValueRef, DestTy: TypeRef) -> ValueRef { if cx.unreachable { ret llvm::LLVMGetUndef(DestTy); } - let instr = llvm::LLVMBuildSExtOrBitCast(B(cx), Val, DestTy, noname()); - //debuginfo::add_line_info(cx, instr); - ret instr; + ret llvm::LLVMBuildSExtOrBitCast(B(cx), Val, DestTy, noname()); } fn TruncOrBitCast(cx: @block_ctxt, Val: ValueRef, DestTy: TypeRef) -> ValueRef { if cx.unreachable { ret llvm::LLVMGetUndef(DestTy); } - let instr = llvm::LLVMBuildTruncOrBitCast(B(cx), Val, DestTy, noname()); - //debuginfo::add_line_info(cx, instr); - ret instr; + ret llvm::LLVMBuildTruncOrBitCast(B(cx), Val, DestTy, noname()); } fn Cast(cx: @block_ctxt, Op: Opcode, Val: ValueRef, DestTy: TypeRef, _Name: sbuf) -> ValueRef { if cx.unreachable { ret llvm::LLVMGetUndef(DestTy); } - let instr = llvm::LLVMBuildCast(B(cx), Op, Val, DestTy, noname()); - //debuginfo::add_line_info(cx, instr); - ret instr; + ret llvm::LLVMBuildCast(B(cx), Op, Val, DestTy, noname()); } fn PointerCast(cx: @block_ctxt, Val: ValueRef, DestTy: TypeRef) -> ValueRef { if cx.unreachable { ret llvm::LLVMGetUndef(DestTy); } - let instr = llvm::LLVMBuildPointerCast(B(cx), Val, DestTy, noname()); - //debuginfo::add_line_info(cx, instr); - ret instr; + ret llvm::LLVMBuildPointerCast(B(cx), Val, DestTy, noname()); } fn IntCast(cx: @block_ctxt, Val: ValueRef, DestTy: TypeRef) -> ValueRef { if cx.unreachable { ret llvm::LLVMGetUndef(DestTy); } - let instr = llvm::LLVMBuildIntCast(B(cx), Val, DestTy, noname()); - //debuginfo::add_line_info(cx, instr); - ret instr; + ret llvm::LLVMBuildIntCast(B(cx), Val, DestTy, noname()); } fn FPCast(cx: @block_ctxt, Val: ValueRef, DestTy: TypeRef) -> ValueRef { if cx.unreachable { ret llvm::LLVMGetUndef(DestTy); } - let instr = llvm::LLVMBuildFPCast(B(cx), Val, DestTy, noname()); - //debuginfo::add_line_info(cx, instr); - ret instr; + ret llvm::LLVMBuildFPCast(B(cx), Val, DestTy, noname()); } /* Comparisons */ fn ICmp(cx: @block_ctxt, Op: uint, LHS: ValueRef, RHS: ValueRef) -> ValueRef { if cx.unreachable { ret llvm::LLVMGetUndef(T_i1()); } - let instr = llvm::LLVMBuildICmp(B(cx), Op, LHS, RHS, noname()); - debuginfo::add_line_info(cx, instr); - ret instr; + ret llvm::LLVMBuildICmp(B(cx), Op, LHS, RHS, noname()); } fn FCmp(cx: @block_ctxt, Op: uint, LHS: ValueRef, RHS: ValueRef) -> ValueRef { if cx.unreachable { ret llvm::LLVMGetUndef(T_i1()); } - let instr = llvm::LLVMBuildFCmp(B(cx), Op, LHS, RHS, noname()); - debuginfo::add_line_info(cx, instr); - ret instr; + ret llvm::LLVMBuildFCmp(B(cx), Op, LHS, RHS, noname()); } /* Miscellaneous instructions */ fn EmptyPhi(cx: @block_ctxt, Ty: TypeRef) -> ValueRef { if cx.unreachable { ret llvm::LLVMGetUndef(Ty); } - let instr = llvm::LLVMBuildPhi(B(cx), Ty, noname()); - debuginfo::add_line_info(cx, instr); - ret instr; + ret llvm::LLVMBuildPhi(B(cx), Ty, noname()); } fn Phi(cx: @block_ctxt, Ty: TypeRef, vals: [ValueRef], bbs: [BasicBlockRef]) @@ -656,7 +515,9 @@ fn _UndefReturn(cx: @block_ctxt, Fn: ValueRef) -> ValueRef { fn add_span_comment(bcx: @block_ctxt, sp: span, text: str) { let ccx = bcx_ccx(bcx); if (!ccx.sess.get_opts().no_asm_comments) { - add_comment(bcx, text + " (" + ccx.sess.span_str(sp) + ")"); + let s = text + " (" + ccx.sess.span_str(sp) + ")"; + log s; + add_comment(bcx, s); } } @@ -676,10 +537,8 @@ fn add_comment(bcx: @block_ctxt, text: str) { fn Call(cx: @block_ctxt, Fn: ValueRef, Args: [ValueRef]) -> ValueRef { if cx.unreachable { ret _UndefReturn(cx, Fn); } unsafe { - let instr = llvm::LLVMBuildCall(B(cx), Fn, vec::to_ptr(Args), - vec::len(Args), noname()); - debuginfo::add_line_info(cx, instr); - ret instr; + ret llvm::LLVMBuildCall(B(cx), Fn, vec::to_ptr(Args), + vec::len(Args), noname()); } } @@ -689,7 +548,6 @@ fn FastCall(cx: @block_ctxt, Fn: ValueRef, Args: [ValueRef]) -> ValueRef { let v = llvm::LLVMBuildCall(B(cx), Fn, vec::to_ptr(Args), vec::len(Args), noname()); llvm::LLVMSetInstructionCallConv(v, lib::llvm::LLVMFastCallConv); - debuginfo::add_line_info(cx, v); ret v; } } @@ -701,7 +559,6 @@ fn CallWithConv(cx: @block_ctxt, Fn: ValueRef, Args: [ValueRef], Conv: uint) let v = llvm::LLVMBuildCall(B(cx), Fn, vec::to_ptr(Args), vec::len(Args), noname()); llvm::LLVMSetInstructionCallConv(v, Conv); - debuginfo::add_line_info(cx, v); ret v; } } @@ -709,76 +566,57 @@ fn CallWithConv(cx: @block_ctxt, Fn: ValueRef, Args: [ValueRef], Conv: uint) fn Select(cx: @block_ctxt, If: ValueRef, Then: ValueRef, Else: ValueRef) -> ValueRef { if cx.unreachable { ret _Undef(Then); } - let instr = llvm::LLVMBuildSelect(B(cx), If, Then, Else, noname()); - debuginfo::add_line_info(cx, instr); - ret instr; + ret llvm::LLVMBuildSelect(B(cx), If, Then, Else, noname()); } fn VAArg(cx: @block_ctxt, list: ValueRef, Ty: TypeRef) -> ValueRef { if cx.unreachable { ret llvm::LLVMGetUndef(Ty); } - let instr = llvm::LLVMBuildVAArg(B(cx), list, Ty, noname()); - debuginfo::add_line_info(cx, instr); - ret instr; + ret llvm::LLVMBuildVAArg(B(cx), list, Ty, noname()); } fn ExtractElement(cx: @block_ctxt, VecVal: ValueRef, Index: ValueRef) -> ValueRef { if cx.unreachable { ret llvm::LLVMGetUndef(T_nil()); } - let instr = llvm::LLVMBuildExtractElement(B(cx), VecVal, Index, noname()); - debuginfo::add_line_info(cx, instr); - ret instr; + ret llvm::LLVMBuildExtractElement(B(cx), VecVal, Index, noname()); } fn InsertElement(cx: @block_ctxt, VecVal: ValueRef, EltVal: ValueRef, Index: ValueRef) { if cx.unreachable { ret; } - let instr = llvm::LLVMBuildInsertElement(B(cx), VecVal, EltVal, Index, - noname()); - debuginfo::add_line_info(cx, instr); + llvm::LLVMBuildInsertElement(B(cx), VecVal, EltVal, Index, noname()); } fn ShuffleVector(cx: @block_ctxt, V1: ValueRef, V2: ValueRef, Mask: ValueRef) { if cx.unreachable { ret; } - let instr = llvm::LLVMBuildShuffleVector(B(cx), V1, V2, Mask, noname()); - debuginfo::add_line_info(cx, instr); + llvm::LLVMBuildShuffleVector(B(cx), V1, V2, Mask, noname()); } fn ExtractValue(cx: @block_ctxt, AggVal: ValueRef, Index: uint) -> ValueRef { if cx.unreachable { ret llvm::LLVMGetUndef(T_nil()); } - let instr = llvm::LLVMBuildExtractValue(B(cx), AggVal, Index, noname()); - debuginfo::add_line_info(cx, instr); - ret instr; + ret llvm::LLVMBuildExtractValue(B(cx), AggVal, Index, noname()); } fn InsertValue(cx: @block_ctxt, AggVal: ValueRef, EltVal: ValueRef, Index: uint) { if cx.unreachable { ret; } - let instr = llvm::LLVMBuildInsertValue(B(cx), AggVal, EltVal, Index, - noname()); - debuginfo::add_line_info(cx, instr); + llvm::LLVMBuildInsertValue(B(cx), AggVal, EltVal, Index, noname()); } fn IsNull(cx: @block_ctxt, Val: ValueRef) -> ValueRef { if cx.unreachable { ret llvm::LLVMGetUndef(T_i1()); } - let instr = llvm::LLVMBuildIsNull(B(cx), Val, noname()); - debuginfo::add_line_info(cx, instr); - ret instr; + ret llvm::LLVMBuildIsNull(B(cx), Val, noname()); } fn IsNotNull(cx: @block_ctxt, Val: ValueRef) -> ValueRef { if cx.unreachable { ret llvm::LLVMGetUndef(T_i1()); } - let instr = llvm::LLVMBuildIsNotNull(B(cx), Val, noname()); - debuginfo::add_line_info(cx, instr); - ret instr; + ret llvm::LLVMBuildIsNotNull(B(cx), Val, noname()); } fn PtrDiff(cx: @block_ctxt, LHS: ValueRef, RHS: ValueRef) -> ValueRef { let ccx = cx.fcx.lcx.ccx; if cx.unreachable { ret llvm::LLVMGetUndef(ccx.int_type); } - let instr = llvm::LLVMBuildPtrDiff(B(cx), LHS, RHS, noname()); - debuginfo::add_line_info(cx, instr); - ret instr; + ret llvm::LLVMBuildPtrDiff(B(cx), LHS, RHS, noname()); } fn Trap(cx: @block_ctxt) { @@ -793,19 +631,14 @@ fn Trap(cx: @block_ctxt) { assert (T as int != 0); let Args: [ValueRef] = []; unsafe { - let instr = llvm::LLVMBuildCall(b, T, vec::to_ptr(Args), - vec::len(Args), noname()); - debuginfo::add_line_info(cx, instr); + llvm::LLVMBuildCall(b, T, vec::to_ptr(Args), vec::len(Args), noname()); } } fn LandingPad(cx: @block_ctxt, Ty: TypeRef, PersFn: ValueRef, NumClauses: uint) -> ValueRef { assert !cx.terminated && !cx.unreachable; - let instr = llvm::LLVMBuildLandingPad(B(cx), Ty, PersFn, NumClauses, - noname()); - debuginfo::add_line_info(cx, instr); - ret instr; + ret llvm::LLVMBuildLandingPad(B(cx), Ty, PersFn, NumClauses, noname()); } fn SetCleanup(_cx: @block_ctxt, LandingPad: ValueRef) { @@ -815,9 +648,7 @@ fn SetCleanup(_cx: @block_ctxt, LandingPad: ValueRef) { fn Resume(cx: @block_ctxt, Exn: ValueRef) -> ValueRef { assert (!cx.terminated); cx.terminated = true; - let instr = llvm::LLVMBuildResume(B(cx), Exn); - debuginfo::add_line_info(cx, instr); - ret instr; + ret llvm::LLVMBuildResume(B(cx), Exn); } // diff --git a/src/comp/middle/trans_common.rs b/src/comp/middle/trans_common.rs index c7333ef74115a..f30184124b050 100644 --- a/src/comp/middle/trans_common.rs +++ b/src/comp/middle/trans_common.rs @@ -385,9 +385,7 @@ type block_ctxt = mutable lpad_dirty: bool, mutable lpad: option::t, sp: span, - fcx: @fn_ctxt, - source_pos: {mutable usable: bool, - mutable pos: [syntax::codemap::loc]}}; + fcx: @fn_ctxt}; // FIXME: we should be able to use option::t<@block_parent> here but // the infinite-tag check in rustboot gets upset. diff --git a/src/comp/middle/trans_vec.rs b/src/comp/middle/trans_vec.rs index 9c1d574aad683..dba2b67410ec9 100644 --- a/src/comp/middle/trans_vec.rs +++ b/src/comp/middle/trans_vec.rs @@ -27,7 +27,6 @@ fn pointer_add(bcx: @block_ctxt, ptr: ValueRef, bytes: ValueRef) -> ValueRef { } fn alloc_raw(bcx: @block_ctxt, fill: ValueRef, alloc: ValueRef) -> result { - let _s = debuginfo::invalidate_source_pos(bcx); let ccx = bcx_ccx(bcx); let llvecty = ccx.opaque_vec_type; let vecsize = Add(bcx, alloc, llsize_of(ccx, llvecty)); @@ -46,7 +45,6 @@ type alloc_result = llunitty: TypeRef}; fn alloc(bcx: @block_ctxt, vec_ty: ty::t, elts: uint) -> alloc_result { - let _s = debuginfo::invalidate_source_pos(bcx); let ccx = bcx_ccx(bcx); let unit_ty = ty::sequence_element_type(bcx_tcx(bcx), vec_ty); let llunitty = type_of_or_i8(bcx, unit_ty); From 52dbe4cc1db040562f5a5c22a0fd917db3040011 Mon Sep 17 00:00:00 2001 From: Josh Matthews Date: Mon, 19 Dec 2011 01:36:37 -0500 Subject: [PATCH 19/21] Fix merge error and rebasing changes for debug information. --- src/comp/middle/ast_map.rs | 1 + src/comp/middle/debuginfo.rs | 10 ++++++---- src/comp/middle/trans_closure.rs | 1 + src/llvm | 2 +- 4 files changed, 9 insertions(+), 5 deletions(-) diff --git a/src/comp/middle/ast_map.rs b/src/comp/middle/ast_map.rs index 63b7131d15d76..0d0eb08698961 100644 --- a/src/comp/middle/ast_map.rs +++ b/src/comp/middle/ast_map.rs @@ -73,6 +73,7 @@ fn map_item(cx: ctx, i: @item) { } item_impl(_, _, ms) { for m in ms { cx.map.insert(m.node.id, node_method(m)); } + } item_res(_, dtor_id, _, ctor_id) { cx.map.insert(ctor_id, node_res_ctor(i)); cx.map.insert(dtor_id, node_item(i)); diff --git a/src/comp/middle/debuginfo.rs b/src/comp/middle/debuginfo.rs index 12b26410c88cb..6478a1a1e6756 100644 --- a/src/comp/middle/debuginfo.rs +++ b/src/comp/middle/debuginfo.rs @@ -1,8 +1,10 @@ -import std::{vec, str, option, unsafe, fs, sys, ctypes}; +import core::{vec, str, option, sys, ctypes, unsafe}; +import std::fs; import std::map::hashmap; import lib::llvm::llvm; import lib::llvm::llvm::ValueRef; import middle::trans_common::*; +import middle::trans_build::B; import middle::ty; import syntax::{ast, codemap}; import ast::ty; @@ -66,7 +68,7 @@ fn llunused() -> ValueRef { lli32(0x0) } fn llnull() -> ValueRef unsafe { - unsafe::reinterpret_cast(std::ptr::null::()) + unsafe::reinterpret_cast(ptr::null::()) } fn add_named_metadata(cx: @crate_ctxt, name: str, val: ValueRef) { @@ -621,7 +623,7 @@ fn create_local_var(bcx: @block_ctxt, local: @ast::local) } let name = alt local.node.pat.node { - ast::pat_bind(ident) { ident } + ast::pat_bind(ident, _) { ident /*XXX deal with optional node binding */ } }; let loc = codemap::lookup_char_pos(cx.sess.get_codemap(), local.span.lo); @@ -727,7 +729,7 @@ fn create_function(fcx: @fn_ctxt) -> @metadata { } ast_map::node_expr(expr) { alt expr.node { - ast::expr_fn(f) { + ast::expr_fn(f, _) { (dbg_cx.names.next("fn"), f.decl.output, expr.id) } } diff --git a/src/comp/middle/trans_closure.rs b/src/comp/middle/trans_closure.rs index 94e1cdc8ca342..43cb0c3f39d45 100644 --- a/src/comp/middle/trans_closure.rs +++ b/src/comp/middle/trans_closure.rs @@ -336,6 +336,7 @@ fn trans_expr_fn(bcx: @block_ctxt, f: ast::_fn, sp: span, let sub_cx = extend_path(bcx.fcx.lcx, ccx.names.next("anon")); let s = mangle_internal_name_by_path(ccx, sub_cx.path); let llfn = decl_internal_cdecl_fn(ccx.llmod, s, llfnty); + register_fn(ccx, sp, sub_cx.path, "anon fn", [], id); let trans_closure_env = lambda(ck: ty::closure_kind) -> ValueRef { let upvars = get_freevars(ccx.tcx, id); diff --git a/src/llvm b/src/llvm index 80c896f8ad46f..a320b2aa41fbe 160000 --- a/src/llvm +++ b/src/llvm @@ -1 +1 @@ -Subproject commit 80c896f8ad46f5c3fb777c32c0c71d58a4bdb1e7 +Subproject commit a320b2aa41fbe3f944bad33780626d65d1b11e6f From 1d3d28bdf169c891a0f3cf82879d8609ba2d44ff Mon Sep 17 00:00:00 2001 From: Josh Matthews Date: Mon, 19 Dec 2011 02:52:21 -0500 Subject: [PATCH 20/21] Long lines. --- src/comp/middle/debuginfo.rs | 21 ++++++++++++--------- src/comp/middle/trans.rs | 5 +++-- src/comp/middle/trans_build.rs | 3 ++- 3 files changed, 17 insertions(+), 12 deletions(-) diff --git a/src/comp/middle/debuginfo.rs b/src/comp/middle/debuginfo.rs index 6478a1a1e6756..7460244d479e6 100644 --- a/src/comp/middle/debuginfo.rs +++ b/src/comp/middle/debuginfo.rs @@ -73,7 +73,8 @@ fn llnull() -> ValueRef unsafe { fn add_named_metadata(cx: @crate_ctxt, name: str, val: ValueRef) { str::as_buf(name, {|sbuf| - llvm::LLVMAddNamedMetadataOperand(cx.llmod, sbuf, str::byte_len(name), val) + llvm::LLVMAddNamedMetadataOperand(cx.llmod, sbuf, str::byte_len(name), + val) }) } @@ -356,7 +357,7 @@ fn create_structure(file: @metadata, name: str, line: int) mutable members: [], mutable total_size: 0, align: 64 //XXX different alignment per arch? - }; + }; ret cx; } @@ -378,8 +379,9 @@ fn create_derived_type(type_tag: int, file: ValueRef, name: str, line: int, fn add_member(cx: @struct_ctxt, name: str, line: int, size: int, align: int, ty: ValueRef) { - cx.members += [create_derived_type(MemberTag, cx.file, name, line, size * 8, - align * 8, cx.total_size, ty)]; + cx.members += [create_derived_type(MemberTag, cx.file, name, line, + size * 8, align * 8, cx.total_size, + ty)]; cx.total_size += size * 8; } @@ -421,10 +423,10 @@ fn create_boxed_type(cx: @crate_ctxt, outer: ty::t, _inner: ty::t, let uint_ty = @{node: ast::ty_uint(ast::ty_u), span: span}; let refcount_type = create_basic_type(cx, uint_t, uint_ty); let scx = create_structure(file_node, ty_to_str(ccx_tcx(cx), outer), 0); - add_member(scx, "refcnt", 0, sys::size_of::() as int, + add_member(scx, "refcnt", 0, sys::size_of::() as int, sys::align_of::() as int, refcount_type.node); add_member(scx, "boxed", 0, 8, //XXX member_size_and_align(??) - 8, //XXX just a guess + 8, //XXX just a guess boxed.node); let llnode = finish_structure(scx); let mdval = @{node: llnode, data: {hash: outer}}; @@ -477,7 +479,7 @@ fn create_vec(cx: @crate_ctxt, vec_t: ty::t, elem_t: ty::t, vec_ty: @ast::ty) arr_size, arr_align, 0, option::some(elem_ty_md.node), option::some([subrange])); - add_member(scx, "data", 0, 0, // according to an equivalent clang dump, the size should be 0 + add_member(scx, "data", 0, 0, // clang says the size should be 0 sys::align_of::() as int, data_ptr); let llnode = finish_structure(scx); ret @{node: llnode, data: {hash: vec_t}}; @@ -521,7 +523,8 @@ fn member_size_and_align(ty: @ast::ty) -> (int, int) { } } -fn create_ty(cx: @crate_ctxt, t: ty::t, ty: @ast::ty) -> @metadata { +fn create_ty(cx: @crate_ctxt, t: ty::t, ty: @ast::ty) + -> @metadata { /*let cache = get_cache(cx); alt cached_metadata::<@metadata>( cache, tg, {|md| t == md.data.hash}) { @@ -623,7 +626,7 @@ fn create_local_var(bcx: @block_ctxt, local: @ast::local) } let name = alt local.node.pat.node { - ast::pat_bind(ident, _) { ident /*XXX deal with optional node binding */ } + ast::pat_bind(ident, _) { ident /*XXX deal w/ optional node binding*/ } }; let loc = codemap::lookup_char_pos(cx.sess.get_codemap(), local.span.lo); diff --git a/src/comp/middle/trans.rs b/src/comp/middle/trans.rs index 7828390ee4fb6..8a37d27d973c9 100644 --- a/src/comp/middle/trans.rs +++ b/src/comp/middle/trans.rs @@ -4015,7 +4015,7 @@ fn trans_stmt(cx: @block_ctxt, s: ast::stmt) -> @block_ctxt { let bcx = cx; debuginfo::update_source_pos(cx, s.span); - + alt s.node { ast::stmt_expr(e, _) { bcx = trans_expr(cx, e, ignore); } ast::stmt_decl(d, _) { @@ -4562,7 +4562,8 @@ fn trans_fn(cx: @local_ctxt, sp: span, f: ast::_fn, llfndecl: ValueRef, let do_time = cx.ccx.sess.get_opts().stats; let start = do_time ? time::get_time() : {sec: 0u32, usec: 0u32}; let fcx = option::none; - trans_closure(cx, sp, f, llfndecl, ty_self, ty_params, id, {|new_fcx| fcx = option::some(new_fcx);}); + trans_closure(cx, sp, f, llfndecl, ty_self, ty_params, id, + {|new_fcx| fcx = option::some(new_fcx);}); if cx.ccx.sess.get_opts().extra_debuginfo { debuginfo::create_function(option::get(fcx)); } diff --git a/src/comp/middle/trans_build.rs b/src/comp/middle/trans_build.rs index af709ec5420e0..5a9c07731473b 100644 --- a/src/comp/middle/trans_build.rs +++ b/src/comp/middle/trans_build.rs @@ -631,7 +631,8 @@ fn Trap(cx: @block_ctxt) { assert (T as int != 0); let Args: [ValueRef] = []; unsafe { - llvm::LLVMBuildCall(b, T, vec::to_ptr(Args), vec::len(Args), noname()); + llvm::LLVMBuildCall(b, T, vec::to_ptr(Args), vec::len(Args), + noname()); } } From 6637340c2860344bacd1554fc025f3d90c80a602 Mon Sep 17 00:00:00 2001 From: Josh Matthews Date: Mon, 19 Dec 2011 03:42:58 -0500 Subject: [PATCH 21/21] Properly calculate base working dir for compile units. --- src/comp/driver/rustc.rs | 10 +++++----- src/comp/driver/session.rs | 6 +++++- src/comp/middle/debuginfo.rs | 13 +++++++++---- 3 files changed, 19 insertions(+), 10 deletions(-) diff --git a/src/comp/driver/rustc.rs b/src/comp/driver/rustc.rs index 35e450244ac8c..8e293e98f0d04 100644 --- a/src/comp/driver/rustc.rs +++ b/src/comp/driver/rustc.rs @@ -489,7 +489,7 @@ fn build_session_options(match: getopts::match) ret sopts; } -fn build_session(sopts: @session::options) -> session::session { +fn build_session(sopts: @session::options, input: str) -> session::session { let target_cfg = build_target_config(sopts); let cstore = cstore::mk_cstore(); let filesearch = filesearch::mk_filesearch( @@ -498,7 +498,7 @@ fn build_session(sopts: @session::options) -> session::session { sopts.addl_lib_search_paths); ret session::session(target_cfg, sopts, cstore, @{cm: codemap::new_codemap(), mutable next_id: 1}, - none, 0u, filesearch, false); + none, 0u, filesearch, false, fs::dirname(input)); } fn parse_pretty(sess: session::session, &&name: str) -> pp_mode { @@ -644,7 +644,7 @@ fn main(args: [str]) { }; let sopts = build_session_options(match); - let sess = build_session(sopts); + let sess = build_session(sopts, ifile); let odir = getopts::opt_maybe_str(match, "out-dir"); let ofile = getopts::opt_maybe_str(match, "o"); let cfg = build_configuration(sess, binary, ifile); @@ -676,7 +676,7 @@ mod test { ok(m) { m } }; let sessopts = build_session_options(match); - let sess = build_session(sessopts); + let sess = build_session(sessopts, ""); let cfg = build_configuration(sess, "whatever", "whatever"); assert (attr::contains_name(cfg, "test")); } @@ -690,7 +690,7 @@ mod test { ok(m) { m } }; let sessopts = build_session_options(match); - let sess = build_session(sessopts); + let sess = build_session(sessopts, ""); let cfg = build_configuration(sess, "whatever", "whatever"); let test_items = attr::find_meta_items_by_name(cfg, "test"); assert (vec::len(test_items) == 1u); diff --git a/src/comp/driver/session.rs b/src/comp/driver/session.rs index 6645d5d68946e..1bedbf87f7eab 100644 --- a/src/comp/driver/session.rs +++ b/src/comp/driver/session.rs @@ -60,7 +60,8 @@ obj session(targ_cfg: @config, mutable main_fn: option::t, mutable err_count: uint, filesearch: filesearch::filesearch, - mutable building_library: bool) { + mutable building_library: bool, + working_dir: str) { fn get_targ_cfg() -> @config { ret targ_cfg; } fn get_opts() -> @options { ret opts; } fn get_cstore() -> metadata::cstore::cstore { cstore } @@ -123,6 +124,9 @@ obj session(targ_cfg: @config, fn set_building_library(crate: @ast::crate) { building_library = session::building_library(opts.crate_type, crate); } + fn get_working_dir() -> str { + ret working_dir; + } } fn building_library(req_crate_type: crate_type, crate: @ast::crate) -> bool { diff --git a/src/comp/middle/debuginfo.rs b/src/comp/middle/debuginfo.rs index 7460244d479e6..c11f65dc34f10 100644 --- a/src/comp/middle/debuginfo.rs +++ b/src/comp/middle/debuginfo.rs @@ -162,13 +162,18 @@ fn create_compile_unit(cx: @crate_ctxt, full_path: str) option::none. {} } - let fname = fs::basename(full_path); - let path = fs::dirname(full_path); + let work_dir = cx.sess.get_working_dir(); + let file_path = if str::starts_with(full_path, work_dir) { + str::slice(full_path, str::byte_len(work_dir), + str::byte_len(full_path)) + } else { + full_path + }; let unit_metadata = [lltag(tg), llunused(), lli32(DW_LANG_RUST), - llstr(fname), - llstr(path), + llstr(file_path), + llstr(work_dir), llstr(#env["CFG_VERSION"]), lli1(false), // main compile unit lli1(cx.sess.get_opts().optimize != 0u),