summaryrefslogtreecommitdiff
path: root/src/librustc_codegen_llvm/debuginfo/create_scope_map.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/librustc_codegen_llvm/debuginfo/create_scope_map.rs')
-rw-r--r--src/librustc_codegen_llvm/debuginfo/create_scope_map.rs82
1 files changed, 56 insertions, 26 deletions
diff --git a/src/librustc_codegen_llvm/debuginfo/create_scope_map.rs b/src/librustc_codegen_llvm/debuginfo/create_scope_map.rs
index 09422f4ec37..e36311b82c3 100644
--- a/src/librustc_codegen_llvm/debuginfo/create_scope_map.rs
+++ b/src/librustc_codegen_llvm/debuginfo/create_scope_map.rs
@@ -1,21 +1,27 @@
use super::metadata::{file_metadata, UNKNOWN_COLUMN_NUMBER, UNKNOWN_LINE_NUMBER};
use super::utils::DIB;
use rustc_codegen_ssa::mir::debuginfo::{DebugScope, FunctionDebugContext};
+use rustc_codegen_ssa::traits::*;
+use crate::abi::FnAbi;
use crate::common::CodegenCx;
use crate::llvm;
-use crate::llvm::debuginfo::{DIScope, DISubprogram};
+use crate::llvm::debuginfo::{DILocation, DIScope};
use rustc::mir::{Body, SourceScope};
+use rustc::ty::layout::FnAbiExt;
+use rustc::ty::{self, Instance};
use rustc_index::bit_set::BitSet;
use rustc_index::vec::Idx;
/// Produces DIScope DIEs for each MIR Scope which has variables defined in it.
+// FIXME(eddyb) almost all of this should be in `rustc_codegen_ssa::mir::debuginfo`.
pub fn compute_mir_scopes(
- cx: &CodegenCx<'ll, '_>,
- mir: &Body<'_>,
- fn_metadata: &'ll DISubprogram,
- debug_context: &mut FunctionDebugContext<&'ll DIScope>,
+ cx: &CodegenCx<'ll, 'tcx>,
+ instance: Instance<'tcx>,
+ mir: &Body<'tcx>,
+ fn_dbg_scope: &'ll DIScope,
+ debug_context: &mut FunctionDebugContext<&'ll DIScope, &'ll DILocation>,
) {
// Find all the scopes with variables defined in them.
let mut has_variables = BitSet::new_empty(mir.source_scopes.len());
@@ -28,58 +34,82 @@ pub fn compute_mir_scopes(
// Instantiate all scopes.
for idx in 0..mir.source_scopes.len() {
let scope = SourceScope::new(idx);
- make_mir_scope(cx, &mir, fn_metadata, &has_variables, debug_context, scope);
+ make_mir_scope(cx, instance, &mir, fn_dbg_scope, &has_variables, debug_context, scope);
}
}
fn make_mir_scope(
- cx: &CodegenCx<'ll, '_>,
- mir: &Body<'_>,
- fn_metadata: &'ll DISubprogram,
+ cx: &CodegenCx<'ll, 'tcx>,
+ instance: Instance<'tcx>,
+ mir: &Body<'tcx>,
+ fn_dbg_scope: &'ll DIScope,
has_variables: &BitSet<SourceScope>,
- debug_context: &mut FunctionDebugContext<&'ll DISubprogram>,
+ debug_context: &mut FunctionDebugContext<&'ll DIScope, &'ll DILocation>,
scope: SourceScope,
) {
- if debug_context.scopes[scope].is_valid() {
+ if debug_context.scopes[scope].dbg_scope.is_some() {
return;
}
let scope_data = &mir.source_scopes[scope];
let parent_scope = if let Some(parent) = scope_data.parent_scope {
- make_mir_scope(cx, mir, fn_metadata, has_variables, debug_context, parent);
+ make_mir_scope(cx, instance, mir, fn_dbg_scope, has_variables, debug_context, parent);
debug_context.scopes[parent]
} else {
// The root is the function itself.
let loc = cx.lookup_debug_loc(mir.span.lo());
debug_context.scopes[scope] = DebugScope {
- scope_metadata: Some(fn_metadata),
+ dbg_scope: Some(fn_dbg_scope),
+ inlined_at: None,
file_start_pos: loc.file.start_pos,
file_end_pos: loc.file.end_pos,
};
return;
};
- if !has_variables.contains(scope) {
- // Do not create a DIScope if there are no variables
- // defined in this MIR Scope, to avoid debuginfo bloat.
+ if !has_variables.contains(scope) && scope_data.inlined.is_none() {
+ // Do not create a DIScope if there are no variables defined in this
+ // MIR `SourceScope`, and it's not `inlined`, to avoid debuginfo bloat.
debug_context.scopes[scope] = parent_scope;
return;
}
let loc = cx.lookup_debug_loc(scope_data.span.lo());
- let file_metadata = file_metadata(cx, &loc.file.name, debug_context.defining_crate);
+ let file_metadata = file_metadata(cx, &loc.file);
- let scope_metadata = unsafe {
- Some(llvm::LLVMRustDIBuilderCreateLexicalBlock(
- DIB(cx),
- parent_scope.scope_metadata.unwrap(),
- file_metadata,
- loc.line.unwrap_or(UNKNOWN_LINE_NUMBER),
- loc.col.unwrap_or(UNKNOWN_COLUMN_NUMBER),
- ))
+ let dbg_scope = match scope_data.inlined {
+ Some((callee, _)) => {
+ // FIXME(eddyb) this would be `self.monomorphize(&callee)`
+ // if this is moved to `rustc_codegen_ssa::mir::debuginfo`.
+ let callee = cx.tcx.subst_and_normalize_erasing_regions(
+ instance.substs,
+ ty::ParamEnv::reveal_all(),
+ &callee,
+ );
+ let callee_fn_abi = FnAbi::of_instance(cx, callee, &[]);
+ cx.dbg_scope_fn(callee, &callee_fn_abi, None)
+ }
+ None => unsafe {
+ llvm::LLVMRustDIBuilderCreateLexicalBlock(
+ DIB(cx),
+ parent_scope.dbg_scope.unwrap(),
+ file_metadata,
+ loc.line.unwrap_or(UNKNOWN_LINE_NUMBER),
+ loc.col.unwrap_or(UNKNOWN_COLUMN_NUMBER),
+ )
+ },
};
+
+ let inlined_at = scope_data.inlined.map(|(_, callsite_span)| {
+ // FIXME(eddyb) this doesn't account for the macro-related
+ // `Span` fixups that `rustc_codegen_ssa::mir::debuginfo` does.
+ let callsite_scope = parent_scope.adjust_dbg_scope_for_span(cx, callsite_span);
+ cx.dbg_loc(callsite_scope, parent_scope.inlined_at, callsite_span)
+ });
+
debug_context.scopes[scope] = DebugScope {
- scope_metadata,
+ dbg_scope: Some(dbg_scope),
+ inlined_at: inlined_at.or(parent_scope.inlined_at),
file_start_pos: loc.file.start_pos,
file_end_pos: loc.file.end_pos,
};