Skip to content

Commit c9e51ce

Browse files
debuginfo: Support for function arguments. (WIP)
1 parent 203f96f commit c9e51ce

File tree

2 files changed

+84
-67
lines changed

2 files changed

+84
-67
lines changed

src/librustc/middle/trans/debuginfo.rs

Lines changed: 83 additions & 64 deletions
Original file line numberDiff line numberDiff line change
@@ -91,14 +91,15 @@ static DW_ATE_unsigned_char: c_uint = 0x08;
9191

9292
/// A context object for maintaining all state needed by the debuginfo module.
9393
pub struct DebugContext {
94-
crate_file: ~str,
95-
llcontext: ContextRef,
96-
builder: DIBuilderRef,
97-
curr_loc: (uint, uint),
98-
created_files: HashMap<~str, DIFile>,
99-
created_functions: HashMap<ast::node_id, DISubprogram>,
100-
created_blocks: HashMap<ast::node_id, DILexicalBlock>,
101-
created_types: HashMap<uint, DIType>
94+
priv crate_file: ~str,
95+
priv llcontext: ContextRef,
96+
priv builder: DIBuilderRef,
97+
priv curr_loc: (uint, uint),
98+
priv created_files: HashMap<~str, DIFile>,
99+
priv created_functions: HashMap<ast::node_id, DISubprogram>,
100+
priv created_blocks: HashMap<ast::node_id, DILexicalBlock>,
101+
priv created_types: HashMap<uint, DIType>,
102+
priv argument_index_counters: HashMap<ast::node_id, uint>,
102103
}
103104

104105
impl DebugContext {
@@ -116,6 +117,7 @@ impl DebugContext {
116117
created_functions: HashMap::new(),
117118
created_blocks: HashMap::new(),
118119
created_types: HashMap::new(),
120+
argument_index_counters: HashMap::new(),
119121
};
120122
}
121123
}
@@ -138,11 +140,14 @@ pub fn create_local_var_metadata(bcx: @mut Block, local: &ast::Local) {
138140
let def_map = cx.tcx.def_map;
139141
let pattern = local.node.pat;
140142

141-
let context = match bcx.parent {
143+
let scope = match bcx.parent {
142144
None => create_function_metadata(bcx.fcx),
143145
Some(_) => lexical_block_metadata(bcx)
144146
};
145147

148+
let filename = span_start(cx, local.span).file.name;
149+
let file_metadata = file_metadata(cx, filename);
150+
146151
do pat_util::pat_bindings(def_map, pattern) |_, node_id, span, path_ref| {
147152

148153
let ident = ast_util::path_to_ident(path_ref);
@@ -151,14 +156,13 @@ pub fn create_local_var_metadata(bcx: @mut Block, local: &ast::Local) {
151156
let loc = span_start(cx, span);
152157
let ty = node_id_type(bcx, node_id);
153158
let type_metadata = type_metadata(cx, ty, span);
154-
let file_metadata = file_metadata(cx, loc.file.name);
155159

156160
let var_metadata = do as_c_str(name) |name| {
157161
unsafe {
158162
llvm::LLVMDIBuilderCreateLocalVariable(
159163
DIB(cx),
160164
DW_TAG_auto_variable,
161-
context,
165+
scope,
162166
name,
163167
file_metadata,
164168
loc.line as c_uint,
@@ -172,9 +176,7 @@ pub fn create_local_var_metadata(bcx: @mut Block, local: &ast::Local) {
172176
let llptr = match bcx.fcx.lllocals.find_copy(&node_id) {
173177
Some(v) => v,
174178
None => {
175-
bcx.tcx().sess.span_bug(
176-
local.span,
177-
fmt!("No entry in lllocals table for %?", local.node.id));
179+
bcx.tcx().sess.span_bug(span, fmt!("No entry in lllocals table for %?", node_id));
178180
}
179181
};
180182

@@ -194,64 +196,77 @@ pub fn create_local_var_metadata(bcx: @mut Block, local: &ast::Local) {
194196
/// Creates debug information for the given function argument.
195197
///
196198
/// Adds the created metadata nodes directly to the crate's IR.
197-
/// The return value should be ignored if called from outside of the debuginfo module.
198-
pub fn create_argument_metadata(bcx: @mut Block, arg: &ast::arg, span: span) -> Option<DIVariable> {
199-
debug!("create_argument_metadata");
200-
if true {
201-
// XXX create_argument_metadata disabled for now because "node_id_type(bcx, arg.id)" below
202-
// blows up:
203-
// "error: internal compiler error: node_id_to_type: no type for node `arg (id=10)`"
204-
return None;
205-
}
206-
199+
pub fn create_argument_metadata(bcx: @mut Block, arg: &ast::arg, span: span) {
207200
let fcx = bcx.fcx;
208201
let cx = fcx.ccx;
209202

210-
let loc = span_start(cx, span);
211-
if "<intrinsic>" == loc.file.name {
212-
return None;
203+
if fcx.span.is_none() {
204+
return;
213205
}
214206

215-
let ty = node_id_type(bcx, arg.id);
216-
let type_metadata = type_metadata(cx, ty, arg.ty.span);
217-
let file_metadata = file_metadata(cx, loc.file.name);
218-
let context = create_function_metadata(fcx);
219-
220-
match arg.pat.node {
221-
ast::pat_ident(_, ref path, _) => {
222-
// XXX: This is wrong; it should work for multiple bindings.
223-
let ident = path.idents.last();
224-
let name: &str = cx.sess.str_of(*ident);
225-
let var_metadata = do name.as_c_str |name| {
226-
unsafe {
227-
llvm::LLVMDIBuilderCreateLocalVariable(
228-
DIB(cx),
229-
DW_TAG_arg_variable as u32,
230-
context,
231-
name,
232-
file_metadata,
233-
loc.line as c_uint,
234-
type_metadata,
235-
false,
236-
0,
237-
0)
238-
// XXX need to pass in a real argument number
239-
}
240-
};
207+
if "<intrinsic>" == span_start(cx, span).file.name {
208+
return;
209+
}
210+
211+
let def_map = cx.tcx.def_map;
212+
let pattern = arg.pat;
213+
214+
let mut argument_index = match dbg_cx(cx).argument_index_counters.find_copy(&arg.id) {
215+
Some(value) => value,
216+
None => 0
217+
};
218+
219+
let filename = span_start(cx, span).file.name;
220+
let file_metadata = file_metadata(cx, filename);
221+
let scope = create_function_metadata(fcx);
222+
223+
do pat_util::pat_bindings(def_map, pattern) |_, node_id, span, path_ref| {
224+
225+
let ty = node_id_type(bcx, node_id);
226+
let type_metadata = type_metadata(cx, ty, codemap::dummy_sp());
227+
let loc = span_start(cx, span);
228+
let ident = ast_util::path_to_ident(path_ref);
229+
let name: &str = cx.sess.str_of(ident);
230+
debug!("create_argument_metadata: %s", name);
241231

242-
let llptr = fcx.llargs.get_copy(&arg.id);
243-
set_debug_location(cx, lexical_block_metadata(bcx), loc.line, loc.col.to_uint());
232+
let arg_metadata = do as_c_str(name) |name| {
244233
unsafe {
245-
let instr = llvm::LLVMDIBuilderInsertDeclareAtEnd(
246-
DIB(cx), llptr, var_metadata, bcx.llbb);
247-
llvm::LLVMSetInstDebugLocation(trans::build::B(bcx).llbuilder, instr);
234+
llvm::LLVMDIBuilderCreateLocalVariable(
235+
DIB(cx),
236+
DW_TAG_arg_variable,
237+
scope,
238+
name,
239+
file_metadata,
240+
loc.line as c_uint,
241+
type_metadata,
242+
false,
243+
0,
244+
argument_index as c_uint)
248245
}
249-
return Some(var_metadata);
250-
}
251-
_ => {
252-
return None;
246+
};
247+
248+
argument_index += 1;
249+
250+
let llptr = match bcx.fcx.llargs.find_copy(&node_id) {
251+
Some(v) => v,
252+
None => {
253+
bcx.tcx().sess.span_bug(span, fmt!("No entry in llargs table for %?", node_id));
254+
}
255+
};
256+
257+
set_debug_location(cx, lexical_block_metadata(bcx), loc.line, loc.col.to_uint());
258+
unsafe {
259+
let instr = llvm::LLVMDIBuilderInsertDeclareAtEnd(
260+
DIB(cx),
261+
llptr,
262+
arg_metadata,
263+
bcx.llbb);
264+
265+
llvm::LLVMSetInstDebugLocation(trans::build::B(bcx), instr);
253266
}
254267
}
268+
269+
dbg_cx(cx).argument_index_counters.insert(arg.id, argument_index);
255270
}
256271

257272
/// Sets the current debug location at the beginning of the span
@@ -272,7 +287,6 @@ pub fn update_source_pos(bcx: @mut Block, span: span) {
272287
/// The return value should be ignored if called from outside of the debuginfo module.
273288
pub fn create_function_metadata(fcx: &FunctionContext) -> DISubprogram {
274289
let cx = fcx.ccx;
275-
let span = fcx.span.get();
276290

277291
let fnitem = cx.tcx.items.get_copy(&fcx.id);
278292
let (ident, ret_ty, id) = match fnitem {
@@ -318,14 +332,19 @@ pub fn create_function_metadata(fcx: &FunctionContext) -> DISubprogram {
318332
_) => {
319333
(ident, ty, id)
320334
}
321-
_ => fcx.ccx.sess.bug("create_function_metadata: unexpected sort of node")
335+
_ => fcx.ccx.sess.bug(fmt!("create_function_metadata: unexpected sort of node: %?", fnitem))
322336
};
323337

324338
match dbg_cx(cx).created_functions.find(&id) {
325339
Some(fn_metadata) => return *fn_metadata,
326340
None => ()
327341
}
328342

343+
let span = match fcx.span {
344+
Some(value) => value,
345+
None => codemap::dummy_sp()
346+
};
347+
329348
debug!("create_function_metadata: %s, %s",
330349
cx.sess.str_of(ident),
331350
cx.sess.codemap.span_to_str(span));

src/test/debug-info/function-arguments.rs

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,6 @@
88
// option. This file may not be copied, modified, or distributed
99
// except according to those terms.
1010

11-
// xfail-test
12-
1311
// compile-flags:-Z extra-debug-info
1412
// debugger:break zzz
1513
// debugger:run
@@ -34,7 +32,7 @@ fn main() {
3432
nested(2000, 3000);
3533

3634
fn nested(a: i32, b: i64) -> (i32, i64) {
37-
zzz()
35+
zzz();
3836
(a, b)
3937
}
4038
}

0 commit comments

Comments
 (0)