1010
1111use libc:: c_uint;
1212use llvm:: { self , ValueRef } ;
13- use llvm:: debuginfo:: DIScope ;
1413use rustc:: ty;
1514use rustc:: mir:: repr as mir;
1615use rustc:: mir:: tcx:: LvalueTy ;
1716use session:: config:: FullDebugInfo ;
1817use base;
1918use common:: { self , Block , BlockAndBuilder , CrateContext , FunctionContext , C_null } ;
20- use debuginfo:: { self , declare_local, DebugLoc , VariableAccess , VariableKind } ;
19+ use debuginfo:: { self , declare_local, DebugLoc , VariableAccess , VariableKind , FunctionDebugContext } ;
2120use machine;
2221use type_of;
2322
24- use syntax_pos:: DUMMY_SP ;
23+ use syntax_pos:: { DUMMY_SP , NO_EXPANSION , COMMAND_LINE_EXPN , BytePos } ;
2524use syntax:: parse:: token:: keywords;
2625
2726use std:: ops:: Deref ;
@@ -103,12 +102,67 @@ pub struct MirContext<'bcx, 'tcx:'bcx> {
103102 locals : IndexVec < mir:: Local , LocalRef < ' tcx > > ,
104103
105104 /// Debug information for MIR scopes.
106- scopes : IndexVec < mir:: VisibilityScope , DIScope >
105+ scopes : IndexVec < mir:: VisibilityScope , debuginfo :: MirDebugScope > ,
107106}
108107
109108impl < ' blk , ' tcx > MirContext < ' blk , ' tcx > {
110- pub fn debug_loc ( & self , source_info : mir:: SourceInfo ) -> DebugLoc {
111- DebugLoc :: ScopeAt ( self . scopes [ source_info. scope ] , source_info. span )
109+ pub fn debug_loc ( & mut self , source_info : mir:: SourceInfo ) -> DebugLoc {
110+ // Bail out if debug info emission is not enabled.
111+ match self . fcx . debug_context {
112+ FunctionDebugContext :: DebugInfoDisabled |
113+ FunctionDebugContext :: FunctionWithoutDebugInfo => {
114+ // Can't return DebugLoc::None here because intrinsic::trans_intrinsic_call()
115+ // relies on debug location to obtain span of the call site.
116+ return DebugLoc :: ScopeAt ( self . scopes [ source_info. scope ] . scope_metadata ,
117+ source_info. span ) ;
118+ }
119+ FunctionDebugContext :: RegularContext ( _) =>{ }
120+ }
121+
122+ // In order to have a good line stepping behavior in debugger, we overwrite debug
123+ // locations of macro expansions with that of the outermost expansion site
124+ // (unless the crate is being compiled with `-Z debug-macros`).
125+ if source_info. span . expn_id == NO_EXPANSION ||
126+ source_info. span . expn_id == COMMAND_LINE_EXPN ||
127+ self . fcx . ccx . sess ( ) . opts . debugging_opts . debug_macros {
128+
129+ let scope_metadata = self . scope_metadata_for_loc ( source_info. scope ,
130+ source_info. span . lo ) ;
131+ DebugLoc :: ScopeAt ( scope_metadata, source_info. span )
132+ } else {
133+ let cm = self . fcx . ccx . sess ( ) . codemap ( ) ;
134+ // Walk up the macro expansion chain until we reach a non-expanded span.
135+ let mut span = source_info. span ;
136+ while span. expn_id != NO_EXPANSION && span. expn_id != COMMAND_LINE_EXPN {
137+ if let Some ( callsite_span) = cm. with_expn_info ( span. expn_id ,
138+ |ei| ei. map ( |ei| ei. call_site . clone ( ) ) ) {
139+ span = callsite_span;
140+ } else {
141+ break ;
142+ }
143+ }
144+ let scope_metadata = self . scope_metadata_for_loc ( source_info. scope , span. lo ) ;
145+ // Use span of the outermost call site, while keeping the original lexical scope
146+ DebugLoc :: ScopeAt ( scope_metadata, span)
147+ }
148+ }
149+
150+ // DILocations inherit source file name from the parent DIScope. Due to macro expansions
151+ // it may so happen that the current span belongs to a different file than the DIScope
152+ // corresponding to span's containing visibility scope. If so, we need to create a DIScope
153+ // "extension" into that file.
154+ fn scope_metadata_for_loc ( & self , scope_id : mir:: VisibilityScope , pos : BytePos )
155+ -> llvm:: debuginfo:: DIScope {
156+ let scope_metadata = self . scopes [ scope_id] . scope_metadata ;
157+ if pos < self . scopes [ scope_id] . file_start_pos ||
158+ pos >= self . scopes [ scope_id] . file_end_pos {
159+ let cm = self . fcx . ccx . sess ( ) . codemap ( ) ;
160+ debuginfo:: extend_scope_to_file ( self . fcx . ccx ,
161+ scope_metadata,
162+ & cm. lookup_char_pos ( pos) . file )
163+ } else {
164+ scope_metadata
165+ }
112166 }
113167}
114168
@@ -155,16 +209,38 @@ pub fn trans_mir<'blk, 'tcx: 'blk>(fcx: &'blk FunctionContext<'blk, 'tcx>) {
155209 analyze:: cleanup_kinds ( bcx, & mir) )
156210 } ) ;
157211
212+ // Allocate a `Block` for every basic block
213+ let block_bcxs: IndexVec < mir:: BasicBlock , Block < ' blk , ' tcx > > =
214+ mir. basic_blocks ( ) . indices ( ) . map ( |bb| {
215+ if bb == mir:: START_BLOCK {
216+ fcx. new_block ( "start" , None )
217+ } else {
218+ fcx. new_block ( & format ! ( "{:?}" , bb) , None )
219+ }
220+ } ) . collect ( ) ;
221+
158222 // Compute debuginfo scopes from MIR scopes.
159223 let scopes = debuginfo:: create_mir_scopes ( fcx) ;
160224
225+ let mut mircx = MirContext {
226+ mir : mir. clone ( ) ,
227+ fcx : fcx,
228+ llpersonalityslot : None ,
229+ blocks : block_bcxs,
230+ unreachable_block : None ,
231+ cleanup_kinds : cleanup_kinds,
232+ landing_pads : IndexVec :: from_elem ( None , mir. basic_blocks ( ) ) ,
233+ scopes : scopes,
234+ locals : IndexVec :: new ( ) ,
235+ } ;
236+
161237 // Allocate variable and temp allocas
162- let locals = {
163- let args = arg_local_refs ( & bcx, & mir, & scopes, & lvalue_locals) ;
238+ mircx . locals = {
239+ let args = arg_local_refs ( & bcx, & mir, & mircx . scopes , & lvalue_locals) ;
164240 let vars = mir. var_decls . iter ( ) . enumerate ( ) . map ( |( i, decl) | {
165241 let ty = bcx. monomorphize ( & decl. ty ) ;
166- let scope = scopes[ decl. source_info . scope ] ;
167- let dbg = !scope . is_null ( ) && bcx. sess ( ) . opts . debuginfo == FullDebugInfo ;
242+ let debug_scope = mircx . scopes [ decl. source_info . scope ] ;
243+ let dbg = debug_scope . is_valid ( ) && bcx. sess ( ) . opts . debuginfo == FullDebugInfo ;
168244
169245 let local = mir. local_index ( & mir:: Lvalue :: Var ( mir:: Var :: new ( i) ) ) . unwrap ( ) ;
170246 if !lvalue_locals. contains ( local. index ( ) ) && !dbg {
@@ -173,11 +249,16 @@ pub fn trans_mir<'blk, 'tcx: 'blk>(fcx: &'blk FunctionContext<'blk, 'tcx>) {
173249
174250 let lvalue = LvalueRef :: alloca ( & bcx, ty, & decl. name . as_str ( ) ) ;
175251 if dbg {
176- bcx. with_block ( |bcx| {
177- declare_local ( bcx, decl. name , ty, scope,
178- VariableAccess :: DirectVariable { alloca : lvalue. llval } ,
179- VariableKind :: LocalVariable , decl. source_info . span ) ;
180- } ) ;
252+ let dbg_loc = mircx. debug_loc ( decl. source_info ) ;
253+ if let DebugLoc :: ScopeAt ( scope, span) = dbg_loc {
254+ bcx. with_block ( |bcx| {
255+ declare_local ( bcx, decl. name , ty, scope,
256+ VariableAccess :: DirectVariable { alloca : lvalue. llval } ,
257+ VariableKind :: LocalVariable , span) ;
258+ } ) ;
259+ } else {
260+ panic ! ( "Unexpected" ) ;
261+ }
181262 }
182263 LocalRef :: Lvalue ( lvalue)
183264 } ) ;
@@ -203,37 +284,15 @@ pub fn trans_mir<'blk, 'tcx: 'blk>(fcx: &'blk FunctionContext<'blk, 'tcx>) {
203284 } ) ) . collect ( )
204285 } ;
205286
206- // Allocate a `Block` for every basic block
207- let block_bcxs: IndexVec < mir:: BasicBlock , Block < ' blk , ' tcx > > =
208- mir. basic_blocks ( ) . indices ( ) . map ( |bb| {
209- if bb == mir:: START_BLOCK {
210- fcx. new_block ( "start" , None )
211- } else {
212- fcx. new_block ( & format ! ( "{:?}" , bb) , None )
213- }
214- } ) . collect ( ) ;
215-
216287 // Branch to the START block
217- let start_bcx = block_bcxs [ mir:: START_BLOCK ] ;
288+ let start_bcx = mircx . blocks [ mir:: START_BLOCK ] ;
218289 bcx. br ( start_bcx. llbb ) ;
219290
220291 // Up until here, IR instructions for this function have explicitly not been annotated with
221292 // source code location, so we don't step into call setup code. From here on, source location
222293 // emitting should be enabled.
223294 debuginfo:: start_emitting_source_locations ( fcx) ;
224295
225- let mut mircx = MirContext {
226- mir : mir. clone ( ) ,
227- fcx : fcx,
228- llpersonalityslot : None ,
229- blocks : block_bcxs,
230- unreachable_block : None ,
231- cleanup_kinds : cleanup_kinds,
232- landing_pads : IndexVec :: from_elem ( None , mir. basic_blocks ( ) ) ,
233- locals : locals,
234- scopes : scopes
235- } ;
236-
237296 let mut visited = BitVector :: new ( mir. basic_blocks ( ) . len ( ) ) ;
238297
239298 let mut rpo = traversal:: reverse_postorder ( & mir) ;
@@ -271,7 +330,7 @@ pub fn trans_mir<'blk, 'tcx: 'blk>(fcx: &'blk FunctionContext<'blk, 'tcx>) {
271330/// indirect.
272331fn arg_local_refs < ' bcx , ' tcx > ( bcx : & BlockAndBuilder < ' bcx , ' tcx > ,
273332 mir : & mir:: Mir < ' tcx > ,
274- scopes : & IndexVec < mir:: VisibilityScope , DIScope > ,
333+ scopes : & IndexVec < mir:: VisibilityScope , debuginfo :: MirDebugScope > ,
275334 lvalue_locals : & BitVector )
276335 -> Vec < LocalRef < ' tcx > > {
277336 let fcx = bcx. fcx ( ) ;
@@ -281,8 +340,8 @@ fn arg_local_refs<'bcx, 'tcx>(bcx: &BlockAndBuilder<'bcx, 'tcx>,
281340
282341 // Get the argument scope, if it exists and if we need it.
283342 let arg_scope = scopes[ mir:: ARGUMENT_VISIBILITY_SCOPE ] ;
284- let arg_scope = if ! arg_scope. is_null ( ) && bcx. sess ( ) . opts . debuginfo == FullDebugInfo {
285- Some ( arg_scope)
343+ let arg_scope = if arg_scope. is_valid ( ) && bcx. sess ( ) . opts . debuginfo == FullDebugInfo {
344+ Some ( arg_scope. scope_metadata )
286345 } else {
287346 None
288347 } ;
0 commit comments