1
1
use self :: InternalDebugLocation :: * ;
2
2
3
- use super :: utils:: { debug_context, span_start } ;
3
+ use super :: utils:: debug_context;
4
4
use super :: metadata:: UNKNOWN_COLUMN_NUMBER ;
5
5
use rustc_codegen_ssa:: mir:: debuginfo:: FunctionDebugContext ;
6
6
7
7
use crate :: llvm;
8
8
use crate :: llvm:: debuginfo:: DIScope ;
9
9
use crate :: builder:: Builder ;
10
+ use crate :: common:: CodegenCx ;
10
11
use rustc_codegen_ssa:: traits:: * ;
11
12
13
+ use std:: num:: NonZeroUsize ;
14
+
12
15
use libc:: c_uint;
13
16
use syntax_pos:: { Span , Pos } ;
14
17
@@ -23,8 +26,7 @@ pub fn set_source_location<D>(
23
26
) {
24
27
let dbg_loc = if debug_context. source_locations_enabled {
25
28
debug ! ( "set_source_location: {}" , bx. sess( ) . source_map( ) . span_to_string( span) ) ;
26
- let loc = span_start ( bx. cx ( ) , span) ;
27
- InternalDebugLocation :: new ( scope, loc. line , loc. col . to_usize ( ) )
29
+ InternalDebugLocation :: from_span ( bx. cx ( ) , scope, span)
28
30
} else {
29
31
UnknownLocation
30
32
} ;
@@ -34,18 +36,43 @@ pub fn set_source_location<D>(
34
36
35
37
#[ derive( Copy , Clone , PartialEq ) ]
36
38
pub enum InternalDebugLocation < ' ll > {
37
- KnownLocation { scope : & ' ll DIScope , line : usize , col : usize } ,
39
+ KnownLocation {
40
+ scope : & ' ll DIScope ,
41
+ line : usize ,
42
+ col : Option < NonZeroUsize > ,
43
+ } ,
38
44
UnknownLocation
39
45
}
40
46
41
47
impl InternalDebugLocation < ' ll > {
42
- pub fn new ( scope : & ' ll DIScope , line : usize , col : usize ) -> Self {
48
+ pub fn new ( scope : & ' ll DIScope , line : usize , col : Option < NonZeroUsize > ) -> Self {
43
49
KnownLocation {
44
50
scope,
45
51
line,
46
52
col,
47
53
}
48
54
}
55
+
56
+ pub fn from_span ( cx : & CodegenCx < ' ll , ' _ > , scope : & ' ll DIScope , span : Span ) -> Self {
57
+ let pos = cx. sess ( ) . source_map ( ) . lookup_char_pos ( span. lo ( ) ) ;
58
+
59
+ // FIXME: Rust likes to emit zero-width spans just after the end of a function. For now,
60
+ // zero-width spans to the preceding column to avoid emitting a column that points past the
61
+ // end of a line. E.g.,
62
+ // |xyz = None
63
+ // x|yz = 1
64
+ // xy|z = 2
65
+ //
66
+ // See discussion in https://github.com/rust-lang/rust/issues/65437
67
+ let col0 = pos. col . to_usize ( ) ;
68
+ let col1 = if span. is_empty ( ) {
69
+ NonZeroUsize :: new ( col0)
70
+ } else {
71
+ NonZeroUsize :: new ( col0 + 1 )
72
+ } ;
73
+
74
+ Self :: new ( scope, pos. line , col1)
75
+ }
49
76
}
50
77
51
78
pub fn set_debug_location (
@@ -60,9 +87,9 @@ pub fn set_debug_location(
60
87
let col_used = if bx. sess ( ) . target . target . options . is_like_msvc {
61
88
UNKNOWN_COLUMN_NUMBER
62
89
} else {
63
- ( col + 1 ) as c_uint
90
+ col. map_or ( UNKNOWN_COLUMN_NUMBER , |c| c . get ( ) as c_uint )
64
91
} ;
65
- debug ! ( "setting debug location to {} {}" , line, col ) ;
92
+ debug ! ( "setting debug location to {} {}" , line, col_used ) ;
66
93
67
94
unsafe {
68
95
Some ( llvm:: LLVMRustDIBuilderCreateDebugLocation (
0 commit comments