提交 b81ea865 编写于 作者: M Michael Woerister

debuginfo: Support for variables captured in closures and closure type descriptions.

上级 67555d9b
......@@ -2084,6 +2084,25 @@ pub fn LLVMDIBuilderCreateTemplateTypeParameter(Builder: DIBuilderRef,
ColumnNo: c_uint)
-> ValueRef;
#[fast_ffi]
pub fn LLVMDIBuilderCreateOpDeref(IntType: TypeRef) -> ValueRef;
#[fast_ffi]
pub fn LLVMDIBuilderCreateOpPlus(IntType: TypeRef) -> ValueRef;
#[fast_ffi]
pub fn LLVMDIBuilderCreateComplexVariable(Builder: DIBuilderRef,
Tag: c_uint,
Scope: ValueRef,
Name: *c_char,
File: ValueRef,
LineNo: c_uint,
Ty: ValueRef,
AddrOps: *ValueRef,
AddrOpsCount: c_uint,
ArgNo: c_uint)
-> ValueRef;
pub fn LLVMInitializeX86TargetInfo();
pub fn LLVMInitializeX86Target();
pub fn LLVMInitializeX86TargetMC();
......
......@@ -143,7 +143,7 @@ struct Foo { a: int, b: ~int }
use syntax::visit::Visitor;
use syntax::codemap::Span;
#[deriving(Encodable, Decodable)]
#[deriving(Eq, Encodable, Decodable)]
pub enum CaptureMode {
CapCopy, // Copy the value into the closure.
CapMove, // Move the value into the closure.
......
......@@ -131,20 +131,6 @@ pub fn push_ctxt(s: &'static str) -> _InsnCtxt {
_InsnCtxt { _x: () }
}
fn fcx_has_nonzero_span(fcx: &FunctionContext) -> bool {
match fcx.span {
None => false,
Some(span) => *span.lo != 0 || *span.hi != 0
}
}
fn span_is_empty(opt_span: &Option<Span>) -> bool {
match *opt_span {
None => true,
Some(span) => *span.lo == 0 && *span.hi == 0
}
}
struct StatRecorder<'self> {
ccx: @mut CrateContext,
name: &'self str,
......@@ -1132,8 +1118,7 @@ pub fn trans_stmt(cx: @mut Block, s: &ast::Stmt) -> @mut Block {
match d.node {
ast::DeclLocal(ref local) => {
bcx = init_local(bcx, *local);
if cx.sess().opts.extra_debuginfo
&& fcx_has_nonzero_span(bcx.fcx) {
if cx.sess().opts.extra_debuginfo {
debuginfo::create_local_var_metadata(bcx, *local);
}
}
......@@ -1633,12 +1618,7 @@ pub fn new_fn_ctxt_w_id(ccx: @mut CrateContext,
}
};
let uses_outptr = type_of::return_uses_outptr(ccx.tcx, substd_output_type);
let debug_context = if id != -1 && ccx.sess.opts.debuginfo && !span_is_empty(&sp) {
Some(debuginfo::create_function_debug_context(ccx, id, param_substs, llfndecl))
} else {
None
};
let debug_context = debuginfo::create_function_debug_context(ccx, id, param_substs, llfndecl);
let fcx = @mut FunctionContext {
llfn: llfndecl,
......@@ -1784,7 +1764,7 @@ pub fn copy_args_to_allocas(fcx: @mut FunctionContext,
fcx.llself = Some(ValSelfData {v: self_val, ..slf});
add_clean(bcx, self_val, slf.t);
if fcx.ccx.sess.opts.extra_debuginfo && fcx_has_nonzero_span(fcx) {
if fcx.ccx.sess.opts.extra_debuginfo {
debuginfo::create_self_argument_metadata(bcx, slf.t, self_val);
}
}
......@@ -1811,7 +1791,7 @@ pub fn copy_args_to_allocas(fcx: @mut FunctionContext,
};
bcx = _match::store_arg(bcx, args[arg_n].pat, llarg);
if fcx.ccx.sess.opts.extra_debuginfo && fcx_has_nonzero_span(fcx) {
if fcx.ccx.sess.opts.extra_debuginfo {
debuginfo::create_argument_metadata(bcx, &args[arg_n]);
}
}
......
......@@ -17,6 +17,7 @@
use middle::trans::build::*;
use middle::trans::common::*;
use middle::trans::datum::{Datum, INIT};
use middle::trans::debuginfo;
use middle::trans::expr;
use middle::trans::glue;
use middle::trans::type_of::*;
......@@ -317,6 +318,11 @@ pub fn load_environment(fcx: @mut FunctionContext,
}
let def_id = ast_util::def_id_of_def(cap_var.def);
fcx.llupvars.insert(def_id.node, upvarptr);
if fcx.ccx.sess.opts.extra_debuginfo {
debuginfo::create_captured_var_metadata(bcx, def_id.node, upvarptr, cap_var.span);
}
i += 1u;
}
}
......
......@@ -228,7 +228,7 @@ pub struct FunctionContext {
ccx: @mut CrateContext,
// Used and maintained by the debuginfo module.
debug_context: Option<~debuginfo::FunctionDebugContext>
debug_context: debuginfo::FunctionDebugContext,
}
impl FunctionContext {
......
......@@ -73,7 +73,7 @@ pub enum ast_node {
node_variant(variant, @item, @path),
node_expr(@Expr),
node_stmt(@Stmt),
node_arg,
node_arg(@pat),
node_local(Ident),
node_block(Block),
node_struct_ctor(@struct_def, @item, @path),
......@@ -171,7 +171,7 @@ fn map_fn(&mut self,
sp: codemap::Span,
id: NodeId) {
for a in decl.inputs.iter() {
self.map.insert(a.id, node_arg);
self.map.insert(a.id, node_arg(a.pat));
}
visit::walk_fn(self, fk, decl, body, sp, id, ());
}
......@@ -487,8 +487,8 @@ pub fn node_id_to_str(map: map, id: NodeId, itr: @ident_interner) -> ~str {
fmt!("stmt %s (id=%?)",
pprust::stmt_to_str(stmt, itr), id)
}
Some(&node_arg) => {
fmt!("arg (id=%?)", id)
Some(&node_arg(pat)) => {
fmt!("arg %s (id=%?)", pprust::pat_to_str(pat, itr), id)
}
Some(&node_local(ident)) => {
fmt!("local (id=%?, name=%s)", id, itr.get(ident.name))
......
......@@ -724,3 +724,39 @@ extern "C" LLVMValueRef LLVMDIBuilderCreateTemplateTypeParameter(
LineNo,
ColumnNo));
}
extern "C" LLVMValueRef LLVMDIBuilderCreateOpDeref(LLVMTypeRef IntTy)
{
return LLVMConstInt(IntTy, DIBuilder::OpDeref, true);
}
extern "C" LLVMValueRef LLVMDIBuilderCreateOpPlus(LLVMTypeRef IntTy)
{
return LLVMConstInt(IntTy, DIBuilder::OpPlus, true);
}
extern "C" LLVMValueRef LLVMDIBuilderCreateComplexVariable(
DIBuilderRef Builder,
unsigned Tag,
LLVMValueRef Scope,
const char *Name,
LLVMValueRef File,
unsigned LineNo,
LLVMValueRef Ty,
LLVMValueRef* AddrOps,
unsigned AddrOpsCount,
unsigned ArgNo)
{
llvm::ArrayRef<llvm::Value*> addr_ops((llvm::Value**)AddrOps, AddrOpsCount);
return wrap(Builder->createComplexVariable(
Tag,
unwrapDI<DIDescriptor>(Scope),
Name,
unwrapDI<DIFile>(File),
LineNo,
unwrapDI<DIType>(Ty),
addr_ops,
ArgNo
));
}
// Copyright 2013 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.
// xfail-win32 Broken because of LLVM bug: http://llvm.org/bugs/show_bug.cgi?id=16249
// compile-flags:-Z extra-debug-info
// debugger:break zzz
// debugger:run
// debugger:finish
// debugger:print constant
// check:$1 = 1
// debugger:print a_struct
// check:$2 = {a = -2, b = 3.5, c = 4}
// debugger:print *owned
// check:$3 = 5
// debugger:print managed->val
// check:$4 = 6
#[allow(unused_variable)];
struct Struct {
a: int,
b: float,
c: uint
}
fn main() {
let constant = 1;
let a_struct = Struct {
a: -2,
b: 3.5,
c: 4
};
let owned = ~5;
let managed = @6;
let closure: @fn() = || {
zzz();
do_something(&constant, &a_struct.a, owned, managed);
};
closure();
}
fn do_something(_: &int, _:&int, _:&int, _:&int) {
}
fn zzz() {()}
// Copyright 2013 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.
// xfail-win32 Broken because of LLVM bug: http://llvm.org/bugs/show_bug.cgi?id=16249
// compile-flags:-Z extra-debug-info
// debugger:break zzz
// debugger:run
// debugger:finish
// debugger:print constant
// check:$1 = 1
// debugger:print a_struct
// check:$2 = {a = -2, b = 3.5, c = 4}
// debugger:print *owned
// check:$3 = 5
#[allow(unused_variable)];
struct Struct {
a: int,
b: float,
c: uint
}
fn main() {
let constant = 1;
let a_struct = Struct {
a: -2,
b: 3.5,
c: 4
};
let owned = ~5;
let closure: ~fn() = || {
zzz();
do_something(&constant, &a_struct.a, owned);
};
closure();
}
fn do_something(_: &int, _:&int, _:&int) {
}
fn zzz() {()}
// Copyright 2013 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.
// xfail-win32 Broken because of LLVM bug: http://llvm.org/bugs/show_bug.cgi?id=16249
// compile-flags:-Z extra-debug-info
// debugger:break zzz
// debugger:run
// debugger:finish
// debugger:print variable
// check:$1 = 1
// debugger:print constant
// check:$2 = 2
// debugger:print a_struct
// check:$3 = {a = -3, b = 4.5, c = 5}
// debugger:print *struct_ref
// check:$4 = {a = -3, b = 4.5, c = 5}
// debugger:print *owned
// check:$5 = 6
// debugger:print managed->val
// check:$6 = 7
#[allow(unused_variable)];
struct Struct {
a: int,
b: float,
c: uint
}
fn main() {
let mut variable = 1;
let constant = 2;
let a_struct = Struct {
a: -3,
b: 4.5,
c: 5
};
let struct_ref = &a_struct;
let owned = ~6;
let managed = @7;
let closure = || {
zzz();
variable = constant + a_struct.a + struct_ref.a + *owned + *managed;
};
closure();
}
fn zzz() {()}
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册