提交 f673e984 编写于 作者: B bors

auto merge of #20167 : michaelwoerister/rust/for-loop-var, r=alexcrichton

... really this time `:)`

I went for the simpler fix after all since it turned out to become a bit too complicated to extract the current iteration value from its containing `Option` with the different memory layouts it can have. It's also what we already do for match bindings.

I also extended the new test case to include the "simple identifier" case.

Fixes #20127, fixes #19732
...@@ -1554,7 +1554,8 @@ pub fn store_for_loop_binding<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, ...@@ -1554,7 +1554,8 @@ pub fn store_for_loop_binding<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
-> Block<'blk, 'tcx> { -> Block<'blk, 'tcx> {
let _icx = push_ctxt("match::store_for_loop_binding"); let _icx = push_ctxt("match::store_for_loop_binding");
if simple_identifier(&*pat).is_some() { if simple_identifier(&*pat).is_some() &&
bcx.sess().opts.debuginfo != FullDebugInfo {
// Generate nicer LLVM for the common case of a `for` loop pattern // Generate nicer LLVM for the common case of a `for` loop pattern
// like `for x in blahblah { ... }`. // like `for x in blahblah { ... }`.
let binding_type = node_id_type(bcx, pat.id); let binding_type = node_id_type(bcx, pat.id);
......
...@@ -286,6 +286,7 @@ pub fn trans_for<'blk, 'tcx>(mut bcx: Block<'blk, 'tcx>, ...@@ -286,6 +286,7 @@ pub fn trans_for<'blk, 'tcx>(mut bcx: Block<'blk, 'tcx>,
debug!("iterator type is {}, datum type is {}", debug!("iterator type is {}, datum type is {}",
ppaux::ty_to_string(bcx.tcx(), iterator_type), ppaux::ty_to_string(bcx.tcx(), iterator_type),
ppaux::ty_to_string(bcx.tcx(), iterator_datum.ty)); ppaux::ty_to_string(bcx.tcx(), iterator_datum.ty));
let lliterator = load_ty(bcx, iterator_datum.val, iterator_datum.ty); let lliterator = load_ty(bcx, iterator_datum.val, iterator_datum.ty);
// Create our basic blocks and set up our loop cleanups. // Create our basic blocks and set up our loop cleanups.
...@@ -365,6 +366,8 @@ pub fn trans_for<'blk, 'tcx>(mut bcx: Block<'blk, 'tcx>, ...@@ -365,6 +366,8 @@ pub fn trans_for<'blk, 'tcx>(mut bcx: Block<'blk, 'tcx>,
llpayload, llpayload,
binding_cleanup_scope_id); binding_cleanup_scope_id);
debuginfo::create_for_loop_var_metadata(body_bcx_in, pat);
// Codegen the body. // Codegen the body.
body_bcx_out = trans_block(body_bcx_out, body, expr::Ignore); body_bcx_out = trans_block(body_bcx_out, body, expr::Ignore);
body_bcx_out = body_bcx_out =
......
...@@ -182,7 +182,6 @@ ...@@ -182,7 +182,6 @@
//! comparatively expensive to construct, though, `ty::type_id()` is still used //! comparatively expensive to construct, though, `ty::type_id()` is still used
//! additionally as an optimization for cases where the exact same type has been //! additionally as an optimization for cases where the exact same type has been
//! seen before (which is most of the time). //! seen before (which is most of the time).
use self::FunctionDebugContextRepr::*;
use self::VariableAccess::*; use self::VariableAccess::*;
use self::VariableKind::*; use self::VariableKind::*;
use self::MemberOffset::*; use self::MemberOffset::*;
...@@ -679,12 +678,8 @@ pub fn new(llmod: ModuleRef) -> CrateDebugContext<'tcx> { ...@@ -679,12 +678,8 @@ pub fn new(llmod: ModuleRef) -> CrateDebugContext<'tcx> {
} }
} }
pub struct FunctionDebugContext { pub enum FunctionDebugContext {
repr: FunctionDebugContextRepr, RegularContext(Box<FunctionDebugContextData>),
}
enum FunctionDebugContextRepr {
DebugInfo(Box<FunctionDebugContextData>),
DebugInfoDisabled, DebugInfoDisabled,
FunctionWithoutDebugInfo, FunctionWithoutDebugInfo,
} }
...@@ -694,13 +689,13 @@ fn get_ref<'a>(&'a self, ...@@ -694,13 +689,13 @@ fn get_ref<'a>(&'a self,
cx: &CrateContext, cx: &CrateContext,
span: Span) span: Span)
-> &'a FunctionDebugContextData { -> &'a FunctionDebugContextData {
match self.repr { match *self {
DebugInfo(box ref data) => data, FunctionDebugContext::RegularContext(box ref data) => data,
DebugInfoDisabled => { FunctionDebugContext::DebugInfoDisabled => {
cx.sess().span_bug(span, cx.sess().span_bug(span,
FunctionDebugContext::debuginfo_disabled_message()); FunctionDebugContext::debuginfo_disabled_message());
} }
FunctionWithoutDebugInfo => { FunctionDebugContext::FunctionWithoutDebugInfo => {
cx.sess().span_bug(span, cx.sess().span_bug(span,
FunctionDebugContext::should_be_ignored_message()); FunctionDebugContext::should_be_ignored_message());
} }
...@@ -844,6 +839,8 @@ pub fn create_global_var_metadata(cx: &CrateContext, ...@@ -844,6 +839,8 @@ pub fn create_global_var_metadata(cx: &CrateContext,
/// Creates debug information for the given local variable. /// 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. /// Adds the created metadata nodes directly to the crate's IR.
pub fn create_local_var_metadata(bcx: Block, local: &ast::Local) { pub fn create_local_var_metadata(bcx: Block, local: &ast::Local) {
if fn_should_be_ignored(bcx.fcx) { if fn_should_be_ignored(bcx.fcx) {
...@@ -852,11 +849,10 @@ pub fn create_local_var_metadata(bcx: Block, local: &ast::Local) { ...@@ -852,11 +849,10 @@ pub fn create_local_var_metadata(bcx: Block, local: &ast::Local) {
let cx = bcx.ccx(); let cx = bcx.ccx();
let def_map = &cx.tcx().def_map; let def_map = &cx.tcx().def_map;
let locals = bcx.fcx.lllocals.borrow();
pat_util::pat_bindings(def_map, &*local.pat, |_, node_id, span, path1| { pat_util::pat_bindings(def_map, &*local.pat, |_, node_id, span, var_ident| {
let var_ident = path1.node; let datum = match locals.get(&node_id) {
let datum = match bcx.fcx.lllocals.borrow().get(&node_id).cloned() {
Some(datum) => datum, Some(datum) => datum,
None => { None => {
bcx.sess().span_bug(span, bcx.sess().span_bug(span,
...@@ -865,10 +861,15 @@ pub fn create_local_var_metadata(bcx: Block, local: &ast::Local) { ...@@ -865,10 +861,15 @@ 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); let scope_metadata = scope_metadata(bcx.fcx, node_id, span);
declare_local(bcx, declare_local(bcx,
var_ident, var_ident.node,
datum.ty, datum.ty,
scope_metadata, scope_metadata,
DirectVariable { alloca: datum.val }, DirectVariable { alloca: datum.val },
...@@ -981,7 +982,7 @@ pub fn create_match_binding_metadata<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, ...@@ -981,7 +982,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 // 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 // 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. // more. For ByCopy we just use the stack slot we created for the binding.
let var_type = match binding.trmode { let var_access = match binding.trmode {
TrByCopy(llbinding) => DirectVariable { TrByCopy(llbinding) => DirectVariable {
alloca: llbinding alloca: llbinding
}, },
...@@ -998,27 +999,31 @@ pub fn create_match_binding_metadata<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, ...@@ -998,27 +999,31 @@ pub fn create_match_binding_metadata<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
variable_ident, variable_ident,
binding.ty, binding.ty,
scope_metadata, scope_metadata,
var_type, var_access,
LocalVariable, LocalVariable,
binding.span); binding.span);
} }
/// Creates debug information for the given function argument. /// 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. /// Adds the created metadata nodes directly to the crate's IR.
pub fn create_argument_metadata(bcx: Block, arg: &ast::Arg) { pub fn create_argument_metadata(bcx: Block, arg: &ast::Arg) {
if fn_should_be_ignored(bcx.fcx) { if fn_should_be_ignored(bcx.fcx) {
return; return;
} }
let fcx = bcx.fcx; let def_map = &bcx.tcx().def_map;
let cx = fcx.ccx; let scope_metadata = bcx
.fcx
let def_map = &cx.tcx().def_map; .debug_context
let scope_metadata = bcx.fcx.debug_context.get_ref(cx, arg.pat.span).fn_metadata; .get_ref(bcx.ccx(), arg.pat.span)
.fn_metadata;
let locals = bcx.fcx.lllocals.borrow();
pat_util::pat_bindings(def_map, &*arg.pat, |_, node_id, span, path1| { pat_util::pat_bindings(def_map, &*arg.pat, |_, node_id, span, var_ident| {
let llarg = match bcx.fcx.lllocals.borrow().get(&node_id).cloned() { let datum = match locals.get(&node_id) {
Some(v) => v, Some(v) => v,
None => { None => {
bcx.sess().span_bug(span, bcx.sess().span_bug(span,
...@@ -1027,28 +1032,72 @@ pub fn create_argument_metadata(bcx: Block, arg: &ast::Arg) { ...@@ -1027,28 +1032,72 @@ pub fn create_argument_metadata(bcx: Block, arg: &ast::Arg) {
} }
}; };
if unsafe { llvm::LLVMIsAAllocaInst(llarg.val) } == ptr::null_mut() { if unsafe { llvm::LLVMIsAAllocaInst(datum.val) } == ptr::null_mut() {
cx.sess().span_bug(span, "debuginfo::create_argument_metadata() - \ bcx.sess().span_bug(span, "debuginfo::create_argument_metadata() - \
Referenced variable location is not an alloca!"); Referenced variable location is not an alloca!");
} }
let argument_index = { let argument_index = {
let counter = &fcx.debug_context.get_ref(cx, span).argument_counter; let counter = &bcx
.fcx
.debug_context
.get_ref(bcx.ccx(), span)
.argument_counter;
let argument_index = counter.get(); let argument_index = counter.get();
counter.set(argument_index + 1); counter.set(argument_index + 1);
argument_index argument_index
}; };
declare_local(bcx, declare_local(bcx,
path1.node, var_ident.node,
llarg.ty, datum.ty,
scope_metadata, scope_metadata,
DirectVariable { alloca: llarg.val }, DirectVariable { alloca: datum.val },
ArgumentVariable(argument_index), ArgumentVariable(argument_index),
span); 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>, pub fn get_cleanup_debug_loc_for_ast_node<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
node_id: ast::NodeId, node_id: ast::NodeId,
node_span: Span, node_span: Span,
...@@ -1117,13 +1166,13 @@ pub fn get_cleanup_debug_loc_for_ast_node<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>, ...@@ -1117,13 +1166,13 @@ pub fn get_cleanup_debug_loc_for_ast_node<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
pub fn set_source_location(fcx: &FunctionContext, pub fn set_source_location(fcx: &FunctionContext,
node_id: ast::NodeId, node_id: ast::NodeId,
span: Span) { span: Span) {
match fcx.debug_context.repr { match fcx.debug_context {
DebugInfoDisabled => return, FunctionDebugContext::DebugInfoDisabled => return,
FunctionWithoutDebugInfo => { FunctionDebugContext::FunctionWithoutDebugInfo => {
set_debug_location(fcx.ccx, UnknownLocation); set_debug_location(fcx.ccx, UnknownLocation);
return; return;
} }
DebugInfo(box ref function_debug_context) => { FunctionDebugContext::RegularContext(box ref function_debug_context) => {
let cx = fcx.ccx; let cx = fcx.ccx;
debug!("set_source_location: {}", cx.sess().codemap().span_to_string(span)); debug!("set_source_location: {}", cx.sess().codemap().span_to_string(span));
...@@ -1160,8 +1209,8 @@ pub fn clear_source_location(fcx: &FunctionContext) { ...@@ -1160,8 +1209,8 @@ pub fn clear_source_location(fcx: &FunctionContext) {
/// switches source location emitting on and must therefore be called before the /// switches source location emitting on and must therefore be called before the
/// first real statement/expression of the function is translated. /// first real statement/expression of the function is translated.
pub fn start_emitting_source_locations(fcx: &FunctionContext) { pub fn start_emitting_source_locations(fcx: &FunctionContext) {
match fcx.debug_context.repr { match fcx.debug_context {
DebugInfo(box ref data) => { FunctionDebugContext::RegularContext(box ref data) => {
data.source_locations_enabled.set(true) data.source_locations_enabled.set(true)
}, },
_ => { /* safe to ignore */ } _ => { /* safe to ignore */ }
...@@ -1179,7 +1228,7 @@ pub fn create_function_debug_context<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>, ...@@ -1179,7 +1228,7 @@ pub fn create_function_debug_context<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
param_substs: &Substs<'tcx>, param_substs: &Substs<'tcx>,
llfn: ValueRef) -> FunctionDebugContext { llfn: ValueRef) -> FunctionDebugContext {
if cx.sess().opts.debuginfo == NoDebugInfo { if cx.sess().opts.debuginfo == NoDebugInfo {
return FunctionDebugContext { repr: DebugInfoDisabled }; return FunctionDebugContext::DebugInfoDisabled;
} }
// Clear the debug location so we don't assign them in the function prelude. // Clear the debug location so we don't assign them in the function prelude.
...@@ -1189,7 +1238,7 @@ pub fn create_function_debug_context<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>, ...@@ -1189,7 +1238,7 @@ pub fn create_function_debug_context<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
if fn_ast_id == ast::DUMMY_NODE_ID { if fn_ast_id == ast::DUMMY_NODE_ID {
// This is a function not linked to any source location, so don't // This is a function not linked to any source location, so don't
// generate debuginfo for it. // generate debuginfo for it.
return FunctionDebugContext { repr: FunctionWithoutDebugInfo }; return FunctionDebugContext::FunctionWithoutDebugInfo;
} }
let empty_generics = ast_util::empty_generics(); let empty_generics = ast_util::empty_generics();
...@@ -1199,7 +1248,7 @@ pub fn create_function_debug_context<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>, ...@@ -1199,7 +1248,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 { let (ident, fn_decl, generics, top_level_block, span, has_path) = match fnitem {
ast_map::NodeItem(ref item) => { ast_map::NodeItem(ref item) => {
if contains_nodebug_attribute(item.attrs.as_slice()) { if contains_nodebug_attribute(item.attrs.as_slice()) {
return FunctionDebugContext { repr: FunctionWithoutDebugInfo }; return FunctionDebugContext::FunctionWithoutDebugInfo;
} }
match item.node { match item.node {
...@@ -1216,9 +1265,7 @@ pub fn create_function_debug_context<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>, ...@@ -1216,9 +1265,7 @@ pub fn create_function_debug_context<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
match **item { match **item {
ast::MethodImplItem(ref method) => { ast::MethodImplItem(ref method) => {
if contains_nodebug_attribute(method.attrs.as_slice()) { if contains_nodebug_attribute(method.attrs.as_slice()) {
return FunctionDebugContext { return FunctionDebugContext::FunctionWithoutDebugInfo;
repr: FunctionWithoutDebugInfo
};
} }
(method.pe_ident(), (method.pe_ident(),
...@@ -1257,9 +1304,7 @@ pub fn create_function_debug_context<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>, ...@@ -1257,9 +1304,7 @@ pub fn create_function_debug_context<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
match **trait_method { match **trait_method {
ast::ProvidedMethod(ref method) => { ast::ProvidedMethod(ref method) => {
if contains_nodebug_attribute(method.attrs.as_slice()) { if contains_nodebug_attribute(method.attrs.as_slice()) {
return FunctionDebugContext { return FunctionDebugContext::FunctionWithoutDebugInfo;
repr: FunctionWithoutDebugInfo
};
} }
(method.pe_ident(), (method.pe_ident(),
...@@ -1280,7 +1325,7 @@ pub fn create_function_debug_context<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>, ...@@ -1280,7 +1325,7 @@ pub fn create_function_debug_context<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
ast_map::NodeForeignItem(..) | ast_map::NodeForeignItem(..) |
ast_map::NodeVariant(..) | ast_map::NodeVariant(..) |
ast_map::NodeStructCtor(..) => { ast_map::NodeStructCtor(..) => {
return FunctionDebugContext { repr: FunctionWithoutDebugInfo }; return FunctionDebugContext::FunctionWithoutDebugInfo;
} }
_ => cx.sess().bug(format!("create_function_debug_context: \ _ => cx.sess().bug(format!("create_function_debug_context: \
unexpected sort of node: {}", unexpected sort of node: {}",
...@@ -1289,7 +1334,7 @@ pub fn create_function_debug_context<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>, ...@@ -1289,7 +1334,7 @@ pub fn create_function_debug_context<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
// This can be the case for functions inlined from another crate // This can be the case for functions inlined from another crate
if span == codemap::DUMMY_SP { if span == codemap::DUMMY_SP {
return FunctionDebugContext { repr: FunctionWithoutDebugInfo }; return FunctionDebugContext::FunctionWithoutDebugInfo;
} }
let loc = span_start(cx, span); let loc = span_start(cx, span);
...@@ -1356,22 +1401,23 @@ pub fn create_function_debug_context<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>, ...@@ -1356,22 +1401,23 @@ 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) // Initialize fn debug context (including scope map and namespace map)
let fn_debug_context = box FunctionDebugContextData { let fn_debug_context = box FunctionDebugContextData {
scope_map: RefCell::new(NodeMap::new()), scope_map: RefCell::new(scope_map),
fn_metadata: fn_metadata, fn_metadata: fn_metadata,
argument_counter: Cell::new(1), argument_counter: Cell::new(1),
source_locations_enabled: Cell::new(false), 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 { repr: DebugInfo(fn_debug_context) };
return FunctionDebugContext::RegularContext(fn_debug_context);
fn get_function_signature<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>, fn get_function_signature<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
fn_ast_id: ast::NodeId, fn_ast_id: ast::NodeId,
...@@ -3134,8 +3180,8 @@ fn DIB(cx: &CrateContext) -> DIBuilderRef { ...@@ -3134,8 +3180,8 @@ fn DIB(cx: &CrateContext) -> DIBuilderRef {
} }
fn fn_should_be_ignored(fcx: &FunctionContext) -> bool { fn fn_should_be_ignored(fcx: &FunctionContext) -> bool {
match fcx.debug_context.repr { match fcx.debug_context {
DebugInfo(_) => false, FunctionDebugContext::RegularContext(_) => false,
_ => true _ => true
} }
} }
...@@ -3169,12 +3215,14 @@ fn get_namespace_and_span_for_item(cx: &CrateContext, def_id: ast::DefId) ...@@ -3169,12 +3215,14 @@ 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 // what belongs to which scope, creating DIScope DIEs along the way, and
// introducing *artificial* lexical scope descriptors where necessary. These // introducing *artificial* lexical scope descriptors where necessary. These
// artificial scopes allow GDB to correctly handle name shadowing. // artificial scopes allow GDB to correctly handle name shadowing.
fn populate_scope_map(cx: &CrateContext, fn create_scope_map(cx: &CrateContext,
args: &[ast::Arg], args: &[ast::Arg],
fn_entry_block: &ast::Block, fn_entry_block: &ast::Block,
fn_metadata: DISubprogram, fn_metadata: DISubprogram,
fn_ast_id: ast::NodeId, fn_ast_id: ast::NodeId)
scope_map: &mut NodeMap<DIScope>) { -> NodeMap<DIScope> {
let mut scope_map = NodeMap::new();
let def_map = &cx.tcx().def_map; let def_map = &cx.tcx().def_map;
struct ScopeStackEntry { struct ScopeStackEntry {
...@@ -3200,11 +3248,14 @@ struct ScopeStackEntry { ...@@ -3200,11 +3248,14 @@ struct ScopeStackEntry {
with_new_scope(cx, with_new_scope(cx,
fn_entry_block.span, fn_entry_block.span,
&mut scope_stack, &mut scope_stack,
scope_map, &mut scope_map,
|cx, scope_stack, scope_map| { |cx, scope_stack, scope_map| {
walk_block(cx, fn_entry_block, scope_stack, scope_map); walk_block(cx, fn_entry_block, scope_stack, scope_map);
}); });
return scope_map;
// local helper functions for walking the AST. // local helper functions for walking the AST.
fn with_new_scope<F>(cx: &CrateContext, fn with_new_scope<F>(cx: &CrateContext,
scope_span: Span, scope_span: Span,
...@@ -3440,7 +3491,7 @@ fn walk_pattern(cx: &CrateContext, ...@@ -3440,7 +3491,7 @@ fn walk_pattern(cx: &CrateContext,
} }
ast::PatMac(_) => { ast::PatMac(_) => {
cx.sess().span_bug(pat.span, "debuginfo::populate_scope_map() - \ cx.sess().span_bug(pat.span, "debuginfo::create_scope_map() - \
Found unexpanded macro."); Found unexpanded macro.");
} }
} }
...@@ -3531,7 +3582,7 @@ fn walk_expr(cx: &CrateContext, ...@@ -3531,7 +3582,7 @@ fn walk_expr(cx: &CrateContext,
} }
ast::ExprIfLet(..) => { ast::ExprIfLet(..) => {
cx.sess().span_bug(exp.span, "debuginfo::populate_scope_map() - \ cx.sess().span_bug(exp.span, "debuginfo::create_scope_map() - \
Found unexpanded if-let."); Found unexpanded if-let.");
} }
...@@ -3548,7 +3599,7 @@ fn walk_expr(cx: &CrateContext, ...@@ -3548,7 +3599,7 @@ fn walk_expr(cx: &CrateContext,
} }
ast::ExprWhileLet(..) => { ast::ExprWhileLet(..) => {
cx.sess().span_bug(exp.span, "debuginfo::populate_scope_map() - \ cx.sess().span_bug(exp.span, "debuginfo::create_scope_map() - \
Found unexpanded while-let."); Found unexpanded while-let.");
} }
...@@ -3573,7 +3624,7 @@ fn walk_expr(cx: &CrateContext, ...@@ -3573,7 +3624,7 @@ fn walk_expr(cx: &CrateContext,
} }
ast::ExprMac(_) => { ast::ExprMac(_) => {
cx.sess().span_bug(exp.span, "debuginfo::populate_scope_map() - \ cx.sess().span_bug(exp.span, "debuginfo::create_scope_map() - \
Found unexpanded macro."); Found unexpanded macro.");
} }
......
// 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 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, 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
// SIMPLE IDENTIFIER
// gdb-command:print i
// gdb-check:$22 = 1234
// gdb-command:continue
// gdb-command:print simple_struct_ident
// gdb-check:$23 = {x = 3537, y = 35437.5, z = true}
// gdb-command:continue
// gdb-command:print simple_tuple_ident
// gdb-check:$24 = {34903493, 232323}
// 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
// SIMPLE IDENTIFIER
// lldb-command:print i
// lldb-check:[...]$21 = 1234
// lldb-command:continue
// lldb-command:print simple_struct_ident
// lldb-check:[...]$22 = Struct { x: 3537, y: 35437.5, z: true }
// lldb-command:continue
// lldb-command:print simple_tuple_ident
// lldb-check:[...]$23 = (34903493, 232323)
// 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<f64>) =
(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
}
for i in range(1234, 1235i) {
zzz(); // #break
}
for simple_struct_ident in
vec![Struct {
x: 3537,
y: 35437.5,
z: true
}].into_iter() {
zzz(); // #break
}
for simple_tuple_ident in vec![(34903493u32, 232323i64)].into_iter() {
zzz(); // #break
}
}
fn zzz() {()}
...@@ -9,7 +9,6 @@ ...@@ -9,7 +9,6 @@
// except according to those terms. // except according to those terms.
// ignore-android: FIXME(#10381) // ignore-android: FIXME(#10381)
// ignore-test: Not sure what is going on here --pcwalton
// min-lldb-version: 310 // min-lldb-version: 310
// compile-flags:-g // compile-flags:-g
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册