Skip to content

Commit 16024c5

Browse files
committed
auto merge of #8855 : michaelwoerister/rust/captured_vars, r=jdm
This pull request includes * support for variables captured in closures*, * a fix for issue #8512: arguments of non-immediate type (structs, tuples, etc) passed by value can now be accessed correctly in GDB. (I managed to fix this by using `llvm::DIBuilder::createComplexVariable()`. However, I am not sure if this relies on unstable implementation details of LLVM's debug info handling. I'll try to clarify this on the LLVM mailing list). * simplification of the `debuginfo` module's public interface: the caller of functions like `create_local_var_metadata()` doesn't have to know and catch all cases when it mustn't call the function, * a cleanup refactoring with unified handling for locals, [self] arguments, captured variables, and match bindings, * and proper span information for self arguments. \* However, see comment at https://github.com/michaelwoerister/rust/blob/1d916ace136a27e354d73d65f488603c65f65bd2/src/test/debug-info/var-captured-in-nested-closure.rs#L62 . This is the same problem as with the fix for issue #8512 above: We are probably using `llvm.dbg.declare` in an unsupported way that works today but might not work after the next LLVM update. Cheers, Michael Fixes #8512 Fixes #1341
2 parents 29449e3 + dde633e commit 16024c5

16 files changed

+820
-216
lines changed

src/librustc/lib/llvm.rs

+25
Original file line numberDiff line numberDiff line change
@@ -2083,6 +2083,31 @@ pub mod llvm {
20832083
ColumnNo: c_uint)
20842084
-> ValueRef;
20852085

2086+
#[fast_ffi]
2087+
pub fn LLVMDIBuilderCreateOpDeref(IntType: TypeRef) -> ValueRef;
2088+
2089+
#[fast_ffi]
2090+
pub fn LLVMDIBuilderCreateOpPlus(IntType: TypeRef) -> ValueRef;
2091+
2092+
#[fast_ffi]
2093+
pub fn LLVMDIBuilderCreateComplexVariable(Builder: DIBuilderRef,
2094+
Tag: c_uint,
2095+
Scope: ValueRef,
2096+
Name: *c_char,
2097+
File: ValueRef,
2098+
LineNo: c_uint,
2099+
Ty: ValueRef,
2100+
AddrOps: *ValueRef,
2101+
AddrOpsCount: c_uint,
2102+
ArgNo: c_uint)
2103+
-> ValueRef;
2104+
2105+
#[fast_ffi]
2106+
pub fn LLVMIsAArgument(value_ref: ValueRef) -> ValueRef;
2107+
2108+
#[fast_ffi]
2109+
pub fn LLVMIsAAllocaInst(value_ref: ValueRef) -> ValueRef;
2110+
20862111
pub fn LLVMInitializeX86TargetInfo();
20872112
pub fn LLVMInitializeX86Target();
20882113
pub fn LLVMInitializeX86TargetMC();

src/librustc/middle/moves.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -143,7 +143,7 @@ use syntax::visit;
143143
use syntax::visit::Visitor;
144144
use syntax::codemap::span;
145145

146-
#[deriving(Encodable, Decodable)]
146+
#[deriving(Eq, Encodable, Decodable)]
147147
pub enum CaptureMode {
148148
CapCopy, // Copy the value into the closure.
149149
CapMove, // Move the value into the closure.

src/librustc/middle/trans/base.rs

+4-24
Original file line numberDiff line numberDiff line change
@@ -131,20 +131,6 @@ pub fn push_ctxt(s: &'static str) -> _InsnCtxt {
131131
_InsnCtxt { _x: () }
132132
}
133133

134-
fn fcx_has_nonzero_span(fcx: &FunctionContext) -> bool {
135-
match fcx.span {
136-
None => false,
137-
Some(span) => *span.lo != 0 || *span.hi != 0
138-
}
139-
}
140-
141-
fn span_is_empty(opt_span: &Option<span>) -> bool {
142-
match *opt_span {
143-
None => true,
144-
Some(span) => *span.lo == 0 && *span.hi == 0
145-
}
146-
}
147-
148134
struct StatRecorder<'self> {
149135
ccx: @mut CrateContext,
150136
name: &'self str,
@@ -1131,8 +1117,7 @@ pub fn trans_stmt(cx: @mut Block, s: &ast::stmt) -> @mut Block {
11311117
match d.node {
11321118
ast::decl_local(ref local) => {
11331119
bcx = init_local(bcx, *local);
1134-
if cx.sess().opts.extra_debuginfo
1135-
&& fcx_has_nonzero_span(bcx.fcx) {
1120+
if cx.sess().opts.extra_debuginfo {
11361121
debuginfo::create_local_var_metadata(bcx, *local);
11371122
}
11381123
}
@@ -1632,12 +1617,7 @@ pub fn new_fn_ctxt_w_id(ccx: @mut CrateContext,
16321617
}
16331618
};
16341619
let uses_outptr = type_of::return_uses_outptr(ccx.tcx, substd_output_type);
1635-
1636-
let debug_context = if id != -1 && ccx.sess.opts.debuginfo && !span_is_empty(&sp) {
1637-
Some(debuginfo::create_function_debug_context(ccx, id, param_substs, llfndecl))
1638-
} else {
1639-
None
1640-
};
1620+
let debug_context = debuginfo::create_function_debug_context(ccx, id, param_substs, llfndecl);
16411621

16421622
let fcx = @mut FunctionContext {
16431623
llfn: llfndecl,
@@ -1783,7 +1763,7 @@ pub fn copy_args_to_allocas(fcx: @mut FunctionContext,
17831763
fcx.llself = Some(ValSelfData {v: self_val, ..slf});
17841764
add_clean(bcx, self_val, slf.t);
17851765

1786-
if fcx.ccx.sess.opts.extra_debuginfo && fcx_has_nonzero_span(fcx) {
1766+
if fcx.ccx.sess.opts.extra_debuginfo {
17871767
debuginfo::create_self_argument_metadata(bcx, slf.t, self_val);
17881768
}
17891769
}
@@ -1810,7 +1790,7 @@ pub fn copy_args_to_allocas(fcx: @mut FunctionContext,
18101790
};
18111791
bcx = _match::store_arg(bcx, args[arg_n].pat, llarg);
18121792

1813-
if fcx.ccx.sess.opts.extra_debuginfo && fcx_has_nonzero_span(fcx) {
1793+
if fcx.ccx.sess.opts.extra_debuginfo {
18141794
debuginfo::create_argument_metadata(bcx, &args[arg_n]);
18151795
}
18161796
}

src/librustc/middle/trans/closure.rs

+6
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ use middle::trans::base::*;
1717
use middle::trans::build::*;
1818
use middle::trans::common::*;
1919
use middle::trans::datum::{Datum, INIT};
20+
use middle::trans::debuginfo;
2021
use middle::trans::expr;
2122
use middle::trans::glue;
2223
use middle::trans::type_of::*;
@@ -317,6 +318,11 @@ pub fn load_environment(fcx: @mut FunctionContext,
317318
}
318319
let def_id = ast_util::def_id_of_def(cap_var.def);
319320
fcx.llupvars.insert(def_id.node, upvarptr);
321+
322+
if fcx.ccx.sess.opts.extra_debuginfo {
323+
debuginfo::create_captured_var_metadata(bcx, def_id.node, upvarptr, cap_var.span);
324+
}
325+
320326
i += 1u;
321327
}
322328
}

src/librustc/middle/trans/common.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -227,7 +227,7 @@ pub struct FunctionContext {
227227
ccx: @mut CrateContext,
228228

229229
// Used and maintained by the debuginfo module.
230-
debug_context: Option<~debuginfo::FunctionDebugContext>
230+
debug_context: debuginfo::FunctionDebugContext,
231231
}
232232

233233
impl FunctionContext {

src/librustc/middle/trans/context.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -111,7 +111,7 @@ pub struct CrateContext {
111111
// decl_gc_metadata knows whether to link to the module metadata, which
112112
// is not emitted by LLVM's GC pass when no functions use GC.
113113
uses_gc: bool,
114-
dbg_cx: Option<debuginfo::DebugContext>,
114+
dbg_cx: Option<debuginfo::CrateDebugContext>,
115115
do_not_commit_warning_issued: bool
116116
}
117117

@@ -161,7 +161,7 @@ impl CrateContext {
161161

162162
let crate_map = decl_crate_map(sess, link_meta, llmod);
163163
let dbg_cx = if sess.opts.debuginfo {
164-
Some(debuginfo::DebugContext::new(llmod, name.to_owned()))
164+
Some(debuginfo::CrateDebugContext::new(llmod, name.to_owned()))
165165
} else {
166166
None
167167
};

0 commit comments

Comments
 (0)