Skip to content

Commit 689929c

Browse files
debuginfo: Added support for self parameter in methods.
1 parent 44557e7 commit 689929c

File tree

2 files changed

+70
-12
lines changed

2 files changed

+70
-12
lines changed

src/librustc/middle/trans/base.rs

+5-1
Original file line numberDiff line numberDiff line change
@@ -133,7 +133,7 @@ pub fn push_ctxt(s: &'static str) -> _InsnCtxt {
133133

134134
fn fcx_has_nonzero_span(fcx: &FunctionContext) -> bool {
135135
match fcx.span {
136-
None => true,
136+
None => false,
137137
Some(span) => *span.lo != 0 || *span.hi != 0
138138
}
139139
}
@@ -1739,6 +1739,10 @@ pub fn copy_args_to_allocas(fcx: @mut FunctionContext,
17391739

17401740
fcx.llself = Some(ValSelfData {v: self_val, ..slf});
17411741
add_clean(bcx, self_val, slf.t);
1742+
1743+
if fcx.ccx.sess.opts.extra_debuginfo && fcx_has_nonzero_span(fcx) {
1744+
debuginfo::create_self_argument_metadata(bcx, slf.t, self_val);
1745+
}
17421746
}
17431747
_ => {}
17441748
}

src/librustc/middle/trans/debuginfo.rs

+65-11
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,7 @@ use std::ptr;
7070
use std::vec;
7171
use syntax::codemap::span;
7272
use syntax::{ast, codemap, ast_util, ast_map};
73+
use syntax::parse::token::keywords;
7374

7475
static DW_LANG_RUST: int = 0x9000;
7576

@@ -140,15 +141,6 @@ pub struct FunctionDebugContext {
140141
priv argument_counter: uint,
141142
}
142143

143-
impl FunctionDebugContext {
144-
fn new() -> FunctionDebugContext {
145-
return FunctionDebugContext {
146-
scope_map: HashMap::new(),
147-
argument_counter: 1,
148-
};
149-
}
150-
}
151-
152144
/// Create any deferred debug metadata nodes
153145
pub fn finalize(cx: @mut CrateContext) {
154146
debug!("finalize");
@@ -175,6 +167,9 @@ pub fn create_local_var_metadata(bcx: @mut Block, local: &ast::Local) {
175167
}
176168
}
177169

170+
/// Creates debug information for a local variable introduced in the head of a match-statement arm.
171+
///
172+
/// Adds the created metadata nodes directly to the crate's IR.
178173
pub fn create_match_binding_metadata(bcx: @mut Block,
179174
variable_ident: ast::ident,
180175
node_id: ast::NodeId,
@@ -183,11 +178,59 @@ pub fn create_match_binding_metadata(bcx: @mut Block,
183178
declare_local(bcx, variable_ident, node_id, variable_type, span);
184179
}
185180

181+
/// Creates debug information for the self argument of a method.
182+
///
183+
/// Adds the created metadata nodes directly to the crate's IR.
184+
pub fn create_self_argument_metadata(bcx: @mut Block,
185+
variable_type: ty::t,
186+
llptr: ValueRef) {
187+
assert_fcx_has_span(bcx.fcx);
188+
let span = bcx.fcx.span.unwrap();
189+
190+
let cx = bcx.ccx();
191+
192+
let filename = span_start(cx, span).file.name;
193+
let file_metadata = file_metadata(cx, filename);
194+
195+
let loc = span_start(cx, span);
196+
let type_metadata = type_metadata(cx, variable_type, span);
197+
let scope = create_function_metadata(bcx.fcx);
198+
let self_ident = keywords::Self.to_ident();
199+
200+
let var_metadata = do cx.sess.str_of(self_ident).to_c_str().with_ref |name| {
201+
unsafe {
202+
llvm::LLVMDIBuilderCreateLocalVariable(
203+
DIB(cx),
204+
DW_TAG_arg_variable,
205+
scope,
206+
name,
207+
file_metadata,
208+
loc.line as c_uint,
209+
type_metadata,
210+
false,
211+
0,
212+
1)
213+
}
214+
};
215+
216+
set_debug_location(cx, scope, loc.line, loc.col.to_uint());
217+
unsafe {
218+
let instr = llvm::LLVMDIBuilderInsertDeclareAtEnd(
219+
DIB(cx),
220+
llptr,
221+
var_metadata,
222+
bcx.llbb);
223+
224+
llvm::LLVMSetInstDebugLocation(trans::build::B(bcx).llbuilder, instr);
225+
}
226+
}
227+
186228
/// Creates debug information for the given function argument.
187229
///
188230
/// Adds the created metadata nodes directly to the crate's IR.
189231
pub fn create_argument_metadata(bcx: @mut Block,
190-
arg: &ast::arg) {
232+
arg: &ast::arg,
233+
needs_deref: bool) {
191234
let fcx = bcx.fcx;
192235
let cx = fcx.ccx;
193236

@@ -393,7 +436,11 @@ pub fn create_function_metadata(fcx: &mut FunctionContext) -> DISubprogram {
393436
{
394437
assert!(fcx.debug_context.is_none());
395438

396-
let mut fn_debug_context = ~FunctionDebugContext::new();
439+
let mut fn_debug_context = ~FunctionDebugContext {
440+
scope_map: HashMap::new(),
441+
argument_counter: if fcx.llself.is_some() { 2 } else { 1 }
442+
};
443+
397444
let entry_block_id = fcx.entry_bcx.get_ref().node_info.get_ref().id;
398445
let entry_block = cx.tcx.items.get(&entry_block_id);
399446

@@ -1408,6 +1455,13 @@ fn DIB(cx: &CrateContext) -> DIBuilderRef {
14081455
cx.dbg_cx.get_ref().builder
14091456
}
14101457

1458+
fn assert_fcx_has_span(fcx: &FunctionContext) {
1459+
if fcx.span.is_none() {
1460+
fcx.ccx.sess.bug(fmt!("debuginfo: Encountered function %s with invalid source span. \
1461+
This function should have been ignored by debuginfo generation.",
1462+
ast_map::path_to_str(fcx.path, fcx.ccx.sess.intr())));
1463+
}
1464+
}
14111465

14121466
// This procedure builds the *scope map* for a given function, which maps any given ast::NodeId in
14131467
// the function's AST to the correct DIScope metadata instance.

0 commit comments

Comments
 (0)