diff --git a/src/librustc_trans/trans/controlflow.rs b/src/librustc_trans/trans/controlflow.rs index 135e192a2fd49..2b73944d2b0ae 100644 --- a/src/librustc_trans/trans/controlflow.rs +++ b/src/librustc_trans/trans/controlflow.rs @@ -286,7 +286,6 @@ pub fn trans_for<'blk, 'tcx>(mut bcx: Block<'blk, 'tcx>, debug!("iterator type is {}, datum type is {}", ppaux::ty_to_string(bcx.tcx(), iterator_type), ppaux::ty_to_string(bcx.tcx(), iterator_datum.ty)); - let lliterator = load_ty(bcx, iterator_datum.val, iterator_datum.ty); // Create our basic blocks and set up our loop cleanups. @@ -366,8 +365,6 @@ pub fn trans_for<'blk, 'tcx>(mut bcx: Block<'blk, 'tcx>, llpayload, binding_cleanup_scope_id); - debuginfo::create_for_loop_var_metadata(body_bcx_in, pat); - // Codegen the body. body_bcx_out = trans_block(body_bcx_out, body, expr::Ignore); body_bcx_out = diff --git a/src/librustc_trans/trans/debuginfo.rs b/src/librustc_trans/trans/debuginfo.rs index 51e3a83f81f5a..cdb36602f1541 100644 --- a/src/librustc_trans/trans/debuginfo.rs +++ b/src/librustc_trans/trans/debuginfo.rs @@ -182,6 +182,7 @@ //! comparatively expensive to construct, though, `ty::type_id()` is still used //! additionally as an optimization for cases where the exact same type has been //! seen before (which is most of the time). +use self::FunctionDebugContextRepr::*; use self::VariableAccess::*; use self::VariableKind::*; use self::MemberOffset::*; @@ -678,8 +679,12 @@ impl<'tcx> CrateDebugContext<'tcx> { } } -pub enum FunctionDebugContext { - RegularContext(Box), +pub struct FunctionDebugContext { + repr: FunctionDebugContextRepr, +} + +enum FunctionDebugContextRepr { + DebugInfo(Box), DebugInfoDisabled, FunctionWithoutDebugInfo, } @@ -689,13 +694,13 @@ impl FunctionDebugContext { cx: &CrateContext, span: Span) -> &'a FunctionDebugContextData { - match *self { - FunctionDebugContext::RegularContext(box ref data) => data, - FunctionDebugContext::DebugInfoDisabled => { + match self.repr { + DebugInfo(box ref data) => data, + DebugInfoDisabled => { cx.sess().span_bug(span, FunctionDebugContext::debuginfo_disabled_message()); } - FunctionDebugContext::FunctionWithoutDebugInfo => { + FunctionWithoutDebugInfo => { cx.sess().span_bug(span, FunctionDebugContext::should_be_ignored_message()); } @@ -839,8 +844,6 @@ pub fn create_global_var_metadata(cx: &CrateContext, /// Creates debug information for the given local variable. /// -/// This function assumes that there's a datum for each pattern component of the -/// local in `bcx.fcx.lllocals`. /// Adds the created metadata nodes directly to the crate's IR. pub fn create_local_var_metadata(bcx: Block, local: &ast::Local) { if fn_should_be_ignored(bcx.fcx) { @@ -849,10 +852,11 @@ pub fn create_local_var_metadata(bcx: Block, local: &ast::Local) { let cx = bcx.ccx(); let def_map = &cx.tcx().def_map; - let locals = bcx.fcx.lllocals.borrow(); - pat_util::pat_bindings(def_map, &*local.pat, |_, node_id, span, var_ident| { - let datum = match locals.get(&node_id) { + pat_util::pat_bindings(def_map, &*local.pat, |_, node_id, span, path1| { + let var_ident = path1.node; + + let datum = match bcx.fcx.lllocals.borrow().get(&node_id).cloned() { Some(datum) => datum, None => { bcx.sess().span_bug(span, @@ -861,15 +865,10 @@ pub fn create_local_var_metadata(bcx: Block, local: &ast::Local) { } }; - if unsafe { llvm::LLVMIsAAllocaInst(datum.val) } == ptr::null_mut() { - cx.sess().span_bug(span, "debuginfo::create_local_var_metadata() - \ - Referenced variable location is not an alloca!"); - } - let scope_metadata = scope_metadata(bcx.fcx, node_id, span); declare_local(bcx, - var_ident.node, + var_ident, datum.ty, scope_metadata, DirectVariable { alloca: datum.val }, @@ -982,7 +981,7 @@ pub fn create_match_binding_metadata<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, // for the binding. For ByRef bindings that's a `T*` but for ByMove bindings we // actually have `T**`. So to get the actual variable we need to dereference once // more. For ByCopy we just use the stack slot we created for the binding. - let var_access = match binding.trmode { + let var_type = match binding.trmode { TrByCopy(llbinding) => DirectVariable { alloca: llbinding }, @@ -999,31 +998,27 @@ pub fn create_match_binding_metadata<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, variable_ident, binding.ty, scope_metadata, - var_access, + var_type, LocalVariable, binding.span); } /// Creates debug information for the given function argument. /// -/// This function assumes that there's a datum for each pattern component of the -/// argument in `bcx.fcx.lllocals`. /// Adds the created metadata nodes directly to the crate's IR. pub fn create_argument_metadata(bcx: Block, arg: &ast::Arg) { if fn_should_be_ignored(bcx.fcx) { return; } - let def_map = &bcx.tcx().def_map; - let scope_metadata = bcx - .fcx - .debug_context - .get_ref(bcx.ccx(), arg.pat.span) - .fn_metadata; - let locals = bcx.fcx.lllocals.borrow(); + let fcx = bcx.fcx; + let cx = fcx.ccx; - pat_util::pat_bindings(def_map, &*arg.pat, |_, node_id, span, var_ident| { - let datum = match locals.get(&node_id) { + let def_map = &cx.tcx().def_map; + let scope_metadata = bcx.fcx.debug_context.get_ref(cx, arg.pat.span).fn_metadata; + + pat_util::pat_bindings(def_map, &*arg.pat, |_, node_id, span, path1| { + let llarg = match bcx.fcx.lllocals.borrow().get(&node_id).cloned() { Some(v) => v, None => { bcx.sess().span_bug(span, @@ -1032,72 +1027,28 @@ pub fn create_argument_metadata(bcx: Block, arg: &ast::Arg) { } }; - if unsafe { llvm::LLVMIsAAllocaInst(datum.val) } == ptr::null_mut() { - bcx.sess().span_bug(span, "debuginfo::create_argument_metadata() - \ - Referenced variable location is not an alloca!"); + if unsafe { llvm::LLVMIsAAllocaInst(llarg.val) } == ptr::null_mut() { + cx.sess().span_bug(span, "debuginfo::create_argument_metadata() - \ + Referenced variable location is not an alloca!"); } let argument_index = { - let counter = &bcx - .fcx - .debug_context - .get_ref(bcx.ccx(), span) - .argument_counter; + let counter = &fcx.debug_context.get_ref(cx, span).argument_counter; let argument_index = counter.get(); counter.set(argument_index + 1); argument_index }; declare_local(bcx, - var_ident.node, - datum.ty, + path1.node, + llarg.ty, scope_metadata, - DirectVariable { alloca: datum.val }, + DirectVariable { alloca: llarg.val }, ArgumentVariable(argument_index), span); }) } -/// Creates debug information for the given for-loop variable. -/// -/// This function assumes that there's a datum for each pattern component of the -/// loop variable in `bcx.fcx.lllocals`. -/// Adds the created metadata nodes directly to the crate's IR. -pub fn create_for_loop_var_metadata(bcx: Block, pat: &ast::Pat) { - if fn_should_be_ignored(bcx.fcx) { - return; - } - - let def_map = &bcx.tcx().def_map; - let locals = bcx.fcx.lllocals.borrow(); - - pat_util::pat_bindings(def_map, pat, |_, node_id, span, var_ident| { - let datum = match locals.get(&node_id) { - Some(datum) => datum, - None => { - bcx.sess().span_bug(span, - format!("no entry in lllocals table for {}", - node_id).as_slice()); - } - }; - - if unsafe { llvm::LLVMIsAAllocaInst(datum.val) } == ptr::null_mut() { - bcx.sess().span_bug(span, "debuginfo::create_for_loop_var_metadata() - \ - Referenced variable location is not an alloca!"); - } - - let scope_metadata = scope_metadata(bcx.fcx, node_id, span); - - declare_local(bcx, - var_ident.node, - datum.ty, - scope_metadata, - DirectVariable { alloca: datum.val }, - LocalVariable, - span); - }) -} - pub fn get_cleanup_debug_loc_for_ast_node<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>, node_id: ast::NodeId, node_span: Span, @@ -1166,13 +1117,13 @@ pub fn get_cleanup_debug_loc_for_ast_node<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>, pub fn set_source_location(fcx: &FunctionContext, node_id: ast::NodeId, span: Span) { - match fcx.debug_context { - FunctionDebugContext::DebugInfoDisabled => return, - FunctionDebugContext::FunctionWithoutDebugInfo => { + match fcx.debug_context.repr { + DebugInfoDisabled => return, + FunctionWithoutDebugInfo => { set_debug_location(fcx.ccx, UnknownLocation); return; } - FunctionDebugContext::RegularContext(box ref function_debug_context) => { + DebugInfo(box ref function_debug_context) => { let cx = fcx.ccx; debug!("set_source_location: {}", cx.sess().codemap().span_to_string(span)); @@ -1209,8 +1160,8 @@ pub fn clear_source_location(fcx: &FunctionContext) { /// switches source location emitting on and must therefore be called before the /// first real statement/expression of the function is translated. pub fn start_emitting_source_locations(fcx: &FunctionContext) { - match fcx.debug_context { - FunctionDebugContext::RegularContext(box ref data) => { + match fcx.debug_context.repr { + DebugInfo(box ref data) => { data.source_locations_enabled.set(true) }, _ => { /* safe to ignore */ } @@ -1228,7 +1179,7 @@ pub fn create_function_debug_context<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>, param_substs: &Substs<'tcx>, llfn: ValueRef) -> FunctionDebugContext { if cx.sess().opts.debuginfo == NoDebugInfo { - return FunctionDebugContext::DebugInfoDisabled; + return FunctionDebugContext { repr: DebugInfoDisabled }; } // Clear the debug location so we don't assign them in the function prelude. @@ -1238,7 +1189,7 @@ pub fn create_function_debug_context<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>, if fn_ast_id == ast::DUMMY_NODE_ID { // This is a function not linked to any source location, so don't // generate debuginfo for it. - return FunctionDebugContext::FunctionWithoutDebugInfo; + return FunctionDebugContext { repr: FunctionWithoutDebugInfo }; } let empty_generics = ast_util::empty_generics(); @@ -1248,7 +1199,7 @@ pub fn create_function_debug_context<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>, let (ident, fn_decl, generics, top_level_block, span, has_path) = match fnitem { ast_map::NodeItem(ref item) => { if contains_nodebug_attribute(item.attrs.as_slice()) { - return FunctionDebugContext::FunctionWithoutDebugInfo; + return FunctionDebugContext { repr: FunctionWithoutDebugInfo }; } match item.node { @@ -1265,7 +1216,9 @@ pub fn create_function_debug_context<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>, match **item { ast::MethodImplItem(ref method) => { if contains_nodebug_attribute(method.attrs.as_slice()) { - return FunctionDebugContext::FunctionWithoutDebugInfo; + return FunctionDebugContext { + repr: FunctionWithoutDebugInfo + }; } (method.pe_ident(), @@ -1304,7 +1257,9 @@ pub fn create_function_debug_context<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>, match **trait_method { ast::ProvidedMethod(ref method) => { if contains_nodebug_attribute(method.attrs.as_slice()) { - return FunctionDebugContext::FunctionWithoutDebugInfo; + return FunctionDebugContext { + repr: FunctionWithoutDebugInfo + }; } (method.pe_ident(), @@ -1325,7 +1280,7 @@ pub fn create_function_debug_context<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>, ast_map::NodeForeignItem(..) | ast_map::NodeVariant(..) | ast_map::NodeStructCtor(..) => { - return FunctionDebugContext::FunctionWithoutDebugInfo; + return FunctionDebugContext { repr: FunctionWithoutDebugInfo }; } _ => cx.sess().bug(format!("create_function_debug_context: \ unexpected sort of node: {}", @@ -1334,7 +1289,7 @@ pub fn create_function_debug_context<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>, // This can be the case for functions inlined from another crate if span == codemap::DUMMY_SP { - return FunctionDebugContext::FunctionWithoutDebugInfo; + return FunctionDebugContext { repr: FunctionWithoutDebugInfo }; } let loc = span_start(cx, span); @@ -1401,23 +1356,22 @@ pub fn create_function_debug_context<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>, }) }); - let scope_map = create_scope_map(cx, - fn_decl.inputs.as_slice(), - &*top_level_block, - fn_metadata, - fn_ast_id); - // Initialize fn debug context (including scope map and namespace map) let fn_debug_context = box FunctionDebugContextData { - scope_map: RefCell::new(scope_map), + scope_map: RefCell::new(NodeMap::new()), fn_metadata: fn_metadata, argument_counter: Cell::new(1), source_locations_enabled: Cell::new(false), }; + populate_scope_map(cx, + fn_decl.inputs.as_slice(), + &*top_level_block, + fn_metadata, + fn_ast_id, + &mut *fn_debug_context.scope_map.borrow_mut()); - - return FunctionDebugContext::RegularContext(fn_debug_context); + return FunctionDebugContext { repr: DebugInfo(fn_debug_context) }; fn get_function_signature<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>, fn_ast_id: ast::NodeId, @@ -3180,8 +3134,8 @@ fn DIB(cx: &CrateContext) -> DIBuilderRef { } fn fn_should_be_ignored(fcx: &FunctionContext) -> bool { - match fcx.debug_context { - FunctionDebugContext::RegularContext(_) => false, + match fcx.debug_context.repr { + DebugInfo(_) => false, _ => true } } @@ -3215,14 +3169,12 @@ fn get_namespace_and_span_for_item(cx: &CrateContext, def_id: ast::DefId) // what belongs to which scope, creating DIScope DIEs along the way, and // introducing *artificial* lexical scope descriptors where necessary. These // artificial scopes allow GDB to correctly handle name shadowing. -fn create_scope_map(cx: &CrateContext, - args: &[ast::Arg], - fn_entry_block: &ast::Block, - fn_metadata: DISubprogram, - fn_ast_id: ast::NodeId) - -> NodeMap { - let mut scope_map = NodeMap::new(); - +fn populate_scope_map(cx: &CrateContext, + args: &[ast::Arg], + fn_entry_block: &ast::Block, + fn_metadata: DISubprogram, + fn_ast_id: ast::NodeId, + scope_map: &mut NodeMap) { let def_map = &cx.tcx().def_map; struct ScopeStackEntry { @@ -3248,14 +3200,11 @@ fn create_scope_map(cx: &CrateContext, with_new_scope(cx, fn_entry_block.span, &mut scope_stack, - &mut scope_map, + scope_map, |cx, scope_stack, scope_map| { walk_block(cx, fn_entry_block, scope_stack, scope_map); }); - return scope_map; - - // local helper functions for walking the AST. fn with_new_scope(cx: &CrateContext, scope_span: Span, @@ -3491,7 +3440,7 @@ fn create_scope_map(cx: &CrateContext, } ast::PatMac(_) => { - cx.sess().span_bug(pat.span, "debuginfo::create_scope_map() - \ + cx.sess().span_bug(pat.span, "debuginfo::populate_scope_map() - \ Found unexpanded macro."); } } @@ -3577,7 +3526,7 @@ fn create_scope_map(cx: &CrateContext, } ast::ExprIfLet(..) => { - cx.sess().span_bug(exp.span, "debuginfo::create_scope_map() - \ + cx.sess().span_bug(exp.span, "debuginfo::populate_scope_map() - \ Found unexpanded if-let."); } @@ -3594,7 +3543,7 @@ fn create_scope_map(cx: &CrateContext, } ast::ExprWhileLet(..) => { - cx.sess().span_bug(exp.span, "debuginfo::create_scope_map() - \ + cx.sess().span_bug(exp.span, "debuginfo::populate_scope_map() - \ Found unexpanded while-let."); } @@ -3619,7 +3568,7 @@ fn create_scope_map(cx: &CrateContext, } ast::ExprMac(_) => { - cx.sess().span_bug(exp.span, "debuginfo::create_scope_map() - \ + cx.sess().span_bug(exp.span, "debuginfo::populate_scope_map() - \ Found unexpanded macro."); } diff --git a/src/test/debuginfo/destructured-for-loop-variable.rs b/src/test/debuginfo/destructured-for-loop-variable.rs deleted file mode 100644 index 19a82ee5e67b3..0000000000000 --- a/src/test/debuginfo/destructured-for-loop-variable.rs +++ /dev/null @@ -1,178 +0,0 @@ -// Copyright 2013-2014 The Rust Project Developers. See the COPYRIGHT -// file at the top-level directory of this distribution and at -// http://rust-lang.org/COPYRIGHT. -// -// Licensed under the Apache License, Version 2.0 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -// ignore-android: FIXME(#10381) -// min-lldb-version: 310 - -// compile-flags:-g - -// === GDB TESTS =================================================================================== - -// gdb-command:run - -// DESTRUCTURED STRUCT -// gdb-command:print x -// gdb-check:$1 = 400 -// gdb-command:print y -// gdb-check:$2 = 401.5 -// gdb-command:print z -// gdb-check:$3 = true -// gdb-command:continue - -// DESTRUCTURED TUPLE -// gdb-command:print/x _i8 -// gdb-check:$4 = 0x6f -// gdb-command:print/x _u8 -// gdb-check:$5 = 0x70 -// gdb-command:print _i16 -// gdb-check:$6 = -113 -// gdb-command:print _u16 -// gdb-check:$7 = 114 -// gdb-command:print _i32 -// gdb-check:$8 = -115 -// gdb-command:print _u32 -// gdb-check:$9 = 116 -// gdb-command:print _i64 -// gdb-check:$10 = -117 -// gdb-command:print _u64 -// gdb-check:$11 = 118 -// gdb-command:print _f32 -// gdb-check:$12 = 119.5 -// gdb-command:print _f64 -// gdb-check:$13 = 120.5 -// gdb-command:continue - -// MORE COMPLEX CASE -// gdb-command:print v1 -// gdb-check:$14 = 80000 -// gdb-command:print x1 -// gdb-check:$15 = 8000 -// gdb-command:print *y1 -// gdb-check:$16 = 80001.5 -// gdb-command:print z1 -// gdb-check:$17 = false -// gdb-command:print *x2 -// gdb-check:$18 = -30000 -// gdb-command:print y2 -// gdb-check:$19 = -300001.5 -// gdb-command:print *z2 -// gdb-check:$20 = true -// gdb-command:print v2 -// gdb-check:$21 = 854237.5 -// gdb-command:continue - - -// === LLDB TESTS ================================================================================== - -// lldb-command:type format add --format hex char -// lldb-command:type format add --format hex 'unsigned char' - -// lldb-command:run - -// DESTRUCTURED STRUCT -// lldb-command:print x -// lldb-check:[...]$0 = 400 -// lldb-command:print y -// lldb-check:[...]$1 = 401.5 -// lldb-command:print z -// lldb-check:[...]$2 = true -// lldb-command:continue - -// DESTRUCTURED TUPLE -// lldb-command:print _i8 -// lldb-check:[...]$3 = 0x6f -// lldb-command:print _u8 -// lldb-check:[...]$4 = 0x70 -// lldb-command:print _i16 -// lldb-check:[...]$5 = -113 -// lldb-command:print _u16 -// lldb-check:[...]$6 = 114 -// lldb-command:print _i32 -// lldb-check:[...]$7 = -115 -// lldb-command:print _u32 -// lldb-check:[...]$8 = 116 -// lldb-command:print _i64 -// lldb-check:[...]$9 = -117 -// lldb-command:print _u64 -// lldb-check:[...]$10 = 118 -// lldb-command:print _f32 -// lldb-check:[...]$11 = 119.5 -// lldb-command:print _f64 -// lldb-check:[...]$12 = 120.5 -// lldb-command:continue - -// MORE COMPLEX CASE -// lldb-command:print v1 -// lldb-check:[...]$13 = 80000 -// lldb-command:print x1 -// lldb-check:[...]$14 = 8000 -// lldb-command:print *y1 -// lldb-check:[...]$15 = 80001.5 -// lldb-command:print z1 -// lldb-check:[...]$16 = false -// lldb-command:print *x2 -// lldb-check:[...]$17 = -30000 -// lldb-command:print y2 -// lldb-check:[...]$18 = -300001.5 -// lldb-command:print *z2 -// lldb-check:[...]$19 = true -// lldb-command:print v2 -// lldb-check:[...]$20 = 854237.5 -// lldb-command:continue - - -struct Struct { - x: i16, - y: f32, - z: bool -} - -fn main() { - - let s = Struct { - x: 400, - y: 401.5, - z: true - }; - - for &Struct { x, y, z } in [s].iter() { - zzz(); // #break - } - - let tuple: (i8, u8, i16, u16, i32, u32, i64, u64, f32, f64) = - (0x6f, 0x70, -113, 114, -115, 116, -117, 118, 119.5, 120.5); - - for &(_i8, _u8, _i16, _u16, _i32, _u32, _i64, _u64, _f32, _f64) in [tuple].iter() { - zzz(); // #break - } - - let more_complex: (i32, &Struct, Struct, Box) = - (80000, - &Struct { - x: 8000, - y: 80001.5, - z: false - }, - Struct { - x: -30000, - y: -300001.5, - z: true - }, - box 854237.5); - - for &(v1, - &Struct { x: x1, y: ref y1, z: z1 }, - Struct { x: ref x2, y: y2, z: ref z2 }, - box v2) in [more_complex].iter() { - zzz(); // #break - } -} - -fn zzz() {()} diff --git a/src/test/debuginfo/lexical-scope-in-for-loop.rs b/src/test/debuginfo/lexical-scope-in-for-loop.rs index 7636ffdb07dcd..bcaebb5c153f5 100644 --- a/src/test/debuginfo/lexical-scope-in-for-loop.rs +++ b/src/test/debuginfo/lexical-scope-in-for-loop.rs @@ -9,6 +9,7 @@ // except according to those terms. // ignore-android: FIXME(#10381) +// ignore-test: Not sure what is going on here --pcwalton // min-lldb-version: 310 // compile-flags:-g