1 use rustc_codegen_ssa::mir::debuginfo::{FunctionDebugContext, DebugScope};
2 use super::metadata::file_metadata;
3 use super::utils::{DIB, span_start};
6 use crate::llvm::debuginfo::{DIScope, DISubprogram};
7 use crate::common::CodegenCx;
8 use rustc::mir::{Body, SourceScope};
14 use rustc_index::bit_set::BitSet;
15 use rustc_index::vec::Idx;
17 /// Produces DIScope DIEs for each MIR Scope which has variables defined in it.
18 pub fn compute_mir_scopes(
19 cx: &CodegenCx<'ll, '_>,
21 fn_metadata: &'ll DISubprogram,
22 debug_context: &mut FunctionDebugContext<&'ll DIScope>,
24 // Find all the scopes with variables defined in them.
25 let mut has_variables = BitSet::new_empty(mir.source_scopes.len());
26 // FIXME(eddyb) take into account that arguments always have debuginfo,
27 // irrespective of their name (assuming full debuginfo is enabled).
28 for var_debug_info in &mir.var_debug_info {
29 has_variables.insert(var_debug_info.source_info.scope);
32 // Instantiate all scopes.
33 for idx in 0..mir.source_scopes.len() {
34 let scope = SourceScope::new(idx);
35 make_mir_scope(cx, &mir, fn_metadata, &has_variables, debug_context, scope);
39 fn make_mir_scope(cx: &CodegenCx<'ll, '_>,
41 fn_metadata: &'ll DISubprogram,
42 has_variables: &BitSet<SourceScope>,
43 debug_context: &mut FunctionDebugContext<&'ll DISubprogram>,
45 if debug_context.scopes[scope].is_valid() {
49 let scope_data = &mir.source_scopes[scope];
50 let parent_scope = if let Some(parent) = scope_data.parent_scope {
51 make_mir_scope(cx, mir, fn_metadata, has_variables, debug_context, parent);
52 debug_context.scopes[parent]
54 // The root is the function itself.
55 let loc = span_start(cx, mir.span);
56 debug_context.scopes[scope] = DebugScope {
57 scope_metadata: Some(fn_metadata),
58 file_start_pos: loc.file.start_pos,
59 file_end_pos: loc.file.end_pos,
64 if !has_variables.contains(scope) {
65 // Do not create a DIScope if there are no variables
66 // defined in this MIR Scope, to avoid debuginfo bloat.
68 // However, we don't skip creating a nested scope if
69 // our parent is the root, because we might want to
70 // put arguments in the root and not have shadowing.
71 if parent_scope.scope_metadata.unwrap() != fn_metadata {
72 debug_context.scopes[scope] = parent_scope;
77 let loc = span_start(cx, scope_data.span);
78 let file_metadata = file_metadata(cx,
80 debug_context.defining_crate);
82 let scope_metadata = unsafe {
83 Some(llvm::LLVMRustDIBuilderCreateLexicalBlock(
85 parent_scope.scope_metadata.unwrap(),
88 loc.col.to_usize() as c_uint))
90 debug_context.scopes[scope] = DebugScope {
92 file_start_pos: loc.file.start_pos,
93 file_end_pos: loc.file.end_pos,