33
44use rustc_codegen_ssa:: mir:: debuginfo:: VariableKind :: * ;
55
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 } ;
78use self :: namespace:: mangled_name_of_instance;
89use self :: type_names:: compute_debuginfo_type_name;
910use self :: utils:: { create_DIArray, is_node_local_to_unit, DIB } ;
@@ -13,14 +14,16 @@ use crate::builder::Builder;
1314use crate :: common:: CodegenCx ;
1415use crate :: llvm;
1516use 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 ,
1719} ;
1820use crate :: value:: Value ;
1921
2022use rustc_codegen_ssa:: debuginfo:: type_names;
2123use rustc_codegen_ssa:: mir:: debuginfo:: { DebugScope , FunctionDebugContext , VariableKind } ;
2224use rustc_codegen_ssa:: traits:: * ;
2325use rustc_data_structures:: fx:: { FxHashMap , FxHashSet } ;
26+ use rustc_data_structures:: sync:: Lrc ;
2427use rustc_hir:: def_id:: { DefId , DefIdMap , LOCAL_CRATE } ;
2528use rustc_index:: vec:: IndexVec ;
2629use rustc_middle:: mir;
@@ -29,7 +32,7 @@ use rustc_middle::ty::subst::{GenericArgKind, SubstsRef};
2932use rustc_middle:: ty:: { self , Instance , ParamEnv , Ty , TypeFoldable } ;
3033use rustc_session:: config:: { self , DebugInfo } ;
3134use rustc_span:: symbol:: Symbol ;
32- use rustc_span:: { self , BytePos , Span } ;
35+ use rustc_span:: { self , BytePos , Pos , SourceFile , SourceFileAndLine , Span } ;
3336use rustc_target:: abi:: { LayoutOf , Primitive , Size } ;
3437
3538use libc:: c_uint;
@@ -41,7 +44,6 @@ mod create_scope_map;
4144pub mod gdb;
4245pub mod metadata;
4346mod namespace;
44- mod source_loc;
4547mod utils;
4648
4749pub use self :: create_scope_map:: compute_mir_scopes;
@@ -141,14 +143,11 @@ impl DebugInfoBuilderMethods for Builder<'a, 'll, 'tcx> {
141143 fn dbg_var_addr (
142144 & mut self ,
143145 dbg_var : & ' ll DIVariable ,
144- scope_metadata : & ' ll DIScope ,
146+ dbg_loc : & ' ll DILocation ,
145147 variable_alloca : Self :: Value ,
146148 direct_offset : Size ,
147149 indirect_offsets : & [ Size ] ,
148- span : Span ,
149150 ) {
150- let cx = self . cx ( ) ;
151-
152151 // Convert the direct and indirect offsets to address ops.
153152 // FIXME(eddyb) use `const`s instead of getting the values via FFI,
154153 // the values should match the ones in the DWARF standard anyway.
@@ -168,14 +167,10 @@ impl DebugInfoBuilderMethods for Builder<'a, 'll, 'tcx> {
168167 }
169168 }
170169
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) ;
175170 unsafe {
176171 // FIXME(eddyb) replace `llvm.dbg.declare` with `llvm.dbg.addr`.
177172 llvm:: LLVMRustDIBuilderInsertDeclareAtEnd (
178- DIB ( cx ) ,
173+ DIB ( self . cx ( ) ) ,
179174 variable_alloca,
180175 dbg_var,
181176 addr_ops. as_ptr ( ) ,
@@ -186,16 +181,13 @@ impl DebugInfoBuilderMethods for Builder<'a, 'll, 'tcx> {
186181 }
187182 }
188183
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 ) {
194185 unsafe {
195186 let dbg_loc_as_llval = llvm:: LLVMRustMetadataAsValue ( self . cx ( ) . llcx , dbg_loc) ;
196187 llvm:: LLVMSetCurrentDebugLocation ( self . llbuilder , dbg_loc_as_llval) ;
197188 }
198189 }
190+
199191 fn insert_reference_to_gdb_debug_scripts_section_global ( & mut self ) {
200192 gdb:: insert_reference_to_gdb_debug_scripts_section_global ( self )
201193 }
@@ -224,6 +216,49 @@ impl DebugInfoBuilderMethods for Builder<'a, 'll, 'tcx> {
224216 }
225217}
226218
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+
227262impl DebugInfoMethods < ' tcx > for CodegenCx < ' ll , ' tcx > {
228263 fn create_function_debug_context (
229264 & self ,
@@ -237,12 +272,9 @@ impl DebugInfoMethods<'tcx> for CodegenCx<'ll, 'tcx> {
237272 }
238273
239274 // 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 ) } ;
246278 let mut fn_debug_context =
247279 FunctionDebugContext { scopes : IndexVec :: from_elem ( empty_scope, & mir. source_scopes ) } ;
248280
@@ -505,6 +537,20 @@ impl DebugInfoMethods<'tcx> for CodegenCx<'ll, 'tcx> {
505537 }
506538 }
507539
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+
508554 fn create_vtable_metadata ( & self , ty : Ty < ' tcx > , vtable : Self :: Value ) {
509555 metadata:: create_vtable_metadata ( self , ty, vtable)
510556 }
0 commit comments