]> git.lizzy.rs Git - rust.git/blob - src/librustc_codegen_llvm/debuginfo/create_scope_map.rs
Rollup merge of #69771 - GuillaumeGomez:cleanup-e0390, r=Dylan-DPC
[rust.git] / src / librustc_codegen_llvm / debuginfo / create_scope_map.rs
1 use super::metadata::file_metadata;
2 use super::utils::{span_start, DIB};
3 use rustc_codegen_ssa::mir::debuginfo::{DebugScope, FunctionDebugContext};
4
5 use crate::common::CodegenCx;
6 use crate::llvm;
7 use crate::llvm::debuginfo::{DIScope, DISubprogram};
8 use rustc::mir::{Body, SourceScope};
9
10 use libc::c_uint;
11
12 use rustc_span::Pos;
13
14 use rustc_index::bit_set::BitSet;
15 use rustc_index::vec::Idx;
16
17 /// Produces DIScope DIEs for each MIR Scope which has variables defined in it.
18 pub fn compute_mir_scopes(
19     cx: &CodegenCx<'ll, '_>,
20     mir: &Body<'_>,
21     fn_metadata: &'ll DISubprogram,
22     debug_context: &mut FunctionDebugContext<&'ll DIScope>,
23 ) {
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);
30     }
31
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);
36     }
37 }
38
39 fn make_mir_scope(
40     cx: &CodegenCx<'ll, '_>,
41     mir: &Body<'_>,
42     fn_metadata: &'ll DISubprogram,
43     has_variables: &BitSet<SourceScope>,
44     debug_context: &mut FunctionDebugContext<&'ll DISubprogram>,
45     scope: SourceScope,
46 ) {
47     if debug_context.scopes[scope].is_valid() {
48         return;
49     }
50
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]
55     } else {
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,
62         };
63         return;
64     };
65
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.
69         debug_context.scopes[scope] = parent_scope;
70         return;
71     }
72
73     let loc = span_start(cx, scope_data.span);
74     let file_metadata = file_metadata(cx, &loc.file.name, debug_context.defining_crate);
75
76     let scope_metadata = unsafe {
77         Some(llvm::LLVMRustDIBuilderCreateLexicalBlock(
78             DIB(cx),
79             parent_scope.scope_metadata.unwrap(),
80             file_metadata,
81             loc.line as c_uint,
82             loc.col.to_usize() as c_uint,
83         ))
84     };
85     debug_context.scopes[scope] = DebugScope {
86         scope_metadata,
87         file_start_pos: loc.file.start_pos,
88         file_end_pos: loc.file.end_pos,
89     };
90 }