Skip to content

Commit 525d0dd

Browse files
committed
Factor out debuginfo offset calculation
1 parent 34246f8 commit 525d0dd

File tree

1 file changed

+49
-27
lines changed

1 file changed

+49
-27
lines changed

compiler/rustc_codegen_ssa/src/mir/debuginfo.rs

+49-27
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,53 @@ impl<'tcx, S: Copy, L: Copy> DebugScope<S, L> {
7676
}
7777
}
7878

79+
struct DebugInfoOffset<T> {
80+
/// Offset from the `base` used to calculate the debuginfo offset.
81+
direct_offset: Size,
82+
/// Each offset in this vector indicates one level of indirection from the base or previous
83+
/// indirect offset plus a dereference.
84+
indirect_offsets: Vec<Size>,
85+
/// The final location debuginfo should point to.
86+
result: T,
87+
}
88+
89+
fn calculate_debuginfo_offset<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>(
90+
bx: &mut Bx,
91+
local: mir::Local,
92+
var: &PerLocalVarDebugInfo<'tcx, Bx::DIVariable>,
93+
base: PlaceRef<'tcx, Bx::Value>,
94+
) -> DebugInfoOffset<PlaceRef<'tcx, Bx::Value>> {
95+
let mut direct_offset = Size::ZERO;
96+
// FIXME(eddyb) use smallvec here.
97+
let mut indirect_offsets = vec![];
98+
let mut place = base;
99+
100+
for elem in &var.projection[..] {
101+
match *elem {
102+
mir::ProjectionElem::Deref => {
103+
indirect_offsets.push(Size::ZERO);
104+
place = bx.load_operand(place).deref(bx.cx());
105+
}
106+
mir::ProjectionElem::Field(field, _) => {
107+
let i = field.index();
108+
let offset = indirect_offsets.last_mut().unwrap_or(&mut direct_offset);
109+
*offset += place.layout.fields.offset(i);
110+
place = place.project_field(bx, i);
111+
}
112+
mir::ProjectionElem::Downcast(_, variant) => {
113+
place = place.project_downcast(bx, variant);
114+
}
115+
_ => span_bug!(
116+
var.source_info.span,
117+
"unsupported var debuginfo place `{:?}`",
118+
mir::Place { local, projection: var.projection },
119+
),
120+
}
121+
}
122+
123+
DebugInfoOffset { direct_offset, indirect_offsets, result: place }
124+
}
125+
79126
impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
80127
pub fn set_debug_loc(&self, bx: &mut Bx, source_info: mir::SourceInfo) {
81128
bx.set_span(source_info.span);
@@ -262,33 +309,8 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
262309
let Some(dbg_var) = var.dbg_var else { continue };
263310
let Some(dbg_loc) = self.dbg_loc(var.source_info) else { continue };
264311

265-
let mut direct_offset = Size::ZERO;
266-
// FIXME(eddyb) use smallvec here.
267-
let mut indirect_offsets = vec![];
268-
let mut place = base;
269-
270-
for elem in &var.projection[..] {
271-
match *elem {
272-
mir::ProjectionElem::Deref => {
273-
indirect_offsets.push(Size::ZERO);
274-
place = bx.load_operand(place).deref(bx.cx());
275-
}
276-
mir::ProjectionElem::Field(field, _) => {
277-
let i = field.index();
278-
let offset = indirect_offsets.last_mut().unwrap_or(&mut direct_offset);
279-
*offset += place.layout.fields.offset(i);
280-
place = place.project_field(bx, i);
281-
}
282-
mir::ProjectionElem::Downcast(_, variant) => {
283-
place = place.project_downcast(bx, variant);
284-
}
285-
_ => span_bug!(
286-
var.source_info.span,
287-
"unsupported var debuginfo place `{:?}`",
288-
mir::Place { local, projection: var.projection },
289-
),
290-
}
291-
}
312+
let DebugInfoOffset { direct_offset, indirect_offsets, result: place } =
313+
calculate_debuginfo_offset(bx, local, &var, base);
292314

293315
// When targeting MSVC, create extra allocas for arguments instead of pointing multiple
294316
// dbg_var_addr() calls into the same alloca with offsets. MSVC uses CodeView records

0 commit comments

Comments
 (0)