1 use super::metadata::file_metadata;
2 use super::utils::{span_start, DIB};
3 use rustc_codegen_ssa::mir::debuginfo::{DebugScope, FunctionDebugContext};
5 use crate::common::CodegenCx;
7 use crate::llvm::debuginfo::{DIScope, DISubprogram};
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);
40 cx: &CodegenCx<'ll, '_>,
42 fn_metadata: &'ll DISubprogram,
43 has_variables: &BitSet<SourceScope>,
44 debug_context: &mut FunctionDebugContext<&'ll DISubprogram>,
47 if debug_context.scopes[scope].is_valid() {
51 let scope_data = &mir.source_scopes[scope];
52 let parent_scope = if let Some(parent) = scope_data.parent_scope {
53 make_mir_scope(cx, mir, fn_metadata, has_variables, debug_context, parent);
54 debug_context.scopes[parent]
56 // The root is the function itself.
57 let loc = span_start(cx, mir.span);
58 debug_context.scopes[scope] = DebugScope {
59 scope_metadata: Some(fn_metadata),
60 file_start_pos: loc.file.start_pos,
61 file_end_pos: loc.file.end_pos,
66 if !has_variables.contains(scope) {
67 // Do not create a DIScope if there are no variables
68 // defined in this MIR Scope, to avoid debuginfo bloat.
70 // However, we don't skip creating a nested scope if
71 // our parent is the root, because we might want to
72 // put arguments in the root and not have shadowing.
73 if parent_scope.scope_metadata.unwrap() != fn_metadata {
74 debug_context.scopes[scope] = parent_scope;
79 let loc = span_start(cx, scope_data.span);
80 let file_metadata = file_metadata(cx, &loc.file.name, 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,
91 debug_context.scopes[scope] = DebugScope {
93 file_start_pos: loc.file.start_pos,
94 file_end_pos: loc.file.end_pos,