Make debuginfo_offset_calcuation generic so we can resuse the logic

This will allow us to separate the act of calculating the offsets from
creating LLVM IR that performs the actions.
This commit is contained in:
Wesley Wiser 2022-12-07 13:47:51 -05:00
parent 525d0dd6e2
commit b33d1e26b2

View File

@ -3,12 +3,12 @@ use rustc_index::vec::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_session::config::DebugInfo;
use rustc_span::symbol::{kw, Symbol};
use rustc_span::{BytePos, Span};
use rustc_target::abi::Abi;
use rustc_target::abi::Size;
use rustc_target::abi::{Abi, Size, VariantIdx};
use super::operand::{OperandRef, OperandValue};
use super::place::PlaceRef;
@ -76,6 +76,33 @@ impl<'tcx, S: Copy, L: Copy> DebugScope<S, L> {
}
}
trait DebugInfoOffsetLocation<'tcx, Bx> {
fn deref(&self, bx: &mut Bx) -> Self;
fn layout(&self) -> TyAndLayout<'tcx>;
fn project_field(&self, bx: &mut Bx, field: mir::Field) -> Self;
fn downcast(&self, bx: &mut Bx, variant: VariantIdx) -> Self;
}
impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> DebugInfoOffsetLocation<'tcx, Bx>
for PlaceRef<'tcx, Bx::Value>
{
fn deref(&self, bx: &mut Bx) -> Self {
bx.load_operand(*self).deref(bx.cx())
}
fn layout(&self) -> TyAndLayout<'tcx> {
self.layout
}
fn project_field(&self, bx: &mut Bx, field: mir::Field) -> Self {
PlaceRef::project_field(*self, bx, field.index())
}
fn downcast(&self, bx: &mut Bx, variant: VariantIdx) -> Self {
self.project_downcast(bx, variant)
}
}
struct DebugInfoOffset<T> {
/// Offset from the `base` used to calculate the debuginfo offset.
direct_offset: Size,
@ -86,12 +113,17 @@ struct DebugInfoOffset<T> {
result: T,
}
fn calculate_debuginfo_offset<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>(
fn calculate_debuginfo_offset<
'a,
'tcx,
Bx: BuilderMethods<'a, 'tcx>,
L: DebugInfoOffsetLocation<'tcx, Bx>,
>(
bx: &mut Bx,
local: mir::Local,
var: &PerLocalVarDebugInfo<'tcx, Bx::DIVariable>,
base: PlaceRef<'tcx, Bx::Value>,
) -> DebugInfoOffset<PlaceRef<'tcx, Bx::Value>> {
base: L,
) -> DebugInfoOffset<L> {
let mut direct_offset = Size::ZERO;
// FIXME(eddyb) use smallvec here.
let mut indirect_offsets = vec![];
@ -101,16 +133,15 @@ fn calculate_debuginfo_offset<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>(
match *elem {
mir::ProjectionElem::Deref => {
indirect_offsets.push(Size::ZERO);
place = bx.load_operand(place).deref(bx.cx());
place = place.deref(bx);
}
mir::ProjectionElem::Field(field, _) => {
let i = field.index();
let offset = indirect_offsets.last_mut().unwrap_or(&mut direct_offset);
*offset += place.layout.fields.offset(i);
place = place.project_field(bx, i);
*offset += place.layout().fields.offset(field.index());
place = place.project_field(bx, field);
}
mir::ProjectionElem::Downcast(_, variant) => {
place = place.project_downcast(bx, variant);
place = place.downcast(bx, variant);
}
_ => span_bug!(
var.source_info.span,