From 5059a3c7d4afd00458d5bd2f033a0b9c91bd8bf8 Mon Sep 17 00:00:00 2001 From: Eduard-Mihai Burtescu Date: Wed, 4 Sep 2019 19:44:58 +0300 Subject: [PATCH] rustc_codegen_ssa: move debuginfo-related things to a new mir::debuginfo module. --- .../debuginfo/create_scope_map.rs | 12 +- src/librustc_codegen_llvm/debuginfo/mod.rs | 11 +- .../debuginfo/source_loc.rs | 2 +- src/librustc_codegen_ssa/debuginfo/mod.rs | 82 +--------- src/librustc_codegen_ssa/mir/debuginfo.rs | 145 ++++++++++++++++++ src/librustc_codegen_ssa/mir/mod.rs | 65 +------- src/librustc_codegen_ssa/traits/debuginfo.rs | 4 +- 7 files changed, 165 insertions(+), 156 deletions(-) create mode 100644 src/librustc_codegen_ssa/mir/debuginfo.rs diff --git a/src/librustc_codegen_llvm/debuginfo/create_scope_map.rs b/src/librustc_codegen_llvm/debuginfo/create_scope_map.rs index bdb7467a1010c..abd6827680e06 100644 --- a/src/librustc_codegen_llvm/debuginfo/create_scope_map.rs +++ b/src/librustc_codegen_llvm/debuginfo/create_scope_map.rs @@ -1,4 +1,4 @@ -use rustc_codegen_ssa::debuginfo::{FunctionDebugContext, FunctionDebugContextData, MirDebugScope}; +use rustc_codegen_ssa::mir::debuginfo::{FunctionDebugContext, FunctionDebugContextData, DebugScope}; use super::metadata::file_metadata; use super::utils::{DIB, span_start}; @@ -22,8 +22,8 @@ pub fn create_mir_scopes( cx: &CodegenCx<'ll, '_>, mir: &Body<'_>, debug_context: &FunctionDebugContext<&'ll DISubprogram>, -) -> IndexVec> { - let null_scope = MirDebugScope { +) -> IndexVec> { + let null_scope = DebugScope { scope_metadata: None, file_start_pos: BytePos(0), file_end_pos: BytePos(0) @@ -59,7 +59,7 @@ fn make_mir_scope(cx: &CodegenCx<'ll, '_>, has_variables: &BitSet, debug_context: &FunctionDebugContextData<&'ll DISubprogram>, scope: SourceScope, - scopes: &mut IndexVec>) { + scopes: &mut IndexVec>) { if scopes[scope].is_valid() { return; } @@ -71,7 +71,7 @@ fn make_mir_scope(cx: &CodegenCx<'ll, '_>, } else { // The root is the function itself. let loc = span_start(cx, mir.span); - scopes[scope] = MirDebugScope { + scopes[scope] = DebugScope { scope_metadata: Some(debug_context.fn_metadata), file_start_pos: loc.file.start_pos, file_end_pos: loc.file.end_pos, @@ -105,7 +105,7 @@ fn make_mir_scope(cx: &CodegenCx<'ll, '_>, loc.line as c_uint, loc.col.to_usize() as c_uint)) }; - scopes[scope] = MirDebugScope { + scopes[scope] = DebugScope { scope_metadata, file_start_pos: loc.file.start_pos, file_end_pos: loc.file.end_pos, diff --git a/src/librustc_codegen_llvm/debuginfo/mod.rs b/src/librustc_codegen_llvm/debuginfo/mod.rs index 5b59f4c28de20..d7706b3251bb0 100644 --- a/src/librustc_codegen_llvm/debuginfo/mod.rs +++ b/src/librustc_codegen_llvm/debuginfo/mod.rs @@ -1,8 +1,8 @@ // See doc.rs for documentation. mod doc; -use rustc_codegen_ssa::debuginfo::VariableAccess::*; -use rustc_codegen_ssa::debuginfo::VariableKind::*; +use rustc_codegen_ssa::mir::debuginfo::VariableAccess::*; +use rustc_codegen_ssa::mir::debuginfo::VariableKind::*; use self::utils::{DIB, span_start, create_DIArray, is_node_local_to_unit}; use self::namespace::mangled_name_of_instance; @@ -27,8 +27,9 @@ use rustc::session::config::{self, DebugInfo}; use rustc::util::nodemap::{DefIdMap, FxHashMap, FxHashSet}; use rustc_data_structures::small_c_str::SmallCStr; use rustc_index::vec::IndexVec; -use rustc_codegen_ssa::debuginfo::{FunctionDebugContext, MirDebugScope, VariableAccess, - VariableKind, FunctionDebugContextData, type_names}; +use rustc_codegen_ssa::debuginfo::type_names; +use rustc_codegen_ssa::mir::debuginfo::{FunctionDebugContext, DebugScope, VariableAccess, + VariableKind, FunctionDebugContextData}; use libc::c_uint; use std::cell::RefCell; @@ -553,7 +554,7 @@ impl DebugInfoMethods<'tcx> for CodegenCx<'ll, 'tcx> { &self, mir: &mir::Body<'_>, debug_context: &mut FunctionDebugContext<&'ll DISubprogram>, - ) -> IndexVec> { + ) -> IndexVec> { create_scope_map::create_mir_scopes(self, mir, debug_context) } diff --git a/src/librustc_codegen_llvm/debuginfo/source_loc.rs b/src/librustc_codegen_llvm/debuginfo/source_loc.rs index dec93a65dbaf4..014c1d285d285 100644 --- a/src/librustc_codegen_llvm/debuginfo/source_loc.rs +++ b/src/librustc_codegen_llvm/debuginfo/source_loc.rs @@ -2,7 +2,7 @@ use self::InternalDebugLocation::*; use super::utils::{debug_context, span_start}; use super::metadata::UNKNOWN_COLUMN_NUMBER; -use rustc_codegen_ssa::debuginfo::FunctionDebugContext; +use rustc_codegen_ssa::mir::debuginfo::FunctionDebugContext; use crate::llvm; use crate::llvm::debuginfo::DIScope; diff --git a/src/librustc_codegen_ssa/debuginfo/mod.rs b/src/librustc_codegen_ssa/debuginfo/mod.rs index c9b1c0260e8c3..d1a0cf78d6a2e 100644 --- a/src/librustc_codegen_ssa/debuginfo/mod.rs +++ b/src/librustc_codegen_ssa/debuginfo/mod.rs @@ -1,82 +1,2 @@ -use syntax_pos::{BytePos, Span}; -use rustc::hir::def_id::CrateNum; - +// FIXME(eddyb) find a place for this (or a way to replace it). pub mod type_names; - -pub enum FunctionDebugContext { - RegularContext(FunctionDebugContextData), - DebugInfoDisabled, - FunctionWithoutDebugInfo, -} - -impl FunctionDebugContext { - pub fn get_ref(&self, span: Span) -> &FunctionDebugContextData { - match *self { - FunctionDebugContext::RegularContext(ref data) => data, - FunctionDebugContext::DebugInfoDisabled => { - span_bug!( - span, - "debuginfo: Error trying to access FunctionDebugContext \ - although debug info is disabled!", - ); - } - FunctionDebugContext::FunctionWithoutDebugInfo => { - span_bug!( - span, - "debuginfo: Error trying to access FunctionDebugContext \ - for function that should be ignored by debug info!", - ); - } - } - } -} - -/// Enables emitting source locations for the given functions. -/// -/// Since we don't want source locations to be emitted for the function prelude, -/// they are disabled when beginning to codegen a new function. This functions -/// switches source location emitting on and must therefore be called before the -/// first real statement/expression of the function is codegened. -pub fn start_emitting_source_locations(dbg_context: &mut FunctionDebugContext) { - match *dbg_context { - FunctionDebugContext::RegularContext(ref mut data) => { - data.source_locations_enabled = true; - }, - _ => { /* safe to ignore */ } - } -} - -pub struct FunctionDebugContextData { - pub fn_metadata: D, - pub source_locations_enabled: bool, - pub defining_crate: CrateNum, -} - -pub enum VariableAccess<'a, V> { - // The llptr given is an alloca containing the variable's value - DirectVariable { alloca: V }, - // The llptr given is an alloca containing the start of some pointer chain - // leading to the variable's content. - IndirectVariable { alloca: V, address_operations: &'a [i64] } -} - -pub enum VariableKind { - ArgumentVariable(usize /*index*/), - LocalVariable, -} - - -#[derive(Clone, Copy, Debug)] -pub struct MirDebugScope { - pub scope_metadata: Option, - // Start and end offsets of the file to which this DIScope belongs. - // These are used to quickly determine whether some span refers to the same file. - pub file_start_pos: BytePos, - pub file_end_pos: BytePos, -} - -impl MirDebugScope { - pub fn is_valid(&self) -> bool { - !self.scope_metadata.is_none() - } -} diff --git a/src/librustc_codegen_ssa/mir/debuginfo.rs b/src/librustc_codegen_ssa/mir/debuginfo.rs new file mode 100644 index 0000000000000..a253523f18120 --- /dev/null +++ b/src/librustc_codegen_ssa/mir/debuginfo.rs @@ -0,0 +1,145 @@ +use rustc::hir::def_id::CrateNum; +use rustc::mir; +use crate::traits::*; + +use syntax_pos::{DUMMY_SP, BytePos, Span}; + +use super::FunctionCx; + +pub enum FunctionDebugContext { + RegularContext(FunctionDebugContextData), + DebugInfoDisabled, + FunctionWithoutDebugInfo, +} + +impl FunctionDebugContext { + pub fn get_ref(&self, span: Span) -> &FunctionDebugContextData { + match *self { + FunctionDebugContext::RegularContext(ref data) => data, + FunctionDebugContext::DebugInfoDisabled => { + span_bug!( + span, + "debuginfo: Error trying to access FunctionDebugContext \ + although debug info is disabled!", + ); + } + FunctionDebugContext::FunctionWithoutDebugInfo => { + span_bug!( + span, + "debuginfo: Error trying to access FunctionDebugContext \ + for function that should be ignored by debug info!", + ); + } + } + } +} + +/// Enables emitting source locations for the given functions. +/// +/// Since we don't want source locations to be emitted for the function prelude, +/// they are disabled when beginning to codegen a new function. This functions +/// switches source location emitting on and must therefore be called before the +/// first real statement/expression of the function is codegened. +pub fn start_emitting_source_locations(dbg_context: &mut FunctionDebugContext) { + match *dbg_context { + FunctionDebugContext::RegularContext(ref mut data) => { + data.source_locations_enabled = true; + }, + _ => { /* safe to ignore */ } + } +} + +pub struct FunctionDebugContextData { + pub fn_metadata: D, + pub source_locations_enabled: bool, + pub defining_crate: CrateNum, +} + +pub enum VariableAccess<'a, V> { + // The llptr given is an alloca containing the variable's value + DirectVariable { alloca: V }, + // The llptr given is an alloca containing the start of some pointer chain + // leading to the variable's content. + IndirectVariable { alloca: V, address_operations: &'a [i64] } +} + +pub enum VariableKind { + ArgumentVariable(usize /*index*/), + LocalVariable, +} + + +#[derive(Clone, Copy, Debug)] +pub struct DebugScope { + pub scope_metadata: Option, + // Start and end offsets of the file to which this DIScope belongs. + // These are used to quickly determine whether some span refers to the same file. + pub file_start_pos: BytePos, + pub file_end_pos: BytePos, +} + +impl DebugScope { + pub fn is_valid(&self) -> bool { + !self.scope_metadata.is_none() + } +} + +impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { + pub fn set_debug_loc( + &mut self, + bx: &mut Bx, + source_info: mir::SourceInfo + ) { + let (scope, span) = self.debug_loc(source_info); + bx.set_source_location(&mut self.debug_context, scope, span); + } + + pub fn debug_loc(&self, source_info: mir::SourceInfo) -> (Option, Span) { + // Bail out if debug info emission is not enabled. + match self.debug_context { + FunctionDebugContext::DebugInfoDisabled | + FunctionDebugContext::FunctionWithoutDebugInfo => { + return (self.scopes[source_info.scope].scope_metadata, source_info.span); + } + FunctionDebugContext::RegularContext(_) =>{} + } + + // In order to have a good line stepping behavior in debugger, we overwrite debug + // locations of macro expansions with that of the outermost expansion site + // (unless the crate is being compiled with `-Z debug-macros`). + if !source_info.span.from_expansion() || + self.cx.sess().opts.debugging_opts.debug_macros { + let scope = self.scope_metadata_for_loc(source_info.scope, source_info.span.lo()); + (scope, source_info.span) + } else { + // Walk up the macro expansion chain until we reach a non-expanded span. + // We also stop at the function body level because no line stepping can occur + // at the level above that. + let span = syntax_pos::hygiene::walk_chain(source_info.span, self.mir.span.ctxt()); + let scope = self.scope_metadata_for_loc(source_info.scope, span.lo()); + // Use span of the outermost expansion site, while keeping the original lexical scope. + (scope, span) + } + } + + // DILocations inherit source file name from the parent DIScope. Due to macro expansions + // it may so happen that the current span belongs to a different file than the DIScope + // corresponding to span's containing source scope. If so, we need to create a DIScope + // "extension" into that file. + fn scope_metadata_for_loc(&self, scope_id: mir::SourceScope, pos: BytePos) + -> Option { + let scope_metadata = self.scopes[scope_id].scope_metadata; + if pos < self.scopes[scope_id].file_start_pos || + pos >= self.scopes[scope_id].file_end_pos { + let sm = self.cx.sess().source_map(); + let defining_crate = self.debug_context.get_ref(DUMMY_SP).defining_crate; + Some(self.cx.extend_scope_to_file( + scope_metadata.unwrap(), + &sm.lookup_char_pos(pos).file, + defining_crate + )) + } else { + scope_metadata + } + } +} diff --git a/src/librustc_codegen_ssa/mir/mod.rs b/src/librustc_codegen_ssa/mir/mod.rs index 1a2e796a5b7be..650584fbdf7bd 100644 --- a/src/librustc_codegen_ssa/mir/mod.rs +++ b/src/librustc_codegen_ssa/mir/mod.rs @@ -5,10 +5,9 @@ use rustc::session::config::DebugInfo; use rustc_target::abi::call::{FnType, PassMode}; use rustc_target::abi::{Variants, VariantIdx}; use crate::base; -use crate::debuginfo::{self, VariableAccess, VariableKind, FunctionDebugContext}; use crate::traits::*; -use syntax_pos::{DUMMY_SP, BytePos, Span}; +use syntax_pos::DUMMY_SP; use syntax::symbol::kw; use std::iter; @@ -17,6 +16,7 @@ use rustc_index::bit_set::BitSet; use rustc_index::vec::IndexVec; use self::analyze::CleanupKind; +use self::debuginfo::{VariableAccess, VariableKind, FunctionDebugContext}; use self::place::PlaceRef; use rustc::mir::traversal; @@ -80,7 +80,7 @@ pub struct FunctionCx<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> { locals: IndexVec>, /// Debug information for MIR scopes. - scopes: IndexVec>, + scopes: IndexVec>, } impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { @@ -93,64 +93,6 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { value, ) } - - pub fn set_debug_loc( - &mut self, - bx: &mut Bx, - source_info: mir::SourceInfo - ) { - let (scope, span) = self.debug_loc(source_info); - bx.set_source_location(&mut self.debug_context, scope, span); - } - - pub fn debug_loc(&self, source_info: mir::SourceInfo) -> (Option, Span) { - // Bail out if debug info emission is not enabled. - match self.debug_context { - FunctionDebugContext::DebugInfoDisabled | - FunctionDebugContext::FunctionWithoutDebugInfo => { - return (self.scopes[source_info.scope].scope_metadata, source_info.span); - } - FunctionDebugContext::RegularContext(_) =>{} - } - - // In order to have a good line stepping behavior in debugger, we overwrite debug - // locations of macro expansions with that of the outermost expansion site - // (unless the crate is being compiled with `-Z debug-macros`). - if !source_info.span.from_expansion() || - self.cx.sess().opts.debugging_opts.debug_macros { - let scope = self.scope_metadata_for_loc(source_info.scope, source_info.span.lo()); - (scope, source_info.span) - } else { - // Walk up the macro expansion chain until we reach a non-expanded span. - // We also stop at the function body level because no line stepping can occur - // at the level above that. - let span = syntax_pos::hygiene::walk_chain(source_info.span, self.mir.span.ctxt()); - let scope = self.scope_metadata_for_loc(source_info.scope, span.lo()); - // Use span of the outermost expansion site, while keeping the original lexical scope. - (scope, span) - } - } - - // DILocations inherit source file name from the parent DIScope. Due to macro expansions - // it may so happen that the current span belongs to a different file than the DIScope - // corresponding to span's containing source scope. If so, we need to create a DIScope - // "extension" into that file. - fn scope_metadata_for_loc(&self, scope_id: mir::SourceScope, pos: BytePos) - -> Option { - let scope_metadata = self.scopes[scope_id].scope_metadata; - if pos < self.scopes[scope_id].file_start_pos || - pos >= self.scopes[scope_id].file_end_pos { - let sm = self.cx.sess().source_map(); - let defining_crate = self.debug_context.get_ref(DUMMY_SP).defining_crate; - Some(self.cx.extend_scope_to_file( - scope_metadata.unwrap(), - &sm.lookup_char_pos(pos).file, - defining_crate - )) - } else { - scope_metadata - } - } } enum LocalRef<'tcx, V> { @@ -721,6 +663,7 @@ fn arg_local_refs<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>( mod analyze; mod block; pub mod constant; +pub mod debuginfo; pub mod place; pub mod operand; mod rvalue; diff --git a/src/librustc_codegen_ssa/traits/debuginfo.rs b/src/librustc_codegen_ssa/traits/debuginfo.rs index 989e6cf9dcaf1..244fe845d7ddf 100644 --- a/src/librustc_codegen_ssa/traits/debuginfo.rs +++ b/src/librustc_codegen_ssa/traits/debuginfo.rs @@ -1,5 +1,5 @@ use super::BackendTypes; -use crate::debuginfo::{FunctionDebugContext, MirDebugScope, VariableAccess, VariableKind}; +use crate::mir::debuginfo::{FunctionDebugContext, DebugScope, VariableAccess, VariableKind}; use rustc::hir::def_id::CrateNum; use rustc::mir; use rustc::ty::{self, Ty, Instance}; @@ -28,7 +28,7 @@ pub trait DebugInfoMethods<'tcx>: BackendTypes { &self, mir: &mir::Body<'_>, debug_context: &mut FunctionDebugContext, - ) -> IndexVec>; + ) -> IndexVec>; fn extend_scope_to_file( &self, scope_metadata: Self::DIScope,