@@ -91,14 +91,15 @@ static DW_ATE_unsigned_char: c_uint = 0x08;
91
91
92
92
/// A context object for maintaining all state needed by the debuginfo module.
93
93
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 > ,
102
103
}
103
104
104
105
impl DebugContext {
@@ -116,6 +117,7 @@ impl DebugContext {
116
117
created_functions : HashMap :: new ( ) ,
117
118
created_blocks : HashMap :: new ( ) ,
118
119
created_types : HashMap :: new ( ) ,
120
+ argument_index_counters : HashMap :: new ( ) ,
119
121
} ;
120
122
}
121
123
}
@@ -138,11 +140,14 @@ pub fn create_local_var_metadata(bcx: @mut Block, local: &ast::Local) {
138
140
let def_map = cx. tcx . def_map ;
139
141
let pattern = local. node . pat ;
140
142
141
- let context = match bcx. parent {
143
+ let scope = match bcx. parent {
142
144
None => create_function_metadata ( bcx. fcx ) ,
143
145
Some ( _) => lexical_block_metadata ( bcx)
144
146
} ;
145
147
148
+ let filename = span_start ( cx, local. span ) . file . name ;
149
+ let file_metadata = file_metadata ( cx, filename) ;
150
+
146
151
do pat_util:: pat_bindings ( def_map, pattern) |_, node_id, span, path_ref| {
147
152
148
153
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) {
151
156
let loc = span_start ( cx, span) ;
152
157
let ty = node_id_type ( bcx, node_id) ;
153
158
let type_metadata = type_metadata ( cx, ty, span) ;
154
- let file_metadata = file_metadata ( cx, loc. file . name ) ;
155
159
156
160
let var_metadata = do as_c_str ( name) |name| {
157
161
unsafe {
158
162
llvm:: LLVMDIBuilderCreateLocalVariable (
159
163
DIB ( cx) ,
160
164
DW_TAG_auto_variable ,
161
- context ,
165
+ scope ,
162
166
name,
163
167
file_metadata,
164
168
loc. line as c_uint ,
@@ -172,9 +176,7 @@ pub fn create_local_var_metadata(bcx: @mut Block, local: &ast::Local) {
172
176
let llptr = match bcx. fcx . lllocals . find_copy ( & node_id) {
173
177
Some ( v) => v,
174
178
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) ) ;
178
180
}
179
181
} ;
180
182
@@ -194,64 +196,77 @@ pub fn create_local_var_metadata(bcx: @mut Block, local: &ast::Local) {
194
196
/// Creates debug information for the given function argument.
195
197
///
196
198
/// 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 ) {
207
200
let fcx = bcx. fcx ;
208
201
let cx = fcx. ccx ;
209
202
210
- let loc = span_start ( cx, span) ;
211
- if "<intrinsic>" == loc. file . name {
212
- return None ;
203
+ if fcx. span . is_none ( ) {
204
+ return ;
213
205
}
214
206
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) ;
241
231
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| {
244
233
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 )
248
245
}
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) ;
253
266
}
254
267
}
268
+
269
+ dbg_cx( cx) . argument_index_counters . insert ( arg. id , argument_index) ;
255
270
}
256
271
257
272
/// 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) {
272
287
/// The return value should be ignored if called from outside of the debuginfo module.
273
288
pub fn create_function_metadata ( fcx : & FunctionContext ) -> DISubprogram {
274
289
let cx = fcx. ccx ;
275
- let span = fcx. span . get ( ) ;
276
290
277
291
let fnitem = cx. tcx . items . get_copy ( & fcx. id ) ;
278
292
let ( ident, ret_ty, id) = match fnitem {
@@ -318,14 +332,19 @@ pub fn create_function_metadata(fcx: &FunctionContext) -> DISubprogram {
318
332
_) => {
319
333
( ident, ty, id)
320
334
}
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 ) )
322
336
} ;
323
337
324
338
match dbg_cx ( cx) . created_functions . find ( & id) {
325
339
Some ( fn_metadata) => return * fn_metadata,
326
340
None => ( )
327
341
}
328
342
343
+ let span = match fcx. span {
344
+ Some ( value) => value,
345
+ None => codemap:: dummy_sp ( )
346
+ } ;
347
+
329
348
debug ! ( "create_function_metadata: %s, %s" ,
330
349
cx. sess. str_of( ident) ,
331
350
cx. sess. codemap. span_to_str( span) ) ;
0 commit comments