summaryrefslogtreecommitdiffstats
path: root/compiler/rustc_codegen_ssa/src/mir/debuginfo.rs
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-05-30 18:31:44 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-05-30 18:31:44 +0000
commitc23a457e72abe608715ac76f076f47dc42af07a5 (patch)
tree2772049aaf84b5c9d0ed12ec8d86812f7a7904b6 /compiler/rustc_codegen_ssa/src/mir/debuginfo.rs
parentReleasing progress-linux version 1.73.0+dfsg1-1~progress7.99u1. (diff)
downloadrustc-c23a457e72abe608715ac76f076f47dc42af07a5.tar.xz
rustc-c23a457e72abe608715ac76f076f47dc42af07a5.zip
Merging upstream version 1.74.1+dfsg1.
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'compiler/rustc_codegen_ssa/src/mir/debuginfo.rs')
-rw-r--r--compiler/rustc_codegen_ssa/src/mir/debuginfo.rs176
1 files changed, 73 insertions, 103 deletions
diff --git a/compiler/rustc_codegen_ssa/src/mir/debuginfo.rs b/compiler/rustc_codegen_ssa/src/mir/debuginfo.rs
index 526c16a59..0dc30d21c 100644
--- a/compiler/rustc_codegen_ssa/src/mir/debuginfo.rs
+++ b/compiler/rustc_codegen_ssa/src/mir/debuginfo.rs
@@ -1,10 +1,12 @@
use crate::traits::*;
+use rustc_data_structures::fx::FxHashMap;
use rustc_index::IndexVec;
use rustc_middle::middle::codegen_fn_attrs::CodegenFnAttrFlags;
use rustc_middle::mir;
use rustc_middle::ty;
use rustc_middle::ty::layout::TyAndLayout;
use rustc_middle::ty::layout::{HasTyCtxt, LayoutOf};
+use rustc_middle::ty::Instance;
use rustc_middle::ty::Ty;
use rustc_session::config::DebugInfo;
use rustc_span::symbol::{kw, Symbol};
@@ -17,10 +19,13 @@ use super::{FunctionCx, LocalRef};
use std::ops::Range;
-pub struct FunctionDebugContext<S, L> {
+pub struct FunctionDebugContext<'tcx, S, L> {
+ /// Maps from source code to the corresponding debug info scope.
pub scopes: IndexVec<mir::SourceScope, DebugScope<S, L>>,
-}
+ /// Maps from an inlined function to its debug info declaration.
+ pub inlined_function_scopes: FxHashMap<Instance<'tcx>, S>,
+}
#[derive(Copy, Clone)]
pub enum VariableKind {
ArgumentVariable(usize /*index*/),
@@ -153,8 +158,7 @@ fn calculate_debuginfo_offset<
L: DebugInfoOffsetLocation<'tcx, Bx>,
>(
bx: &mut Bx,
- local: mir::Local,
- var: &PerLocalVarDebugInfo<'tcx, Bx::DIVariable>,
+ projection: &[mir::PlaceElem<'tcx>],
base: L,
) -> DebugInfoOffset<L> {
let mut direct_offset = Size::ZERO;
@@ -162,7 +166,7 @@ fn calculate_debuginfo_offset<
let mut indirect_offsets = vec![];
let mut place = base;
- for elem in &var.projection[..] {
+ for elem in projection {
match *elem {
mir::ProjectionElem::Deref => {
indirect_offsets.push(Size::ZERO);
@@ -183,11 +187,7 @@ fn calculate_debuginfo_offset<
} => {
let offset = indirect_offsets.last_mut().unwrap_or(&mut direct_offset);
let FieldsShape::Array { stride, count: _ } = place.layout().fields else {
- span_bug!(
- var.source_info.span,
- "ConstantIndex on non-array type {:?}",
- place.layout()
- )
+ bug!("ConstantIndex on non-array type {:?}", place.layout())
};
*offset += stride * index;
place = place.project_constant_index(bx, index);
@@ -195,11 +195,7 @@ fn calculate_debuginfo_offset<
_ => {
// Sanity check for `can_use_in_debuginfo`.
debug_assert!(!elem.can_use_in_debuginfo());
- span_bug!(
- var.source_info.span,
- "unsupported var debuginfo place `{:?}`",
- mir::Place { local, projection: var.projection },
- )
+ bug!("unsupported var debuginfo projection `{:?}`", projection)
}
}
}
@@ -402,7 +398,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
let Some(dbg_loc) = self.dbg_loc(var.source_info) else { return };
let DebugInfoOffset { direct_offset, indirect_offsets, result: _ } =
- calculate_debuginfo_offset(bx, local, &var, base.layout);
+ calculate_debuginfo_offset(bx, &var.projection, base.layout);
// When targeting MSVC, create extra allocas for arguments instead of pointing multiple
// dbg_var_addr() calls into the same alloca with offsets. MSVC uses CodeView records
@@ -420,7 +416,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
if should_create_individual_allocas {
let DebugInfoOffset { direct_offset: _, indirect_offsets: _, result: place } =
- calculate_debuginfo_offset(bx, local, &var, base);
+ calculate_debuginfo_offset(bx, &var.projection, base);
// Create a variable which will be a pointer to the actual value
let ptr_ty = Ty::new_ptr(
@@ -484,54 +480,75 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
None
};
- let dbg_var = dbg_scope_and_span.map(|(dbg_scope, _, span)| {
- let (var_ty, var_kind) = match var.value {
+ let var_ty = if let Some(ref fragment) = var.composite {
+ self.monomorphize(fragment.ty)
+ } else {
+ match var.value {
mir::VarDebugInfoContents::Place(place) => {
- let var_ty = self.monomorphized_place_ty(place.as_ref());
- let var_kind = if let Some(arg_index) = var.argument_index
- && place.projection.is_empty()
- {
- let arg_index = arg_index as usize;
- if target_is_msvc {
- // ScalarPair parameters are spilled to the stack so they need to
- // be marked as a `LocalVariable` for MSVC debuggers to visualize
- // their data correctly. (See #81894 & #88625)
- let var_ty_layout = self.cx.layout_of(var_ty);
- if let Abi::ScalarPair(_, _) = var_ty_layout.abi {
- VariableKind::LocalVariable
- } else {
- VariableKind::ArgumentVariable(arg_index)
- }
- } else {
- // FIXME(eddyb) shouldn't `ArgumentVariable` indices be
- // offset in closures to account for the hidden environment?
- VariableKind::ArgumentVariable(arg_index)
- }
- } else {
- VariableKind::LocalVariable
- };
- (var_ty, var_kind)
- }
- mir::VarDebugInfoContents::Const(c) => {
- let ty = self.monomorphize(c.ty());
- (ty, VariableKind::LocalVariable)
+ self.monomorphized_place_ty(place.as_ref())
}
- mir::VarDebugInfoContents::Composite { ty, fragments: _ } => {
- let ty = self.monomorphize(ty);
- (ty, VariableKind::LocalVariable)
+ mir::VarDebugInfoContents::Const(c) => self.monomorphize(c.ty()),
+ }
+ };
+
+ let dbg_var = dbg_scope_and_span.map(|(dbg_scope, _, span)| {
+ let var_kind = if let Some(arg_index) = var.argument_index
+ && var.composite.is_none()
+ && let mir::VarDebugInfoContents::Place(place) = var.value
+ && place.projection.is_empty()
+ {
+ let arg_index = arg_index as usize;
+ if target_is_msvc {
+ // ScalarPair parameters are spilled to the stack so they need to
+ // be marked as a `LocalVariable` for MSVC debuggers to visualize
+ // their data correctly. (See #81894 & #88625)
+ let var_ty_layout = self.cx.layout_of(var_ty);
+ if let Abi::ScalarPair(_, _) = var_ty_layout.abi {
+ VariableKind::LocalVariable
+ } else {
+ VariableKind::ArgumentVariable(arg_index)
+ }
+ } else {
+ // FIXME(eddyb) shouldn't `ArgumentVariable` indices be
+ // offset in closures to account for the hidden environment?
+ VariableKind::ArgumentVariable(arg_index)
}
+ } else {
+ VariableKind::LocalVariable
};
self.cx.create_dbg_var(var.name, var_ty, dbg_scope, var_kind, span)
});
+ let fragment = if let Some(ref fragment) = var.composite {
+ let var_layout = self.cx.layout_of(var_ty);
+
+ let DebugInfoOffset { direct_offset, indirect_offsets, result: fragment_layout } =
+ calculate_debuginfo_offset(bx, &fragment.projection, var_layout);
+ debug_assert!(indirect_offsets.is_empty());
+
+ if fragment_layout.size == Size::ZERO {
+ // Fragment is a ZST, so does not represent anything. Avoid generating anything
+ // as this may conflict with a fragment that covers the entire variable.
+ continue;
+ } else if fragment_layout.size == var_layout.size {
+ // Fragment covers entire variable, so as far as
+ // DWARF is concerned, it's not really a fragment.
+ None
+ } else {
+ Some(direct_offset..direct_offset + fragment_layout.size)
+ }
+ } else {
+ None
+ };
+
match var.value {
mir::VarDebugInfoContents::Place(place) => {
per_local[place.local].push(PerLocalVarDebugInfo {
name: var.name,
source_info: var.source_info,
dbg_var,
- fragment: None,
+ fragment,
projection: place.projection,
});
}
@@ -539,59 +556,12 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
if let Some(dbg_var) = dbg_var {
let Some(dbg_loc) = self.dbg_loc(var.source_info) else { continue };
- if let Ok(operand) = self.eval_mir_constant_to_operand(bx, &c) {
- self.set_debug_loc(bx, var.source_info);
- let base = Self::spill_operand_to_stack(
- operand,
- Some(var.name.to_string()),
- bx,
- );
+ let operand = self.eval_mir_constant_to_operand(bx, &c);
+ self.set_debug_loc(bx, var.source_info);
+ let base =
+ Self::spill_operand_to_stack(operand, Some(var.name.to_string()), bx);
- bx.dbg_var_addr(dbg_var, dbg_loc, base.llval, Size::ZERO, &[], None);
- }
- }
- }
- mir::VarDebugInfoContents::Composite { ty, ref fragments } => {
- let var_ty = self.monomorphize(ty);
- let var_layout = self.cx.layout_of(var_ty);
- for fragment in fragments {
- let mut fragment_start = Size::ZERO;
- let mut fragment_layout = var_layout;
-
- for elem in &fragment.projection {
- match *elem {
- mir::ProjectionElem::Field(field, _) => {
- let i = field.index();
- fragment_start += fragment_layout.fields.offset(i);
- fragment_layout = fragment_layout.field(self.cx, i);
- }
- _ => span_bug!(
- var.source_info.span,
- "unsupported fragment projection `{:?}`",
- elem,
- ),
- }
- }
-
- let place = fragment.contents;
- let fragment = if fragment_layout.size == Size::ZERO {
- // Fragment is a ZST, so does not represent anything.
- continue;
- } else if fragment_layout.size == var_layout.size {
- // Fragment covers entire variable, so as far as
- // DWARF is concerned, it's not really a fragment.
- None
- } else {
- Some(fragment_start..fragment_start + fragment_layout.size)
- };
-
- per_local[place.local].push(PerLocalVarDebugInfo {
- name: var.name,
- source_info: var.source_info,
- dbg_var,
- fragment,
- projection: place.projection,
- });
+ bx.dbg_var_addr(dbg_var, dbg_loc, base.llval, Size::ZERO, &[], fragment);
}
}
}