@@ -96,7 +96,7 @@ pub struct DebugContext {
96
96
priv crate_file : ~str ,
97
97
priv llcontext : ContextRef ,
98
98
priv builder : DIBuilderRef ,
99
- priv curr_loc : ( uint , uint ) ,
99
+ priv curr_loc : DebugLocation ,
100
100
priv created_files : HashMap < ~str , DIFile > ,
101
101
priv created_types : HashMap < uint , DIType > ,
102
102
}
@@ -111,7 +111,7 @@ impl DebugContext {
111
111
crate_file: crate ,
112
112
llcontext : llcontext,
113
113
builder : builder,
114
- curr_loc : ( 0 , 0 ) ,
114
+ curr_loc : UnknownLocation ,
115
115
created_files : HashMap :: new ( ) ,
116
116
created_types : HashMap :: new ( ) ,
117
117
} ;
@@ -122,6 +122,7 @@ pub struct FunctionDebugContext {
122
122
priv scope_map : HashMap < ast:: NodeId , DIScope > ,
123
123
priv fn_metadata : DISubprogram ,
124
124
priv argument_counter : uint ,
125
+ priv source_locations_enabled : bool ,
125
126
}
126
127
127
128
/// Create any deferred debug metadata nodes
@@ -202,7 +203,7 @@ pub fn create_self_argument_metadata(bcx: @mut Block,
202
203
}
203
204
} ;
204
205
205
- set_debug_location ( cx, scope, loc. line , loc. col . to_uint ( ) ) ;
206
+ set_debug_location ( cx, DebugLocation :: new ( scope, loc. line , * loc. col ) ) ;
206
207
unsafe {
207
208
let instr = llvm:: LLVMDIBuilderInsertDeclareAtEnd (
208
209
DIB ( cx) ,
@@ -212,6 +213,7 @@ pub fn create_self_argument_metadata(bcx: @mut Block,
212
213
213
214
llvm:: LLVMSetInstDebugLocation ( trans:: build:: B ( bcx) . llbuilder , instr) ;
214
215
}
216
+ set_debug_location ( cx, UnknownLocation ) ;
215
217
}
216
218
217
219
/// Creates debug information for the given function argument.
@@ -274,7 +276,7 @@ pub fn create_argument_metadata(bcx: @mut Block,
274
276
}
275
277
} ;
276
278
277
- set_debug_location ( cx, scope, loc. line , loc. col . to_uint ( ) ) ;
279
+ set_debug_location ( cx, DebugLocation :: new ( scope, loc. line , * loc. col ) ) ;
278
280
unsafe {
279
281
let instr = llvm:: LLVMDIBuilderInsertDeclareAtEnd (
280
282
DIB ( cx) ,
@@ -284,28 +286,39 @@ pub fn create_argument_metadata(bcx: @mut Block,
284
286
285
287
llvm:: LLVMSetInstDebugLocation ( trans:: build:: B ( bcx) . llbuilder , instr) ;
286
288
}
289
+ set_debug_location ( cx, UnknownLocation ) ;
287
290
}
288
291
}
289
292
290
293
/// Sets the current debug location at the beginning of the span.
291
294
///
292
295
/// Maps to a call to llvm::LLVMSetCurrentDebugLocation(...). The node_id parameter is used to
293
296
/// reliably find the correct visibility scope for the code position.
294
- pub fn update_source_pos ( fcx : & FunctionContext ,
295
- node_id : ast:: NodeId ,
296
- span : span ) {
297
+ pub fn set_source_location ( fcx : & FunctionContext ,
298
+ node_id : ast:: NodeId ,
299
+ span : span ) {
297
300
let cx: & mut CrateContext = fcx. ccx ;
298
301
299
302
if !cx. sess . opts . debuginfo || ( * span. lo == 0 && * span. hi == 0 ) {
300
303
return ;
301
304
}
302
305
303
- debug ! ( "update_source_pos : %s" , cx. sess. codemap. span_to_str( span) ) ;
306
+ debug ! ( "set_source_location : %s" , cx. sess. codemap. span_to_str( span) ) ;
304
307
305
- let loc = span_start ( cx, span) ;
306
- let scope = scope_metadata ( fcx, node_id, span) ;
308
+ if fcx. debug_context . get_ref ( ) . source_locations_enabled {
309
+ let loc = span_start ( cx, span) ;
310
+ let scope = scope_metadata ( fcx, node_id, span) ;
307
311
308
- set_debug_location ( cx, scope, loc. line , loc. col . to_uint ( ) ) ;
312
+ set_debug_location ( cx, DebugLocation :: new ( scope, loc. line , * loc. col ) ) ;
313
+ } else {
314
+ set_debug_location ( cx, UnknownLocation ) ;
315
+ }
316
+ }
317
+
318
+ pub fn start_emitting_source_locations ( fcx : & mut FunctionContext ) {
319
+ for debug_context in fcx. debug_context . mut_iter ( ) {
320
+ debug_context. source_locations_enabled = true ;
321
+ }
309
322
}
310
323
311
324
pub fn create_function_debug_context ( cx : & mut CrateContext ,
@@ -401,6 +414,8 @@ pub fn create_function_debug_context(cx: &mut CrateContext,
401
414
ptr:: null ( )
402
415
} ;
403
416
417
+ let scope_line = get_scope_line ( cx, top_level_block, loc. line ) ;
418
+
404
419
let fn_metadata = do function_name. to_c_str ( ) . with_ref |function_name| {
405
420
unsafe {
406
421
llvm:: LLVMDIBuilderCreateFunction (
@@ -413,7 +428,7 @@ pub fn create_function_debug_context(cx: &mut CrateContext,
413
428
function_type_metadata,
414
429
false ,
415
430
true ,
416
- loc . line as c_uint ,
431
+ scope_line as c_uint ,
417
432
FlagPrototyped as c_uint ,
418
433
cx. sess . opts . optimize != session:: No ,
419
434
llfn,
@@ -427,6 +442,7 @@ pub fn create_function_debug_context(cx: &mut CrateContext,
427
442
scope_map : HashMap :: new ( ) ,
428
443
fn_metadata : fn_metadata,
429
444
argument_counter : 1 ,
445
+ source_locations_enabled : false ,
430
446
} ;
431
447
432
448
let arg_pats = do fn_decl. inputs . map |arg_ref| { arg_ref. pat } ;
@@ -438,8 +454,6 @@ pub fn create_function_debug_context(cx: &mut CrateContext,
438
454
fn_ast_id : ast:: NodeId ,
439
455
fn_decl : & ast:: fn_decl ,
440
456
param_substs : Option < @param_substs > ) -> DIArray {
441
- //let cx = fcx.ccx;
442
-
443
457
if !cx. sess . opts . extra_debuginfo {
444
458
return create_DIArray ( DIB ( cx) , [ ] ) ;
445
459
}
@@ -575,9 +589,22 @@ pub fn create_function_debug_context(cx: &mut CrateContext,
575
589
576
590
return create_DIArray ( DIB ( cx) , template_params) ;
577
591
}
578
- }
579
-
580
592
593
+ fn get_scope_line ( cx : & CrateContext ,
594
+ top_level_block : Option < & ast:: Block > ,
595
+ default : uint )
596
+ -> uint {
597
+ match top_level_block {
598
+ Some ( & ast:: Block { stmts : ref statements, _ } ) if statements. len ( ) > 0 => {
599
+ span_start ( cx, statements[ 0 ] . span ) . line
600
+ }
601
+ Some ( & ast:: Block { expr : Some ( @ref expr) , _ } ) => {
602
+ span_start ( cx, expr. span ) . line
603
+ }
604
+ _ => default
605
+ }
606
+ }
607
+ }
581
608
582
609
//=-------------------------------------------------------------------------------------------------
583
610
// Module-Internal debug info creation functions
@@ -650,7 +677,7 @@ fn declare_local(bcx: @mut Block,
650
677
}
651
678
} ;
652
679
653
- set_debug_location ( cx, scope, loc. line , loc. col . to_uint ( ) ) ;
680
+ set_debug_location ( cx, DebugLocation :: new ( scope, loc. line , * loc. col ) ) ;
654
681
unsafe {
655
682
let instr = llvm:: LLVMDIBuilderInsertDeclareAtEnd (
656
683
DIB ( cx) ,
@@ -1409,22 +1436,51 @@ fn type_metadata(cx: &mut CrateContext,
1409
1436
return type_metadata;
1410
1437
}
1411
1438
1412
- fn set_debug_location ( cx : & mut CrateContext , scope : DIScope , line : uint , col : uint ) {
1413
- if dbg_cx ( cx) . curr_loc == ( line, col) {
1439
+ #[ deriving( Eq ) ]
1440
+ enum DebugLocation {
1441
+ KnownLocation { scope : DIScope , line : uint , col : uint } ,
1442
+ UnknownLocation
1443
+ }
1444
+
1445
+ impl DebugLocation {
1446
+ fn new ( scope : DIScope , line : uint , col : uint ) -> DebugLocation {
1447
+ KnownLocation {
1448
+ scope : scope,
1449
+ line : line,
1450
+ col : col,
1451
+ }
1452
+ }
1453
+ }
1454
+
1455
+ fn set_debug_location ( cx : & mut CrateContext , debug_location : DebugLocation ) {
1456
+ if debug_location == dbg_cx ( cx) . curr_loc {
1414
1457
return ;
1415
1458
}
1416
- debug ! ( "setting debug location to %u %u" , line, col) ;
1417
- dbg_cx ( cx) . curr_loc = ( line, col) ;
1418
1459
1419
- let elems = ~[ C_i32 ( line as i32 ) , C_i32 ( col as i32 ) , scope, ptr:: null ( ) ] ;
1420
- unsafe {
1421
- let dbg_loc = llvm:: LLVMMDNodeInContext (
1422
- dbg_cx ( cx) . llcontext ,
1423
- vec:: raw:: to_ptr ( elems) ,
1424
- elems. len ( ) as c_uint ) ;
1425
1460
1426
- llvm:: LLVMSetCurrentDebugLocation ( cx. builder . B , dbg_loc) ;
1461
+ let metadata_node;
1462
+
1463
+ match debug_location {
1464
+ KnownLocation { scope, line, col } => {
1465
+ debug ! ( "setting debug location to %u %u" , line, col) ;
1466
+ let elements = [ C_i32 ( line as i32 ) , C_i32 ( col as i32 ) , scope, ptr:: null ( ) ] ;
1467
+ unsafe {
1468
+ metadata_node = llvm:: LLVMMDNodeInContext ( dbg_cx ( cx) . llcontext ,
1469
+ vec:: raw:: to_ptr ( elements) ,
1470
+ elements. len ( ) as c_uint ) ;
1471
+ }
1472
+ }
1473
+ UnknownLocation => {
1474
+ debug ! ( "clearing debug location " ) ;
1475
+ metadata_node = ptr:: null ( ) ;
1476
+ }
1477
+ } ;
1478
+
1479
+ unsafe {
1480
+ llvm:: LLVMSetCurrentDebugLocation ( cx. builder . B , metadata_node) ;
1427
1481
}
1482
+
1483
+ dbg_cx ( cx) . curr_loc = debug_location;
1428
1484
}
1429
1485
1430
1486
//=-------------------------------------------------------------------------------------------------
0 commit comments