]> git.proxmox.com Git - rustc.git/blame - src/librustc_codegen_llvm/debuginfo/create_scope_map.rs
New upstream version 1.41.1+dfsg1
[rustc.git] / src / librustc_codegen_llvm / debuginfo / create_scope_map.rs
CommitLineData
e74abb32 1use rustc_codegen_ssa::mir::debuginfo::{FunctionDebugContext, DebugScope};
d9579d0f 2use super::metadata::file_metadata;
a7813a04 3use super::utils::{DIB, span_start};
d9579d0f 4
9fa01778
XL
5use crate::llvm;
6use crate::llvm::debuginfo::{DIScope, DISubprogram};
7use crate::common::CodegenCx;
dc9dc135 8use rustc::mir::{Body, SourceScope};
d9579d0f
AL
9
10use libc::c_uint;
a7813a04 11
9e0c209e 12use syntax_pos::Pos;
e9174d1e 13
e74abb32
XL
14use rustc_index::bit_set::BitSet;
15use rustc_index::vec::Idx;
d9579d0f 16
9fa01778 17/// Produces DIScope DIEs for each MIR Scope which has variables defined in it.
e74abb32 18pub fn compute_mir_scopes(
b7449926 19 cx: &CodegenCx<'ll, '_>,
dc9dc135 20 mir: &Body<'_>,
e74abb32
XL
21 fn_metadata: &'ll DISubprogram,
22 debug_context: &mut FunctionDebugContext<&'ll DIScope>,
23) {
a7813a04 24 // Find all the scopes with variables defined in them.
0bf4aa26 25 let mut has_variables = BitSet::new_empty(mir.source_scopes.len());
e74abb32
XL
26 // FIXME(eddyb) take into account that arguments always have debuginfo,
27 // irrespective of their name (assuming full debuginfo is enabled).
60c5eb7d
XL
28 for var_debug_info in &mir.var_debug_info {
29 has_variables.insert(var_debug_info.source_info.scope);
a7813a04
XL
30 }
31
32 // Instantiate all scopes.
94b46f34
XL
33 for idx in 0..mir.source_scopes.len() {
34 let scope = SourceScope::new(idx);
e74abb32 35 make_mir_scope(cx, &mir, fn_metadata, &has_variables, debug_context, scope);
a7813a04 36 }
a7813a04
XL
37}
38
b7449926 39fn make_mir_scope(cx: &CodegenCx<'ll, '_>,
dc9dc135 40 mir: &Body<'_>,
e74abb32 41 fn_metadata: &'ll DISubprogram,
0bf4aa26 42 has_variables: &BitSet<SourceScope>,
e74abb32
XL
43 debug_context: &mut FunctionDebugContext<&'ll DISubprogram>,
44 scope: SourceScope) {
45 if debug_context.scopes[scope].is_valid() {
a7813a04
XL
46 return;
47 }
48
94b46f34 49 let scope_data = &mir.source_scopes[scope];
a7813a04 50 let parent_scope = if let Some(parent) = scope_data.parent_scope {
e74abb32
XL
51 make_mir_scope(cx, mir, fn_metadata, has_variables, debug_context, parent);
52 debug_context.scopes[parent]
a7813a04
XL
53 } else {
54 // The root is the function itself.
2c00a5a8 55 let loc = span_start(cx, mir.span);
e74abb32
XL
56 debug_context.scopes[scope] = DebugScope {
57 scope_metadata: Some(fn_metadata),
9e0c209e
SL
58 file_start_pos: loc.file.start_pos,
59 file_end_pos: loc.file.end_pos,
60 };
a7813a04
XL
61 return;
62 };
63
8faf50e0 64 if !has_variables.contains(scope) {
a7813a04
XL
65 // Do not create a DIScope if there are no variables
66 // defined in this MIR Scope, to avoid debuginfo bloat.
67
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.
e74abb32
XL
71 if parent_scope.scope_metadata.unwrap() != fn_metadata {
72 debug_context.scopes[scope] = parent_scope;
a7813a04
XL
73 return;
74 }
75 }
76
2c00a5a8
XL
77 let loc = span_start(cx, scope_data.span);
78 let file_metadata = file_metadata(cx,
7cac9316
XL
79 &loc.file.name,
80 debug_context.defining_crate);
81
9e0c209e 82 let scope_metadata = unsafe {
b7449926 83 Some(llvm::LLVMRustDIBuilderCreateLexicalBlock(
2c00a5a8 84 DIB(cx),
b7449926 85 parent_scope.scope_metadata.unwrap(),
a7813a04
XL
86 file_metadata,
87 loc.line as c_uint,
b7449926 88 loc.col.to_usize() as c_uint))
a7813a04 89 };
e74abb32 90 debug_context.scopes[scope] = DebugScope {
3b2f2976 91 scope_metadata,
9e0c209e
SL
92 file_start_pos: loc.file.start_pos,
93 file_end_pos: loc.file.end_pos,
d9579d0f 94 };
92a42be0 95}