3
3
4
4
use rustc_codegen_ssa:: mir:: debuginfo:: VariableKind :: * ;
5
5
6
- use self :: metadata:: { file_metadata, type_metadata, TypeMap , UNKNOWN_LINE_NUMBER } ;
6
+ use self :: metadata:: { file_metadata, type_metadata, TypeMap } ;
7
+ use self :: metadata:: { UNKNOWN_COLUMN_NUMBER , UNKNOWN_LINE_NUMBER } ;
7
8
use self :: namespace:: mangled_name_of_instance;
8
9
use self :: type_names:: compute_debuginfo_type_name;
9
10
use self :: utils:: { create_DIArray, is_node_local_to_unit, DIB } ;
@@ -13,14 +14,16 @@ use crate::builder::Builder;
13
14
use crate :: common:: CodegenCx ;
14
15
use crate :: llvm;
15
16
use crate :: llvm:: debuginfo:: {
16
- DIArray , DIBuilder , DIFile , DIFlags , DILexicalBlock , DISPFlags , DIScope , DIType , DIVariable ,
17
+ DIArray , DIBuilder , DIFile , DIFlags , DILexicalBlock , DILocation , DISPFlags , DIScope , DIType ,
18
+ DIVariable ,
17
19
} ;
18
20
use crate :: value:: Value ;
19
21
20
22
use rustc_codegen_ssa:: debuginfo:: type_names;
21
23
use rustc_codegen_ssa:: mir:: debuginfo:: { DebugScope , FunctionDebugContext , VariableKind } ;
22
24
use rustc_codegen_ssa:: traits:: * ;
23
25
use rustc_data_structures:: fx:: { FxHashMap , FxHashSet } ;
26
+ use rustc_data_structures:: sync:: Lrc ;
24
27
use rustc_hir:: def_id:: { DefId , DefIdMap , LOCAL_CRATE } ;
25
28
use rustc_index:: vec:: IndexVec ;
26
29
use rustc_middle:: mir;
@@ -29,7 +32,7 @@ use rustc_middle::ty::subst::{GenericArgKind, SubstsRef};
29
32
use rustc_middle:: ty:: { self , Instance , ParamEnv , Ty , TypeFoldable } ;
30
33
use rustc_session:: config:: { self , DebugInfo } ;
31
34
use rustc_span:: symbol:: Symbol ;
32
- use rustc_span:: { self , BytePos , Span } ;
35
+ use rustc_span:: { self , BytePos , Pos , SourceFile , SourceFileAndLine , Span } ;
33
36
use rustc_target:: abi:: { LayoutOf , Primitive , Size } ;
34
37
35
38
use libc:: c_uint;
@@ -41,7 +44,6 @@ mod create_scope_map;
41
44
pub mod gdb;
42
45
pub mod metadata;
43
46
mod namespace;
44
- mod source_loc;
45
47
mod utils;
46
48
47
49
pub use self :: create_scope_map:: compute_mir_scopes;
@@ -141,14 +143,11 @@ impl DebugInfoBuilderMethods for Builder<'a, 'll, 'tcx> {
141
143
fn dbg_var_addr (
142
144
& mut self ,
143
145
dbg_var : & ' ll DIVariable ,
144
- scope_metadata : & ' ll DIScope ,
146
+ dbg_loc : & ' ll DILocation ,
145
147
variable_alloca : Self :: Value ,
146
148
direct_offset : Size ,
147
149
indirect_offsets : & [ Size ] ,
148
- span : Span ,
149
150
) {
150
- let cx = self . cx ( ) ;
151
-
152
151
// Convert the direct and indirect offsets to address ops.
153
152
// FIXME(eddyb) use `const`s instead of getting the values via FFI,
154
153
// the values should match the ones in the DWARF standard anyway.
@@ -168,14 +167,10 @@ impl DebugInfoBuilderMethods for Builder<'a, 'll, 'tcx> {
168
167
}
169
168
}
170
169
171
- // FIXME(eddyb) maybe this information could be extracted from `dbg_var`,
172
- // to avoid having to pass it down in both places?
173
- // NB: `var` doesn't seem to know about the column, so that's a limitation.
174
- let dbg_loc = cx. create_debug_loc ( scope_metadata, span) ;
175
170
unsafe {
176
171
// FIXME(eddyb) replace `llvm.dbg.declare` with `llvm.dbg.addr`.
177
172
llvm:: LLVMRustDIBuilderInsertDeclareAtEnd (
178
- DIB ( cx ) ,
173
+ DIB ( self . cx ( ) ) ,
179
174
variable_alloca,
180
175
dbg_var,
181
176
addr_ops. as_ptr ( ) ,
@@ -186,16 +181,13 @@ impl DebugInfoBuilderMethods for Builder<'a, 'll, 'tcx> {
186
181
}
187
182
}
188
183
189
- fn set_source_location ( & mut self , scope : & ' ll DIScope , span : Span ) {
190
- debug ! ( "set_source_location: {}" , self . sess( ) . source_map( ) . span_to_string( span) ) ;
191
-
192
- let dbg_loc = self . cx ( ) . create_debug_loc ( scope, span) ;
193
-
184
+ fn set_dbg_loc ( & mut self , dbg_loc : & ' ll DILocation ) {
194
185
unsafe {
195
186
let dbg_loc_as_llval = llvm:: LLVMRustMetadataAsValue ( self . cx ( ) . llcx , dbg_loc) ;
196
187
llvm:: LLVMSetCurrentDebugLocation ( self . llbuilder , dbg_loc_as_llval) ;
197
188
}
198
189
}
190
+
199
191
fn insert_reference_to_gdb_debug_scripts_section_global ( & mut self ) {
200
192
gdb:: insert_reference_to_gdb_debug_scripts_section_global ( self )
201
193
}
@@ -224,6 +216,49 @@ impl DebugInfoBuilderMethods for Builder<'a, 'll, 'tcx> {
224
216
}
225
217
}
226
218
219
+ /// A source code location used to generate debug information.
220
+ // FIXME(eddyb) rename this to better indicate it's a duplicate of
221
+ // `rustc_span::Loc` rather than `DILocation`, perhaps by making
222
+ // `lookup_char_pos` return the right information instead.
223
+ pub struct DebugLoc {
224
+ /// Information about the original source file.
225
+ pub file : Lrc < SourceFile > ,
226
+ /// The (1-based) line number.
227
+ pub line : Option < u32 > ,
228
+ /// The (1-based) column number.
229
+ pub col : Option < u32 > ,
230
+ }
231
+
232
+ impl CodegenCx < ' ll , ' _ > {
233
+ /// Looks up debug source information about a `BytePos`.
234
+ // FIXME(eddyb) rename this to better indicate it's a duplicate of
235
+ // `lookup_char_pos` rather than `dbg_loc`, perhaps by making
236
+ // `lookup_char_pos` return the right information instead.
237
+ pub fn lookup_debug_loc ( & self , pos : BytePos ) -> DebugLoc {
238
+ let ( file, line, col) = match self . sess ( ) . source_map ( ) . lookup_line ( pos) {
239
+ Ok ( SourceFileAndLine { sf : file, line } ) => {
240
+ let line_pos = file. line_begin_pos ( pos) ;
241
+
242
+ // Use 1-based indexing.
243
+ let line = ( line + 1 ) as u32 ;
244
+ let col = ( pos - line_pos) . to_u32 ( ) + 1 ;
245
+
246
+ ( file, Some ( line) , Some ( col) )
247
+ }
248
+ Err ( file) => ( file, None , None ) ,
249
+ } ;
250
+
251
+ // For MSVC, omit the column number.
252
+ // Otherwise, emit it. This mimics clang behaviour.
253
+ // See discussion in https://github.com/rust-lang/rust/issues/42921
254
+ if self . sess ( ) . target . options . is_like_msvc {
255
+ DebugLoc { file, line, col : None }
256
+ } else {
257
+ DebugLoc { file, line, col }
258
+ }
259
+ }
260
+ }
261
+
227
262
impl DebugInfoMethods < ' tcx > for CodegenCx < ' ll , ' tcx > {
228
263
fn create_function_debug_context (
229
264
& self ,
@@ -237,12 +272,9 @@ impl DebugInfoMethods<'tcx> for CodegenCx<'ll, 'tcx> {
237
272
}
238
273
239
274
// Initialize fn debug context (including scopes).
240
- // FIXME(eddyb) figure out a way to not need `Option` for `scope_metadata`.
241
- let empty_scope = DebugScope {
242
- scope_metadata : None ,
243
- file_start_pos : BytePos ( 0 ) ,
244
- file_end_pos : BytePos ( 0 ) ,
245
- } ;
275
+ // FIXME(eddyb) figure out a way to not need `Option` for `dbg_scope`.
276
+ let empty_scope =
277
+ DebugScope { dbg_scope : None , file_start_pos : BytePos ( 0 ) , file_end_pos : BytePos ( 0 ) } ;
246
278
let mut fn_debug_context =
247
279
FunctionDebugContext { scopes : IndexVec :: from_elem ( empty_scope, & mir. source_scopes ) } ;
248
280
@@ -505,6 +537,20 @@ impl DebugInfoMethods<'tcx> for CodegenCx<'ll, 'tcx> {
505
537
}
506
538
}
507
539
540
+ fn dbg_loc ( & self , scope : & ' ll DIScope , span : Span ) -> & ' ll DILocation {
541
+ let DebugLoc { line, col, .. } = self . lookup_debug_loc ( span. lo ( ) ) ;
542
+
543
+ unsafe {
544
+ llvm:: LLVMRustDIBuilderCreateDebugLocation (
545
+ utils:: debug_context ( self ) . llcontext ,
546
+ line. unwrap_or ( UNKNOWN_LINE_NUMBER ) ,
547
+ col. unwrap_or ( UNKNOWN_COLUMN_NUMBER ) ,
548
+ scope,
549
+ None ,
550
+ )
551
+ }
552
+ }
553
+
508
554
fn create_vtable_metadata ( & self , ty : Ty < ' tcx > , vtable : Self :: Value ) {
509
555
metadata:: create_vtable_metadata ( self , ty, vtable)
510
556
}
0 commit comments