]> git.proxmox.com Git - rustc.git/blame - compiler/rustc_codegen_llvm/src/debuginfo/create_scope_map.rs
New upstream version 1.71.1+dfsg1
[rustc.git] / compiler / rustc_codegen_llvm / src / debuginfo / create_scope_map.rs
CommitLineData
6a06907d 1use super::metadata::file_metadata;
ba9703b0 2use super::utils::DIB;
dfeec247 3use rustc_codegen_ssa::mir::debuginfo::{DebugScope, FunctionDebugContext};
ba9703b0 4use rustc_codegen_ssa::traits::*;
d9579d0f 5
dfeec247 6use crate::common::CodegenCx;
9fa01778 7use crate::llvm;
29967ef6 8use crate::llvm::debuginfo::{DILocation, DIScope};
ba9703b0 9use rustc_middle::mir::{Body, SourceScope};
c295e0f8 10use rustc_middle::ty::layout::FnAbiOf;
29967ef6 11use rustc_middle::ty::{self, Instance};
ba9703b0 12use rustc_session::config::DebugInfo;
e9174d1e 13
e74abb32 14use rustc_index::bit_set::BitSet;
49aad941 15use rustc_index::Idx;
d9579d0f 16
9fa01778 17/// Produces DIScope DIEs for each MIR Scope which has variables defined in it.
29967ef6 18// FIXME(eddyb) almost all of this should be in `rustc_codegen_ssa::mir::debuginfo`.
a2a8927a 19pub fn compute_mir_scopes<'ll, 'tcx>(
29967ef6
XL
20 cx: &CodegenCx<'ll, 'tcx>,
21 instance: Instance<'tcx>,
22 mir: &Body<'tcx>,
29967ef6 23 debug_context: &mut FunctionDebugContext<&'ll DIScope, &'ll DILocation>,
e74abb32 24) {
5e7ed085
FG
25 // Find all scopes with variables defined in them.
26 let variables = if cx.sess().opts.debuginfo == DebugInfo::Full {
27 let mut vars = BitSet::new_empty(mir.source_scopes.len());
ba9703b0
XL
28 // FIXME(eddyb) take into account that arguments always have debuginfo,
29 // irrespective of their name (assuming full debuginfo is enabled).
30 // NOTE(eddyb) actually, on second thought, those are always in the
31 // function scope, which always exists.
32 for var_debug_info in &mir.var_debug_info {
5e7ed085 33 vars.insert(var_debug_info.source_info.scope);
ba9703b0 34 }
5e7ed085
FG
35 Some(vars)
36 } else {
37 // Nothing to emit, of course.
38 None
39 };
04454e1e 40 let mut instantiated = BitSet::new_empty(mir.source_scopes.len());
a7813a04 41 // Instantiate all scopes.
94b46f34
XL
42 for idx in 0..mir.source_scopes.len() {
43 let scope = SourceScope::new(idx);
04454e1e 44 make_mir_scope(cx, instance, mir, &variables, debug_context, &mut instantiated, scope);
a7813a04 45 }
04454e1e 46 assert!(instantiated.count() == mir.source_scopes.len());
a7813a04
XL
47}
48
a2a8927a 49fn make_mir_scope<'ll, 'tcx>(
29967ef6
XL
50 cx: &CodegenCx<'ll, 'tcx>,
51 instance: Instance<'tcx>,
52 mir: &Body<'tcx>,
5e7ed085 53 variables: &Option<BitSet<SourceScope>>,
29967ef6 54 debug_context: &mut FunctionDebugContext<&'ll DIScope, &'ll DILocation>,
04454e1e 55 instantiated: &mut BitSet<SourceScope>,
dfeec247
XL
56 scope: SourceScope,
57) {
04454e1e 58 if instantiated.contains(scope) {
a7813a04
XL
59 return;
60 }
61
94b46f34 62 let scope_data = &mir.source_scopes[scope];
a7813a04 63 let parent_scope = if let Some(parent) = scope_data.parent_scope {
04454e1e 64 make_mir_scope(cx, instance, mir, variables, debug_context, instantiated, parent);
e74abb32 65 debug_context.scopes[parent]
a7813a04
XL
66 } else {
67 // The root is the function itself.
ba9703b0 68 let loc = cx.lookup_debug_loc(mir.span.lo());
e74abb32 69 debug_context.scopes[scope] = DebugScope {
9e0c209e
SL
70 file_start_pos: loc.file.start_pos,
71 file_end_pos: loc.file.end_pos,
04454e1e 72 ..debug_context.scopes[scope]
9e0c209e 73 };
04454e1e 74 instantiated.insert(scope);
a7813a04
XL
75 return;
76 };
77
5e7ed085 78 if let Some(vars) = variables && !vars.contains(scope) && scope_data.inlined.is_none() {
29967ef6
XL
79 // Do not create a DIScope if there are no variables defined in this
80 // MIR `SourceScope`, and it's not `inlined`, to avoid debuginfo bloat.
74b04a01 81 debug_context.scopes[scope] = parent_scope;
04454e1e 82 instantiated.insert(scope);
74b04a01 83 return;
a7813a04
XL
84 }
85
ba9703b0 86 let loc = cx.lookup_debug_loc(scope_data.span.lo());
29967ef6 87 let file_metadata = file_metadata(cx, &loc.file);
7cac9316 88
29967ef6
XL
89 let dbg_scope = match scope_data.inlined {
90 Some((callee, _)) => {
91 // FIXME(eddyb) this would be `self.monomorphize(&callee)`
92 // if this is moved to `rustc_codegen_ssa::mir::debuginfo`.
93 let callee = cx.tcx.subst_and_normalize_erasing_regions(
94 instance.substs,
95 ty::ParamEnv::reveal_all(),
49aad941 96 ty::EarlyBinder(callee),
29967ef6 97 );
c295e0f8
XL
98 let callee_fn_abi = cx.fn_abi_of_instance(callee, ty::List::empty());
99 cx.dbg_scope_fn(callee, callee_fn_abi, None)
29967ef6
XL
100 }
101 None => unsafe {
102 llvm::LLVMRustDIBuilderCreateLexicalBlock(
103 DIB(cx),
04454e1e 104 parent_scope.dbg_scope,
29967ef6 105 file_metadata,
6a06907d
XL
106 loc.line,
107 loc.col,
29967ef6
XL
108 )
109 },
a7813a04 110 };
29967ef6
XL
111
112 let inlined_at = scope_data.inlined.map(|(_, callsite_span)| {
113 // FIXME(eddyb) this doesn't account for the macro-related
114 // `Span` fixups that `rustc_codegen_ssa::mir::debuginfo` does.
115 let callsite_scope = parent_scope.adjust_dbg_scope_for_span(cx, callsite_span);
116 cx.dbg_loc(callsite_scope, parent_scope.inlined_at, callsite_span)
117 });
118
e74abb32 119 debug_context.scopes[scope] = DebugScope {
04454e1e 120 dbg_scope,
29967ef6 121 inlined_at: inlined_at.or(parent_scope.inlined_at),
9e0c209e
SL
122 file_start_pos: loc.file.start_pos,
123 file_end_pos: loc.file.end_pos,
d9579d0f 124 };
04454e1e 125 instantiated.insert(scope);
92a42be0 126}