From 30d019d52088eef214a492a252f85038df79f129 Mon Sep 17 00:00:00 2001 From: Josh Matthews Date: Fri, 9 Dec 2011 11:32:23 -0500 Subject: [PATCH] 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 ee33d9dcd5f8..1e5cbadc4492 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 81f15d6b4de1..e92095f67e56 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 b47a00f8a685..c7333ef74115 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],