Extract debug_introduce_local_as_var.
This commit is contained in:
parent
69fef92ab2
commit
1c36f50b3e
1 changed files with 44 additions and 42 deletions
|
@ -358,54 +358,56 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
|
||||||
let vars = vars.iter().cloned().chain(fallback_var);
|
let vars = vars.iter().cloned().chain(fallback_var);
|
||||||
|
|
||||||
for var in vars {
|
for var in vars {
|
||||||
let Some(dbg_var) = var.dbg_var else { continue };
|
self.debug_introduce_local_as_var(bx, local, base, var);
|
||||||
let Some(dbg_loc) = self.dbg_loc(var.source_info) else { continue };
|
}
|
||||||
|
}
|
||||||
|
|
||||||
let DebugInfoOffset { direct_offset, indirect_offsets, result: _ } =
|
fn debug_introduce_local_as_var(
|
||||||
calculate_debuginfo_offset(bx, local, &var, base.layout);
|
&self,
|
||||||
|
bx: &mut Bx,
|
||||||
|
local: mir::Local,
|
||||||
|
base: PlaceRef<'tcx, Bx::Value>,
|
||||||
|
var: PerLocalVarDebugInfo<'tcx, Bx::DIVariable>,
|
||||||
|
) {
|
||||||
|
let Some(dbg_var) = var.dbg_var else { return };
|
||||||
|
let Some(dbg_loc) = self.dbg_loc(var.source_info) else { return };
|
||||||
|
|
||||||
// When targeting MSVC, create extra allocas for arguments instead of pointing multiple
|
let DebugInfoOffset { direct_offset, indirect_offsets, result: _ } =
|
||||||
// dbg_var_addr() calls into the same alloca with offsets. MSVC uses CodeView records
|
calculate_debuginfo_offset(bx, local, &var, base.layout);
|
||||||
// not DWARF and LLVM doesn't support translating the resulting
|
|
||||||
// [DW_OP_deref, DW_OP_plus_uconst, offset, DW_OP_deref] debug info to CodeView.
|
|
||||||
// Creating extra allocas on the stack makes the resulting debug info simple enough
|
|
||||||
// that LLVM can generate correct CodeView records and thus the values appear in the
|
|
||||||
// debugger. (#83709)
|
|
||||||
let should_create_individual_allocas = bx.cx().sess().target.is_like_msvc
|
|
||||||
&& self.mir.local_kind(local) == mir::LocalKind::Arg
|
|
||||||
// LLVM can handle simple things but anything more complex than just a direct
|
|
||||||
// offset or one indirect offset of 0 is too complex for it to generate CV records
|
|
||||||
// correctly.
|
|
||||||
&& (direct_offset != Size::ZERO
|
|
||||||
|| !matches!(&indirect_offsets[..], [Size::ZERO] | []));
|
|
||||||
|
|
||||||
if should_create_individual_allocas {
|
// When targeting MSVC, create extra allocas for arguments instead of pointing multiple
|
||||||
let DebugInfoOffset { direct_offset: _, indirect_offsets: _, result: place } =
|
// dbg_var_addr() calls into the same alloca with offsets. MSVC uses CodeView records
|
||||||
calculate_debuginfo_offset(bx, local, &var, base);
|
// not DWARF and LLVM doesn't support translating the resulting
|
||||||
|
// [DW_OP_deref, DW_OP_plus_uconst, offset, DW_OP_deref] debug info to CodeView.
|
||||||
|
// Creating extra allocas on the stack makes the resulting debug info simple enough
|
||||||
|
// that LLVM can generate correct CodeView records and thus the values appear in the
|
||||||
|
// debugger. (#83709)
|
||||||
|
let should_create_individual_allocas = bx.cx().sess().target.is_like_msvc
|
||||||
|
&& self.mir.local_kind(local) == mir::LocalKind::Arg
|
||||||
|
// LLVM can handle simple things but anything more complex than just a direct
|
||||||
|
// offset or one indirect offset of 0 is too complex for it to generate CV records
|
||||||
|
// correctly.
|
||||||
|
&& (direct_offset != Size::ZERO || !matches!(&indirect_offsets[..], [Size::ZERO] | []));
|
||||||
|
|
||||||
// Create a variable which will be a pointer to the actual value
|
if should_create_individual_allocas {
|
||||||
let ptr_ty = bx
|
let DebugInfoOffset { direct_offset: _, indirect_offsets: _, result: place } =
|
||||||
.tcx()
|
calculate_debuginfo_offset(bx, local, &var, base);
|
||||||
.mk_ptr(ty::TypeAndMut { mutbl: mir::Mutability::Mut, ty: place.layout.ty });
|
|
||||||
let ptr_layout = bx.layout_of(ptr_ty);
|
|
||||||
let alloca = PlaceRef::alloca(bx, ptr_layout);
|
|
||||||
bx.set_var_name(alloca.llval, &(var.name.to_string() + ".dbg.spill"));
|
|
||||||
|
|
||||||
// Write the pointer to the variable
|
// Create a variable which will be a pointer to the actual value
|
||||||
bx.store(place.llval, alloca.llval, alloca.align);
|
let ptr_ty = bx
|
||||||
|
.tcx()
|
||||||
|
.mk_ptr(ty::TypeAndMut { mutbl: mir::Mutability::Mut, ty: place.layout.ty });
|
||||||
|
let ptr_layout = bx.layout_of(ptr_ty);
|
||||||
|
let alloca = PlaceRef::alloca(bx, ptr_layout);
|
||||||
|
bx.set_var_name(alloca.llval, &(var.name.to_string() + ".dbg.spill"));
|
||||||
|
|
||||||
// Point the debug info to `*alloca` for the current variable
|
// Write the pointer to the variable
|
||||||
bx.dbg_var_addr(dbg_var, dbg_loc, alloca.llval, Size::ZERO, &[Size::ZERO], None);
|
bx.store(place.llval, alloca.llval, alloca.align);
|
||||||
} else {
|
|
||||||
bx.dbg_var_addr(
|
// Point the debug info to `*alloca` for the current variable
|
||||||
dbg_var,
|
bx.dbg_var_addr(dbg_var, dbg_loc, alloca.llval, Size::ZERO, &[Size::ZERO], None);
|
||||||
dbg_loc,
|
} else {
|
||||||
base.llval,
|
bx.dbg_var_addr(dbg_var, dbg_loc, base.llval, direct_offset, &indirect_offsets, None);
|
||||||
direct_offset,
|
|
||||||
&indirect_offsets,
|
|
||||||
None,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue