From 868f9a88d6a0a495c10baa35a2fb359b5681375f Mon Sep 17 00:00:00 2001 From: Vadim Chugunov Date: Fri, 14 Jun 2013 11:38:29 -0700 Subject: [PATCH 01/11] Use DIBuilder in debuginfo --- src/librustc/lib/llvm.rs | 185 +++- src/librustc/middle/trans/base.rs | 6 +- src/librustc/middle/trans/debuginfo.rs | 1129 +++++++++--------------- src/rustllvm/RustWrapper.cpp | 201 +++++ src/rustllvm/rustllvm.def.in | 17 + src/rustllvm/rustllvm.h | 2 + 6 files changed, 832 insertions(+), 708 deletions(-) diff --git a/src/librustc/lib/llvm.rs b/src/librustc/lib/llvm.rs index 289bb4f63f59e..ece0c1cb19092 100644 --- a/src/librustc/lib/llvm.rs +++ b/src/librustc/lib/llvm.rs @@ -224,13 +224,51 @@ pub type SectionIteratorRef = *SectionIterator_opaque; pub enum Pass_opaque {} pub type PassRef = *Pass_opaque; +pub mod debuginfo { + use core::prelude::*; + use super::{ValueRef}; + + pub enum DIBuilder_opaque {} + pub type DIBuilderRef = *DIBuilder_opaque; + + pub type DIDescriptor = ValueRef; + pub type DIScope = DIDescriptor; + pub type DILocation = DIDescriptor; + pub type DIFile = DIScope; + pub type DILexicalBlock = DIScope; + pub type DISubprogram = DIScope; + pub type DIType = DIDescriptor; + pub type DIBasicType = DIType; + pub type DIDerivedType = DIType; + pub type DICompositeType = DIDerivedType; + pub type DIVariable = DIDescriptor; + pub type DIArray = DIDescriptor; + pub type DISubrange = DIDescriptor; + + pub enum DIDescriptorFlags { + FlagPrivate = 1 << 0, + FlagProtected = 1 << 1, + FlagFwdDecl = 1 << 2, + FlagAppleBlock = 1 << 3, + FlagBlockByrefStruct = 1 << 4, + FlagVirtual = 1 << 5, + FlagArtificial = 1 << 6, + FlagExplicit = 1 << 7, + FlagPrototyped = 1 << 8, + FlagObjcClassComplete = 1 << 9, + FlagObjectPointer = 1 << 10, + FlagVector = 1 << 11, + FlagStaticMember = 1 << 12 + } +} + pub mod llvm { use super::{AtomicBinOp, AtomicOrdering, BasicBlockRef, ExecutionEngineRef}; use super::{Bool, BuilderRef, ContextRef, MemoryBufferRef, ModuleRef}; use super::{ObjectFileRef, Opcode, PassManagerRef, PassManagerBuilderRef}; use super::{SectionIteratorRef, TargetDataRef, TypeKind, TypeRef, UseRef}; - use super::{ValueRef,PassRef}; - + use super::{ValueRef, PassRef}; + use super::debuginfo::*; use core::libc::{c_char, c_int, c_longlong, c_ushort, c_uint, c_ulonglong}; #[link_args = "-Lrustllvm -lrustllvm"] @@ -1885,6 +1923,149 @@ pub mod llvm { AlignStack: Bool, Dialect: c_uint) -> ValueRef; + + #[fast_ffi] + pub unsafe fn DIBuilder_new(M: ModuleRef) -> DIBuilderRef; + + #[fast_ffi] + pub unsafe fn DIBuilder_delete(Builder: DIBuilderRef); + + #[fast_ffi] + pub unsafe fn DIBuilder_finalize(Builder: DIBuilderRef); + + #[fast_ffi] + pub unsafe fn DIBuilder_createCompileUnit( + Builder: DIBuilderRef, + Lang: c_uint, + File: *c_char, + Dir: *c_char, + Producer: *c_char, + isOptimized: bool, + Flags: *c_char, + RuntimeVer: c_uint, + SplitName: *c_char); + + #[fast_ffi] + pub unsafe fn DIBuilder_createFile( + Builder: DIBuilderRef, + Filename: *c_char, + Directory: *c_char) -> DIFile; + + #[fast_ffi] + pub unsafe fn DIBuilder_createSubroutineType( + Builder: DIBuilderRef, + File: DIFile, + ParameterTypes: DIArray) -> DICompositeType; + + #[fast_ffi] + pub unsafe fn DIBuilder_createFunction( + Builder: DIBuilderRef, + Scope: DIDescriptor, + Name: *c_char, + LinkageName: *c_char, + File: DIFile, + LineNo: c_uint, + Ty: DIType, + isLocalToUnit: bool, + isDefinition: bool, + ScopeLine: c_uint, + Flags: c_uint, + isOptimized: bool, + Fn: ValueRef, + TParam: ValueRef, + Decl: ValueRef) -> DISubprogram; + + #[fast_ffi] + pub unsafe fn DIBuilder_createBasicType( + Builder: DIBuilderRef, + Name: *c_char, + SizeInBits: c_ulonglong, + AlignInBits: c_ulonglong, + Encoding: c_uint) -> DIBasicType; + + #[fast_ffi] + pub unsafe fn DIBuilder_createPointerType( + Builder: DIBuilderRef, + PointeeTy: DIType, + SizeInBits: c_ulonglong, + AlignInBits: c_ulonglong, + Name: *c_char) -> DIDerivedType; + + #[fast_ffi] + pub unsafe fn DIBuilder_createStructType( + Builder: DIBuilderRef, + Scope: DIDescriptor, + Name: *c_char, + File: DIFile, + LineNumber: c_uint, + SizeInBits: c_ulonglong, + AlignInBits: c_ulonglong, + Flags: c_uint, + DerivedFrom: DIType, + Elements: DIArray, + RunTimeLang: c_uint, + VTableHolder: ValueRef) -> DICompositeType; + + #[fast_ffi] + pub unsafe fn DIBuilder_createMemberType( + Builder: DIBuilderRef, + Scope: DIDescriptor, + Name: *c_char, + File: DIFile, + LineNo: c_uint, + SizeInBits: c_ulonglong, + AlignInBits: c_ulonglong, + OffsetInBits: c_ulonglong, + Flags: c_uint, + Ty: DIType) -> DIDerivedType; + + #[fast_ffi] + pub unsafe fn DIBuilder_createLexicalBlock( + Builder: DIBuilderRef, + Scope: DIDescriptor, + File: DIFile, + Line: c_uint, + Col: c_uint) -> DILexicalBlock; + + #[fast_ffi] + pub unsafe fn DIBuilder_createLocalVariable( + Builder: DIBuilderRef, + Tag: c_uint, + Scope: DIDescriptor, + Name: *c_char, + File: DIFile, + LineNo: c_uint, + Ty: DIType, + AlwaysPreserve: bool, + Flags: c_uint, + ArgNo: c_uint) -> DIVariable; + + #[fast_ffi] + pub unsafe fn DIBuilder_createVectorType( + Builder: DIBuilderRef, + Size: c_ulonglong, + AlignInBits: c_ulonglong, + Ty: DIType, + Subscripts: DIArray) -> DIType; + + #[fast_ffi] + pub unsafe fn DIBuilder_getOrCreateSubrange( + Builder: DIBuilderRef, + Lo: c_longlong, + Count: c_longlong) -> DISubrange; + + #[fast_ffi] + pub unsafe fn DIBuilder_getOrCreateArray( + Builder: DIBuilderRef, + Ptr: *DIDescriptor, + Count: c_uint) -> DIArray; + + #[fast_ffi] + pub unsafe fn DIBuilder_insertDeclare( + Builder: DIBuilderRef, + Val: ValueRef, + VarInfo: DIVariable, + InsertBefore: *c_void) -> *c_void; } } diff --git a/src/librustc/middle/trans/base.rs b/src/librustc/middle/trans/base.rs index 53f2729c38e91..580e7fa1900a8 100644 --- a/src/librustc/middle/trans/base.rs +++ b/src/librustc/middle/trans/base.rs @@ -3074,6 +3074,7 @@ pub fn trans_crate(sess: session::Session, // 1. http://llvm.org/bugs/show_bug.cgi?id=11479 let llmod_id = link_meta.name.to_owned() + ".rc"; + Some(debuginfo::mk_ctxt(llmod, copy llmod_id)) // FIXME(#6511): get LLVM building with --enable-threads so this // function can be called // if !llvm::LLVMRustStartMultithreading() { @@ -3102,7 +3103,10 @@ pub fn trans_crate(sess: session::Session, fill_crate_map(ccx, ccx.crate_map); glue::emit_tydescs(ccx); write_abi_version(ccx); - + if ccx.sess.opts.debuginfo { + debuginfo::finalize(ccx); + } + // Translate the metadata. write_metadata(ccx, crate); if ccx.sess.trans_stats() { diff --git a/src/librustc/middle/trans/debuginfo.rs b/src/librustc/middle/trans/debuginfo.rs index 87c33ce64f54b..a01c2b89bf9d0 100644 --- a/src/librustc/middle/trans/debuginfo.rs +++ b/src/librustc/middle/trans/debuginfo.rs @@ -11,9 +11,9 @@ use core::prelude::*; use driver::session; -use lib::llvm::ValueRef; use lib::llvm::llvm; -use middle::trans::context::task_llcx; +use lib::llvm::{ValueRef, ModuleRef, ContextRef}; +use lib::llvm::debuginfo::*; use middle::trans::common::*; use middle::trans::machine; use middle::trans::type_of; @@ -21,21 +21,17 @@ use middle::trans; use middle::ty; use util::ppaux::ty_to_str; -use core::cast; use core::hashmap::HashMap; use core::libc; -use core::option; -use core::ptr; -use core::str; -use core::sys; -use core::vec; +use core::libc::c_uint; +use core::str::as_c_str; use syntax::codemap::span; +use syntax::parse::token::ident_interner; use syntax::{ast, codemap, ast_util, ast_map}; -static LLVMDebugVersion: int = (9 << 16); +static LLVMDebugVersion: int = (12 << 16); -static DW_LANG_RUST: int = 0x9000; -static DW_VIRTUALITY_none: int = 0; +static DW_LANG_RUST: int = 12; //0x9000; static CompileUnitTag: int = 17; static FileDescriptorTag: int = 41; @@ -59,302 +55,185 @@ static DW_ATE_signed_char: int = 0x06; static DW_ATE_unsigned: int = 0x07; static DW_ATE_unsigned_char: int = 0x08; -fn llstr(s: &str) -> ValueRef { - do str::as_c_str(s) |sbuf| { - unsafe { - llvm::LLVMMDStringInContext(task_llcx(), - sbuf, - s.len() as libc::c_uint) - } - } -} -fn lltag(lltag: int) -> ValueRef { - 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_i1(bval) -} -fn llmdnode(elems: &[ValueRef]) -> ValueRef { - unsafe { - llvm::LLVMMDNodeInContext(task_llcx(), - vec::raw::to_ptr(elems), - elems.len() as libc::c_uint) - } -} -fn llunused() -> ValueRef { - lli32(0x0) -} -fn llnull() -> ValueRef { - unsafe { - cast::transmute(ptr::null::()) - } -} - -fn add_named_metadata(cx: &CrateContext, name: ~str, val: ValueRef) { - str::as_c_str(name, |sbuf| { - unsafe { - llvm::LLVMAddNamedMetadataOperand(cx.llmod, sbuf, val) - } - }) -} - //////////////// pub struct DebugContext { - llmetadata: metadata_cache, + //llmetadata: metadata_cache, names: namegen, - crate_file: ~str -} - -pub fn mk_ctxt(crate: ~str) -> DebugContext { + crate_file: ~str, + builder: DIBuilderRef, + + created_files: @mut HashMap<~str, DIFile>, + created_functions: @mut HashMap, + created_blocks: @mut HashMap, + created_types: @mut HashMap +} + +/** Create new DebugContext */ +pub fn mk_ctxt(llmod: ModuleRef, crate: ~str, intr: @ident_interner) -> DebugContext { + debug!("mk_ctxt"); + let builder = unsafe { llvm::DIBuilder_new(llmod) }; DebugContext { - llmetadata: @mut HashMap::new(), - names: new_namegen(), - crate_file: crate - } + //llmetadata: @mut HashMap::new(), + names: new_namegen(intr), + crate_file: crate, + builder: builder, + created_files: @mut HashMap::new(), + created_functions: @mut HashMap::new(), + created_blocks: @mut HashMap::new(), + created_types: @mut HashMap::new(), } - -fn update_cache(cache: metadata_cache, mdtag: int, val: debug_metadata) { - let mut existing = match cache.pop(&mdtag) { - Some(arr) => arr, None => ~[] - }; - existing.push(val); - cache.insert(mdtag, existing); } -struct Metadata { - node: ValueRef, - data: T +#[inline(always)] +fn get_builder(cx: @CrateContext) -> DIBuilderRef { + let dbg_cx = cx.dbg_cx.get_ref(); + return dbg_cx.builder; } -struct FileMetadata { - path: ~str -} -struct CompileUnitMetadata { - name: ~str -} -struct SubProgramMetadata { - id: ast::node_id -} -struct LocalVarMetadata { - id: ast::node_id -} -struct TyDescMetadata { - hash: uint -} -struct BlockMetadata { - start: codemap::Loc, - end: codemap::Loc -} -struct ArgumentMetadata { - id: ast::node_id -} -struct RetvalMetadata { - id: ast::node_id -} - -type metadata_cache = @mut HashMap; - -enum debug_metadata { - file_metadata(@Metadata), - compile_unit_metadata(@Metadata), - subprogram_metadata(@Metadata), - local_var_metadata(@Metadata), - tydesc_metadata(@Metadata), - block_metadata(@Metadata), - argument_metadata(@Metadata), - retval_metadata(@Metadata), +fn create_DIArray(builder: DIBuilderRef, arr: &[DIDescriptor]) -> DIArray { + return unsafe { + llvm::DIBuilder_getOrCreateArray(builder, vec::raw::to_ptr(arr), arr.len() as u32) + }; } -fn cast_safely(val: T) -> U { +/** Create any deferred debug metadata nodes */ +pub fn finalize(cx: @CrateContext) { + debug!("finalize"); + create_compile_unit(cx); unsafe { - let val2 = val; - return cast::transmute(val2); - } + llvm::DIBuilder_finalize(get_builder(cx)); + llvm::DIBuilder_delete(get_builder(cx)); + }; } -fn md_from_metadata(val: debug_metadata) -> T { - match val { - 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), - argument_metadata(md) => cast_safely(md), - retval_metadata(md) => cast_safely(md) - } +fn filename_from_span(cx: @CrateContext, sp: codemap::span) -> ~str { + /*bad*/copy cx.sess.codemap.lookup_char_pos(sp.lo).file.name } -fn cached_metadata(cache: metadata_cache, - mdtag: int, - eq_fn: &fn(md: T) -> bool) - -> Option { - if cache.contains_key(&mdtag) { - let items = cache.get(&mdtag); - for items.each |item| { - let md: T = md_from_metadata::(*item); - if eq_fn(copy md) { - return option::Some(copy md); - } - } - } - return option::None; -} - -fn create_compile_unit(cx: &mut CrateContext) -> @Metadata { - let cache = get_cache(cx); - let crate_name = /*bad*/copy (/*bad*/copy cx.dbg_cx).get().crate_file; - let tg = CompileUnitTag; - match cached_metadata::<@Metadata>(cache, tg, - |md| md.data.name == crate_name) { - option::Some(md) => return md, - option::None => () - } +//fn filename_from_span<'cx>(cx: &'cx CrateContext, sp: codemap::span) -> &'cx str { +// let fname: &str = cx.sess.codemap.lookup_char_pos(sp.lo).file.name; +// return fname; +//} - let (_, work_dir) = get_file_path_and_dir( - cx.sess.working_dir.to_str(), crate_name); - let unit_metadata = ~[lltag(tg), - llunused(), - lli32(DW_LANG_RUST), - llstr(crate_name), - llstr(work_dir), - llstr(env!("CFG_VERSION")), - lli1(true), // deprecated: main compile unit - lli1(cx.sess.opts.optimize != session::No), - llstr(""), // flags (???) - lli32(0) // runtime version (???) - ]; - let unit_node = llmdnode(unit_metadata); - add_named_metadata(cx, ~"llvm.dbg.cu", unit_node); - let mdval = @Metadata { - node: unit_node, - data: CompileUnitMetadata { - name: crate_name - } +fn get_file_path_and_dir(work_dir: &str, full_path: &str) -> (~str, ~str) { + let full_path = + if str::starts_with(full_path, work_dir) { + str::slice(full_path, str::len(work_dir) + 1u, + str::len(full_path)).to_owned() + } else { + full_path.to_owned() }; - update_cache(cache, tg, compile_unit_metadata(mdval)); - - return mdval; + + return (full_path, work_dir.to_owned()); } -fn get_cache(cx: &CrateContext) -> metadata_cache { - cx.dbg_cx.get_ref().llmetadata -} - -fn get_file_path_and_dir(work_dir: &str, full_path: &str) -> (~str, ~str) { - (if full_path.starts_with(work_dir) { - full_path.slice(work_dir.len() + 1u, - full_path.len()).to_owned() - } else { - full_path.to_owned() - }, work_dir.to_owned()) -} +fn create_compile_unit(cx: @CrateContext) { + let crate_name: &str = cx.dbg_cx.get_ref().crate_file; -fn create_file(cx: &mut CrateContext, full_path: ~str) - -> @Metadata { - let cache = get_cache(cx);; - let tg = FileDescriptorTag; - match cached_metadata::<@Metadata>( - cache, tg, |md| md.data.path == full_path) { - option::Some(md) => return md, - option::None => () + let (_, work_dir) = get_file_path_and_dir( + cx.sess.working_dir.to_str(), crate_name); + + let producer = fmt!("rustc version %s", env!("CFG_VERSION")); + + do as_c_str(crate_name) |crate_name| { + do as_c_str(work_dir) |work_dir| { + do as_c_str(producer) |producer| { + do as_c_str("") |flags| { + do as_c_str("") |split_name| { unsafe { + llvm::DIBuilder_createCompileUnit(get_builder(cx), + DW_LANG_RUST as c_uint, crate_name, work_dir, producer, + cx.sess.opts.optimize != session::No, + flags, 0, split_name); + }}}}}}; +} + +fn create_file(cx: @CrateContext, full_path: &str) -> DIFile { + let mut dbg_cx = cx.dbg_cx.get_ref(); + + match dbg_cx.created_files.find(&full_path.to_owned()) { + Some(file_md) => return *file_md, + None => () } + debug!("create_file: %s", full_path); + let (file_path, work_dir) = get_file_path_and_dir(cx.sess.working_dir.to_str(), full_path); - let unit_node = create_compile_unit(cx).node; - let file_md = ~[lltag(tg), - llstr(file_path), - llstr(work_dir), - unit_node]; - let val = llmdnode(file_md); - let mdval = @Metadata { - node: val, - data: FileMetadata { - path: full_path - } - }; - update_cache(cache, tg, file_metadata(mdval)); - return mdval; + + let file_md = + do as_c_str(file_path) |file_path| { + do as_c_str(work_dir) |work_dir| { unsafe { + llvm::DIBuilder_createFile(get_builder(cx), file_path, work_dir) + }}}; + + dbg_cx.created_files.insert(full_path.to_owned(), file_md); + return file_md; } fn line_from_span(cm: @codemap::CodeMap, sp: span) -> uint { cm.lookup_char_pos(sp.lo).line } -fn create_block(mut cx: block) -> @Metadata { - let cache = get_cache(cx.ccx()); - while cx.node_info.is_none() { - match cx.parent { - Some(b) => cx = b, +fn create_block(bcx: block) -> DILexicalBlock { + let mut bcx = bcx; + let mut dbg_cx = bcx.ccx().dbg_cx.get_ref(); + + while bcx.node_info.is_none() { + match bcx.parent { + Some(b) => bcx = b, None => fail!() } } - let sp = cx.node_info.get().span; - - let start = cx.sess().codemap.lookup_char_pos(sp.lo); - let fname = /*bad*/copy start.file.name; - let end = cx.sess().codemap.lookup_char_pos(sp.hi); - let tg = LexicalBlockTag; - /*match cached_metadata::<@Metadata>( - cache, tg, - {|md| start == md.data.start && end == md.data.end}) { - option::Some(md) { return md; } - option::None {} - }*/ - - let parent = match cx.parent { - None => create_function(cx.fcx).node, - Some(bcx) => create_block(bcx).node - }; - let file_node = create_file(cx.ccx(), /* bad */ fname.to_owned()); - let unique_id = match cache.find(&LexicalBlockTag) { - option::Some(v) => v.len() as int, - option::None => 0 + let sp = bcx.node_info.get().span; + let id = bcx.node_info.get().id; + + match dbg_cx.created_blocks.find(&id) { + Some(block) => return *block, + None => () + } + + debug!("create_block: %s", bcx.sess().codemap.span_to_str(sp)); + + let start = bcx.sess().codemap.lookup_char_pos(sp.lo); + let end = bcx.sess().codemap.lookup_char_pos(sp.hi); + + let parent = match bcx.parent { + None => create_function(bcx.fcx), + Some(b) => create_block(b) }; - let lldata = ~[lltag(tg), - parent, - lli32(start.line.to_int()), - lli32(start.col.to_int()), - file_node.node, - lli32(unique_id) - ]; - let val = llmdnode(lldata); - let mdval = @Metadata { - node: val, - data: BlockMetadata { - start: start, - end: end - } + + let file_md = create_file(bcx.ccx(), start.file.name); + + let block_md = unsafe { + llvm::LLVMDIBuilderCreateLexicalBlock( + dcx.builder, + parent, file_md, + start.line.to_int() as c_uint, start.col.to_int() as c_uint) }; - //update_cache(cache, tg, block_metadata(mdval)); - return mdval; + + dbg_cx.created_blocks.insert(id, block_md); + + return block_md; } -fn size_and_align_of(cx: &mut CrateContext, t: ty::t) -> (int, int) { +fn size_and_align_of(cx: @CrateContext, t: ty::t) -> (uint, uint) { let llty = type_of::type_of(cx, t); - (machine::llsize_of_real(cx, llty) as int, - machine::llalign_of_pref(cx, llty) as int) + (machine::llsize_of_real(cx, llty), + machine::llalign_of_pref(cx, llty)) } -fn create_basic_type(cx: &mut CrateContext, t: ty::t, span: span) - -> @Metadata { - let cache = get_cache(cx); - let tg = BasicTypeDescriptorTag; - match cached_metadata::<@Metadata>( - cache, tg, |md| ty::type_id(t) == md.data.hash) { - option::Some(md) => return md, - option::None => () +fn create_basic_type(cx: @CrateContext, t: ty::t, span: span) -> DIType{ + let mut dbg_cx = cx.dbg_cx.get_ref(); + let ty_id = ty::type_id(t); + match dbg_cx.created_types.find(&ty_id) { + Some(ty_md) => return *ty_md, + None => () } + debug!("create_basic_type: %?", ty::get(t)); + let (name, encoding) = match ty::get(t).sty { ty::ty_nil | ty::ty_bot => (~"uint", DW_ATE_unsigned), ty::ty_bool => (~"bool", DW_ATE_boolean), @@ -378,383 +257,255 @@ fn create_basic_type(cx: &mut CrateContext, t: ty::t, span: span) ast::ty_f32 => (~"f32", DW_ATE_float), ast::ty_f64 => (~"f64", DW_ATE_float) }, - _ => cx.sess.bug("debuginfo::create_basic_type - t is invalid type") + _ => cx.sess.bug(~"debuginfo::create_basic_type - t is invalid type") }; - let fname = filename_from_span(cx, span); - let file_node = create_file(cx, fname.to_owned()); - let cu_node = create_compile_unit(cx); let (size, align) = size_and_align_of(cx, t); - let lldata = ~[lltag(tg), - cu_node.node, - llstr(name), - 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), //XXX flags? - lli32(encoding)]; - let llnode = llmdnode(lldata); - let mdval = @Metadata { - node: llnode, - data: TyDescMetadata { - hash: ty::type_id(t) - } - }; - update_cache(cache, tg, tydesc_metadata(mdval)); - add_named_metadata(cx, ~"llvm.dbg.ty", llnode); - return mdval; + let ty_md = do as_c_str(name) |name| { unsafe { + llvm::LLVMDIBuilderCreateBasicType( + dcx.builder, name, + size * 8 as u64, align * 8 as u64, encoding as c_uint) + }}; + + dbg_cx.created_types.insert(ty_id, ty_md); + return ty_md; } -fn create_pointer_type(cx: &mut CrateContext, t: ty::t, span: span, - pointee: @Metadata) - -> @Metadata { - let tg = PointerTypeTag; - /*let cache = cx.llmetadata; - match cached_metadata::<@Metadata>( - cache, tg, {|md| ty::hash_ty(t) == ty::hash_ty(md.data.hash)}) { - option::Some(md) { return md; } - option::None {} - }*/ +fn create_pointer_type(cx: @CrateContext, t: ty::t, span: span, pointee: DIType) -> DIType { let (size, align) = size_and_align_of(cx, t); - let fname = filename_from_span(cx, span); - let file_node = create_file(cx, fname.to_owned()); - //let cu_node = create_compile_unit(cx, fname); let name = ty_to_str(cx.tcx, t); - let llnode = create_derived_type(tg, file_node.node, name, 0, size * 8, - align * 8, 0, pointee.node); - let mdval = @Metadata { - node: llnode, - data: TyDescMetadata { - hash: ty::type_id(t) - } - }; - //update_cache(cache, tg, tydesc_metadata(mdval)); - add_named_metadata(cx, ~"llvm.dbg.ty", llnode); - return mdval; -} - -struct StructCtxt { - file: ValueRef, - name: @str, - line: int, - members: ~[ValueRef], - total_size: int, - align: int -} - -fn finish_structure(cx: @mut StructCtxt) -> ValueRef { - return create_composite_type(StructureTypeTag, - cx.name, - cx.file, - cx.line, - cx.total_size, - cx.align, - 0, - None, - Some(/*bad*/copy cx.members)); -} - -fn create_structure(file: @Metadata, name: @str, line: int) - -> @mut StructCtxt { - let cx = @mut StructCtxt { - file: file.node, - name: name, - line: line, - members: ~[], - total_size: 0, - align: 64 //XXX different alignment per arch? - }; - return cx; -} + let ptr_md = do as_c_str(name) |name| { unsafe { + llvm::DIBuilder_createPointerType(get_builder(cx), + pointee, size * 8 as u64, align * 8 as u64, name) + }}; + return ptr_md; +} + +struct StructContext { + cx: @CrateContext, + file: DIFile, + name: ~str, + line: uint, + members: ~[DIDerivedType], + total_size: uint, + align: uint +} + +impl StructContext { + fn create(cx: @CrateContext, file: DIFile, name: ~str, line: uint) -> ~StructContext { + let scx = ~StructContext { + cx: cx, + file: file, + name: name, + line: line, + members: ~[], + total_size: 0, + align: 64 //XXX different alignment per arch? + }; + return scx; + } -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), - file, - lli32(line), - lli64(size), - lli64(align), - lli64(offset), - lli32(0), - ty]; - return llmdnode(lldata); -} + fn add_member(&mut self, name: &str, line: uint, size: uint, align: uint, ty: DIType) { + let mem_t = do as_c_str(name) |name| { unsafe { + llvm::DIBuilder_createMemberType(get_builder(self.cx), + ptr::null(), name, self.file, line as c_uint, + size * 8 as u64, align * 8 as u64, self.total_size as u64, + 0, ty) + }}; + // XXX What about member alignment??? + self.members.push(mem_t); + self.total_size += size * 8; + } -fn add_member(cx: @mut StructCtxt, - name: &str, - line: int, - size: int, - align: int, - ty: ValueRef) { - cx.members.push(create_derived_type(MemberTag, cx.file, name, line, - size * 8, align * 8, cx.total_size, - ty)); - cx.total_size += size * 8; + fn finalize(&self) -> DICompositeType { + let members_md = create_DIArray(get_builder(self.cx), self.members); + + let struct_md = + do as_c_str(self.name) |name| { unsafe { + llvm::LLVMDIBuilderCreateStructType( + dcx.builder, ptr::null(), name, + self.file, self.line as c_uint, + self.total_size as u64, self.align as u64, 0, ptr::null(), + members_md, 0, ptr::null()) + }}; + return struct_md; + } } -fn create_struct(cx: &mut CrateContext, t: ty::t, fields: ~[ty::field], - span: span) -> @Metadata { +fn create_struct(cx: @CrateContext, t: ty::t, fields: ~[ty::field], span: span) -> DICompositeType { let fname = filename_from_span(cx, span); - let file_node = create_file(cx, fname.to_owned()); - let scx = create_structure(file_node, (ty_to_str(cx.tcx, t)).to_managed(), - line_from_span(cx.sess.codemap, span) as int); + let file_md = create_file(cx, fname); + let line = line_from_span(cx.sess.codemap, span); + + let mut scx = StructContext::create(cx, file_md, ty_to_str(cx.tcx, t), line); for fields.each |field| { let field_t = field.mt.ty; let ty_md = create_ty(cx, field_t, span); let (size, align) = size_and_align_of(cx, field_t); - add_member(scx, cx.sess.str_of(field.ident), - line_from_span(cx.sess.codemap, span) as int, - size as int, align as int, ty_md.node); + scx.add_member(cx.sess.str_of(field.ident), + line_from_span(cx.sess.codemap, span), + size, align, ty_md); } - let mdval = @Metadata { - node: finish_structure(scx), - data: TyDescMetadata { - hash: ty::type_id(t) - } - }; - return mdval; + return scx.finalize(); } -fn create_tuple(cx: &mut CrateContext, t: ty::t, elements: &[ty::t], span: span) - -> @Metadata { +// returns (void* type as a ValueRef, size in bytes, align in bytes) +fn voidptr() -> (DIDerivedType, uint, uint) { + let size = sys::size_of::(); + let align = sys::min_align_of::(); + let vp = ptr::null(); + /* + let vp = create_derived_type(PointerTypeTag, null, ~"", 0, + size, align, 0, null); + */ + return (vp, size, align); +} + +fn create_tuple(cx: @CrateContext, t: ty::t, elements: &[ty::t], span: span) -> DICompositeType { let fname = filename_from_span(cx, span); - let file_node = create_file(cx, fname.to_owned()); - let scx = create_structure(file_node, - cx.sess.str_of( - ((/*bad*/copy cx.dbg_cx).get().names) - ("tuple")), - line_from_span(cx.sess.codemap, span) as int); + let file_md = create_file(cx, fname); + + let name = (cx.sess.str_of((dcx.names)("tuple"))).to_owned(); + let mut scx = StructContext::create(cx, file_md, name, loc.line); + for elements.each |element| { let ty_md = create_ty(cx, *element, span); let (size, align) = size_and_align_of(cx, *element); - add_member(scx, "", line_from_span(cx.sess.codemap, span) as int, - size as int, align as int, ty_md.node); + scx.add_member("", line_from_span(cx.sess.codemap, span), + size, align, ty_md); } - let mdval = @Metadata { - node: finish_structure(scx), - data: TyDescMetadata { - hash: ty::type_id(t) - } - }; - return mdval; -} - -// returns (void* type as a ValueRef, size in bytes, align in bytes) -fn voidptr() -> (ValueRef, int, int) { - let null = ptr::null(); - let size = sys::size_of::() as int; - let align = sys::min_align_of::() as int; - let vp = create_derived_type(PointerTypeTag, null, "", 0, - size, align, 0, null); - return (vp, size, align); + return scx.finalize(); } -fn create_boxed_type(cx: &mut CrateContext, contents: ty::t, - span: span, boxed: @Metadata) - -> @Metadata { - //let tg = StructureTypeTag; - /*let cache = cx.llmetadata; - match cached_metadata::<@Metadata>( - cache, tg, {|md| ty::hash_ty(contents) == ty::hash_ty(md.data.hash)}) { - option::Some(md) { return md; } - option::None {} - }*/ +fn create_boxed_type(cx: @CrateContext, contents: ty::t, + span: span, boxed: DIType) -> DICompositeType { let fname = filename_from_span(cx, span); - let file_node = create_file(cx, fname.to_owned()); - //let cu_node = create_compile_unit_metadata(cx, fname); + let file_md = create_file(cx, fname); let int_t = ty::mk_int(); let refcount_type = create_basic_type(cx, int_t, span); let name = ty_to_str(cx.tcx, contents); - let scx = create_structure(file_node, (fmt!("box<%s>", name)).to_managed(), 0); - add_member(scx, "refcnt", 0, sys::size_of::() as int, - sys::min_align_of::() as int, refcount_type.node); + + let mut scx = StructContext::create(cx, file_md, fmt!("box<%s>", name), 0); + scx.add_member("refcnt", 0, sys::size_of::(), + sys::min_align_of::(), refcount_type); // the tydesc and other pointers should be irrelevant to the // debugger, so treat them as void* types let (vp, vpsize, vpalign) = voidptr(); - add_member(scx, "tydesc", 0, vpsize, vpalign, vp); - add_member(scx, "prev", 0, vpsize, vpalign, vp); - add_member(scx, "next", 0, vpsize, vpalign, vp); + scx.add_member("tydesc", 0, vpsize, vpalign, vp); + scx.add_member("prev", 0, vpsize, vpalign, vp); + scx.add_member("next", 0, vpsize, vpalign, vp); let (size, align) = size_and_align_of(cx, contents); - add_member(scx, "boxed", 0, size, align, boxed.node); - let llnode = finish_structure(scx); - let mdval = @Metadata { - node: llnode, - data: TyDescMetadata { - hash: ty::type_id(contents) - } - }; - //update_cache(cache, tg, tydesc_metadata(mdval)); - add_named_metadata(cx, ~"llvm.dbg.ty", llnode); - return mdval; -} - -fn create_composite_type(type_tag: int, name: &str, file: ValueRef, - line: int, size: int, align: int, offset: int, - derived: Option, - members: Option<~[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 - lli32/*64*/(offset), // offset - lli32(0), // flags - if derived.is_none() { - llnull() - } else { // derived from - derived.get() - }, - if members.is_none() { - llnull() - } else { //members - llmdnode(members.get()) - }, - lli32(0), // runtime language - llnull() - ]; - return llmdnode(lldata); + scx.add_member("boxed", 0, size, align, boxed); + return scx.finalize(); } -fn create_fixed_vec(cx: &mut CrateContext, vec_t: ty::t, elem_t: ty::t, - len: int, span: span) -> @Metadata { - let t_md = create_ty(cx, elem_t, span); +fn create_fixed_vec(cx: @CrateContext, vec_t: ty::t, elem_t: ty::t, + len: uint, span: span) -> DIType { + let elem_ty_md = create_ty(cx, elem_t, span); let fname = filename_from_span(cx, span); - let file_node = create_file(cx, fname.to_owned()); + let file_md = create_file(cx, fname); let (size, align) = size_and_align_of(cx, elem_t); - let subrange = llmdnode([lltag(SubrangeTag), lli64(0), lli64(len - 1)]); - let name = fmt!("[%s]", ty_to_str(cx.tcx, elem_t)); - let array = create_composite_type(ArrayTypeTag, name, file_node.node, 0, - size * len, align, 0, Some(t_md.node), - Some(~[subrange])); - @Metadata { - node: array, - data: TyDescMetadata { - hash: ty::type_id(vec_t) - } - } + + let subrange = unsafe { + llvm::DIBuilder_getOrCreateSubrange(get_builder(cx), 0_i64, (len-1) as i64) }; + + let subscripts = create_DIArray(get_builder(cx), [subrange]); + return unsafe { + llvm::DIBuilder_createVectorType(get_builder(cx), + size * len as u64, align as u64, elem_ty_md, subscripts) + }; } -fn create_boxed_vec(cx: &mut CrateContext, vec_t: ty::t, elem_t: ty::t, - vec_ty_span: codemap::span) - -> @Metadata { +fn create_boxed_vec(cx: @CrateContext, vec_t: ty::t, elem_t: ty::t, + vec_ty_span: codemap::span) -> DICompositeType { let fname = filename_from_span(cx, vec_ty_span); - let file_node = create_file(cx, fname.to_owned()); + let file_md = create_file(cx, fname); let elem_ty_md = create_ty(cx, elem_t, vec_ty_span); - let vec_scx = create_structure(file_node, - ty_to_str(cx.tcx, vec_t).to_managed(), 0); + + let mut vec_scx = StructContext::create(cx, file_md, ty_to_str(cx.tcx, vec_t), 0); + let size_t_type = create_basic_type(cx, ty::mk_uint(), vec_ty_span); - add_member(vec_scx, "fill", 0, sys::size_of::() as int, - sys::min_align_of::() as int, size_t_type.node); - add_member(vec_scx, "alloc", 0, sys::size_of::() as int, - sys::min_align_of::() as int, size_t_type.node); - let subrange = llmdnode([lltag(SubrangeTag), lli64(0), lli64(0)]); + vec_scx.add_member("fill", 0, sys::size_of::(), + sys::min_align_of::(), size_t_type); + vec_scx.add_member("alloc", 0, sys::size_of::(), + sys::min_align_of::(), size_t_type); + let subrange = unsafe { llvm::DIBuilder_getOrCreateSubrange(get_builder(cx), 0_i64, 0_i64) }; let (arr_size, arr_align) = size_and_align_of(cx, elem_t); let name = fmt!("[%s]", ty_to_str(cx.tcx, elem_t)); - let data_ptr = create_composite_type(ArrayTypeTag, name, file_node.node, 0, - arr_size, arr_align, 0, - Some(elem_ty_md.node), - Some(~[subrange])); - add_member(vec_scx, "data", 0, 0, // clang says the size should be 0 - sys::min_align_of::() as int, data_ptr); - let llnode = finish_structure(vec_scx); - let vec_md = @Metadata { - node: llnode, - data: TyDescMetadata { - hash: ty::type_id(vec_t) - } - }; - let box_scx = create_structure(file_node, (fmt!("box<%s>", name)).to_managed(), 0); + let subscripts = create_DIArray(get_builder(cx), [subrange]); + let data_ptr = unsafe { llvm::DIBuilder_createVectorType(get_builder(cx), + arr_size as u64, arr_align as u64, elem_ty_md, subscripts) }; + vec_scx.add_member("data", 0, 0, // clang says the size should be 0 + sys::min_align_of::(), data_ptr); + let vec_md = vec_scx.finalize(); + + let mut box_scx = StructContext::create(cx, file_md, fmt!("box<%s>", name), 0); let int_t = ty::mk_int(); let refcount_type = create_basic_type(cx, int_t, vec_ty_span); - add_member(box_scx, "refcnt", 0, sys::size_of::() as int, - sys::min_align_of::() as int, refcount_type.node); + box_scx.add_member("refcnt", 0, sys::size_of::(), + sys::min_align_of::(), refcount_type); let (vp, vpsize, vpalign) = voidptr(); - add_member(box_scx, "tydesc", 0, vpsize, vpalign, vp); - add_member(box_scx, "prev", 0, vpsize, vpalign, vp); - add_member(box_scx, "next", 0, vpsize, vpalign, vp); - let size = 2 * sys::size_of::() as int; - let align = sys::min_align_of::() as int; - add_member(box_scx, "boxed", 0, size, align, vec_md.node); - let llnode = finish_structure(box_scx); - let mdval = @Metadata { - node: llnode, - data: TyDescMetadata { - hash: ty::type_id(elem_t) - } - }; + box_scx.add_member("tydesc", 0, vpsize, vpalign, vp); + box_scx.add_member("prev", 0, vpsize, vpalign, vp); + box_scx.add_member("next", 0, vpsize, vpalign, vp); + let size = 2 * sys::size_of::(); + let align = sys::min_align_of::(); + box_scx.add_member("boxed", 0, size, align, vec_md); + let mdval = box_scx.finalize(); return mdval; } -fn create_vec_slice(cx: &mut CrateContext, vec_t: ty::t, elem_t: ty::t, span: span) - -> @Metadata { +fn create_vec_slice(cx: @CrateContext, vec_t: ty::t, elem_t: ty::t, span: span) -> DICompositeType { let fname = filename_from_span(cx, span); - let file_node = create_file(cx, fname.to_owned()); + let file_md = create_file(cx, fname); let elem_ty_md = create_ty(cx, elem_t, span); let uint_type = create_basic_type(cx, ty::mk_uint(), span); let elem_ptr = create_pointer_type(cx, elem_t, span, elem_ty_md); - let scx = create_structure(file_node, ty_to_str(cx.tcx, vec_t).to_managed(), 0); + + let mut scx = StructContext::create(cx, file_md, ty_to_str(cx.tcx, vec_t), 0); let (_, ptr_size, ptr_align) = voidptr(); - add_member(scx, "vec", 0, ptr_size, ptr_align, elem_ptr.node); - add_member(scx, "length", 0, sys::size_of::() as int, - sys::min_align_of::() as int, uint_type.node); - let llnode = finish_structure(scx); - let mdval = @Metadata { - node: llnode, - data: TyDescMetadata { - hash: ty::type_id(vec_t) - } - }; - return mdval; + scx.add_member("vec", 0, ptr_size, ptr_align, elem_ptr); + scx.add_member("length", 0, sys::size_of::(), + sys::min_align_of::(), uint_type); + return scx.finalize(); } -fn create_fn_ty(cx: &mut CrateContext, fn_ty: ty::t, inputs: ~[ty::t], output: ty::t, - span: span) -> @Metadata { +fn create_fn_ty(cx: @CrateContext, fn_ty: ty::t, inputs: ~[ty::t], output: ty::t, + span: span) -> DICompositeType { let fname = filename_from_span(cx, span); - let file_node = create_file(cx, fname.to_owned()); + let file_md = create_file(cx, fname); let (vp, _, _) = voidptr(); let output_md = create_ty(cx, output, span); let output_ptr_md = create_pointer_type(cx, output, span, output_md); - let inputs_vals = do inputs.map |arg| { create_ty(cx, *arg, span).node }; - let members = ~[output_ptr_md.node, vp] + inputs_vals; - let llnode = create_composite_type(SubroutineTag, "", file_node.node, - 0, 0, 0, 0, None, Some(members)); - let mdval = @Metadata { - node: llnode, - data: TyDescMetadata { - hash: ty::type_id(fn_ty) - } + let inputs_vals = do inputs.map |arg| { create_ty(cx, *arg, span) }; + let members = ~[output_ptr_md, vp] + inputs_vals; + + return unsafe { + llvm::DIBuilder_createSubroutineType(get_builder(cx), file_md, + create_DIArray(get_builder(cx), members)) }; - return mdval; } -fn create_ty(cx: &mut CrateContext, t: ty::t, span: span) - -> @Metadata { +fn create_ty(cx: @CrateContext, t: ty::t, span: span) -> DIType { + let mut dbg_cx = cx.dbg_cx.get_ref(); + let ty_id = ty::type_id(t); + match dbg_cx.created_types.find(&ty_id) { + Some(ty_md) => return *ty_md, + None => () + } + debug!("create_ty: %?", ty::get(t)); - /*let cache = get_cache(cx); - match cached_metadata::<@Metadata>( - cache, tg, {|md| t == md.data.hash}) { - option::Some(md) { return md; } - option::None {} - }*/ let sty = copy ty::get(t).sty; - match sty { + let ty_md = match sty { ty::ty_nil | ty::ty_bot | ty::ty_bool | ty::ty_int(_) | ty::ty_uint(_) | ty::ty_float(_) => create_basic_type(cx, t, span), ty::ty_estr(ref vstore) => { let i8_t = ty::mk_i8(); match *vstore { ty::vstore_fixed(len) => { - create_fixed_vec(cx, t, i8_t, len as int + 1, span) + create_fixed_vec(cx, t, i8_t, len + 1, span) }, ty::vstore_uniq | ty::vstore_box => { let box_md = create_boxed_vec(cx, t, i8_t, span); @@ -776,7 +527,7 @@ fn create_ty(cx: &mut CrateContext, t: ty::t, span: span) ty::ty_evec(ref mt, ref vstore) => { match *vstore { ty::vstore_fixed(len) => { - create_fixed_vec(cx, t, mt.ty, len as int, span) + create_fixed_vec(cx, t, mt.ty, len, span) }, ty::vstore_uniq | ty::vstore_box => { let box_md = create_boxed_vec(cx, t, mt.ty, span); @@ -812,30 +563,17 @@ fn create_ty(cx: &mut CrateContext, t: ty::t, span: span) ty::ty_tup(ref elements) => { create_tuple(cx, t, *elements, span) }, - _ => cx.sess.bug("debuginfo: unexpected type in create_ty") - } -} - -fn filename_from_span(cx: &CrateContext, sp: codemap::span) -> @str { - cx.sess.codemap.lookup_char_pos(sp.lo).file.name -} + _ => cx.sess.bug(~"debuginfo: unexpected type in create_ty") + }; -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) - ]; - return llmdnode(lldata); + dbg_cx.created_types.insert(ty_id, ty_md); + return ty_md; } -pub fn create_local_var(bcx: block, local: @ast::local) - -> @Metadata { +pub fn create_local_var(bcx: block, local: @ast::local) -> DIVariable { + debug!("create_local_var"); let cx = bcx.ccx(); + /* let cache = get_cache(cx); let tg = AutoVariableTag; match cached_metadata::<@Metadata>( @@ -843,49 +581,56 @@ pub fn create_local_var(bcx: block, local: @ast::local) option::Some(md) => return md, option::None => () } + */ let name = match local.node.pat.node { ast::pat_ident(_, pth, _) => ast_util::path_to_ident(pth), // FIXME this should be handled (#2533) _ => fail!("no single variable name for local") }; - let loc = cx.sess.codemap.lookup_char_pos(local.span.lo); + let name: &str = cx.sess.str_of(ident); + debug!("create_local_var: %s", name); + + let loc = span_start(cx, local.span); let ty = node_id_type(bcx, local.node.id); let tymd = create_ty(cx, ty, local.node.ty.span); - let filemd = create_file(cx, /*bad*/ loc.file.name.to_owned()); + let filemd = create_file(cx, /*bad*/copy loc.file.name); let context = match bcx.parent { - None => create_function(bcx.fcx).node, - Some(_) => create_block(bcx).node + None => create_function(bcx.fcx), + Some(_) => create_block(bcx) }; - let mdnode = create_var(tg, context, cx.sess.str_of(name), - filemd.node, loc.line as int, tymd.node); - let mdval = @Metadata { - node: mdnode, - data: LocalVarMetadata { - id: local.node.id - } - }; - update_cache(cache, AutoVariableTag, local_var_metadata(mdval)); - - // FIXME(#6814) Should use `pat_util::pat_bindings` for pats like (a, b) etc - let llptr = match bcx.fcx.lllocals.find_copy(&local.node.pat.id) { - Some(v) => v, - None => { - bcx.tcx().sess.span_bug( - local.span, - fmt!("No entry in lllocals table for %?", local.node.id)); + + let mdval = do as_c_str(*cx.sess.str_of(name)) |name| { unsafe { + llvm::DIBuilder_createLocalVariable(get_builder(cx), AutoVariableTag as u32, + ptr::null(), name, filemd, loc.line as c_uint, tymd, false, 0, 0) + }}; + + let llptr = match bcx.fcx.lllocals.find(&local.node.id) { + option::Some(&local_mem(v)) => v, + option::Some(_) => { + bcx.tcx().sess.span_bug(local.span, "local is bound to something weird"); } + option::None => { + match bcx.fcx.lllocals.get_copy(&local.node.pat.id) { + local_imm(v) => v, + _ => bcx.tcx().sess.span_bug(local.span, "local is bound to something weird") + } + } }; - let declargs = ~[llmdnode([llptr]), mdnode]; - trans::build::Call(bcx, cx.intrinsics.get_copy(&("llvm.dbg.declare")), + /* + llvm::DIBuilder_insertDeclare(get_builder(cx), llptr, mdval, + + let declargs = ~[llmdnode(~[llptr]), mdnode]; + trans::build::Call(bcx, *cx.intrinsics.get(&~"llvm.dbg.declare"), declargs); + */ return mdval; -} + } -pub fn create_arg(bcx: block, arg: ast::arg, sp: span) - -> Option<@Metadata> { - let fcx = bcx.fcx; - let cx = fcx.ccx; +pub fn create_arg(bcx: block, arg: ast::arg, sp: span) -> Option { + debug!("create_arg"); + let fcx = bcx.fcx, cx = *fcx.ccx; + /* let cache = get_cache(cx); let tg = ArgVariableTag; match cached_metadata::<@Metadata>( @@ -893,6 +638,7 @@ pub fn create_arg(bcx: block, arg: ast::arg, sp: span) option::Some(md) => return Some(md), option::None => () } + */ let loc = cx.sess.codemap.lookup_char_pos(sp.lo); if "" == loc.file.name { @@ -900,35 +646,30 @@ pub fn create_arg(bcx: block, arg: ast::arg, sp: span) } let ty = node_id_type(bcx, arg.id); let tymd = create_ty(cx, ty, arg.ty.span); - let filemd = create_file(cx, /* bad */ loc.file.name.to_owned()); + let filemd = create_file(cx, /*bad*/copy loc.file.name); let context = create_function(bcx.fcx); match arg.pat.node { ast::pat_ident(_, path, _) => { // XXX: This is wrong; it should work for multiple bindings. - let mdnode = create_var( - tg, - context.node, - cx.sess.str_of(*path.idents.last()), - filemd.node, - loc.line as int, - tymd.node - ); - - let mdval = @Metadata { - node: mdnode, - data: ArgumentMetadata { - id: arg.id - } + let ident = path.idents.last(); + let name: &str = cx.sess.str_of(*ident); + let mdnode = do as_c_str(name) |name| { unsafe { + llvm::LLVMDIBuilderCreateLocalVariable(dcx.builder, + ArgVariableTag as u32, context, name, + filemd, loc.line as c_uint, tymd, false, 0, 0) + // XXX need to pass a real argument number + }}; + + let llptr = match fcx.llargs.get_copy(&arg.id) { + local_mem(v) | local_imm(v) => v, }; - update_cache(cache, tg, argument_metadata(mdval)); - - let llptr = fcx.llargs.get_copy(&arg.id); - let declargs = ~[llmdnode([llptr]), mdnode]; - trans::build::Call(bcx, - cx.intrinsics.get_copy(&("llvm.dbg.declare")), - declargs); - return Some(mdval); + + /* + llvm::DIBuilder_insertDeclare(get_builder(cx), mdnode, llptr, mdnode + */ + + return Some(mdnode); } _ => { return None; @@ -936,32 +677,27 @@ pub fn create_arg(bcx: block, arg: ast::arg, sp: span) } } -pub fn update_source_pos(cx: block, s: span) { - if !cx.sess().opts.debuginfo || (*s.lo == 0 && *s.hi == 0) { - return; - } - let cm = cx.sess().codemap; - let blockmd = create_block(cx); - let loc = cm.lookup_char_pos(s.lo); - let scopedata = ~[lli32(loc.line.to_int()), - lli32(loc.col.to_int()), - blockmd.node, - llnull()]; - let dbgscope = llmdnode(scopedata); +fn create_debug_loc(line: int, col: int, scope: DIScope) -> DILocation { + let elems = ~[C_i32(line as i32), C_i32(col as i32), scope, ptr::null()]; unsafe { - llvm::LLVMSetCurrentDebugLocation(trans::build::B(cx), dbgscope); + return llvm::LLVMMDNode(vec::raw::to_ptr(elems), elems.len() as libc::c_uint); } } -pub fn create_function(fcx: fn_ctxt) -> @Metadata { - let mut cx = fcx.ccx; - - debug!("~~"); + let cm = bcx.sess().codemap; + let blockmd = create_block(bcx); + let loc = cm.lookup_char_pos(sp.lo); + let dbgscope = create_debug_loc(loc.line.to_int(), loc.col.to_int(), blockmd); + unsafe { + llvm::LLVMSetCurrentDebugLocation(trans::build::B(bcx), dbgscope); + } +} +pub fn create_function(fcx: fn_ctxt) -> DISubprogram { + let cx = *fcx.ccx; + let mut dbg_cx = cx.dbg_cx.get_ref(); let fcx = &mut *fcx; - let sp = fcx.span.get(); - debug!("%s", cx.sess.codemap.span_to_str(sp)); let (ident, ret_ty, id) = match cx.tcx.items.get_copy(&fcx.id) { ast_map::node_item(item, _) => { @@ -978,7 +714,6 @@ pub fn create_function(fcx: fn_ctxt) -> @Metadata { ast_map::node_expr(expr) => { match expr.node { ast::expr_fn_block(ref decl, _) => { - let dbg_cx = cx.dbg_cx.get_ref(); ((dbg_cx.names)("fn"), decl.output, expr.id) } _ => fcx.ccx.sess.span_bug(expr.span, @@ -988,62 +723,46 @@ pub fn create_function(fcx: fn_ctxt) -> @Metadata { _ => fcx.ccx.sess.bug("create_function: unexpected sort of node") }; - debug!("%?", ident); - debug!("%?", id); - - let cache = get_cache(cx); - match cached_metadata::<@Metadata>( - cache, SubprogramTag, |md| md.data.id == id) { - option::Some(md) => return md, - option::None => () + match dbg_cx.created_functions.find(&id) { + Some(fn_md) => return *fn_md, + None => () } + debug!("create_function: %s, %s", cx.sess.str_of(ident), cx.sess.codemap.span_to_str(span)); + let loc = cx.sess.codemap.lookup_char_pos(sp.lo); - let file_node = create_file(cx, loc.file.name.to_owned()).node; - let ty_node = if cx.sess.opts.extra_debuginfo { + let file_md = create_file(cx, loc.file.name); + + let ret_ty_md = if cx.sess.opts.extra_debuginfo { match ret_ty.node { - ast::ty_nil => llnull(), + ast::ty_nil => ptr::null(), _ => create_ty(cx, ty::node_id_to_type(cx.tcx, id), - ret_ty.span).node + ret_ty.span) } } else { - llnull() + ptr::null() }; - 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, - llstr(cx.sess.str_of(ident)), - //XXX fully-qualified C++ name: - llstr(cx.sess.str_of(ident)), - llstr(""), //XXX MIPS name????? - file_node, - lli32(loc.line as int), - sub_node, - lli1(false), //XXX static (check export) - lli1(true), // defined in compilation unit - lli32(DW_VIRTUALITY_none), // virtual-ness - lli32(0i), //index into virt func - /*llnull()*/ lli32(0), // base type with vtbl - lli32(256), // flags - lli1(cx.sess.opts.optimize != session::No), - 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 = @Metadata { - node: val, - data: SubProgramMetadata { - id: id - } - }; - update_cache(cache, SubprogramTag, subprogram_metadata(mdval)); - return mdval; + let fn_ty = unsafe { + llvm::DIBuilder_createSubroutineType(get_builder(cx), + file_md, create_DIArray(get_builder(cx), [ret_ty_md])) + }; + + let fn_md = + do as_c_str(cx.sess.str_of(ident)) |name| { + do as_c_str(cx.sess.str_of(ident)) |linkage| { unsafe { + llvm::LLVMDIBuilderCreateFunction( + dcx.builder, + file_md, + name, linkage, + file_md, loc.line as c_uint, + fn_ty, false, true, + loc.line as c_uint, + FlagPrototyped as c_uint, + cx.sess.opts.optimize != session::No, + fcx.llfn, ptr::null(), ptr::null()) + }}}; + + dbg_cx.created_functions.insert(id, fn_md); + return fn_md; } diff --git a/src/rustllvm/RustWrapper.cpp b/src/rustllvm/RustWrapper.cpp index ba87624e2dde3..315e7c4bcb120 100644 --- a/src/rustllvm/RustWrapper.cpp +++ b/src/rustllvm/RustWrapper.cpp @@ -560,3 +560,204 @@ extern "C" bool LLVMRustStartMultithreading() { assert(lock.release()); return ret; } + + +typedef DIBuilder* DIBuilderRef; + +template +DIT unwrapDI(LLVMValueRef ref) { return DIT(ref ? unwrap(ref) : NULL); } + +extern "C" DIBuilderRef DIBuilder_new(LLVMModuleRef M) { + return new DIBuilder(*unwrap(M)); +} + +extern "C" void DIBuilder_delete(DIBuilderRef Builder) { + delete Builder; +} + +extern "C" void DIBuilder_finalize(DIBuilderRef Builder) { + Builder->finalize(); +} + +extern "C" void DIBuilder_createCompileUnit( + DIBuilderRef Builder, + unsigned Lang, + const char* File, + const char* Dir, + const char* Producer, + bool isOptimized, + const char* Flags, + unsigned RuntimeVer, + const char* SplitName) { + Builder->createCompileUnit(Lang, File, Dir, Producer, isOptimized, + Flags, RuntimeVer, SplitName); +} + +extern "C" LLVMValueRef DIBuilder_createFile( + DIBuilderRef Builder, + const char* Filename, + const char* Directory) { + return wrap(Builder->createFile(Filename, Directory)); +} + +extern "C" LLVMValueRef DIBuilder_createSubroutineType( + DIBuilderRef Builder, + LLVMValueRef File, + LLVMValueRef ParameterTypes) { + return wrap(Builder->createSubroutineType( + unwrapDI(File), + unwrapDI(ParameterTypes))); +} + +extern "C" LLVMValueRef DIBuilder_createFunction( + DIBuilderRef Builder, + LLVMValueRef Scope, + const char* Name, + const char* LinkageName, + LLVMValueRef File, + unsigned LineNo, + LLVMValueRef Ty, + bool isLocalToUnit, + bool isDefinition, + unsigned ScopeLine, + unsigned Flags, + bool isOptimized, + LLVMValueRef Fn, + LLVMValueRef TParam, + LLVMValueRef Decl) { + return wrap(Builder->createFunction( + unwrapDI(Scope), Name, LinkageName, + unwrapDI(File), LineNo, + unwrapDI(Ty), isLocalToUnit, isDefinition, ScopeLine, + Flags, isOptimized, + unwrap(Fn), + unwrapDI(TParam), + unwrapDI(Decl))); +} + +extern "C" LLVMValueRef DIBuilder_createBasicType( + DIBuilderRef Builder, + const char* Name, + uint64_t SizeInBits, + uint64_t AlignInBits, + unsigned Encoding) { + return wrap(Builder->createBasicType( + Name, SizeInBits, + AlignInBits, Encoding)); +} + +extern "C" LLVMValueRef DIBuilder_createPointerType( + DIBuilderRef Builder, + LLVMValueRef PointeeTy, + uint64_t SizeInBits, + uint64_t AlignInBits, + const char* Name) { + return wrap(Builder->createPointerType( + unwrapDI(PointeeTy), SizeInBits, AlignInBits, Name)); +} + +extern "C" LLVMValueRef DIBuilder_createStructType( + DIBuilderRef Builder, + LLVMValueRef Scope, + const char* Name, + LLVMValueRef File, + unsigned LineNumber, + uint64_t SizeInBits, + uint64_t AlignInBits, + unsigned Flags, + LLVMValueRef DerivedFrom, + LLVMValueRef Elements, + unsigned RunTimeLang, + LLVMValueRef VTableHolder) { + return wrap(Builder->createStructType( + unwrapDI(Scope), Name, + unwrapDI(File), LineNumber, + SizeInBits, AlignInBits, Flags, + unwrapDI(DerivedFrom), + unwrapDI(Elements), RunTimeLang, + unwrapDI(VTableHolder))); +} + +extern "C" LLVMValueRef DIBuilder_createMemberType( + DIBuilderRef Builder, + LLVMValueRef Scope, + const char* Name, + LLVMValueRef File, + unsigned LineNo, + uint64_t SizeInBits, + uint64_t AlignInBits, + uint64_t OffsetInBits, + unsigned Flags, + LLVMValueRef Ty) { + return wrap(Builder->createMemberType( + unwrapDI(Scope), Name, + unwrapDI(File), LineNo, + SizeInBits, AlignInBits, OffsetInBits, Flags, + unwrapDI(Ty))); +} + +extern "C" LLVMValueRef DIBuilder_createLexicalBlock( + DIBuilderRef Builder, + LLVMValueRef Scope, + LLVMValueRef File, + unsigned Line, + unsigned Col) { + return wrap(Builder->createLexicalBlock( + unwrapDI(Scope), + unwrapDI(File), Line, Col)); +} + +extern "C" LLVMValueRef DIBuilder_createLocalVariable( + DIBuilderRef Builder, + unsigned Tag, + LLVMValueRef Scope, + const char* Name, + LLVMValueRef File, + unsigned LineNo, + LLVMValueRef Ty, + bool AlwaysPreserve, + unsigned Flags, + unsigned ArgNo) { + return wrap(Builder->createLocalVariable(Tag, + unwrapDI(Scope), Name, + unwrapDI(File), + LineNo, + unwrapDI(Ty), AlwaysPreserve, Flags, ArgNo)); +} + +extern "C" LLVMValueRef DIBuilder_createVectorType( + DIBuilderRef Builder, + uint64_t Size, + uint64_t AlignInBits, + LLVMValueRef Ty, + LLVMValueRef Subscripts) { + return wrap(Builder->createVectorType(Size, AlignInBits, + unwrapDI(Ty), + unwrapDI(Subscripts))); +} + +extern "C" LLVMValueRef DIBuilder_getOrCreateSubrange( + DIBuilderRef Builder, + int64_t Lo, + int64_t Count) { + return wrap(Builder->getOrCreateSubrange(Lo, Count)); +} + +extern "C" LLVMValueRef DIBuilder_getOrCreateArray( + DIBuilderRef Builder, + LLVMValueRef* Ptr, + unsigned Count) { + return wrap(Builder->getOrCreateArray( + ArrayRef(reinterpret_cast(Ptr), Count))); +} + +extern "C" LLVMValueRef DIBuilder_insertDeclare( + DIBuilderRef Builder, + LLVMValueRef Val, + LLVMValueRef VarInfo, + LLVMValueRef InsertBefore) { + return wrap(Builder->insertDeclare( + unwrap(Val), + unwrapDI(VarInfo), + unwrap(InsertBefore))); +} diff --git a/src/rustllvm/rustllvm.def.in b/src/rustllvm/rustllvm.def.in index f539716578199..71d574aecbec0 100644 --- a/src/rustllvm/rustllvm.def.in +++ b/src/rustllvm/rustllvm.def.in @@ -588,3 +588,20 @@ LLVMInlineAsm LLVMInitializePasses LLVMAddPass LLVMCreatePass +DIBuilder_new +DIBuilder_delete +DIBuilder_finalize +DIBuilder_createCompileUnit +DIBuilder_createLocalVariable +DIBuilder_createFunction +DIBuilder_createFile +DIBuilder_createLexicalBlock +DIBuilder_createBasicType +DIBuilder_createPointerType +DIBuilder_createMemberType +DIBuilder_createStructType +DIBuilder_getOrCreateSubrange +DIBuilder_createVectorType +DIBuilder_createSubroutineType +DIBuilder_getOrCreateArray +DIBuilder_insertDeclare diff --git a/src/rustllvm/rustllvm.h b/src/rustllvm/rustllvm.h index 6f11202800cd7..d4202abd2854e 100644 --- a/src/rustllvm/rustllvm.h +++ b/src/rustllvm/rustllvm.h @@ -43,6 +43,8 @@ #include "llvm/Transforms/IPO.h" #include "llvm/Transforms/Instrumentation.h" #include "llvm/Transforms/Vectorize.h" +#include "llvm/DebugInfo.h" +#include "llvm/DIBuilder.h" #include "llvm-c/Core.h" #include "llvm-c/BitReader.h" #include "llvm-c/ExecutionEngine.h" From 6cc318978796ca67e9350561601dee9931c1da12 Mon Sep 17 00:00:00 2001 From: Vadim Chugunov Date: Tue, 11 Jun 2013 00:57:25 -0700 Subject: [PATCH 02/11] Made the while DebugContext mutable, not just created_* hashes Disabled create_arg --- src/librustc/lib/llvm.rs | 43 +-- src/librustc/middle/trans/debuginfo.rs | 349 +++++++++++++------------ src/rustllvm/RustWrapper.cpp | 45 ++-- src/rustllvm/rustllvm.def.in | 35 +-- 4 files changed, 248 insertions(+), 224 deletions(-) diff --git a/src/librustc/lib/llvm.rs b/src/librustc/lib/llvm.rs index ece0c1cb19092..a367de059b8bf 100644 --- a/src/librustc/lib/llvm.rs +++ b/src/librustc/lib/llvm.rs @@ -1925,16 +1925,16 @@ pub mod llvm { #[fast_ffi] - pub unsafe fn DIBuilder_new(M: ModuleRef) -> DIBuilderRef; + pub unsafe fn LLVMDIBuilderCreate(M: ModuleRef) -> DIBuilderRef; #[fast_ffi] - pub unsafe fn DIBuilder_delete(Builder: DIBuilderRef); + pub unsafe fn LLVMDIBuilderDispose(Builder: DIBuilderRef); #[fast_ffi] - pub unsafe fn DIBuilder_finalize(Builder: DIBuilderRef); + pub unsafe fn LLVMDIBuilderFinalize(Builder: DIBuilderRef); #[fast_ffi] - pub unsafe fn DIBuilder_createCompileUnit( + pub unsafe fn LLVMDIBuilderCreateCompileUnit( Builder: DIBuilderRef, Lang: c_uint, File: *c_char, @@ -1946,19 +1946,19 @@ pub mod llvm { SplitName: *c_char); #[fast_ffi] - pub unsafe fn DIBuilder_createFile( + pub unsafe fn LLVMDIBuilderCreateFile( Builder: DIBuilderRef, Filename: *c_char, Directory: *c_char) -> DIFile; #[fast_ffi] - pub unsafe fn DIBuilder_createSubroutineType( + pub unsafe fn LLVMDIBuilderCreateSubroutineType( Builder: DIBuilderRef, File: DIFile, ParameterTypes: DIArray) -> DICompositeType; #[fast_ffi] - pub unsafe fn DIBuilder_createFunction( + pub unsafe fn LLVMDIBuilderCreateFunction( Builder: DIBuilderRef, Scope: DIDescriptor, Name: *c_char, @@ -1976,7 +1976,7 @@ pub mod llvm { Decl: ValueRef) -> DISubprogram; #[fast_ffi] - pub unsafe fn DIBuilder_createBasicType( + pub unsafe fn LLVMDIBuilderCreateBasicType( Builder: DIBuilderRef, Name: *c_char, SizeInBits: c_ulonglong, @@ -1984,7 +1984,7 @@ pub mod llvm { Encoding: c_uint) -> DIBasicType; #[fast_ffi] - pub unsafe fn DIBuilder_createPointerType( + pub unsafe fn LLVMDIBuilderCreatePointerType( Builder: DIBuilderRef, PointeeTy: DIType, SizeInBits: c_ulonglong, @@ -1992,7 +1992,7 @@ pub mod llvm { Name: *c_char) -> DIDerivedType; #[fast_ffi] - pub unsafe fn DIBuilder_createStructType( + pub unsafe fn LLVMDIBuilderCreateStructType( Builder: DIBuilderRef, Scope: DIDescriptor, Name: *c_char, @@ -2007,7 +2007,7 @@ pub mod llvm { VTableHolder: ValueRef) -> DICompositeType; #[fast_ffi] - pub unsafe fn DIBuilder_createMemberType( + pub unsafe fn LLVMDIBuilderCreateMemberType( Builder: DIBuilderRef, Scope: DIDescriptor, Name: *c_char, @@ -2020,7 +2020,7 @@ pub mod llvm { Ty: DIType) -> DIDerivedType; #[fast_ffi] - pub unsafe fn DIBuilder_createLexicalBlock( + pub unsafe fn LLVMDIBuilderCreateLexicalBlock( Builder: DIBuilderRef, Scope: DIDescriptor, File: DIFile, @@ -2028,7 +2028,7 @@ pub mod llvm { Col: c_uint) -> DILexicalBlock; #[fast_ffi] - pub unsafe fn DIBuilder_createLocalVariable( + pub unsafe fn LLVMDIBuilderCreateLocalVariable( Builder: DIBuilderRef, Tag: c_uint, Scope: DIDescriptor, @@ -2041,7 +2041,7 @@ pub mod llvm { ArgNo: c_uint) -> DIVariable; #[fast_ffi] - pub unsafe fn DIBuilder_createVectorType( + pub unsafe fn LLVMDIBuilderCreateVectorType( Builder: DIBuilderRef, Size: c_ulonglong, AlignInBits: c_ulonglong, @@ -2049,23 +2049,30 @@ pub mod llvm { Subscripts: DIArray) -> DIType; #[fast_ffi] - pub unsafe fn DIBuilder_getOrCreateSubrange( + pub unsafe fn LLVMDIBuilderGetOrCreateSubrange( Builder: DIBuilderRef, Lo: c_longlong, Count: c_longlong) -> DISubrange; #[fast_ffi] - pub unsafe fn DIBuilder_getOrCreateArray( + pub unsafe fn LLVMDIBuilderGetOrCreateArray( Builder: DIBuilderRef, Ptr: *DIDescriptor, Count: c_uint) -> DIArray; #[fast_ffi] - pub unsafe fn DIBuilder_insertDeclare( + pub unsafe fn LLVMDIBuilderInsertDeclareAtEnd( Builder: DIBuilderRef, Val: ValueRef, VarInfo: DIVariable, - InsertBefore: *c_void) -> *c_void; + InsertAtEnd: BasicBlockRef) -> ValueRef; + + #[fast_ffi] + pub unsafe fn LLVMDIBuilderInsertDeclareBefore( + Builder: DIBuilderRef, + Val: ValueRef, + VarInfo: DIVariable, + InsertBefore: ValueRef) -> ValueRef; } } diff --git a/src/librustc/middle/trans/debuginfo.rs b/src/librustc/middle/trans/debuginfo.rs index a01c2b89bf9d0..2a1b2b575f7e4 100644 --- a/src/librustc/middle/trans/debuginfo.rs +++ b/src/librustc/middle/trans/debuginfo.rs @@ -24,7 +24,11 @@ use util::ppaux::ty_to_str; use core::hashmap::HashMap; use core::libc; use core::libc::c_uint; +use core::ptr; +use core::str; use core::str::as_c_str; +use core::sys; +use core::vec; use syntax::codemap::span; use syntax::parse::token::ident_interner; use syntax::{ast, codemap, ast_util, ast_map}; @@ -57,43 +61,45 @@ static DW_ATE_unsigned_char: int = 0x08; //////////////// -pub struct DebugContext { - //llmetadata: metadata_cache, +pub type DebugContext = @mut _DebugContext; + +struct _DebugContext { names: namegen, crate_file: ~str, builder: DIBuilderRef, - - created_files: @mut HashMap<~str, DIFile>, - created_functions: @mut HashMap, - created_blocks: @mut HashMap, - created_types: @mut HashMap + curr_loc: (int, int), + created_files: HashMap<~str, DIFile>, + created_functions: HashMap, + created_blocks: HashMap, + created_types: HashMap } /** Create new DebugContext */ pub fn mk_ctxt(llmod: ModuleRef, crate: ~str, intr: @ident_interner) -> DebugContext { debug!("mk_ctxt"); - let builder = unsafe { llvm::DIBuilder_new(llmod) }; - DebugContext { - //llmetadata: @mut HashMap::new(), + let builder = unsafe { llvm::LLVMDIBuilderCreate(llmod) }; + let dcx = @mut _DebugContext { names: new_namegen(intr), crate_file: crate, builder: builder, - created_files: @mut HashMap::new(), - created_functions: @mut HashMap::new(), - created_blocks: @mut HashMap::new(), - created_types: @mut HashMap::new(), -} + curr_loc: (-1, -1), + created_files: HashMap::new(), + created_functions: HashMap::new(), + created_blocks: HashMap::new(), + created_types: HashMap::new(), + }; + return dcx; } #[inline(always)] -fn get_builder(cx: @CrateContext) -> DIBuilderRef { - let dbg_cx = cx.dbg_cx.get_ref(); - return dbg_cx.builder; +fn dbg_cx(cx: &CrateContext) -> DebugContext +{ + return cx.dbg_cx.get(); } fn create_DIArray(builder: DIBuilderRef, arr: &[DIDescriptor]) -> DIArray { return unsafe { - llvm::DIBuilder_getOrCreateArray(builder, vec::raw::to_ptr(arr), arr.len() as u32) + llvm::LLVMDIBuilderGetOrCreateArray(builder, vec::raw::to_ptr(arr), arr.len() as u32) }; } @@ -101,9 +107,10 @@ fn create_DIArray(builder: DIBuilderRef, arr: &[DIDescriptor]) -> DIArray { pub fn finalize(cx: @CrateContext) { debug!("finalize"); create_compile_unit(cx); - unsafe { - llvm::DIBuilder_finalize(get_builder(cx)); - llvm::DIBuilder_delete(get_builder(cx)); + let dcx = dbg_cx(cx); + unsafe { + llvm::LLVMDIBuilderFinalize(dcx.builder); + llvm::LLVMDIBuilderDispose(dcx.builder); }; } @@ -123,52 +130,52 @@ fn get_file_path_and_dir(work_dir: &str, full_path: &str) -> (~str, ~str) { str::len(full_path)).to_owned() } else { full_path.to_owned() - }; + }; return (full_path, work_dir.to_owned()); } fn create_compile_unit(cx: @CrateContext) { - let crate_name: &str = cx.dbg_cx.get_ref().crate_file; + let crate_name: &str = dbg_cx(cx).crate_file; let (_, work_dir) = get_file_path_and_dir( cx.sess.working_dir.to_str(), crate_name); let producer = fmt!("rustc version %s", env!("CFG_VERSION")); - + do as_c_str(crate_name) |crate_name| { do as_c_str(work_dir) |work_dir| { do as_c_str(producer) |producer| { do as_c_str("") |flags| { do as_c_str("") |split_name| { unsafe { - llvm::DIBuilder_createCompileUnit(get_builder(cx), - DW_LANG_RUST as c_uint, crate_name, work_dir, producer, + llvm::LLVMDIBuilderCreateCompileUnit(dbg_cx(cx).builder, + DW_LANG_RUST as c_uint, crate_name, work_dir, producer, cx.sess.opts.optimize != session::No, flags, 0, split_name); }}}}}}; } fn create_file(cx: @CrateContext, full_path: &str) -> DIFile { - let mut dbg_cx = cx.dbg_cx.get_ref(); - - match dbg_cx.created_files.find(&full_path.to_owned()) { + let dcx = dbg_cx(cx); + + match dcx.created_files.find(&full_path.to_owned()) { Some(file_md) => return *file_md, None => () } debug!("create_file: %s", full_path); - + let (file_path, work_dir) = get_file_path_and_dir(cx.sess.working_dir.to_str(), full_path); - let file_md = + let file_md = do as_c_str(file_path) |file_path| { do as_c_str(work_dir) |work_dir| { unsafe { - llvm::DIBuilder_createFile(get_builder(cx), file_path, work_dir) + llvm::LLVMDIBuilderCreateFile(dcx.builder, file_path, work_dir) }}}; - - dbg_cx.created_files.insert(full_path.to_owned(), file_md); + + dcx.created_files.insert(full_path.to_owned(), file_md); return file_md; } @@ -178,8 +185,9 @@ fn line_from_span(cm: @codemap::CodeMap, sp: span) -> uint { fn create_block(bcx: block) -> DILexicalBlock { let mut bcx = bcx; - let mut dbg_cx = bcx.ccx().dbg_cx.get_ref(); - + let cx = bcx.ccx(); + let mut dcx = dbg_cx(cx); + while bcx.node_info.is_none() { match bcx.parent { Some(b) => bcx = b, @@ -188,33 +196,33 @@ fn create_block(bcx: block) -> DILexicalBlock { } let sp = bcx.node_info.get().span; let id = bcx.node_info.get().id; - - match dbg_cx.created_blocks.find(&id) { + + match dcx.created_blocks.find(&id) { Some(block) => return *block, None => () } - + debug!("create_block: %s", bcx.sess().codemap.span_to_str(sp)); - + let start = bcx.sess().codemap.lookup_char_pos(sp.lo); - let end = bcx.sess().codemap.lookup_char_pos(sp.hi); + //let end = bcx.sess().codemap.lookup_char_pos(sp.hi); let parent = match bcx.parent { None => create_function(bcx.fcx), Some(b) => create_block(b) }; - + let file_md = create_file(bcx.ccx(), start.file.name); - let block_md = unsafe { + let block_md = unsafe { llvm::LLVMDIBuilderCreateLexicalBlock( - dcx.builder, - parent, file_md, + dcx.builder, + parent, file_md, start.line.to_int() as c_uint, start.col.to_int() as c_uint) }; - - dbg_cx.created_blocks.insert(id, block_md); - + + dcx.created_blocks.insert(id, block_md); + return block_md; } @@ -225,14 +233,14 @@ fn size_and_align_of(cx: @CrateContext, t: ty::t) -> (uint, uint) { } fn create_basic_type(cx: @CrateContext, t: ty::t, span: span) -> DIType{ - let mut dbg_cx = cx.dbg_cx.get_ref(); + let mut dcx = dbg_cx(cx); let ty_id = ty::type_id(t); - match dbg_cx.created_types.find(&ty_id) { + match dcx.created_types.find(&ty_id) { Some(ty_md) => return *ty_md, None => () } - - debug!("create_basic_type: %?", ty::get(t)); + + debug!("create_basic_type: %?", ty::get(t)); let (name, encoding) = match ty::get(t).sty { ty::ty_nil | ty::ty_bot => (~"uint", DW_ATE_unsigned), @@ -263,11 +271,11 @@ fn create_basic_type(cx: @CrateContext, t: ty::t, span: span) -> DIType{ let (size, align) = size_and_align_of(cx, t); let ty_md = do as_c_str(name) |name| { unsafe { llvm::LLVMDIBuilderCreateBasicType( - dcx.builder, name, + dcx.builder, name, size * 8 as u64, align * 8 as u64, encoding as c_uint) }}; - - dbg_cx.created_types.insert(ty_id, ty_md); + + dcx.created_types.insert(ty_id, ty_md); return ty_md; } @@ -275,7 +283,7 @@ fn create_pointer_type(cx: @CrateContext, t: ty::t, span: span, pointee: DIType) let (size, align) = size_and_align_of(cx, t); let name = ty_to_str(cx.tcx, t); let ptr_md = do as_c_str(name) |name| { unsafe { - llvm::DIBuilder_createPointerType(get_builder(cx), + llvm::LLVMDIBuilderCreatePointerType(dbg_cx(cx).builder, pointee, size * 8 as u64, align * 8 as u64, name) }}; return ptr_md; @@ -304,11 +312,11 @@ impl StructContext { }; return scx; } - + fn add_member(&mut self, name: &str, line: uint, size: uint, align: uint, ty: DIType) { let mem_t = do as_c_str(name) |name| { unsafe { - llvm::DIBuilder_createMemberType(get_builder(self.cx), - ptr::null(), name, self.file, line as c_uint, + llvm::LLVMDIBuilderCreateMemberType(dbg_cx(self.cx).builder, + ptr::null(), name, self.file, line as c_uint, size * 8 as u64, align * 8 as u64, self.total_size as u64, 0, ty) }}; @@ -316,11 +324,12 @@ impl StructContext { self.members.push(mem_t); self.total_size += size * 8; } - + fn finalize(&self) -> DICompositeType { - let members_md = create_DIArray(get_builder(self.cx), self.members); - - let struct_md = + let dcx = dbg_cx(self.cx); + let members_md = create_DIArray(dcx.builder, self.members); + + let struct_md = do as_c_str(self.name) |name| { unsafe { llvm::LLVMDIBuilderCreateStructType( dcx.builder, ptr::null(), name, @@ -336,7 +345,7 @@ fn create_struct(cx: @CrateContext, t: ty::t, fields: ~[ty::field], span: span) let fname = filename_from_span(cx, span); let file_md = create_file(cx, fname); let line = line_from_span(cx.sess.codemap, span); - + let mut scx = StructContext::create(cx, file_md, ty_to_str(cx.tcx, t), line); for fields.each |field| { let field_t = field.mt.ty; @@ -350,24 +359,24 @@ fn create_struct(cx: @CrateContext, t: ty::t, fields: ~[ty::field], span: span) } // returns (void* type as a ValueRef, size in bytes, align in bytes) -fn voidptr() -> (DIDerivedType, uint, uint) { +fn voidptr(cx: @CrateContext) -> (DIDerivedType, uint, uint) { let size = sys::size_of::(); let align = sys::min_align_of::(); - let vp = ptr::null(); - /* - let vp = create_derived_type(PointerTypeTag, null, ~"", 0, - size, align, 0, null); - */ + let vp = do as_c_str("*void") |name| { unsafe { + llvm::LLVMDIBuilderCreatePointerType(dbg_cx(cx).builder, ptr::null(), + size*8 as u64, align*8 as u64, name) + }}; return (vp, size, align); } fn create_tuple(cx: @CrateContext, t: ty::t, elements: &[ty::t], span: span) -> DICompositeType { + let dcx = dbg_cx(cx); let fname = filename_from_span(cx, span); let file_md = create_file(cx, fname); let name = (cx.sess.str_of((dcx.names)("tuple"))).to_owned(); let mut scx = StructContext::create(cx, file_md, name, loc.line); - + for elements.each |element| { let ty_md = create_ty(cx, *element, span); let (size, align) = size_and_align_of(cx, *element); @@ -384,13 +393,13 @@ fn create_boxed_type(cx: @CrateContext, contents: ty::t, let int_t = ty::mk_int(); let refcount_type = create_basic_type(cx, int_t, span); let name = ty_to_str(cx.tcx, contents); - + let mut scx = StructContext::create(cx, file_md, fmt!("box<%s>", name), 0); scx.add_member("refcnt", 0, sys::size_of::(), sys::min_align_of::(), refcount_type); // the tydesc and other pointers should be irrelevant to the // debugger, so treat them as void* types - let (vp, vpsize, vpalign) = voidptr(); + let (vp, vpsize, vpalign) = voidptr(cx); scx.add_member("tydesc", 0, vpsize, vpalign, vp); scx.add_member("prev", 0, vpsize, vpalign, vp); scx.add_member("next", 0, vpsize, vpalign, vp); @@ -401,40 +410,42 @@ fn create_boxed_type(cx: @CrateContext, contents: ty::t, fn create_fixed_vec(cx: @CrateContext, vec_t: ty::t, elem_t: ty::t, len: uint, span: span) -> DIType { + let dcx = dbg_cx(cx); let elem_ty_md = create_ty(cx, elem_t, span); let fname = filename_from_span(cx, span); let file_md = create_file(cx, fname); let (size, align) = size_and_align_of(cx, elem_t); - let subrange = unsafe { - llvm::DIBuilder_getOrCreateSubrange(get_builder(cx), 0_i64, (len-1) as i64) }; + let subrange = unsafe { + llvm::LLVMDIBuilderGetOrCreateSubrange(dcx.builder, 0_i64, (len-1) as i64) }; - let subscripts = create_DIArray(get_builder(cx), [subrange]); - return unsafe { - llvm::DIBuilder_createVectorType(get_builder(cx), + let subscripts = create_DIArray(dcx.builder, [subrange]); + return unsafe { + llvm::LLVMDIBuilderCreateVectorType(dcx.builder, size * len as u64, align as u64, elem_ty_md, subscripts) }; } fn create_boxed_vec(cx: @CrateContext, vec_t: ty::t, elem_t: ty::t, vec_ty_span: codemap::span) -> DICompositeType { + let dcx = dbg_cx(cx); let fname = filename_from_span(cx, vec_ty_span); let file_md = create_file(cx, fname); let elem_ty_md = create_ty(cx, elem_t, vec_ty_span); - + let mut vec_scx = StructContext::create(cx, file_md, ty_to_str(cx.tcx, vec_t), 0); - + let size_t_type = create_basic_type(cx, ty::mk_uint(), vec_ty_span); vec_scx.add_member("fill", 0, sys::size_of::(), sys::min_align_of::(), size_t_type); vec_scx.add_member("alloc", 0, sys::size_of::(), sys::min_align_of::(), size_t_type); - let subrange = unsafe { llvm::DIBuilder_getOrCreateSubrange(get_builder(cx), 0_i64, 0_i64) }; + let subrange = unsafe { llvm::LLVMDIBuilderGetOrCreateSubrange(dcx.builder, 0_i64, 0_i64) }; let (arr_size, arr_align) = size_and_align_of(cx, elem_t); let name = fmt!("[%s]", ty_to_str(cx.tcx, elem_t)); - - let subscripts = create_DIArray(get_builder(cx), [subrange]); - let data_ptr = unsafe { llvm::DIBuilder_createVectorType(get_builder(cx), + + let subscripts = create_DIArray(dcx.builder, [subrange]); + let data_ptr = unsafe { llvm::LLVMDIBuilderCreateVectorType(dcx.builder, arr_size as u64, arr_align as u64, elem_ty_md, subscripts) }; vec_scx.add_member("data", 0, 0, // clang says the size should be 0 sys::min_align_of::(), data_ptr); @@ -445,7 +456,7 @@ fn create_boxed_vec(cx: @CrateContext, vec_t: ty::t, elem_t: ty::t, let refcount_type = create_basic_type(cx, int_t, vec_ty_span); box_scx.add_member("refcnt", 0, sys::size_of::(), sys::min_align_of::(), refcount_type); - let (vp, vpsize, vpalign) = voidptr(); + let (vp, vpsize, vpalign) = voidptr(cx); box_scx.add_member("tydesc", 0, vpsize, vpalign, vp); box_scx.add_member("prev", 0, vpsize, vpalign, vp); box_scx.add_member("next", 0, vpsize, vpalign, vp); @@ -462,9 +473,9 @@ fn create_vec_slice(cx: @CrateContext, vec_t: ty::t, elem_t: ty::t, span: span) let elem_ty_md = create_ty(cx, elem_t, span); let uint_type = create_basic_type(cx, ty::mk_uint(), span); let elem_ptr = create_pointer_type(cx, elem_t, span, elem_ty_md); - + let mut scx = StructContext::create(cx, file_md, ty_to_str(cx.tcx, vec_t), 0); - let (_, ptr_size, ptr_align) = voidptr(); + let (_, ptr_size, ptr_align) = voidptr(cx); scx.add_member("vec", 0, ptr_size, ptr_align, elem_ptr); scx.add_member("length", 0, sys::size_of::(), sys::min_align_of::(), uint_type); @@ -473,24 +484,25 @@ fn create_vec_slice(cx: @CrateContext, vec_t: ty::t, elem_t: ty::t, span: span) fn create_fn_ty(cx: @CrateContext, fn_ty: ty::t, inputs: ~[ty::t], output: ty::t, span: span) -> DICompositeType { + let dcx = dbg_cx(cx); let fname = filename_from_span(cx, span); let file_md = create_file(cx, fname); - let (vp, _, _) = voidptr(); + let (vp, _, _) = voidptr(cx); let output_md = create_ty(cx, output, span); let output_ptr_md = create_pointer_type(cx, output, span, output_md); let inputs_vals = do inputs.map |arg| { create_ty(cx, *arg, span) }; let members = ~[output_ptr_md, vp] + inputs_vals; - - return unsafe { - llvm::DIBuilder_createSubroutineType(get_builder(cx), file_md, - create_DIArray(get_builder(cx), members)) + + return unsafe { + llvm::LLVMDIBuilderCreateSubroutineType(dcx.builder, file_md, + create_DIArray(dcx.builder, members)) }; } fn create_ty(cx: @CrateContext, t: ty::t, span: span) -> DIType { - let mut dbg_cx = cx.dbg_cx.get_ref(); + let mut dcx = dbg_cx(cx); let ty_id = ty::type_id(t); - match dbg_cx.created_types.find(&ty_id) { + match dcx.created_types.find(&ty_id) { Some(ty_md) => return *ty_md, None => () } @@ -565,25 +577,16 @@ fn create_ty(cx: @CrateContext, t: ty::t, span: span) -> DIType { }, _ => cx.sess.bug(~"debuginfo: unexpected type in create_ty") }; - - dbg_cx.created_types.insert(ty_id, ty_md); + + dcx.created_types.insert(ty_id, ty_md); return ty_md; } pub fn create_local_var(bcx: block, local: @ast::local) -> DIVariable { - debug!("create_local_var"); let cx = bcx.ccx(); - /* - let cache = get_cache(cx); - let tg = AutoVariableTag; - match cached_metadata::<@Metadata>( - cache, tg, |md| md.data.id == local.node.id) { - option::Some(md) => return md, - option::None => () - } - */ + let dcx = dbg_cx(cx); - let name = match local.node.pat.node { + let ident = match local.node.pat.node { ast::pat_ident(_, pth, _) => ast_util::path_to_ident(pth), // FIXME this should be handled (#2533) _ => fail!("no single variable name for local") @@ -594,59 +597,51 @@ pub fn create_local_var(bcx: block, local: @ast::local) -> DIVariable { let loc = span_start(cx, local.span); let ty = node_id_type(bcx, local.node.id); let tymd = create_ty(cx, ty, local.node.ty.span); - let filemd = create_file(cx, /*bad*/copy loc.file.name); + let filemd = create_file(cx, loc.file.name); let context = match bcx.parent { None => create_function(bcx.fcx), Some(_) => create_block(bcx) }; - - let mdval = do as_c_str(*cx.sess.str_of(name)) |name| { unsafe { - llvm::DIBuilder_createLocalVariable(get_builder(cx), AutoVariableTag as u32, - ptr::null(), name, filemd, loc.line as c_uint, tymd, false, 0, 0) + + let var_md = do as_c_str(name) |name| { unsafe { + llvm::LLVMDIBuilderCreateLocalVariable( + dcx.builder, AutoVariableTag as u32, + context, name, filemd, + loc.line as c_uint, tymd, false, 0, 0) }}; - - let llptr = match bcx.fcx.lllocals.find(&local.node.id) { - option::Some(&local_mem(v)) => v, - option::Some(_) => { - bcx.tcx().sess.span_bug(local.span, "local is bound to something weird"); + + // FIXME(#6814) Should use `pat_util::pat_bindings` for pats like (a, b) etc + let llptr = match bcx.fcx.lllocals.find_copy(&local.node.pat.id) { + Some(v) => v, + None => { + bcx.tcx().sess.span_bug( + local.span, + fmt!("No entry in lllocals table for %?", local.node.id)); } - option::None => { - match bcx.fcx.lllocals.get_copy(&local.node.pat.id) { - local_imm(v) => v, - _ => bcx.tcx().sess.span_bug(local.span, "local is bound to something weird") - } - } }; - /* - llvm::DIBuilder_insertDeclare(get_builder(cx), llptr, mdval, - - let declargs = ~[llmdnode(~[llptr]), mdnode]; - trans::build::Call(bcx, *cx.intrinsics.get(&~"llvm.dbg.declare"), - declargs); - */ - return mdval; + unsafe { + llvm::LLVMDIBuilderInsertDeclareAtEnd(dcx.builder, llptr, var_md, bcx.llbb); } + return var_md; +} pub fn create_arg(bcx: block, arg: ast::arg, sp: span) -> Option { debug!("create_arg"); let fcx = bcx.fcx, cx = *fcx.ccx; - /* - let cache = get_cache(cx); - let tg = ArgVariableTag; - match cached_metadata::<@Metadata>( - cache, ArgVariableTag, |md| md.data.id == arg.id) { - option::Some(md) => return Some(md), - option::None => () - } - */ + let dcx = dbg_cx(cx); let loc = cx.sess.codemap.lookup_char_pos(sp.lo); if "" == loc.file.name { return None; } + // FIXME: Disabled for now because "node_id_type(bcx, arg.id)" below blows up: + // "error: internal compiler error: node_id_to_type: no type for node `arg (id=10)`" + // (same as https://github.com/mozilla/rust/issues/5848) + return None; + let ty = node_id_type(bcx, arg.id); let tymd = create_ty(cx, ty, arg.ty.span); - let filemd = create_file(cx, /*bad*/copy loc.file.name); + let filemd = create_file(cx, loc.file.name); let context = create_function(bcx.fcx); match arg.pat.node { @@ -656,19 +651,15 @@ pub fn create_arg(bcx: block, arg: ast::arg, sp: span) -> Option { let name: &str = cx.sess.str_of(*ident); let mdnode = do as_c_str(name) |name| { unsafe { llvm::LLVMDIBuilderCreateLocalVariable(dcx.builder, - ArgVariableTag as u32, context, name, + ArgVariableTag as u32, context, name, filemd, loc.line as c_uint, tymd, false, 0, 0) - // XXX need to pass a real argument number + // FIXME need to pass a real argument number }}; - - let llptr = match fcx.llargs.get_copy(&arg.id) { - local_mem(v) | local_imm(v) => v, - }; - - /* - llvm::DIBuilder_insertDeclare(get_builder(cx), mdnode, llptr, mdnode - */ - + + let llptr = fcx.llargs.get_copy(&arg.id); + unsafe { + llvm::LLVMDIBuilderInsertDeclareAtEnd(dcx.builder, llptr, mdnode, bcx.llbb); + } return Some(mdnode); } _ => { @@ -684,9 +675,23 @@ fn create_debug_loc(line: int, col: int, scope: DIScope) -> DILocation { } } +pub fn update_source_pos(bcx: block, sp: span) { + if !bcx.sess().opts.debuginfo || (*sp.lo == 0 && *sp.hi == 0) { + return; + } + + debug!("update_source_pos: %s", bcx.sess().codemap.span_to_str(sp)); + let cm = bcx.sess().codemap; - let blockmd = create_block(bcx); let loc = cm.lookup_char_pos(sp.lo); + let cx = bcx.ccx(); + let mut dcx = dbg_cx(cx); + if (loc.line.to_int(), loc.col.to_int()) == dcx.curr_loc { + return; + } + + dcx.curr_loc = (loc.line.to_int(), loc.col.to_int()); + let blockmd = create_block(bcx); let dbgscope = create_debug_loc(loc.line.to_int(), loc.col.to_int(), blockmd); unsafe { llvm::LLVMSetCurrentDebugLocation(trans::build::B(bcx), dbgscope); @@ -695,7 +700,7 @@ fn create_debug_loc(line: int, col: int, scope: DIScope) -> DILocation { pub fn create_function(fcx: fn_ctxt) -> DISubprogram { let cx = *fcx.ccx; - let mut dbg_cx = cx.dbg_cx.get_ref(); + let mut dcx = dbg_cx(cx); let fcx = &mut *fcx; let sp = fcx.span.get(); @@ -714,7 +719,7 @@ pub fn create_function(fcx: fn_ctxt) -> DISubprogram { ast_map::node_expr(expr) => { match expr.node { ast::expr_fn_block(ref decl, _) => { - ((dbg_cx.names)("fn"), decl.output, expr.id) + ((dcx.names)("fn"), decl.output, expr.id) } _ => fcx.ccx.sess.span_bug(expr.span, "create_function: expected an expr_fn_block here") @@ -722,8 +727,8 @@ pub fn create_function(fcx: fn_ctxt) -> DISubprogram { } _ => fcx.ccx.sess.bug("create_function: unexpected sort of node") }; - - match dbg_cx.created_functions.find(&id) { + + match dcx.created_functions.find(&id) { Some(fn_md) => return *fn_md, None => () } @@ -742,27 +747,27 @@ pub fn create_function(fcx: fn_ctxt) -> DISubprogram { } else { ptr::null() }; - + let fn_ty = unsafe { - llvm::DIBuilder_createSubroutineType(get_builder(cx), - file_md, create_DIArray(get_builder(cx), [ret_ty_md])) + llvm::LLVMDIBuilderCreateSubroutineType(dcx.builder, + file_md, create_DIArray(dcx.builder, [ret_ty_md])) }; - - let fn_md = + + let fn_md = do as_c_str(cx.sess.str_of(ident)) |name| { do as_c_str(cx.sess.str_of(ident)) |linkage| { unsafe { llvm::LLVMDIBuilderCreateFunction( - dcx.builder, - file_md, - name, linkage, - file_md, loc.line as c_uint, - fn_ty, false, true, - loc.line as c_uint, + dcx.builder, + file_md, + name, linkage, + file_md, loc.line as c_uint, + fn_ty, false, true, + loc.line as c_uint, FlagPrototyped as c_uint, - cx.sess.opts.optimize != session::No, + cx.sess.opts.optimize != session::No, fcx.llfn, ptr::null(), ptr::null()) }}}; - - dbg_cx.created_functions.insert(id, fn_md); + + dcx.created_functions.insert(id, fn_md); return fn_md; } diff --git a/src/rustllvm/RustWrapper.cpp b/src/rustllvm/RustWrapper.cpp index 315e7c4bcb120..b7a67f984f737 100644 --- a/src/rustllvm/RustWrapper.cpp +++ b/src/rustllvm/RustWrapper.cpp @@ -567,19 +567,19 @@ typedef DIBuilder* DIBuilderRef; template DIT unwrapDI(LLVMValueRef ref) { return DIT(ref ? unwrap(ref) : NULL); } -extern "C" DIBuilderRef DIBuilder_new(LLVMModuleRef M) { +extern "C" DIBuilderRef LLVMDIBuilderCreate(LLVMModuleRef M) { return new DIBuilder(*unwrap(M)); } -extern "C" void DIBuilder_delete(DIBuilderRef Builder) { +extern "C" void LLVMDIBuilderDispose(DIBuilderRef Builder) { delete Builder; } -extern "C" void DIBuilder_finalize(DIBuilderRef Builder) { +extern "C" void LLVMDIBuilderFinalize(DIBuilderRef Builder) { Builder->finalize(); } -extern "C" void DIBuilder_createCompileUnit( +extern "C" void LLVMDIBuilderCreateCompileUnit( DIBuilderRef Builder, unsigned Lang, const char* File, @@ -593,14 +593,14 @@ extern "C" void DIBuilder_createCompileUnit( Flags, RuntimeVer, SplitName); } -extern "C" LLVMValueRef DIBuilder_createFile( +extern "C" LLVMValueRef LLVMDIBuilderCreateFile( DIBuilderRef Builder, const char* Filename, const char* Directory) { return wrap(Builder->createFile(Filename, Directory)); } -extern "C" LLVMValueRef DIBuilder_createSubroutineType( +extern "C" LLVMValueRef LLVMDIBuilderCreateSubroutineType( DIBuilderRef Builder, LLVMValueRef File, LLVMValueRef ParameterTypes) { @@ -609,7 +609,7 @@ extern "C" LLVMValueRef DIBuilder_createSubroutineType( unwrapDI(ParameterTypes))); } -extern "C" LLVMValueRef DIBuilder_createFunction( +extern "C" LLVMValueRef LLVMDIBuilderCreateFunction( DIBuilderRef Builder, LLVMValueRef Scope, const char* Name, @@ -635,7 +635,7 @@ extern "C" LLVMValueRef DIBuilder_createFunction( unwrapDI(Decl))); } -extern "C" LLVMValueRef DIBuilder_createBasicType( +extern "C" LLVMValueRef LLVMDIBuilderCreateBasicType( DIBuilderRef Builder, const char* Name, uint64_t SizeInBits, @@ -646,7 +646,7 @@ extern "C" LLVMValueRef DIBuilder_createBasicType( AlignInBits, Encoding)); } -extern "C" LLVMValueRef DIBuilder_createPointerType( +extern "C" LLVMValueRef LLVMDIBuilderCreatePointerType( DIBuilderRef Builder, LLVMValueRef PointeeTy, uint64_t SizeInBits, @@ -656,7 +656,7 @@ extern "C" LLVMValueRef DIBuilder_createPointerType( unwrapDI(PointeeTy), SizeInBits, AlignInBits, Name)); } -extern "C" LLVMValueRef DIBuilder_createStructType( +extern "C" LLVMValueRef LLVMDIBuilderCreateStructType( DIBuilderRef Builder, LLVMValueRef Scope, const char* Name, @@ -678,7 +678,7 @@ extern "C" LLVMValueRef DIBuilder_createStructType( unwrapDI(VTableHolder))); } -extern "C" LLVMValueRef DIBuilder_createMemberType( +extern "C" LLVMValueRef LLVMDIBuilderCreateMemberType( DIBuilderRef Builder, LLVMValueRef Scope, const char* Name, @@ -696,7 +696,7 @@ extern "C" LLVMValueRef DIBuilder_createMemberType( unwrapDI(Ty))); } -extern "C" LLVMValueRef DIBuilder_createLexicalBlock( +extern "C" LLVMValueRef LLVMDIBuilderCreateLexicalBlock( DIBuilderRef Builder, LLVMValueRef Scope, LLVMValueRef File, @@ -707,7 +707,7 @@ extern "C" LLVMValueRef DIBuilder_createLexicalBlock( unwrapDI(File), Line, Col)); } -extern "C" LLVMValueRef DIBuilder_createLocalVariable( +extern "C" LLVMValueRef LLVMDIBuilderCreateLocalVariable( DIBuilderRef Builder, unsigned Tag, LLVMValueRef Scope, @@ -725,7 +725,7 @@ extern "C" LLVMValueRef DIBuilder_createLocalVariable( unwrapDI(Ty), AlwaysPreserve, Flags, ArgNo)); } -extern "C" LLVMValueRef DIBuilder_createVectorType( +extern "C" LLVMValueRef LLVMDIBuilderCreateVectorType( DIBuilderRef Builder, uint64_t Size, uint64_t AlignInBits, @@ -736,14 +736,14 @@ extern "C" LLVMValueRef DIBuilder_createVectorType( unwrapDI(Subscripts))); } -extern "C" LLVMValueRef DIBuilder_getOrCreateSubrange( +extern "C" LLVMValueRef LLVMDIBuilderGetOrCreateSubrange( DIBuilderRef Builder, int64_t Lo, int64_t Count) { return wrap(Builder->getOrCreateSubrange(Lo, Count)); } -extern "C" LLVMValueRef DIBuilder_getOrCreateArray( +extern "C" LLVMValueRef LLVMDIBuilderGetOrCreateArray( DIBuilderRef Builder, LLVMValueRef* Ptr, unsigned Count) { @@ -751,7 +751,18 @@ extern "C" LLVMValueRef DIBuilder_getOrCreateArray( ArrayRef(reinterpret_cast(Ptr), Count))); } -extern "C" LLVMValueRef DIBuilder_insertDeclare( +extern "C" LLVMValueRef LLVMDIBuilderInsertDeclareAtEnd( + DIBuilderRef Builder, + LLVMValueRef Val, + LLVMValueRef VarInfo, + LLVMBasicBlockRef InsertAtEnd) { + return wrap(Builder->insertDeclare( + unwrap(Val), + unwrapDI(VarInfo), + unwrap(InsertAtEnd))); +} + +extern "C" LLVMValueRef LLVMDIBuilderInsertDeclareBefore( DIBuilderRef Builder, LLVMValueRef Val, LLVMValueRef VarInfo, diff --git a/src/rustllvm/rustllvm.def.in b/src/rustllvm/rustllvm.def.in index 71d574aecbec0..d1ed69feb04b6 100644 --- a/src/rustllvm/rustllvm.def.in +++ b/src/rustllvm/rustllvm.def.in @@ -588,20 +588,21 @@ LLVMInlineAsm LLVMInitializePasses LLVMAddPass LLVMCreatePass -DIBuilder_new -DIBuilder_delete -DIBuilder_finalize -DIBuilder_createCompileUnit -DIBuilder_createLocalVariable -DIBuilder_createFunction -DIBuilder_createFile -DIBuilder_createLexicalBlock -DIBuilder_createBasicType -DIBuilder_createPointerType -DIBuilder_createMemberType -DIBuilder_createStructType -DIBuilder_getOrCreateSubrange -DIBuilder_createVectorType -DIBuilder_createSubroutineType -DIBuilder_getOrCreateArray -DIBuilder_insertDeclare +LLVMDIBuilderCreate +LLVMDIBuilderDispose +LLVMDIBuilderFinalize +LLVMDIBuilderCreateCompileUnit +LLVMDIBuilderCreateLocalVariable +LLVMDIBuilderCreateFunction +LLVMDIBuilderCreateFile +LLVMDIBuilderCreateLexicalBlock +LLVMDIBuilderCreateBasicType +LLVMDIBuilderCreatePointerType +LLVMDIBuilderCreateMemberType +LLVMDIBuilderCreateStructType +LLVMDIBuilderGetOrCreateSubrange +LLVMDIBuilderCreateVectorType +LLVMDIBuilderCreateSubroutineType +LLVMDIBuilderGetOrCreateArray +LLVMDIBuilderInsertDeclareAtEnd +LLVMDIBuilderInsertDeclareBefore From 1079e41143e2f94fc0f969b967aaf89b2f4448a2 Mon Sep 17 00:00:00 2001 From: Vadim Chugunov Date: Mon, 10 Jun 2013 12:32:12 -0700 Subject: [PATCH 03/11] Move "return" basic block after all other function blocks. --- src/librustc/lib/llvm.rs | 6 ++++++ src/librustc/middle/trans/base.rs | 2 ++ 2 files changed, 8 insertions(+) diff --git a/src/librustc/lib/llvm.rs b/src/librustc/lib/llvm.rs index a367de059b8bf..81d5efa6314ca 100644 --- a/src/librustc/lib/llvm.rs +++ b/src/librustc/lib/llvm.rs @@ -966,6 +966,12 @@ pub mod llvm { -> BasicBlockRef; #[fast_ffi] pub unsafe fn LLVMDeleteBasicBlock(BB: BasicBlockRef); + + #[fast_ffi] + pub unsafe fn LLVMMoveBasicBlockAfter(BB: BasicBlockRef, MoveAfter: BasicBlockRef); + + #[fast_ffi] + pub unsafe fn LLVMMoveBasicBlockBefore(BB: BasicBlockRef, MoveBefore: BasicBlockRef); /* Operations on instructions */ #[fast_ffi] diff --git a/src/librustc/middle/trans/base.rs b/src/librustc/middle/trans/base.rs index 580e7fa1900a8..70b6c2ba03626 100644 --- a/src/librustc/middle/trans/base.rs +++ b/src/librustc/middle/trans/base.rs @@ -1907,6 +1907,8 @@ pub fn trans_closure(ccx: @mut CrateContext, finish(bcx); cleanup_and_Br(bcx, bcx_top, fcx.llreturn); + + unsafe { llvm::LLVMMoveBasicBlockAfter(fcx.llreturn, bcx.llbb); } // Insert the mandatory first few basic blocks before lltop. finish_fn(fcx, lltop); From 6db3302b354c47dba4463752e21c37049860b761 Mon Sep 17 00:00:00 2001 From: Vadim Chugunov Date: Mon, 10 Jun 2013 16:28:10 -0700 Subject: [PATCH 04/11] Debug loc for local var declarations --- src/librustc/middle/trans/debuginfo.rs | 32 +++++++++++++++----------- 1 file changed, 18 insertions(+), 14 deletions(-) diff --git a/src/librustc/middle/trans/debuginfo.rs b/src/librustc/middle/trans/debuginfo.rs index 2a1b2b575f7e4..4b00b027968b3 100644 --- a/src/librustc/middle/trans/debuginfo.rs +++ b/src/librustc/middle/trans/debuginfo.rs @@ -67,7 +67,7 @@ struct _DebugContext { names: namegen, crate_file: ~str, builder: DIBuilderRef, - curr_loc: (int, int), + curr_loc: (uint, uint), created_files: HashMap<~str, DIFile>, created_functions: HashMap, created_blocks: HashMap, @@ -82,7 +82,7 @@ pub fn mk_ctxt(llmod: ModuleRef, crate: ~str, intr: @ident_interner) -> DebugCon names: new_namegen(intr), crate_file: crate, builder: builder, - curr_loc: (-1, -1), + curr_loc: (0, 0), created_files: HashMap::new(), created_functions: HashMap::new(), created_blocks: HashMap::new(), @@ -619,9 +619,13 @@ pub fn create_local_var(bcx: block, local: @ast::local) -> DIVariable { fmt!("No entry in lllocals table for %?", local.node.id)); } }; + + set_debug_location(bcx, loc.line, loc.col.to_uint()); unsafe { - llvm::LLVMDIBuilderInsertDeclareAtEnd(dcx.builder, llptr, var_md, bcx.llbb); + let instr = llvm::LLVMDIBuilderInsertDeclareAtEnd(dcx.builder, llptr, var_md, bcx.llbb); + llvm::LLVMSetInstDebugLocation(trans::build::B(bcx), instr); } + return var_md; } @@ -668,10 +672,12 @@ pub fn create_arg(bcx: block, arg: ast::arg, sp: span) -> Option { } } -fn create_debug_loc(line: int, col: int, scope: DIScope) -> DILocation { - let elems = ~[C_i32(line as i32), C_i32(col as i32), scope, ptr::null()]; +fn set_debug_location(bcx: block, line: uint, col: uint) { + let blockmd = create_block(bcx); + let elems = ~[C_i32(line as i32), C_i32(col as i32), blockmd, ptr::null()]; unsafe { - return llvm::LLVMMDNode(vec::raw::to_ptr(elems), elems.len() as libc::c_uint); + let dbg_loc = llvm::LLVMMDNode(vec::raw::to_ptr(elems), elems.len() as libc::c_uint); + llvm::LLVMSetCurrentDebugLocation(trans::build::B(bcx), dbg_loc); } } @@ -686,16 +692,14 @@ pub fn update_source_pos(bcx: block, sp: span) { let loc = cm.lookup_char_pos(sp.lo); let cx = bcx.ccx(); let mut dcx = dbg_cx(cx); - if (loc.line.to_int(), loc.col.to_int()) == dcx.curr_loc { - return; - } - dcx.curr_loc = (loc.line.to_int(), loc.col.to_int()); - let blockmd = create_block(bcx); - let dbgscope = create_debug_loc(loc.line.to_int(), loc.col.to_int(), blockmd); - unsafe { - llvm::LLVMSetCurrentDebugLocation(trans::build::B(bcx), dbgscope); + let loc = (loc.line, loc.col.to_uint()); + if loc == dcx.curr_loc { + return; } + debug!("setting_location to %u %u", loc.first(), loc.second()); + dcx.curr_loc = loc; + set_debug_location(bcx, loc.first(), loc.second()); } pub fn create_function(fcx: fn_ctxt) -> DISubprogram { From 00bb15bf726e0aa440557131224bdab77dd46682 Mon Sep 17 00:00:00 2001 From: Vadim Chugunov Date: Mon, 10 Jun 2013 18:34:51 -0700 Subject: [PATCH 05/11] Removed extraneous string allocations. Misc refactoring. --- src/librustc/middle/trans/debuginfo.rs | 126 ++++++++++--------------- 1 file changed, 50 insertions(+), 76 deletions(-) diff --git a/src/librustc/middle/trans/debuginfo.rs b/src/librustc/middle/trans/debuginfo.rs index 4b00b027968b3..c0e7f6472a6b6 100644 --- a/src/librustc/middle/trans/debuginfo.rs +++ b/src/librustc/middle/trans/debuginfo.rs @@ -75,11 +75,11 @@ struct _DebugContext { } /** Create new DebugContext */ -pub fn mk_ctxt(llmod: ModuleRef, crate: ~str, intr: @ident_interner) -> DebugContext { +pub fn mk_ctxt(llmod: ModuleRef, crate: ~str) -> DebugContext { debug!("mk_ctxt"); let builder = unsafe { llvm::LLVMDIBuilderCreate(llmod) }; let dcx = @mut _DebugContext { - names: new_namegen(intr), + names: new_namegen(), crate_file: crate, builder: builder, curr_loc: (0, 0), @@ -114,33 +114,9 @@ pub fn finalize(cx: @CrateContext) { }; } -fn filename_from_span(cx: @CrateContext, sp: codemap::span) -> ~str { - /*bad*/copy cx.sess.codemap.lookup_char_pos(sp.lo).file.name -} - -//fn filename_from_span<'cx>(cx: &'cx CrateContext, sp: codemap::span) -> &'cx str { -// let fname: &str = cx.sess.codemap.lookup_char_pos(sp.lo).file.name; -// return fname; -//} - -fn get_file_path_and_dir(work_dir: &str, full_path: &str) -> (~str, ~str) { - let full_path = - if str::starts_with(full_path, work_dir) { - str::slice(full_path, str::len(work_dir) + 1u, - str::len(full_path)).to_owned() - } else { - full_path.to_owned() - }; - - return (full_path, work_dir.to_owned()); -} - fn create_compile_unit(cx: @CrateContext) { let crate_name: &str = dbg_cx(cx).crate_file; - - let (_, work_dir) = get_file_path_and_dir( - cx.sess.working_dir.to_str(), crate_name); - + let work_dir = cx.sess.working_dir.to_str(); let producer = fmt!("rustc version %s", env!("CFG_VERSION")); do as_c_str(crate_name) |crate_name| { @@ -158,29 +134,33 @@ fn create_compile_unit(cx: @CrateContext) { fn create_file(cx: @CrateContext, full_path: &str) -> DIFile { let dcx = dbg_cx(cx); - match dcx.created_files.find(&full_path.to_owned()) { + match dcx.created_files.find_equiv(&full_path) { Some(file_md) => return *file_md, None => () } debug!("create_file: %s", full_path); - let (file_path, work_dir) = - get_file_path_and_dir(cx.sess.working_dir.to_str(), - full_path); - + let work_dir = cx.sess.working_dir.to_str(); + let file_name = + if full_path.starts_with(work_dir) { + full_path.slice(work_dir.len() + 1u, full_path.len()) + } else { + full_path + }; + let file_md = - do as_c_str(file_path) |file_path| { + do as_c_str(file_name) |file_name| { do as_c_str(work_dir) |work_dir| { unsafe { - llvm::LLVMDIBuilderCreateFile(dcx.builder, file_path, work_dir) + llvm::LLVMDIBuilderCreateFile(dcx.builder, file_name, work_dir) }}}; dcx.created_files.insert(full_path.to_owned(), file_md); return file_md; } -fn line_from_span(cm: @codemap::CodeMap, sp: span) -> uint { - cm.lookup_char_pos(sp.lo).line +fn span_start(cx: @CrateContext, span: span) -> codemap::Loc { + return cx.sess.codemap.lookup_char_pos(span.lo); } fn create_block(bcx: block) -> DILexicalBlock { @@ -194,7 +174,7 @@ fn create_block(bcx: block) -> DILexicalBlock { None => fail!() } } - let sp = bcx.node_info.get().span; + let span = bcx.node_info.get().span; let id = bcx.node_info.get().id; match dcx.created_blocks.find(&id) { @@ -202,23 +182,21 @@ fn create_block(bcx: block) -> DILexicalBlock { None => () } - debug!("create_block: %s", bcx.sess().codemap.span_to_str(sp)); - - let start = bcx.sess().codemap.lookup_char_pos(sp.lo); - //let end = bcx.sess().codemap.lookup_char_pos(sp.hi); + debug!("create_block: %s", bcx.sess().codemap.span_to_str(span)); let parent = match bcx.parent { None => create_function(bcx.fcx), Some(b) => create_block(b) }; - - let file_md = create_file(bcx.ccx(), start.file.name); + let cx = bcx.ccx(); + let loc = span_start(cx, span); + let file_md = create_file(cx, loc.file.name); let block_md = unsafe { llvm::LLVMDIBuilderCreateLexicalBlock( dcx.builder, parent, file_md, - start.line.to_int() as c_uint, start.col.to_int() as c_uint) + loc.line as c_uint, loc.col.to_uint() as c_uint) }; dcx.created_blocks.insert(id, block_md); @@ -342,18 +320,16 @@ impl StructContext { } fn create_struct(cx: @CrateContext, t: ty::t, fields: ~[ty::field], span: span) -> DICompositeType { - let fname = filename_from_span(cx, span); - let file_md = create_file(cx, fname); - let line = line_from_span(cx.sess.codemap, span); + let loc = span_start(cx, span); + let file_md = create_file(cx, loc.file.name); - let mut scx = StructContext::create(cx, file_md, ty_to_str(cx.tcx, t), line); + let mut scx = StructContext::create(cx, file_md, ty_to_str(cx.tcx, t), loc.line); for fields.each |field| { let field_t = field.mt.ty; let ty_md = create_ty(cx, field_t, span); let (size, align) = size_and_align_of(cx, field_t); scx.add_member(cx.sess.str_of(field.ident), - line_from_span(cx.sess.codemap, span), - size, align, ty_md); + loc.line, size, align, ty_md); } return scx.finalize(); } @@ -371,8 +347,8 @@ fn voidptr(cx: @CrateContext) -> (DIDerivedType, uint, uint) { fn create_tuple(cx: @CrateContext, t: ty::t, elements: &[ty::t], span: span) -> DICompositeType { let dcx = dbg_cx(cx); - let fname = filename_from_span(cx, span); - let file_md = create_file(cx, fname); + let loc = span_start(cx, span); + let file_md = create_file(cx, loc.file.name); let name = (cx.sess.str_of((dcx.names)("tuple"))).to_owned(); let mut scx = StructContext::create(cx, file_md, name, loc.line); @@ -380,16 +356,15 @@ fn create_tuple(cx: @CrateContext, t: ty::t, elements: &[ty::t], span: span) -> for elements.each |element| { let ty_md = create_ty(cx, *element, span); let (size, align) = size_and_align_of(cx, *element); - scx.add_member("", line_from_span(cx.sess.codemap, span), - size, align, ty_md); + scx.add_member("", loc.line, size, align, ty_md); } return scx.finalize(); } fn create_boxed_type(cx: @CrateContext, contents: ty::t, span: span, boxed: DIType) -> DICompositeType { - let fname = filename_from_span(cx, span); - let file_md = create_file(cx, fname); + let loc = span_start(cx, span); + let file_md = create_file(cx, loc.file.name); let int_t = ty::mk_int(); let refcount_type = create_basic_type(cx, int_t, span); let name = ty_to_str(cx.tcx, contents); @@ -412,8 +387,8 @@ fn create_fixed_vec(cx: @CrateContext, vec_t: ty::t, elem_t: ty::t, len: uint, span: span) -> DIType { let dcx = dbg_cx(cx); let elem_ty_md = create_ty(cx, elem_t, span); - let fname = filename_from_span(cx, span); - let file_md = create_file(cx, fname); + let loc = span_start(cx, span); + let file_md = create_file(cx, loc.file.name); let (size, align) = size_and_align_of(cx, elem_t); let subrange = unsafe { @@ -427,10 +402,10 @@ fn create_fixed_vec(cx: @CrateContext, vec_t: ty::t, elem_t: ty::t, } fn create_boxed_vec(cx: @CrateContext, vec_t: ty::t, elem_t: ty::t, - vec_ty_span: codemap::span) -> DICompositeType { + vec_ty_span: span) -> DICompositeType { let dcx = dbg_cx(cx); - let fname = filename_from_span(cx, vec_ty_span); - let file_md = create_file(cx, fname); + let loc = span_start(cx, vec_ty_span); + let file_md = create_file(cx, loc.file.name); let elem_ty_md = create_ty(cx, elem_t, vec_ty_span); let mut vec_scx = StructContext::create(cx, file_md, ty_to_str(cx.tcx, vec_t), 0); @@ -468,8 +443,8 @@ fn create_boxed_vec(cx: @CrateContext, vec_t: ty::t, elem_t: ty::t, } fn create_vec_slice(cx: @CrateContext, vec_t: ty::t, elem_t: ty::t, span: span) -> DICompositeType { - let fname = filename_from_span(cx, span); - let file_md = create_file(cx, fname); + let loc = span_start(cx, span); + let file_md = create_file(cx, loc.file.name); let elem_ty_md = create_ty(cx, elem_t, span); let uint_type = create_basic_type(cx, ty::mk_uint(), span); let elem_ptr = create_pointer_type(cx, elem_t, span, elem_ty_md); @@ -485,8 +460,8 @@ fn create_vec_slice(cx: @CrateContext, vec_t: ty::t, elem_t: ty::t, span: span) fn create_fn_ty(cx: @CrateContext, fn_ty: ty::t, inputs: ~[ty::t], output: ty::t, span: span) -> DICompositeType { let dcx = dbg_cx(cx); - let fname = filename_from_span(cx, span); - let file_md = create_file(cx, fname); + let loc = span_start(cx, span); + let file_md = create_file(cx, loc.file.name); let (vp, _, _) = voidptr(cx); let output_md = create_ty(cx, output, span); let output_ptr_md = create_pointer_type(cx, output, span, output_md); @@ -593,7 +568,7 @@ pub fn create_local_var(bcx: block, local: @ast::local) -> DIVariable { }; let name: &str = cx.sess.str_of(ident); debug!("create_local_var: %s", name); - + let loc = span_start(cx, local.span); let ty = node_id_type(bcx, local.node.id); let tymd = create_ty(cx, ty, local.node.ty.span); @@ -629,12 +604,12 @@ pub fn create_local_var(bcx: block, local: @ast::local) -> DIVariable { return var_md; } -pub fn create_arg(bcx: block, arg: ast::arg, sp: span) -> Option { +pub fn create_arg(bcx: block, arg: ast::arg, span: span) -> Option { debug!("create_arg"); let fcx = bcx.fcx, cx = *fcx.ccx; let dcx = dbg_cx(cx); - let loc = cx.sess.codemap.lookup_char_pos(sp.lo); + let loc = span_start(cx, span); if "" == loc.file.name { return None; } @@ -654,7 +629,7 @@ pub fn create_arg(bcx: block, arg: ast::arg, sp: span) -> Option { let ident = path.idents.last(); let name: &str = cx.sess.str_of(*ident); let mdnode = do as_c_str(name) |name| { unsafe { - llvm::LLVMDIBuilderCreateLocalVariable(dcx.builder, + llvm::LLVMDIBuilderCreateLocalVariable(dcx.builder, ArgVariableTag as u32, context, name, filemd, loc.line as c_uint, tymd, false, 0, 0) // FIXME need to pass a real argument number @@ -681,16 +656,15 @@ fn set_debug_location(bcx: block, line: uint, col: uint) { } } -pub fn update_source_pos(bcx: block, sp: span) { - if !bcx.sess().opts.debuginfo || (*sp.lo == 0 && *sp.hi == 0) { +pub fn update_source_pos(bcx: block, span: span) { + if !bcx.sess().opts.debuginfo || (*span.lo == 0 && *span.hi == 0) { return; } - debug!("update_source_pos: %s", bcx.sess().codemap.span_to_str(sp)); + debug!("update_source_pos: %s", bcx.sess().codemap.span_to_str(span)); - let cm = bcx.sess().codemap; - let loc = cm.lookup_char_pos(sp.lo); let cx = bcx.ccx(); + let loc = span_start(cx, span); let mut dcx = dbg_cx(cx); let loc = (loc.line, loc.col.to_uint()); @@ -706,7 +680,7 @@ pub fn create_function(fcx: fn_ctxt) -> DISubprogram { let cx = *fcx.ccx; let mut dcx = dbg_cx(cx); let fcx = &mut *fcx; - let sp = fcx.span.get(); + let span = fcx.span.get(); let (ident, ret_ty, id) = match cx.tcx.items.get_copy(&fcx.id) { ast_map::node_item(item, _) => { @@ -739,7 +713,7 @@ pub fn create_function(fcx: fn_ctxt) -> DISubprogram { debug!("create_function: %s, %s", cx.sess.str_of(ident), cx.sess.codemap.span_to_str(span)); - let loc = cx.sess.codemap.lookup_char_pos(sp.lo); + let loc = span_start(cx, span); let file_md = create_file(cx, loc.file.name); let ret_ty_md = if cx.sess.opts.extra_debuginfo { From 62e86e044db030b2ffb7883075720360a8dccdd4 Mon Sep 17 00:00:00 2001 From: Vadim Chugunov Date: Tue, 11 Jun 2013 12:41:09 -0700 Subject: [PATCH 06/11] Fixed compile warnings. Fixed whitespace "errors". --- src/librustc/lib/llvm.rs | 8 +- src/librustc/middle/trans/base.rs | 2 +- src/librustc/middle/trans/debuginfo.rs | 181 +++++++++++++------------ 3 files changed, 96 insertions(+), 95 deletions(-) diff --git a/src/librustc/lib/llvm.rs b/src/librustc/lib/llvm.rs index 81d5efa6314ca..d248627907ac0 100644 --- a/src/librustc/lib/llvm.rs +++ b/src/librustc/lib/llvm.rs @@ -966,10 +966,10 @@ pub mod llvm { -> BasicBlockRef; #[fast_ffi] pub unsafe fn LLVMDeleteBasicBlock(BB: BasicBlockRef); - + #[fast_ffi] pub unsafe fn LLVMMoveBasicBlockAfter(BB: BasicBlockRef, MoveAfter: BasicBlockRef); - + #[fast_ffi] pub unsafe fn LLVMMoveBasicBlockBefore(BB: BasicBlockRef, MoveBefore: BasicBlockRef); @@ -2072,13 +2072,13 @@ pub mod llvm { Val: ValueRef, VarInfo: DIVariable, InsertAtEnd: BasicBlockRef) -> ValueRef; - + #[fast_ffi] pub unsafe fn LLVMDIBuilderInsertDeclareBefore( Builder: DIBuilderRef, Val: ValueRef, VarInfo: DIVariable, - InsertBefore: ValueRef) -> ValueRef; + InsertBefore: ValueRef) -> ValueRef; } } diff --git a/src/librustc/middle/trans/base.rs b/src/librustc/middle/trans/base.rs index 70b6c2ba03626..ddc8207dfe04f 100644 --- a/src/librustc/middle/trans/base.rs +++ b/src/librustc/middle/trans/base.rs @@ -1907,7 +1907,7 @@ pub fn trans_closure(ccx: @mut CrateContext, finish(bcx); cleanup_and_Br(bcx, bcx_top, fcx.llreturn); - + unsafe { llvm::LLVMMoveBasicBlockAfter(fcx.llreturn, bcx.llbb); } // Insert the mandatory first few basic blocks before lltop. diff --git a/src/librustc/middle/trans/debuginfo.rs b/src/librustc/middle/trans/debuginfo.rs index c0e7f6472a6b6..bbdfefaaa5963 100644 --- a/src/librustc/middle/trans/debuginfo.rs +++ b/src/librustc/middle/trans/debuginfo.rs @@ -25,12 +25,10 @@ use core::hashmap::HashMap; use core::libc; use core::libc::c_uint; use core::ptr; -use core::str; use core::str::as_c_str; use core::sys; use core::vec; use syntax::codemap::span; -use syntax::parse::token::ident_interner; use syntax::{ast, codemap, ast_util, ast_map}; static LLVMDebugVersion: int = (12 << 16); @@ -98,8 +96,8 @@ fn dbg_cx(cx: &CrateContext) -> DebugContext } fn create_DIArray(builder: DIBuilderRef, arr: &[DIDescriptor]) -> DIArray { - return unsafe { - llvm::LLVMDIBuilderGetOrCreateArray(builder, vec::raw::to_ptr(arr), arr.len() as u32) + return unsafe { + llvm::LLVMDIBuilderGetOrCreateArray(builder, vec::raw::to_ptr(arr), arr.len() as u32) }; } @@ -108,7 +106,7 @@ pub fn finalize(cx: @CrateContext) { debug!("finalize"); create_compile_unit(cx); let dcx = dbg_cx(cx); - unsafe { + unsafe { llvm::LLVMDIBuilderFinalize(dcx.builder); llvm::LLVMDIBuilderDispose(dcx.builder); }; @@ -118,14 +116,14 @@ fn create_compile_unit(cx: @CrateContext) { let crate_name: &str = dbg_cx(cx).crate_file; let work_dir = cx.sess.working_dir.to_str(); let producer = fmt!("rustc version %s", env!("CFG_VERSION")); - + do as_c_str(crate_name) |crate_name| { do as_c_str(work_dir) |work_dir| { do as_c_str(producer) |producer| { do as_c_str("") |flags| { do as_c_str("") |split_name| { unsafe { llvm::LLVMDIBuilderCreateCompileUnit(dbg_cx(cx).builder, - DW_LANG_RUST as c_uint, crate_name, work_dir, producer, + DW_LANG_RUST as c_uint, crate_name, work_dir, producer, cx.sess.opts.optimize != session::No, flags, 0, split_name); }}}}}}; @@ -133,28 +131,28 @@ fn create_compile_unit(cx: @CrateContext) { fn create_file(cx: @CrateContext, full_path: &str) -> DIFile { let dcx = dbg_cx(cx); - + match dcx.created_files.find_equiv(&full_path) { Some(file_md) => return *file_md, None => () } debug!("create_file: %s", full_path); - + let work_dir = cx.sess.working_dir.to_str(); - let file_name = + let file_name = if full_path.starts_with(work_dir) { full_path.slice(work_dir.len() + 1u, full_path.len()) } else { full_path }; - - let file_md = + + let file_md = do as_c_str(file_name) |file_name| { do as_c_str(work_dir) |work_dir| { unsafe { llvm::LLVMDIBuilderCreateFile(dcx.builder, file_name, work_dir) }}}; - + dcx.created_files.insert(full_path.to_owned(), file_md); return file_md; } @@ -166,8 +164,8 @@ fn span_start(cx: @CrateContext, span: span) -> codemap::Loc { fn create_block(bcx: block) -> DILexicalBlock { let mut bcx = bcx; let cx = bcx.ccx(); - let mut dcx = dbg_cx(cx); - + let dcx = dbg_cx(cx); + while bcx.node_info.is_none() { match bcx.parent { Some(b) => bcx = b, @@ -176,14 +174,14 @@ fn create_block(bcx: block) -> DILexicalBlock { } let span = bcx.node_info.get().span; let id = bcx.node_info.get().id; - + match dcx.created_blocks.find(&id) { Some(block) => return *block, None => () } - + debug!("create_block: %s", bcx.sess().codemap.span_to_str(span)); - + let parent = match bcx.parent { None => create_function(bcx.fcx), Some(b) => create_block(b) @@ -191,16 +189,16 @@ fn create_block(bcx: block) -> DILexicalBlock { let cx = bcx.ccx(); let loc = span_start(cx, span); let file_md = create_file(cx, loc.file.name); - - let block_md = unsafe { + + let block_md = unsafe { llvm::LLVMDIBuilderCreateLexicalBlock( - dcx.builder, - parent, file_md, - loc.line as c_uint, loc.col.to_uint() as c_uint) + dcx.builder, + parent, file_md, + loc.line as c_uint, loc.col.to_uint() as c_uint) }; - + dcx.created_blocks.insert(id, block_md); - + return block_md; } @@ -211,14 +209,14 @@ fn size_and_align_of(cx: @CrateContext, t: ty::t) -> (uint, uint) { } fn create_basic_type(cx: @CrateContext, t: ty::t, span: span) -> DIType{ - let mut dcx = dbg_cx(cx); + let dcx = dbg_cx(cx); let ty_id = ty::type_id(t); match dcx.created_types.find(&ty_id) { Some(ty_md) => return *ty_md, None => () } - - debug!("create_basic_type: %?", ty::get(t)); + + debug!("create_basic_type: %?", ty::get(t)); let (name, encoding) = match ty::get(t).sty { ty::ty_nil | ty::ty_bot => (~"uint", DW_ATE_unsigned), @@ -249,10 +247,10 @@ fn create_basic_type(cx: @CrateContext, t: ty::t, span: span) -> DIType{ let (size, align) = size_and_align_of(cx, t); let ty_md = do as_c_str(name) |name| { unsafe { llvm::LLVMDIBuilderCreateBasicType( - dcx.builder, name, + dcx.builder, name, size * 8 as u64, align * 8 as u64, encoding as c_uint) }}; - + dcx.created_types.insert(ty_id, ty_md); return ty_md; } @@ -261,7 +259,7 @@ fn create_pointer_type(cx: @CrateContext, t: ty::t, span: span, pointee: DIType) let (size, align) = size_and_align_of(cx, t); let name = ty_to_str(cx.tcx, t); let ptr_md = do as_c_str(name) |name| { unsafe { - llvm::LLVMDIBuilderCreatePointerType(dbg_cx(cx).builder, + llvm::LLVMDIBuilderCreatePointerType(dbg_cx(cx).builder, pointee, size * 8 as u64, align * 8 as u64, name) }}; return ptr_md; @@ -290,27 +288,27 @@ impl StructContext { }; return scx; } - + fn add_member(&mut self, name: &str, line: uint, size: uint, align: uint, ty: DIType) { let mem_t = do as_c_str(name) |name| { unsafe { - llvm::LLVMDIBuilderCreateMemberType(dbg_cx(self.cx).builder, - ptr::null(), name, self.file, line as c_uint, - size * 8 as u64, align * 8 as u64, self.total_size as u64, + llvm::LLVMDIBuilderCreateMemberType(dbg_cx(self.cx).builder, + ptr::null(), name, self.file, line as c_uint, + size * 8 as u64, align * 8 as u64, self.total_size as u64, 0, ty) }}; // XXX What about member alignment??? self.members.push(mem_t); self.total_size += size * 8; } - + fn finalize(&self) -> DICompositeType { let dcx = dbg_cx(self.cx); let members_md = create_DIArray(dcx.builder, self.members); - - let struct_md = + + let struct_md = do as_c_str(self.name) |name| { unsafe { llvm::LLVMDIBuilderCreateStructType( - dcx.builder, ptr::null(), name, + dcx.builder, ptr::null(), name, self.file, self.line as c_uint, self.total_size as u64, self.align as u64, 0, ptr::null(), members_md, 0, ptr::null()) @@ -322,7 +320,7 @@ impl StructContext { fn create_struct(cx: @CrateContext, t: ty::t, fields: ~[ty::field], span: span) -> DICompositeType { let loc = span_start(cx, span); let file_md = create_file(cx, loc.file.name); - + let mut scx = StructContext::create(cx, file_md, ty_to_str(cx.tcx, t), loc.line); for fields.each |field| { let field_t = field.mt.ty; @@ -339,7 +337,7 @@ fn voidptr(cx: @CrateContext) -> (DIDerivedType, uint, uint) { let size = sys::size_of::(); let align = sys::min_align_of::(); let vp = do as_c_str("*void") |name| { unsafe { - llvm::LLVMDIBuilderCreatePointerType(dbg_cx(cx).builder, ptr::null(), + llvm::LLVMDIBuilderCreatePointerType(dbg_cx(cx).builder, ptr::null(), size*8 as u64, align*8 as u64, name) }}; return (vp, size, align); @@ -352,7 +350,7 @@ fn create_tuple(cx: @CrateContext, t: ty::t, elements: &[ty::t], span: span) -> let name = (cx.sess.str_of((dcx.names)("tuple"))).to_owned(); let mut scx = StructContext::create(cx, file_md, name, loc.line); - + for elements.each |element| { let ty_md = create_ty(cx, *element, span); let (size, align) = size_and_align_of(cx, *element); @@ -368,7 +366,7 @@ fn create_boxed_type(cx: @CrateContext, contents: ty::t, let int_t = ty::mk_int(); let refcount_type = create_basic_type(cx, int_t, span); let name = ty_to_str(cx.tcx, contents); - + let mut scx = StructContext::create(cx, file_md, fmt!("box<%s>", name), 0); scx.add_member("refcnt", 0, sys::size_of::(), sys::min_align_of::(), refcount_type); @@ -391,13 +389,13 @@ fn create_fixed_vec(cx: @CrateContext, vec_t: ty::t, elem_t: ty::t, let file_md = create_file(cx, loc.file.name); let (size, align) = size_and_align_of(cx, elem_t); - let subrange = unsafe { + let subrange = unsafe { llvm::LLVMDIBuilderGetOrCreateSubrange(dcx.builder, 0_i64, (len-1) as i64) }; let subscripts = create_DIArray(dcx.builder, [subrange]); - return unsafe { - llvm::LLVMDIBuilderCreateVectorType(dcx.builder, - size * len as u64, align as u64, elem_ty_md, subscripts) + return unsafe { + llvm::LLVMDIBuilderCreateVectorType(dcx.builder, + size * len as u64, align as u64, elem_ty_md, subscripts) }; } @@ -407,9 +405,9 @@ fn create_boxed_vec(cx: @CrateContext, vec_t: ty::t, elem_t: ty::t, let loc = span_start(cx, vec_ty_span); let file_md = create_file(cx, loc.file.name); let elem_ty_md = create_ty(cx, elem_t, vec_ty_span); - + let mut vec_scx = StructContext::create(cx, file_md, ty_to_str(cx.tcx, vec_t), 0); - + let size_t_type = create_basic_type(cx, ty::mk_uint(), vec_ty_span); vec_scx.add_member("fill", 0, sys::size_of::(), sys::min_align_of::(), size_t_type); @@ -418,9 +416,9 @@ fn create_boxed_vec(cx: @CrateContext, vec_t: ty::t, elem_t: ty::t, let subrange = unsafe { llvm::LLVMDIBuilderGetOrCreateSubrange(dcx.builder, 0_i64, 0_i64) }; let (arr_size, arr_align) = size_and_align_of(cx, elem_t); let name = fmt!("[%s]", ty_to_str(cx.tcx, elem_t)); - + let subscripts = create_DIArray(dcx.builder, [subrange]); - let data_ptr = unsafe { llvm::LLVMDIBuilderCreateVectorType(dcx.builder, + let data_ptr = unsafe { llvm::LLVMDIBuilderCreateVectorType(dcx.builder, arr_size as u64, arr_align as u64, elem_ty_md, subscripts) }; vec_scx.add_member("data", 0, 0, // clang says the size should be 0 sys::min_align_of::(), data_ptr); @@ -448,7 +446,7 @@ fn create_vec_slice(cx: @CrateContext, vec_t: ty::t, elem_t: ty::t, span: span) let elem_ty_md = create_ty(cx, elem_t, span); let uint_type = create_basic_type(cx, ty::mk_uint(), span); let elem_ptr = create_pointer_type(cx, elem_t, span, elem_ty_md); - + let mut scx = StructContext::create(cx, file_md, ty_to_str(cx.tcx, vec_t), 0); let (_, ptr_size, ptr_align) = voidptr(cx); scx.add_member("vec", 0, ptr_size, ptr_align, elem_ptr); @@ -467,15 +465,15 @@ fn create_fn_ty(cx: @CrateContext, fn_ty: ty::t, inputs: ~[ty::t], output: ty::t let output_ptr_md = create_pointer_type(cx, output, span, output_md); let inputs_vals = do inputs.map |arg| { create_ty(cx, *arg, span) }; let members = ~[output_ptr_md, vp] + inputs_vals; - - return unsafe { - llvm::LLVMDIBuilderCreateSubroutineType(dcx.builder, file_md, - create_DIArray(dcx.builder, members)) + + return unsafe { + llvm::LLVMDIBuilderCreateSubroutineType(dcx.builder, file_md, + create_DIArray(dcx.builder, members)) }; } fn create_ty(cx: @CrateContext, t: ty::t, span: span) -> DIType { - let mut dcx = dbg_cx(cx); + let dcx = dbg_cx(cx); let ty_id = ty::type_id(t); match dcx.created_types.find(&ty_id) { Some(ty_md) => return *ty_md, @@ -552,7 +550,7 @@ fn create_ty(cx: @CrateContext, t: ty::t, span: span) -> DIType { }, _ => cx.sess.bug(~"debuginfo: unexpected type in create_ty") }; - + dcx.created_types.insert(ty_id, ty_md); return ty_md; } @@ -568,7 +566,7 @@ pub fn create_local_var(bcx: block, local: @ast::local) -> DIVariable { }; let name: &str = cx.sess.str_of(ident); debug!("create_local_var: %s", name); - + let loc = span_start(cx, local.span); let ty = node_id_type(bcx, local.node.id); let tymd = create_ty(cx, ty, local.node.ty.span); @@ -577,14 +575,14 @@ pub fn create_local_var(bcx: block, local: @ast::local) -> DIVariable { None => create_function(bcx.fcx), Some(_) => create_block(bcx) }; - + let var_md = do as_c_str(name) |name| { unsafe { llvm::LLVMDIBuilderCreateLocalVariable( dcx.builder, AutoVariableTag as u32, - context, name, filemd, + context, name, filemd, loc.line as c_uint, tymd, false, 0, 0) }}; - + // FIXME(#6814) Should use `pat_util::pat_bindings` for pats like (a, b) etc let llptr = match bcx.fcx.lllocals.find_copy(&local.node.pat.id) { Some(v) => v, @@ -594,30 +592,33 @@ pub fn create_local_var(bcx: block, local: @ast::local) -> DIVariable { fmt!("No entry in lllocals table for %?", local.node.id)); } }; - + set_debug_location(bcx, loc.line, loc.col.to_uint()); unsafe { let instr = llvm::LLVMDIBuilderInsertDeclareAtEnd(dcx.builder, llptr, var_md, bcx.llbb); llvm::LLVMSetInstDebugLocation(trans::build::B(bcx), instr); } - + return var_md; } pub fn create_arg(bcx: block, arg: ast::arg, span: span) -> Option { debug!("create_arg"); - let fcx = bcx.fcx, cx = *fcx.ccx; + if true { + // FIXME(5848) create_arg disabled for now because "node_id_type(bcx, arg.id)" below blows + // up: "error: internal compiler error: node_id_to_type: no type for node `arg (id=10)`" + return None; + } + + let fcx = bcx.fcx; + let cx = *fcx.ccx; let dcx = dbg_cx(cx); let loc = span_start(cx, span); if "" == loc.file.name { return None; } - // FIXME: Disabled for now because "node_id_type(bcx, arg.id)" below blows up: - // "error: internal compiler error: node_id_to_type: no type for node `arg (id=10)`" - // (same as https://github.com/mozilla/rust/issues/5848) - return None; - + let ty = node_id_type(bcx, arg.id); let tymd = create_ty(cx, ty, arg.ty.span); let filemd = create_file(cx, loc.file.name); @@ -629,12 +630,12 @@ pub fn create_arg(bcx: block, arg: ast::arg, span: span) -> Option { let ident = path.idents.last(); let name: &str = cx.sess.str_of(*ident); let mdnode = do as_c_str(name) |name| { unsafe { - llvm::LLVMDIBuilderCreateLocalVariable(dcx.builder, - ArgVariableTag as u32, context, name, + llvm::LLVMDIBuilderCreateLocalVariable(dcx.builder, + ArgVariableTag as u32, context, name, filemd, loc.line as c_uint, tymd, false, 0, 0) // FIXME need to pass a real argument number }}; - + let llptr = fcx.llargs.get_copy(&arg.id); unsafe { llvm::LLVMDIBuilderInsertDeclareAtEnd(dcx.builder, llptr, mdnode, bcx.llbb); @@ -652,7 +653,7 @@ fn set_debug_location(bcx: block, line: uint, col: uint) { let elems = ~[C_i32(line as i32), C_i32(col as i32), blockmd, ptr::null()]; unsafe { let dbg_loc = llvm::LLVMMDNode(vec::raw::to_ptr(elems), elems.len() as libc::c_uint); - llvm::LLVMSetCurrentDebugLocation(trans::build::B(bcx), dbg_loc); + llvm::LLVMSetCurrentDebugLocation(trans::build::B(bcx), dbg_loc); } } @@ -660,13 +661,13 @@ pub fn update_source_pos(bcx: block, span: span) { if !bcx.sess().opts.debuginfo || (*span.lo == 0 && *span.hi == 0) { return; } - + debug!("update_source_pos: %s", bcx.sess().codemap.span_to_str(span)); let cx = bcx.ccx(); let loc = span_start(cx, span); - let mut dcx = dbg_cx(cx); - + let dcx = dbg_cx(cx); + let loc = (loc.line, loc.col.to_uint()); if loc == dcx.curr_loc { return; @@ -678,7 +679,7 @@ pub fn update_source_pos(bcx: block, span: span) { pub fn create_function(fcx: fn_ctxt) -> DISubprogram { let cx = *fcx.ccx; - let mut dcx = dbg_cx(cx); + let dcx = dbg_cx(cx); let fcx = &mut *fcx; let span = fcx.span.get(); @@ -705,7 +706,7 @@ pub fn create_function(fcx: fn_ctxt) -> DISubprogram { } _ => fcx.ccx.sess.bug("create_function: unexpected sort of node") }; - + match dcx.created_functions.find(&id) { Some(fn_md) => return *fn_md, None => () @@ -725,27 +726,27 @@ pub fn create_function(fcx: fn_ctxt) -> DISubprogram { } else { ptr::null() }; - + let fn_ty = unsafe { llvm::LLVMDIBuilderCreateSubroutineType(dcx.builder, file_md, create_DIArray(dcx.builder, [ret_ty_md])) }; - - let fn_md = + + let fn_md = do as_c_str(cx.sess.str_of(ident)) |name| { do as_c_str(cx.sess.str_of(ident)) |linkage| { unsafe { llvm::LLVMDIBuilderCreateFunction( - dcx.builder, - file_md, - name, linkage, - file_md, loc.line as c_uint, - fn_ty, false, true, - loc.line as c_uint, + dcx.builder, + file_md, + name, linkage, + file_md, loc.line as c_uint, + fn_ty, false, true, + loc.line as c_uint, FlagPrototyped as c_uint, - cx.sess.opts.optimize != session::No, + cx.sess.opts.optimize != session::No, fcx.llfn, ptr::null(), ptr::null()) }}}; - + dcx.created_functions.insert(id, fn_md); return fn_md; } From 65dd6218afe62fa36e701ceb27bd4e17ec764acc Mon Sep 17 00:00:00 2001 From: Vadim Chugunov Date: Fri, 14 Jun 2013 12:23:42 -0700 Subject: [PATCH 07/11] Fixed remaining issues to pass debug-test/* tests. Made debugger scripts source line insensitive. --- src/librustc/lib/llvm.rs | 8 ++++++ src/librustc/middle/trans/debuginfo.rs | 36 ++++++++++++++++---------- src/rustllvm/RustWrapper.cpp | 11 ++++++++ src/rustllvm/rustllvm.def.in | 1 + src/test/debug-info/basic-types.rs | 9 ++++--- src/test/debug-info/box.rs | 9 ++++--- src/test/debug-info/struct.rs | 9 ++++--- src/test/debug-info/tuple.rs | 9 ++++--- src/test/debug-info/vec.rs | 9 ++++--- 9 files changed, 73 insertions(+), 28 deletions(-) diff --git a/src/librustc/lib/llvm.rs b/src/librustc/lib/llvm.rs index d248627907ac0..559db3f9b848d 100644 --- a/src/librustc/lib/llvm.rs +++ b/src/librustc/lib/llvm.rs @@ -2045,6 +2045,14 @@ pub mod llvm { AlwaysPreserve: bool, Flags: c_uint, ArgNo: c_uint) -> DIVariable; + + #[fast_ffi] + pub unsafe fn LLVMDIBuilderCreateArrayType( + Builder: DIBuilderRef, + Size: c_ulonglong, + AlignInBits: c_ulonglong, + Ty: DIType, + Subscripts: DIArray) -> DIType; #[fast_ffi] pub unsafe fn LLVMDIBuilderCreateVectorType( diff --git a/src/librustc/middle/trans/debuginfo.rs b/src/librustc/middle/trans/debuginfo.rs index bbdfefaaa5963..07aedf4b2c909 100644 --- a/src/librustc/middle/trans/debuginfo.rs +++ b/src/librustc/middle/trans/debuginfo.rs @@ -24,6 +24,7 @@ use util::ppaux::ty_to_str; use core::hashmap::HashMap; use core::libc; use core::libc::c_uint; +use core::cmp; use core::ptr; use core::str::as_c_str; use core::sys; @@ -204,8 +205,7 @@ fn create_block(bcx: block) -> DILexicalBlock { fn size_and_align_of(cx: @CrateContext, t: ty::t) -> (uint, uint) { let llty = type_of::type_of(cx, t); - (machine::llsize_of_real(cx, llty), - machine::llalign_of_pref(cx, llty)) + (machine::llsize_of_real(cx, llty), machine::llalign_of_min(cx, llty)) } fn create_basic_type(cx: @CrateContext, t: ty::t, span: span) -> DIType{ @@ -277,6 +277,7 @@ struct StructContext { impl StructContext { fn create(cx: @CrateContext, file: DIFile, name: ~str, line: uint) -> ~StructContext { + debug!("StructContext::create: %s", name); let scx = ~StructContext { cx: cx, file: file, @@ -284,39 +285,48 @@ impl StructContext { line: line, members: ~[], total_size: 0, - align: 64 //XXX different alignment per arch? + align: 1 }; return scx; } fn add_member(&mut self, name: &str, line: uint, size: uint, align: uint, ty: DIType) { + debug!("StructContext(%s)::add_member: %s, size=%u, align=%u", self.name, name, size, align); + let offset = roundup(self.total_size, align); let mem_t = do as_c_str(name) |name| { unsafe { llvm::LLVMDIBuilderCreateMemberType(dbg_cx(self.cx).builder, ptr::null(), name, self.file, line as c_uint, - size * 8 as u64, align * 8 as u64, self.total_size as u64, + size * 8 as u64, align * 8 as u64, offset * 8 as u64, 0, ty) }}; - // XXX What about member alignment??? self.members.push(mem_t); - self.total_size += size * 8; + self.total_size = offset + size; + // struct alignment is the max alignment of its' members + self.align = cmp::max(self.align, align); } fn finalize(&self) -> DICompositeType { + debug!("StructContext(%s)::finalize: total_size=%u, align=%u", self.name, self.total_size, self.align); let dcx = dbg_cx(self.cx); let members_md = create_DIArray(dcx.builder, self.members); let struct_md = do as_c_str(self.name) |name| { unsafe { llvm::LLVMDIBuilderCreateStructType( - dcx.builder, ptr::null(), name, + dcx.builder, self.file, name, self.file, self.line as c_uint, - self.total_size as u64, self.align as u64, 0, ptr::null(), + self.total_size * 8 as u64, self.align * 8 as u64, 0, ptr::null(), members_md, 0, ptr::null()) }}; return struct_md; } } +#[inline(always)] +fn roundup(x: uint, a: uint) -> uint { + ((x + (a - 1)) / a) * a +} + fn create_struct(cx: @CrateContext, t: ty::t, fields: ~[ty::field], span: span) -> DICompositeType { let loc = span_start(cx, span); let file_md = create_file(cx, loc.file.name); @@ -390,12 +400,12 @@ fn create_fixed_vec(cx: @CrateContext, vec_t: ty::t, elem_t: ty::t, let (size, align) = size_and_align_of(cx, elem_t); let subrange = unsafe { - llvm::LLVMDIBuilderGetOrCreateSubrange(dcx.builder, 0_i64, (len-1) as i64) }; + llvm::LLVMDIBuilderGetOrCreateSubrange(dcx.builder, 0_i64, len as i64) }; let subscripts = create_DIArray(dcx.builder, [subrange]); return unsafe { - llvm::LLVMDIBuilderCreateVectorType(dcx.builder, - size * len as u64, align as u64, elem_ty_md, subscripts) + llvm::LLVMDIBuilderCreateArrayType(dcx.builder, + size * len * 8 as u64, align * 8 as u64, elem_ty_md, subscripts) }; } @@ -418,8 +428,8 @@ fn create_boxed_vec(cx: @CrateContext, vec_t: ty::t, elem_t: ty::t, let name = fmt!("[%s]", ty_to_str(cx.tcx, elem_t)); let subscripts = create_DIArray(dcx.builder, [subrange]); - let data_ptr = unsafe { llvm::LLVMDIBuilderCreateVectorType(dcx.builder, - arr_size as u64, arr_align as u64, elem_ty_md, subscripts) }; + let data_ptr = unsafe { llvm::LLVMDIBuilderCreateArrayType(dcx.builder, + arr_size * 8 as u64, arr_align * 8 as u64, elem_ty_md, subscripts) }; vec_scx.add_member("data", 0, 0, // clang says the size should be 0 sys::min_align_of::(), data_ptr); let vec_md = vec_scx.finalize(); diff --git a/src/rustllvm/RustWrapper.cpp b/src/rustllvm/RustWrapper.cpp index b7a67f984f737..6537e232f8b3b 100644 --- a/src/rustllvm/RustWrapper.cpp +++ b/src/rustllvm/RustWrapper.cpp @@ -725,6 +725,17 @@ extern "C" LLVMValueRef LLVMDIBuilderCreateLocalVariable( unwrapDI(Ty), AlwaysPreserve, Flags, ArgNo)); } +extern "C" LLVMValueRef LLVMDIBuilderCreateArrayType( + DIBuilderRef Builder, + uint64_t Size, + uint64_t AlignInBits, + LLVMValueRef Ty, + LLVMValueRef Subscripts) { + return wrap(Builder->createArrayType(Size, AlignInBits, + unwrapDI(Ty), + unwrapDI(Subscripts))); +} + extern "C" LLVMValueRef LLVMDIBuilderCreateVectorType( DIBuilderRef Builder, uint64_t Size, diff --git a/src/rustllvm/rustllvm.def.in b/src/rustllvm/rustllvm.def.in index d1ed69feb04b6..2a3f7de9bf5a0 100644 --- a/src/rustllvm/rustllvm.def.in +++ b/src/rustllvm/rustllvm.def.in @@ -601,6 +601,7 @@ LLVMDIBuilderCreatePointerType LLVMDIBuilderCreateMemberType LLVMDIBuilderCreateStructType LLVMDIBuilderGetOrCreateSubrange +LLVMDIBuilderCreateArrayType LLVMDIBuilderCreateVectorType LLVMDIBuilderCreateSubroutineType LLVMDIBuilderGetOrCreateArray diff --git a/src/test/debug-info/basic-types.rs b/src/test/debug-info/basic-types.rs index 20da6b557f18d..616740c850c54 100644 --- a/src/test/debug-info/basic-types.rs +++ b/src/test/debug-info/basic-types.rs @@ -8,7 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -// xfail-test +// xfail-win32 Broken because of LLVM bug: http://llvm.org/bugs/show_bug.cgi?id=16249 // Caveats - gdb prints any 8-bit value (meaning rust i8 and u8 values) // as its numerical value along with its associated ASCII char, there @@ -17,8 +17,9 @@ // its numerical value. // compile-flags:-Z extra-debug-info -// debugger:break 67 +// debugger:break _zzz // debugger:run +// debugger:finish // debugger:print b // check:$1 = false // debugger:print i @@ -66,5 +67,7 @@ fn main() { let f: float = 1.5; let f32: f32 = 2.5; let f64: f64 = 3.5; - let _z = (); + _zzz(); } + +fn _zzz() {()} diff --git a/src/test/debug-info/box.rs b/src/test/debug-info/box.rs index 54aa0c12578b9..3e5483ad75b3a 100644 --- a/src/test/debug-info/box.rs +++ b/src/test/debug-info/box.rs @@ -8,12 +8,13 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -// xfail-test +// xfail-win32 Broken because of LLVM bug: http://llvm.org/bugs/show_bug.cgi?id=16249 // compile-flags:-Z extra-debug-info // debugger:set print pretty off -// debugger:break 29 +// debugger:break _zzz // debugger:run +// debugger:finish // debugger:print a->boxed // check:$1 = 1 // debugger:print b->boxed @@ -28,5 +29,7 @@ fn main() { let b = ~(2, 3.5); let c = @4; let d = @false; - let _z = 0; + _zzz(); } + +fn _zzz() {()} \ No newline at end of file diff --git a/src/test/debug-info/struct.rs b/src/test/debug-info/struct.rs index 16ba6cda5900a..ddfac9cbeea8f 100644 --- a/src/test/debug-info/struct.rs +++ b/src/test/debug-info/struct.rs @@ -8,12 +8,13 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -// xfail-test +// xfail-win32 Broken because of LLVM bug: http://llvm.org/bugs/show_bug.cgi?id=16249 // compile-flags:-Z extra-debug-info // debugger:set print pretty off -// debugger:break 29 +// debugger:break _zzz // debugger:run +// debugger:finish // debugger:print pair // check:$1 = {x = 1, y = 2} // debugger:print pair.x @@ -28,5 +29,7 @@ struct Pair { fn main() { let pair = Pair { x: 1, y: 2 }; - let _z = (); + _zzz(); } + +fn _zzz() {()} \ No newline at end of file diff --git a/src/test/debug-info/tuple.rs b/src/test/debug-info/tuple.rs index 35e2977f562e9..a50996871cee9 100644 --- a/src/test/debug-info/tuple.rs +++ b/src/test/debug-info/tuple.rs @@ -8,16 +8,19 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -// xfail-test +// xfail-win32 Broken because of LLVM bug: http://llvm.org/bugs/show_bug.cgi?id=16249 // compile-flags:-Z extra-debug-info // debugger:set print pretty off -// debugger:break 20 +// debugger:break _zzz // debugger:run +// debugger:finish // debugger:print t // check:$1 = {4, 5.5, true} fn main() { let t = (4, 5.5, true); - let _z = (); + _zzz(); } + +fn _zzz() {()} \ No newline at end of file diff --git a/src/test/debug-info/vec.rs b/src/test/debug-info/vec.rs index 3876f1c46d487..c87849ac4b6dd 100644 --- a/src/test/debug-info/vec.rs +++ b/src/test/debug-info/vec.rs @@ -8,12 +8,13 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -// xfail-test +// xfail-win32 Broken because of LLVM bug: http://llvm.org/bugs/show_bug.cgi?id=16249 // compile-flags:-Z extra-debug-info // debugger:set print pretty off -// debugger:break 29 +// debugger:break _zzz // debugger:run +// debugger:finish // debugger:print a // check:$1 = {1, 2, 3} // debugger:print b.vec[0] @@ -28,5 +29,7 @@ fn main() { let b = &[4, 5, 6]; let c = @[7, 8, 9]; let d = ~[10, 11, 12]; - let _z = 0; + _zzz(); } + +fn _zzz() {()} \ No newline at end of file From 51d82f572fe3e286f45b60a9594a2fafd286cb39 Mon Sep 17 00:00:00 2001 From: Vadim Chugunov Date: Tue, 11 Jun 2013 18:06:38 -0700 Subject: [PATCH 08/11] Converted vec::map to member. --- src/compiletest/procsrv.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/compiletest/procsrv.rs b/src/compiletest/procsrv.rs index b5404e38ec961..93fe258d167ed 100644 --- a/src/compiletest/procsrv.rs +++ b/src/compiletest/procsrv.rs @@ -23,7 +23,7 @@ fn target_env(lib_path: &str, prog: &str) -> ~[(~str,~str)] { assert!(prog.ends_with(".exe")); let aux_path = prog.slice(0u, prog.len() - 4u).to_owned() + ".libaux"; - env = do vec::map(env) |pair| { + env = do env.map() |pair| { let (k,v) = copy *pair; if k == ~"PATH" { (~"PATH", v + ";" + lib_path + ";" + aux_path) } else { (k,v) } From 2b45591daf9edb09d95007ecc658ac6cbaa7ee8a Mon Sep 17 00:00:00 2001 From: Vadim Chugunov Date: Fri, 14 Jun 2013 12:08:59 -0700 Subject: [PATCH 09/11] Made unimplemented debuginfo a note rather than a compiler error. --- src/librustc/middle/trans/debuginfo.rs | 28 +++++++++++++++++++++----- 1 file changed, 23 insertions(+), 5 deletions(-) diff --git a/src/librustc/middle/trans/debuginfo.rs b/src/librustc/middle/trans/debuginfo.rs index 07aedf4b2c909..12c774046d8ba 100644 --- a/src/librustc/middle/trans/debuginfo.rs +++ b/src/librustc/middle/trans/debuginfo.rs @@ -482,6 +482,17 @@ fn create_fn_ty(cx: @CrateContext, fn_ty: ty::t, inputs: ~[ty::t], output: ty::t }; } +fn create_unimpl_ty(cx: @CrateContext, t: ty::t) -> DIType { + let dcx = dbg_cx(cx); + let name = ty_to_str(cx.tcx, t); + let md = do as_c_str(fmt!("NYI<%s>", name)) |name| { unsafe { + llvm::LLVMDIBuilderCreateBasicType( + dcx.builder, name, + 0_u64, 8_u64, DW_ATE_unsigned as c_uint) + }}; + return md; +} + fn create_ty(cx: @CrateContext, t: ty::t, span: span) -> DIType { let dcx = dbg_cx(cx); let ty_id = ty::type_id(t); @@ -512,7 +523,8 @@ fn create_ty(cx: @CrateContext, t: ty::t, span: span) -> DIType { } }, ty::ty_enum(_did, ref _substs) => { - cx.sess.span_bug(span, "debuginfo for enum NYI") + cx.sess.span_note(span, "debuginfo for enum NYI"); + create_unimpl_ty(cx, t) } ty::ty_box(ref mt) | ty::ty_uniq(ref mt) => { let boxed = create_ty(cx, mt.ty, span); @@ -538,7 +550,8 @@ fn create_ty(cx: @CrateContext, t: ty::t, span: span) -> DIType { create_pointer_type(cx, t, span, pointee) }, ty::ty_rptr(ref _region, ref _mt) => { - cx.sess.span_bug(span, "debuginfo for rptr NYI") + cx.sess.span_note(span, "debuginfo for rptr NYI"); + create_unimpl_ty(cx, t) }, ty::ty_bare_fn(ref barefnty) => { let inputs = barefnty.sig.inputs.map(|a| *a); @@ -546,10 +559,12 @@ fn create_ty(cx: @CrateContext, t: ty::t, span: span) -> DIType { create_fn_ty(cx, t, inputs, output, span) }, ty::ty_closure(ref _closurety) => { - cx.sess.span_bug(span, "debuginfo for closure NYI") + cx.sess.span_note(span, "debuginfo for closure NYI"); + create_unimpl_ty(cx, t) }, ty::ty_trait(_did, ref _substs, ref _vstore, _) => { - cx.sess.span_bug(span, "debuginfo for trait NYI") + cx.sess.span_note(span, "debuginfo for trait NYI"); + create_unimpl_ty(cx, t) }, ty::ty_struct(did, ref substs) => { let fields = ty::struct_fields(cx.tcx, did, substs); @@ -572,7 +587,10 @@ pub fn create_local_var(bcx: block, local: @ast::local) -> DIVariable { let ident = match local.node.pat.node { ast::pat_ident(_, pth, _) => ast_util::path_to_ident(pth), // FIXME this should be handled (#2533) - _ => fail!("no single variable name for local") + _ => { + bcx.sess().span_note(local.span, "debuginfo for pattern bindings NYI"); + return ptr::null(); + } }; let name: &str = cx.sess.str_of(ident); debug!("create_local_var: %s", name); From 1e682e29eb8f5ddaf36e6374f46d8d8ac364d824 Mon Sep 17 00:00:00 2001 From: Vadim Chugunov Date: Fri, 14 Jun 2013 11:59:49 -0700 Subject: [PATCH 10/11] Refactoring and tidy warnings cleanup. --- src/librustc/lib/llvm.rs | 11 +-- src/librustc/middle/trans/base.rs | 8 ++- src/librustc/middle/trans/debuginfo.rs | 99 +++++++++++++------------- 3 files changed, 63 insertions(+), 55 deletions(-) diff --git a/src/librustc/lib/llvm.rs b/src/librustc/lib/llvm.rs index 559db3f9b848d..c00bb390edd28 100644 --- a/src/librustc/lib/llvm.rs +++ b/src/librustc/lib/llvm.rs @@ -225,12 +225,11 @@ pub enum Pass_opaque {} pub type PassRef = *Pass_opaque; pub mod debuginfo { - use core::prelude::*; use super::{ValueRef}; - + pub enum DIBuilder_opaque {} pub type DIBuilderRef = *DIBuilder_opaque; - + pub type DIDescriptor = ValueRef; pub type DIScope = DIDescriptor; pub type DILocation = DIDescriptor; @@ -295,6 +294,8 @@ pub mod llvm { pub unsafe fn LLVMGetModuleContext(M: ModuleRef) -> ContextRef; #[fast_ffi] pub unsafe fn LLVMDisposeModule(M: ModuleRef); + #[fast_ffi] + pub unsafe fn LLVMGetModuleContext(M: ModuleRef) -> ContextRef; /** Data layout. See Module::getDataLayout. */ #[fast_ffi] @@ -2045,14 +2046,14 @@ pub mod llvm { AlwaysPreserve: bool, Flags: c_uint, ArgNo: c_uint) -> DIVariable; - + #[fast_ffi] pub unsafe fn LLVMDIBuilderCreateArrayType( Builder: DIBuilderRef, Size: c_ulonglong, AlignInBits: c_ulonglong, Ty: DIType, - Subscripts: DIArray) -> DIType; + Subscripts: DIArray) -> DIType; #[fast_ffi] pub unsafe fn LLVMDIBuilderCreateVectorType( diff --git a/src/librustc/middle/trans/base.rs b/src/librustc/middle/trans/base.rs index ddc8207dfe04f..467185f007e5a 100644 --- a/src/librustc/middle/trans/base.rs +++ b/src/librustc/middle/trans/base.rs @@ -1908,7 +1908,11 @@ pub fn trans_closure(ccx: @mut CrateContext, finish(bcx); cleanup_and_Br(bcx, bcx_top, fcx.llreturn); - unsafe { llvm::LLVMMoveBasicBlockAfter(fcx.llreturn, bcx.llbb); } + // Put return block after all other blocks. + // This somewhat improves single-stepping experience in debugger. + unsafe { + llvm::LLVMMoveBasicBlockAfter(fcx.llreturn, bcx.llbb); + } // Insert the mandatory first few basic blocks before lltop. finish_fn(fcx, lltop); @@ -3108,7 +3112,7 @@ pub fn trans_crate(sess: session::Session, if ccx.sess.opts.debuginfo { debuginfo::finalize(ccx); } - + // Translate the metadata. write_metadata(ccx, crate); if ccx.sess.trans_stats() { diff --git a/src/librustc/middle/trans/debuginfo.rs b/src/librustc/middle/trans/debuginfo.rs index 12c774046d8ba..1f8b75d9e77d5 100644 --- a/src/librustc/middle/trans/debuginfo.rs +++ b/src/librustc/middle/trans/debuginfo.rs @@ -1,4 +1,4 @@ -// Copyright 2012 The Rust Project Developers. See the COPYRIGHT +// Copyright 2012-2013 The Rust Project Developers. See the COPYRIGHT // file at the top-level directory of this distribution and at // http://rust-lang.org/COPYRIGHT. // @@ -32,9 +32,7 @@ use core::vec; use syntax::codemap::span; use syntax::{ast, codemap, ast_util, ast_map}; -static LLVMDebugVersion: int = (12 << 16); - -static DW_LANG_RUST: int = 12; //0x9000; +static DW_LANG_RUST: int = 0x9000; static CompileUnitTag: int = 17; static FileDescriptorTag: int = 41; @@ -65,6 +63,7 @@ pub type DebugContext = @mut _DebugContext; struct _DebugContext { names: namegen, crate_file: ~str, + llcontext: ContextRef, builder: DIBuilderRef, curr_loc: (uint, uint), created_files: HashMap<~str, DIFile>, @@ -73,13 +72,16 @@ struct _DebugContext { created_types: HashMap } -/** Create new DebugContext */ +/// Create new DebugContext pub fn mk_ctxt(llmod: ModuleRef, crate: ~str) -> DebugContext { debug!("mk_ctxt"); let builder = unsafe { llvm::LLVMDIBuilderCreate(llmod) }; + // DIBuilder inherits context from the module, so we'd better use the same one + let llcontext = unsafe { llvm::LLVMGetModuleContext(llmod) }; let dcx = @mut _DebugContext { names: new_namegen(), crate_file: crate, + llcontext: llcontext, builder: builder, curr_loc: (0, 0), created_files: HashMap::new(), @@ -91,18 +93,11 @@ pub fn mk_ctxt(llmod: ModuleRef, crate: ~str) -> DebugContext { } #[inline(always)] -fn dbg_cx(cx: &CrateContext) -> DebugContext -{ +fn dbg_cx(cx: &CrateContext) -> DebugContext { return cx.dbg_cx.get(); } -fn create_DIArray(builder: DIBuilderRef, arr: &[DIDescriptor]) -> DIArray { - return unsafe { - llvm::LLVMDIBuilderGetOrCreateArray(builder, vec::raw::to_ptr(arr), arr.len() as u32) - }; -} - -/** Create any deferred debug metadata nodes */ +/// Create any deferred debug metadata nodes pub fn finalize(cx: @CrateContext) { debug!("finalize"); create_compile_unit(cx); @@ -113,6 +108,12 @@ pub fn finalize(cx: @CrateContext) { }; } +fn create_DIArray(builder: DIBuilderRef, arr: &[DIDescriptor]) -> DIArray { + return unsafe { + llvm::LLVMDIBuilderGetOrCreateArray(builder, vec::raw::to_ptr(arr), arr.len() as u32) + }; +} + fn create_compile_unit(cx: @CrateContext) { let crate_name: &str = dbg_cx(cx).crate_file; let work_dir = cx.sess.working_dir.to_str(); @@ -158,6 +159,7 @@ fn create_file(cx: @CrateContext, full_path: &str) -> DIFile { return file_md; } +/// Return codemap::Loc corresponding to the beginning of the span fn span_start(cx: @CrateContext, span: span) -> codemap::Loc { return cx.sess.codemap.lookup_char_pos(span.lo); } @@ -208,7 +210,7 @@ fn size_and_align_of(cx: @CrateContext, t: ty::t) -> (uint, uint) { (machine::llsize_of_real(cx, llty), machine::llalign_of_min(cx, llty)) } -fn create_basic_type(cx: @CrateContext, t: ty::t, span: span) -> DIType{ +fn create_basic_type(cx: @CrateContext, t: ty::t, _span: span) -> DIType{ let dcx = dbg_cx(cx); let ty_id = ty::type_id(t); match dcx.created_types.find(&ty_id) { @@ -255,7 +257,7 @@ fn create_basic_type(cx: @CrateContext, t: ty::t, span: span) -> DIType{ return ty_md; } -fn create_pointer_type(cx: @CrateContext, t: ty::t, span: span, pointee: DIType) -> DIType { +fn create_pointer_type(cx: @CrateContext, t: ty::t, _span: span, pointee: DIType) -> DIType { let (size, align) = size_and_align_of(cx, t); let name = ty_to_str(cx.tcx, t); let ptr_md = do as_c_str(name) |name| { unsafe { @@ -291,7 +293,8 @@ impl StructContext { } fn add_member(&mut self, name: &str, line: uint, size: uint, align: uint, ty: DIType) { - debug!("StructContext(%s)::add_member: %s, size=%u, align=%u", self.name, name, size, align); + debug!("StructContext(%s)::add_member: %s, size=%u, align=%u", + self.name, name, size, align); let offset = roundup(self.total_size, align); let mem_t = do as_c_str(name) |name| { unsafe { llvm::LLVMDIBuilderCreateMemberType(dbg_cx(self.cx).builder, @@ -306,7 +309,8 @@ impl StructContext { } fn finalize(&self) -> DICompositeType { - debug!("StructContext(%s)::finalize: total_size=%u, align=%u", self.name, self.total_size, self.align); + debug!("StructContext(%s)::finalize: total_size=%u, align=%u", + self.name, self.total_size, self.align); let dcx = dbg_cx(self.cx); let members_md = create_DIArray(dcx.builder, self.members); @@ -323,8 +327,8 @@ impl StructContext { } #[inline(always)] -fn roundup(x: uint, a: uint) -> uint { - ((x + (a - 1)) / a) * a +fn roundup(x: uint, a: uint) -> uint { + ((x + (a - 1)) / a) * a } fn create_struct(cx: @CrateContext, t: ty::t, fields: ~[ty::field], span: span) -> DICompositeType { @@ -353,7 +357,7 @@ fn voidptr(cx: @CrateContext) -> (DIDerivedType, uint, uint) { return (vp, size, align); } -fn create_tuple(cx: @CrateContext, t: ty::t, elements: &[ty::t], span: span) -> DICompositeType { +fn create_tuple(cx: @CrateContext, _t: ty::t, elements: &[ty::t], span: span) -> DICompositeType { let dcx = dbg_cx(cx); let loc = span_start(cx, span); let file_md = create_file(cx, loc.file.name); @@ -391,12 +395,10 @@ fn create_boxed_type(cx: @CrateContext, contents: ty::t, return scx.finalize(); } -fn create_fixed_vec(cx: @CrateContext, vec_t: ty::t, elem_t: ty::t, +fn create_fixed_vec(cx: @CrateContext, _vec_t: ty::t, elem_t: ty::t, len: uint, span: span) -> DIType { let dcx = dbg_cx(cx); let elem_ty_md = create_ty(cx, elem_t, span); - let loc = span_start(cx, span); - let file_md = create_file(cx, loc.file.name); let (size, align) = size_and_align_of(cx, elem_t); let subrange = unsafe { @@ -465,7 +467,7 @@ fn create_vec_slice(cx: @CrateContext, vec_t: ty::t, elem_t: ty::t, span: span) return scx.finalize(); } -fn create_fn_ty(cx: @CrateContext, fn_ty: ty::t, inputs: ~[ty::t], output: ty::t, +fn create_fn_ty(cx: @CrateContext, _fn_ty: ty::t, inputs: ~[ty::t], output: ty::t, span: span) -> DICompositeType { let dcx = dbg_cx(cx); let loc = span_start(cx, span); @@ -487,7 +489,7 @@ fn create_unimpl_ty(cx: @CrateContext, t: ty::t) -> DIType { let name = ty_to_str(cx.tcx, t); let md = do as_c_str(fmt!("NYI<%s>", name)) |name| { unsafe { llvm::LLVMDIBuilderCreateBasicType( - dcx.builder, name, + dcx.builder, name, 0_u64, 8_u64, DW_ATE_unsigned as c_uint) }}; return md; @@ -621,7 +623,7 @@ pub fn create_local_var(bcx: block, local: @ast::local) -> DIVariable { } }; - set_debug_location(bcx, loc.line, loc.col.to_uint()); + set_debug_location(cx, create_block(bcx), loc.line, loc.col.to_uint()); unsafe { let instr = llvm::LLVMDIBuilderInsertDeclareAtEnd(dcx.builder, llptr, var_md, bcx.llbb); llvm::LLVMSetInstDebugLocation(trans::build::B(bcx), instr); @@ -633,7 +635,7 @@ pub fn create_local_var(bcx: block, local: @ast::local) -> DIVariable { pub fn create_arg(bcx: block, arg: ast::arg, span: span) -> Option { debug!("create_arg"); if true { - // FIXME(5848) create_arg disabled for now because "node_id_type(bcx, arg.id)" below blows + // XXX create_arg disabled for now because "node_id_type(bcx, arg.id)" below blows // up: "error: internal compiler error: node_id_to_type: no type for node `arg (id=10)`" return None; } @@ -661,12 +663,15 @@ pub fn create_arg(bcx: block, arg: ast::arg, span: span) -> Option { llvm::LLVMDIBuilderCreateLocalVariable(dcx.builder, ArgVariableTag as u32, context, name, filemd, loc.line as c_uint, tymd, false, 0, 0) - // FIXME need to pass a real argument number + // XXX need to pass in a real argument number }}; let llptr = fcx.llargs.get_copy(&arg.id); + set_debug_location(cx, create_block(bcx), loc.line, loc.col.to_uint()); unsafe { - llvm::LLVMDIBuilderInsertDeclareAtEnd(dcx.builder, llptr, mdnode, bcx.llbb); + let instr = llvm::LLVMDIBuilderInsertDeclareAtEnd( + dcx.builder, llptr, mdnode, bcx.llbb); + llvm::LLVMSetInstDebugLocation(trans::build::B(bcx), instr); } return Some(mdnode); } @@ -676,33 +681,31 @@ pub fn create_arg(bcx: block, arg: ast::arg, span: span) -> Option { } } -fn set_debug_location(bcx: block, line: uint, col: uint) { - let blockmd = create_block(bcx); - let elems = ~[C_i32(line as i32), C_i32(col as i32), blockmd, ptr::null()]; +fn set_debug_location(cx: @CrateContext, scope: DIScope, line: uint, col: uint) { + let dcx = dbg_cx(cx); + if dcx.curr_loc == (line, col) { + return; + } + debug!("setting debug location to %u %u", line, col); + dcx.curr_loc = (line, col); + + let elems = ~[C_i32(line as i32), C_i32(col as i32), scope, ptr::null()]; unsafe { - let dbg_loc = llvm::LLVMMDNode(vec::raw::to_ptr(elems), elems.len() as libc::c_uint); - llvm::LLVMSetCurrentDebugLocation(trans::build::B(bcx), dbg_loc); + let dbg_loc = llvm::LLVMMDNodeInContext( + dcx.llcontext, vec::raw::to_ptr(elems), + elems.len() as libc::c_uint); + llvm::LLVMSetCurrentDebugLocation(cx.builder.B, dbg_loc); } } +/// Set current debug location at the beginning of the span pub fn update_source_pos(bcx: block, span: span) { if !bcx.sess().opts.debuginfo || (*span.lo == 0 && *span.hi == 0) { return; } - debug!("update_source_pos: %s", bcx.sess().codemap.span_to_str(span)); - - let cx = bcx.ccx(); - let loc = span_start(cx, span); - let dcx = dbg_cx(cx); - - let loc = (loc.line, loc.col.to_uint()); - if loc == dcx.curr_loc { - return; - } - debug!("setting_location to %u %u", loc.first(), loc.second()); - dcx.curr_loc = loc; - set_debug_location(bcx, loc.first(), loc.second()); + let loc = span_start(bcx.ccx(), span); + set_debug_location(bcx.ccx(), create_block(bcx), loc.line, loc.col.to_uint()) } pub fn create_function(fcx: fn_ctxt) -> DISubprogram { From adff46250ed9e9b3c31da65b2997a5458e41305a Mon Sep 17 00:00:00 2001 From: Vadim Chugunov Date: Mon, 17 Jun 2013 08:42:05 -0700 Subject: [PATCH 11/11] Fixed rebase fallout . --- src/librustc/lib/llvm.rs | 2 - src/librustc/middle/trans/base.rs | 7 +- src/librustc/middle/trans/context.rs | 2 +- src/librustc/middle/trans/debuginfo.rs | 237 ++++++++++++------------- src/rustllvm/RustWrapper.cpp | 4 +- 5 files changed, 122 insertions(+), 130 deletions(-) diff --git a/src/librustc/lib/llvm.rs b/src/librustc/lib/llvm.rs index c00bb390edd28..835dd55711b57 100644 --- a/src/librustc/lib/llvm.rs +++ b/src/librustc/lib/llvm.rs @@ -294,8 +294,6 @@ pub mod llvm { pub unsafe fn LLVMGetModuleContext(M: ModuleRef) -> ContextRef; #[fast_ffi] pub unsafe fn LLVMDisposeModule(M: ModuleRef); - #[fast_ffi] - pub unsafe fn LLVMGetModuleContext(M: ModuleRef) -> ContextRef; /** Data layout. See Module::getDataLayout. */ #[fast_ffi] diff --git a/src/librustc/middle/trans/base.rs b/src/librustc/middle/trans/base.rs index 467185f007e5a..55fc22a8fcc02 100644 --- a/src/librustc/middle/trans/base.rs +++ b/src/librustc/middle/trans/base.rs @@ -3080,7 +3080,6 @@ pub fn trans_crate(sess: session::Session, // 1. http://llvm.org/bugs/show_bug.cgi?id=11479 let llmod_id = link_meta.name.to_owned() + ".rc"; - Some(debuginfo::mk_ctxt(llmod, copy llmod_id)) // FIXME(#6511): get LLVM building with --enable-threads so this // function can be called // if !llvm::LLVMRustStartMultithreading() { @@ -3109,9 +3108,9 @@ pub fn trans_crate(sess: session::Session, fill_crate_map(ccx, ccx.crate_map); glue::emit_tydescs(ccx); write_abi_version(ccx); - if ccx.sess.opts.debuginfo { - debuginfo::finalize(ccx); - } + if ccx.sess.opts.debuginfo { + debuginfo::finalize(ccx); + } // Translate the metadata. write_metadata(ccx, crate); diff --git a/src/librustc/middle/trans/context.rs b/src/librustc/middle/trans/context.rs index 75d7aaa88a6d0..7aab1d0239e6f 100644 --- a/src/librustc/middle/trans/context.rs +++ b/src/librustc/middle/trans/context.rs @@ -148,7 +148,7 @@ impl CrateContext { lib::llvm::associate_type(tn, @"tydesc", tydesc_type); let crate_map = decl_crate_map(sess, link_meta, llmod); let dbg_cx = if sess.opts.debuginfo { - Some(debuginfo::mk_ctxt(name.to_owned())) + Some(debuginfo::DebugContext::new(llmod, name.to_owned())) } else { None }; diff --git a/src/librustc/middle/trans/debuginfo.rs b/src/librustc/middle/trans/debuginfo.rs index 1f8b75d9e77d5..91e3276d8aa64 100644 --- a/src/librustc/middle/trans/debuginfo.rs +++ b/src/librustc/middle/trans/debuginfo.rs @@ -58,9 +58,7 @@ static DW_ATE_unsigned_char: int = 0x08; //////////////// -pub type DebugContext = @mut _DebugContext; - -struct _DebugContext { +pub struct DebugContext { names: namegen, crate_file: ~str, llcontext: ContextRef, @@ -72,39 +70,43 @@ struct _DebugContext { created_types: HashMap } -/// Create new DebugContext -pub fn mk_ctxt(llmod: ModuleRef, crate: ~str) -> DebugContext { - debug!("mk_ctxt"); - let builder = unsafe { llvm::LLVMDIBuilderCreate(llmod) }; - // DIBuilder inherits context from the module, so we'd better use the same one - let llcontext = unsafe { llvm::LLVMGetModuleContext(llmod) }; - let dcx = @mut _DebugContext { - names: new_namegen(), - crate_file: crate, - llcontext: llcontext, - builder: builder, - curr_loc: (0, 0), - created_files: HashMap::new(), - created_functions: HashMap::new(), - created_blocks: HashMap::new(), - created_types: HashMap::new(), - }; - return dcx; +impl DebugContext { + pub fn new(llmod: ModuleRef, crate: ~str) -> DebugContext { + debug!("DebugContext::new"); + let builder = unsafe { llvm::LLVMDIBuilderCreate(llmod) }; + // DIBuilder inherits context from the module, so we'd better use the same one + let llcontext = unsafe { llvm::LLVMGetModuleContext(llmod) }; + return DebugContext { + names: new_namegen(), + crate_file: crate, + llcontext: llcontext, + builder: builder, + curr_loc: (0, 0), + created_files: HashMap::new(), + created_functions: HashMap::new(), + created_blocks: HashMap::new(), + created_types: HashMap::new(), + }; + } } -#[inline(always)] -fn dbg_cx(cx: &CrateContext) -> DebugContext { - return cx.dbg_cx.get(); +#[inline] +fn dbg_cx<'a>(cx: &'a mut CrateContext) -> &'a mut DebugContext { + cx.dbg_cx.get_mut_ref() +} + +#[inline] +fn DIB(cx: &CrateContext) -> DIBuilderRef { + cx.dbg_cx.get_ref().builder } /// Create any deferred debug metadata nodes -pub fn finalize(cx: @CrateContext) { +pub fn finalize(cx: @mut CrateContext) { debug!("finalize"); create_compile_unit(cx); - let dcx = dbg_cx(cx); unsafe { - llvm::LLVMDIBuilderFinalize(dcx.builder); - llvm::LLVMDIBuilderDispose(dcx.builder); + llvm::LLVMDIBuilderFinalize(DIB(cx)); + llvm::LLVMDIBuilderDispose(DIB(cx)); }; } @@ -114,8 +116,9 @@ fn create_DIArray(builder: DIBuilderRef, arr: &[DIDescriptor]) -> DIArray { }; } -fn create_compile_unit(cx: @CrateContext) { - let crate_name: &str = dbg_cx(cx).crate_file; +fn create_compile_unit(cx: @mut CrateContext) { + let dcx = dbg_cx(cx); + let crate_name: &str = dcx.crate_file; let work_dir = cx.sess.working_dir.to_str(); let producer = fmt!("rustc version %s", env!("CFG_VERSION")); @@ -124,17 +127,15 @@ fn create_compile_unit(cx: @CrateContext) { do as_c_str(producer) |producer| { do as_c_str("") |flags| { do as_c_str("") |split_name| { unsafe { - llvm::LLVMDIBuilderCreateCompileUnit(dbg_cx(cx).builder, + llvm::LLVMDIBuilderCreateCompileUnit(dcx.builder, DW_LANG_RUST as c_uint, crate_name, work_dir, producer, cx.sess.opts.optimize != session::No, flags, 0, split_name); }}}}}}; } -fn create_file(cx: @CrateContext, full_path: &str) -> DIFile { - let dcx = dbg_cx(cx); - - match dcx.created_files.find_equiv(&full_path) { +fn create_file(cx: @mut CrateContext, full_path: &str) -> DIFile { + match dbg_cx(cx).created_files.find_equiv(&full_path) { Some(file_md) => return *file_md, None => () } @@ -152,22 +153,21 @@ fn create_file(cx: @CrateContext, full_path: &str) -> DIFile { let file_md = do as_c_str(file_name) |file_name| { do as_c_str(work_dir) |work_dir| { unsafe { - llvm::LLVMDIBuilderCreateFile(dcx.builder, file_name, work_dir) + llvm::LLVMDIBuilderCreateFile(DIB(cx), file_name, work_dir) }}}; - dcx.created_files.insert(full_path.to_owned(), file_md); + dbg_cx(cx).created_files.insert(full_path.to_owned(), file_md); return file_md; } /// Return codemap::Loc corresponding to the beginning of the span -fn span_start(cx: @CrateContext, span: span) -> codemap::Loc { +fn span_start(cx: &CrateContext, span: span) -> codemap::Loc { return cx.sess.codemap.lookup_char_pos(span.lo); } fn create_block(bcx: block) -> DILexicalBlock { let mut bcx = bcx; let cx = bcx.ccx(); - let dcx = dbg_cx(cx); while bcx.node_info.is_none() { match bcx.parent { @@ -178,7 +178,7 @@ fn create_block(bcx: block) -> DILexicalBlock { let span = bcx.node_info.get().span; let id = bcx.node_info.get().id; - match dcx.created_blocks.find(&id) { + match dbg_cx(cx).created_blocks.find(&id) { Some(block) => return *block, None => () } @@ -195,25 +195,24 @@ fn create_block(bcx: block) -> DILexicalBlock { let block_md = unsafe { llvm::LLVMDIBuilderCreateLexicalBlock( - dcx.builder, + DIB(cx), parent, file_md, loc.line as c_uint, loc.col.to_uint() as c_uint) }; - dcx.created_blocks.insert(id, block_md); + dbg_cx(cx).created_blocks.insert(id, block_md); return block_md; } -fn size_and_align_of(cx: @CrateContext, t: ty::t) -> (uint, uint) { +fn size_and_align_of(cx: @mut CrateContext, t: ty::t) -> (uint, uint) { let llty = type_of::type_of(cx, t); (machine::llsize_of_real(cx, llty), machine::llalign_of_min(cx, llty)) } -fn create_basic_type(cx: @CrateContext, t: ty::t, _span: span) -> DIType{ - let dcx = dbg_cx(cx); +fn create_basic_type(cx: @mut CrateContext, t: ty::t, _span: span) -> DIType { let ty_id = ty::type_id(t); - match dcx.created_types.find(&ty_id) { + match dbg_cx(cx).created_types.find(&ty_id) { Some(ty_md) => return *ty_md, None => () } @@ -249,26 +248,26 @@ fn create_basic_type(cx: @CrateContext, t: ty::t, _span: span) -> DIType{ let (size, align) = size_and_align_of(cx, t); let ty_md = do as_c_str(name) |name| { unsafe { llvm::LLVMDIBuilderCreateBasicType( - dcx.builder, name, + DIB(cx), name, size * 8 as u64, align * 8 as u64, encoding as c_uint) }}; - dcx.created_types.insert(ty_id, ty_md); + dbg_cx(cx).created_types.insert(ty_id, ty_md); return ty_md; } -fn create_pointer_type(cx: @CrateContext, t: ty::t, _span: span, pointee: DIType) -> DIType { +fn create_pointer_type(cx: @mut CrateContext, t: ty::t, _span: span, pointee: DIType) -> DIType { let (size, align) = size_and_align_of(cx, t); let name = ty_to_str(cx.tcx, t); let ptr_md = do as_c_str(name) |name| { unsafe { - llvm::LLVMDIBuilderCreatePointerType(dbg_cx(cx).builder, + llvm::LLVMDIBuilderCreatePointerType(DIB(cx), pointee, size * 8 as u64, align * 8 as u64, name) }}; return ptr_md; } struct StructContext { - cx: @CrateContext, + builder: DIBuilderRef, file: DIFile, name: ~str, line: uint, @@ -278,10 +277,10 @@ struct StructContext { } impl StructContext { - fn create(cx: @CrateContext, file: DIFile, name: ~str, line: uint) -> ~StructContext { + fn new(cx: &CrateContext, name: ~str, file: DIFile, line: uint) -> ~StructContext { debug!("StructContext::create: %s", name); let scx = ~StructContext { - cx: cx, + builder: DIB(cx), file: file, name: name, line: line, @@ -297,8 +296,8 @@ impl StructContext { self.name, name, size, align); let offset = roundup(self.total_size, align); let mem_t = do as_c_str(name) |name| { unsafe { - llvm::LLVMDIBuilderCreateMemberType(dbg_cx(self.cx).builder, - ptr::null(), name, self.file, line as c_uint, + llvm::LLVMDIBuilderCreateMemberType( + self.builder, ptr::null(), name, self.file, line as c_uint, size * 8 as u64, align * 8 as u64, offset * 8 as u64, 0, ty) }}; @@ -311,13 +310,12 @@ impl StructContext { fn finalize(&self) -> DICompositeType { debug!("StructContext(%s)::finalize: total_size=%u, align=%u", self.name, self.total_size, self.align); - let dcx = dbg_cx(self.cx); - let members_md = create_DIArray(dcx.builder, self.members); + let members_md = create_DIArray(self.builder, self.members); let struct_md = do as_c_str(self.name) |name| { unsafe { llvm::LLVMDIBuilderCreateStructType( - dcx.builder, self.file, name, + self.builder, self.file, name, self.file, self.line as c_uint, self.total_size * 8 as u64, self.align * 8 as u64, 0, ptr::null(), members_md, 0, ptr::null()) @@ -326,45 +324,44 @@ impl StructContext { } } -#[inline(always)] +#[inline] fn roundup(x: uint, a: uint) -> uint { ((x + (a - 1)) / a) * a } -fn create_struct(cx: @CrateContext, t: ty::t, fields: ~[ty::field], span: span) -> DICompositeType { +fn create_struct(cx: @mut CrateContext, t: ty::t, fields: ~[ty::field], span: span) + -> DICompositeType { let loc = span_start(cx, span); let file_md = create_file(cx, loc.file.name); - let mut scx = StructContext::create(cx, file_md, ty_to_str(cx.tcx, t), loc.line); + let mut scx = StructContext::new(cx, ty_to_str(cx.tcx, t), file_md, loc.line); for fields.each |field| { let field_t = field.mt.ty; let ty_md = create_ty(cx, field_t, span); let (size, align) = size_and_align_of(cx, field_t); - scx.add_member(cx.sess.str_of(field.ident), - loc.line, size, align, ty_md); + scx.add_member(cx.sess.str_of(field.ident), loc.line, size, align, ty_md); } return scx.finalize(); } // returns (void* type as a ValueRef, size in bytes, align in bytes) -fn voidptr(cx: @CrateContext) -> (DIDerivedType, uint, uint) { +fn voidptr(cx: @mut CrateContext) -> (DIDerivedType, uint, uint) { let size = sys::size_of::(); let align = sys::min_align_of::(); let vp = do as_c_str("*void") |name| { unsafe { - llvm::LLVMDIBuilderCreatePointerType(dbg_cx(cx).builder, ptr::null(), + llvm::LLVMDIBuilderCreatePointerType(DIB(cx), ptr::null(), size*8 as u64, align*8 as u64, name) }}; return (vp, size, align); } -fn create_tuple(cx: @CrateContext, _t: ty::t, elements: &[ty::t], span: span) -> DICompositeType { - let dcx = dbg_cx(cx); +fn create_tuple(cx: @mut CrateContext, _t: ty::t, elements: &[ty::t], span: span) + -> DICompositeType { let loc = span_start(cx, span); let file_md = create_file(cx, loc.file.name); - let name = (cx.sess.str_of((dcx.names)("tuple"))).to_owned(); - let mut scx = StructContext::create(cx, file_md, name, loc.line); - + let name = (cx.sess.str_of((dbg_cx(cx).names)("tuple"))).to_owned(); + let mut scx = StructContext::new(cx, name, file_md, loc.line); for elements.each |element| { let ty_md = create_ty(cx, *element, span); let (size, align) = size_and_align_of(cx, *element); @@ -373,7 +370,7 @@ fn create_tuple(cx: @CrateContext, _t: ty::t, elements: &[ty::t], span: span) -> return scx.finalize(); } -fn create_boxed_type(cx: @CrateContext, contents: ty::t, +fn create_boxed_type(cx: @mut CrateContext, contents: ty::t, span: span, boxed: DIType) -> DICompositeType { let loc = span_start(cx, span); let file_md = create_file(cx, loc.file.name); @@ -381,7 +378,7 @@ fn create_boxed_type(cx: @CrateContext, contents: ty::t, let refcount_type = create_basic_type(cx, int_t, span); let name = ty_to_str(cx.tcx, contents); - let mut scx = StructContext::create(cx, file_md, fmt!("box<%s>", name), 0); + let mut scx = StructContext::new(cx, fmt!("box<%s>", name), file_md, 0); scx.add_member("refcnt", 0, sys::size_of::(), sys::min_align_of::(), refcount_type); // the tydesc and other pointers should be irrelevant to the @@ -395,48 +392,50 @@ fn create_boxed_type(cx: @CrateContext, contents: ty::t, return scx.finalize(); } -fn create_fixed_vec(cx: @CrateContext, _vec_t: ty::t, elem_t: ty::t, +fn create_fixed_vec(cx: @mut CrateContext, _vec_t: ty::t, elem_t: ty::t, len: uint, span: span) -> DIType { - let dcx = dbg_cx(cx); let elem_ty_md = create_ty(cx, elem_t, span); let (size, align) = size_and_align_of(cx, elem_t); let subrange = unsafe { - llvm::LLVMDIBuilderGetOrCreateSubrange(dcx.builder, 0_i64, len as i64) }; + llvm::LLVMDIBuilderGetOrCreateSubrange(DIB(cx), 0_i64, len as i64) + }; - let subscripts = create_DIArray(dcx.builder, [subrange]); + let subscripts = create_DIArray(DIB(cx), [subrange]); return unsafe { - llvm::LLVMDIBuilderCreateArrayType(dcx.builder, + llvm::LLVMDIBuilderCreateArrayType(DIB(cx), size * len * 8 as u64, align * 8 as u64, elem_ty_md, subscripts) }; } -fn create_boxed_vec(cx: @CrateContext, vec_t: ty::t, elem_t: ty::t, +fn create_boxed_vec(cx: @mut CrateContext, vec_t: ty::t, elem_t: ty::t, vec_ty_span: span) -> DICompositeType { - let dcx = dbg_cx(cx); let loc = span_start(cx, vec_ty_span); let file_md = create_file(cx, loc.file.name); let elem_ty_md = create_ty(cx, elem_t, vec_ty_span); - let mut vec_scx = StructContext::create(cx, file_md, ty_to_str(cx.tcx, vec_t), 0); - + let mut vec_scx = StructContext::new(cx, ty_to_str(cx.tcx, vec_t), file_md, 0); let size_t_type = create_basic_type(cx, ty::mk_uint(), vec_ty_span); vec_scx.add_member("fill", 0, sys::size_of::(), sys::min_align_of::(), size_t_type); vec_scx.add_member("alloc", 0, sys::size_of::(), sys::min_align_of::(), size_t_type); - let subrange = unsafe { llvm::LLVMDIBuilderGetOrCreateSubrange(dcx.builder, 0_i64, 0_i64) }; + let subrange = unsafe { + llvm::LLVMDIBuilderGetOrCreateSubrange(DIB(cx), 0_i64, 0_i64) + }; let (arr_size, arr_align) = size_and_align_of(cx, elem_t); let name = fmt!("[%s]", ty_to_str(cx.tcx, elem_t)); - let subscripts = create_DIArray(dcx.builder, [subrange]); - let data_ptr = unsafe { llvm::LLVMDIBuilderCreateArrayType(dcx.builder, - arr_size * 8 as u64, arr_align * 8 as u64, elem_ty_md, subscripts) }; + let subscripts = create_DIArray(DIB(cx), [subrange]); + let data_ptr = unsafe { + llvm::LLVMDIBuilderCreateArrayType(DIB(cx), + arr_size * 8 as u64, arr_align * 8 as u64, elem_ty_md, subscripts) + }; vec_scx.add_member("data", 0, 0, // clang says the size should be 0 sys::min_align_of::(), data_ptr); let vec_md = vec_scx.finalize(); - let mut box_scx = StructContext::create(cx, file_md, fmt!("box<%s>", name), 0); + let mut box_scx = StructContext::new(cx, fmt!("box<%s>", name), file_md, 0); let int_t = ty::mk_int(); let refcount_type = create_basic_type(cx, int_t, vec_ty_span); box_scx.add_member("refcnt", 0, sys::size_of::(), @@ -452,24 +451,24 @@ fn create_boxed_vec(cx: @CrateContext, vec_t: ty::t, elem_t: ty::t, return mdval; } -fn create_vec_slice(cx: @CrateContext, vec_t: ty::t, elem_t: ty::t, span: span) -> DICompositeType { +fn create_vec_slice(cx: @mut CrateContext, vec_t: ty::t, elem_t: ty::t, span: span) + -> DICompositeType { let loc = span_start(cx, span); let file_md = create_file(cx, loc.file.name); let elem_ty_md = create_ty(cx, elem_t, span); let uint_type = create_basic_type(cx, ty::mk_uint(), span); let elem_ptr = create_pointer_type(cx, elem_t, span, elem_ty_md); - let mut scx = StructContext::create(cx, file_md, ty_to_str(cx.tcx, vec_t), 0); + let mut scx = StructContext::new(cx, ty_to_str(cx.tcx, vec_t), file_md, 0); let (_, ptr_size, ptr_align) = voidptr(cx); scx.add_member("vec", 0, ptr_size, ptr_align, elem_ptr); scx.add_member("length", 0, sys::size_of::(), - sys::min_align_of::(), uint_type); + sys::min_align_of::(), uint_type); return scx.finalize(); } -fn create_fn_ty(cx: @CrateContext, _fn_ty: ty::t, inputs: ~[ty::t], output: ty::t, +fn create_fn_ty(cx: @mut CrateContext, _fn_ty: ty::t, inputs: ~[ty::t], output: ty::t, span: span) -> DICompositeType { - let dcx = dbg_cx(cx); let loc = span_start(cx, span); let file_md = create_file(cx, loc.file.name); let (vp, _, _) = voidptr(cx); @@ -479,26 +478,24 @@ fn create_fn_ty(cx: @CrateContext, _fn_ty: ty::t, inputs: ~[ty::t], output: ty:: let members = ~[output_ptr_md, vp] + inputs_vals; return unsafe { - llvm::LLVMDIBuilderCreateSubroutineType(dcx.builder, file_md, - create_DIArray(dcx.builder, members)) + llvm::LLVMDIBuilderCreateSubroutineType(DIB(cx), file_md, + create_DIArray(DIB(cx), members)) }; } -fn create_unimpl_ty(cx: @CrateContext, t: ty::t) -> DIType { - let dcx = dbg_cx(cx); +fn create_unimpl_ty(cx: @mut CrateContext, t: ty::t) -> DIType { let name = ty_to_str(cx.tcx, t); let md = do as_c_str(fmt!("NYI<%s>", name)) |name| { unsafe { llvm::LLVMDIBuilderCreateBasicType( - dcx.builder, name, + DIB(cx), name, 0_u64, 8_u64, DW_ATE_unsigned as c_uint) }}; return md; } -fn create_ty(cx: @CrateContext, t: ty::t, span: span) -> DIType { - let dcx = dbg_cx(cx); +fn create_ty(cx: @mut CrateContext, t: ty::t, span: span) -> DIType { let ty_id = ty::type_id(t); - match dcx.created_types.find(&ty_id) { + match dbg_cx(cx).created_types.find(&ty_id) { Some(ty_md) => return *ty_md, None => () } @@ -578,13 +575,12 @@ fn create_ty(cx: @CrateContext, t: ty::t, span: span) -> DIType { _ => cx.sess.bug(~"debuginfo: unexpected type in create_ty") }; - dcx.created_types.insert(ty_id, ty_md); + dbg_cx(cx).created_types.insert(ty_id, ty_md); return ty_md; } pub fn create_local_var(bcx: block, local: @ast::local) -> DIVariable { let cx = bcx.ccx(); - let dcx = dbg_cx(cx); let ident = match local.node.pat.node { ast::pat_ident(_, pth, _) => ast_util::path_to_ident(pth), @@ -608,7 +604,7 @@ pub fn create_local_var(bcx: block, local: @ast::local) -> DIVariable { let var_md = do as_c_str(name) |name| { unsafe { llvm::LLVMDIBuilderCreateLocalVariable( - dcx.builder, AutoVariableTag as u32, + DIB(cx), AutoVariableTag as u32, context, name, filemd, loc.line as c_uint, tymd, false, 0, 0) }}; @@ -625,7 +621,7 @@ pub fn create_local_var(bcx: block, local: @ast::local) -> DIVariable { set_debug_location(cx, create_block(bcx), loc.line, loc.col.to_uint()); unsafe { - let instr = llvm::LLVMDIBuilderInsertDeclareAtEnd(dcx.builder, llptr, var_md, bcx.llbb); + let instr = llvm::LLVMDIBuilderInsertDeclareAtEnd(DIB(cx), llptr, var_md, bcx.llbb); llvm::LLVMSetInstDebugLocation(trans::build::B(bcx), instr); } @@ -641,8 +637,7 @@ pub fn create_arg(bcx: block, arg: ast::arg, span: span) -> Option { } let fcx = bcx.fcx; - let cx = *fcx.ccx; - let dcx = dbg_cx(cx); + let cx = fcx.ccx; let loc = span_start(cx, span); if "" == loc.file.name { @@ -652,7 +647,7 @@ pub fn create_arg(bcx: block, arg: ast::arg, span: span) -> Option { let ty = node_id_type(bcx, arg.id); let tymd = create_ty(cx, ty, arg.ty.span); let filemd = create_file(cx, loc.file.name); - let context = create_function(bcx.fcx); + let context = create_function(fcx); match arg.pat.node { ast::pat_ident(_, path, _) => { @@ -660,7 +655,7 @@ pub fn create_arg(bcx: block, arg: ast::arg, span: span) -> Option { let ident = path.idents.last(); let name: &str = cx.sess.str_of(*ident); let mdnode = do as_c_str(name) |name| { unsafe { - llvm::LLVMDIBuilderCreateLocalVariable(dcx.builder, + llvm::LLVMDIBuilderCreateLocalVariable(DIB(cx), ArgVariableTag as u32, context, name, filemd, loc.line as c_uint, tymd, false, 0, 0) // XXX need to pass in a real argument number @@ -670,7 +665,7 @@ pub fn create_arg(bcx: block, arg: ast::arg, span: span) -> Option { set_debug_location(cx, create_block(bcx), loc.line, loc.col.to_uint()); unsafe { let instr = llvm::LLVMDIBuilderInsertDeclareAtEnd( - dcx.builder, llptr, mdnode, bcx.llbb); + DIB(cx), llptr, mdnode, bcx.llbb); llvm::LLVMSetInstDebugLocation(trans::build::B(bcx), instr); } return Some(mdnode); @@ -681,18 +676,17 @@ pub fn create_arg(bcx: block, arg: ast::arg, span: span) -> Option { } } -fn set_debug_location(cx: @CrateContext, scope: DIScope, line: uint, col: uint) { - let dcx = dbg_cx(cx); - if dcx.curr_loc == (line, col) { +fn set_debug_location(cx: @mut CrateContext, scope: DIScope, line: uint, col: uint) { + if dbg_cx(cx).curr_loc == (line, col) { return; } debug!("setting debug location to %u %u", line, col); - dcx.curr_loc = (line, col); + dbg_cx(cx).curr_loc = (line, col); let elems = ~[C_i32(line as i32), C_i32(col as i32), scope, ptr::null()]; unsafe { let dbg_loc = llvm::LLVMMDNodeInContext( - dcx.llcontext, vec::raw::to_ptr(elems), + dbg_cx(cx).llcontext, vec::raw::to_ptr(elems), elems.len() as libc::c_uint); llvm::LLVMSetCurrentDebugLocation(cx.builder.B, dbg_loc); } @@ -709,8 +703,7 @@ pub fn update_source_pos(bcx: block, span: span) { } pub fn create_function(fcx: fn_ctxt) -> DISubprogram { - let cx = *fcx.ccx; - let dcx = dbg_cx(cx); + let cx = fcx.ccx; let fcx = &mut *fcx; let span = fcx.span.get(); @@ -729,7 +722,7 @@ pub fn create_function(fcx: fn_ctxt) -> DISubprogram { ast_map::node_expr(expr) => { match expr.node { ast::expr_fn_block(ref decl, _) => { - ((dcx.names)("fn"), decl.output, expr.id) + ((dbg_cx(cx).names)("fn"), decl.output, expr.id) } _ => fcx.ccx.sess.span_bug(expr.span, "create_function: expected an expr_fn_block here") @@ -738,7 +731,7 @@ pub fn create_function(fcx: fn_ctxt) -> DISubprogram { _ => fcx.ccx.sess.bug("create_function: unexpected sort of node") }; - match dcx.created_functions.find(&id) { + match dbg_cx(cx).created_functions.find(&id) { Some(fn_md) => return *fn_md, None => () } @@ -759,15 +752,15 @@ pub fn create_function(fcx: fn_ctxt) -> DISubprogram { }; let fn_ty = unsafe { - llvm::LLVMDIBuilderCreateSubroutineType(dcx.builder, - file_md, create_DIArray(dcx.builder, [ret_ty_md])) - }; + llvm::LLVMDIBuilderCreateSubroutineType(DIB(cx), + file_md, create_DIArray(DIB(cx), [ret_ty_md])) + }; let fn_md = do as_c_str(cx.sess.str_of(ident)) |name| { do as_c_str(cx.sess.str_of(ident)) |linkage| { unsafe { llvm::LLVMDIBuilderCreateFunction( - dcx.builder, + DIB(cx), file_md, name, linkage, file_md, loc.line as c_uint, @@ -778,6 +771,6 @@ pub fn create_function(fcx: fn_ctxt) -> DISubprogram { fcx.llfn, ptr::null(), ptr::null()) }}}; - dcx.created_functions.insert(id, fn_md); + dbg_cx(cx).created_functions.insert(id, fn_md); return fn_md; } diff --git a/src/rustllvm/RustWrapper.cpp b/src/rustllvm/RustWrapper.cpp index 6537e232f8b3b..614c1723c5fb7 100644 --- a/src/rustllvm/RustWrapper.cpp +++ b/src/rustllvm/RustWrapper.cpp @@ -565,7 +565,9 @@ extern "C" bool LLVMRustStartMultithreading() { typedef DIBuilder* DIBuilderRef; template -DIT unwrapDI(LLVMValueRef ref) { return DIT(ref ? unwrap(ref) : NULL); } +DIT unwrapDI(LLVMValueRef ref) { + return DIT(ref ? unwrap(ref) : NULL); +} extern "C" DIBuilderRef LLVMDIBuilderCreate(LLVMModuleRef M) { return new DIBuilder(*unwrap(M));