1
Fork 0

rustc_codegen_ssa: split declare_local into create_dbg_var and dbg_var_addr.

This commit is contained in:
Eduard-Mihai Burtescu 2020-01-26 18:50:13 +02:00
parent 0d34a87722
commit 0b633c82f0
8 changed files with 79 additions and 43 deletions

View file

@ -57,6 +57,7 @@ impl BackendTypes for Builder<'_, 'll, 'tcx> {
type Funclet = <CodegenCx<'ll, 'tcx> as BackendTypes>::Funclet; type Funclet = <CodegenCx<'ll, 'tcx> as BackendTypes>::Funclet;
type DIScope = <CodegenCx<'ll, 'tcx> as BackendTypes>::DIScope; type DIScope = <CodegenCx<'ll, 'tcx> as BackendTypes>::DIScope;
type DIVariable = <CodegenCx<'ll, 'tcx> as BackendTypes>::DIVariable;
} }
impl ty::layout::HasDataLayout for Builder<'_, '_, '_> { impl ty::layout::HasDataLayout for Builder<'_, '_, '_> {

View file

@ -91,6 +91,7 @@ impl BackendTypes for CodegenCx<'ll, 'tcx> {
type Funclet = Funclet<'ll>; type Funclet = Funclet<'ll>;
type DIScope = &'ll llvm::debuginfo::DIScope; type DIScope = &'ll llvm::debuginfo::DIScope;
type DIVariable = &'ll llvm::debuginfo::DIVariable;
} }
impl CodegenCx<'ll, 'tcx> { impl CodegenCx<'ll, 'tcx> {

View file

@ -11,7 +11,7 @@ use self::utils::{create_DIArray, is_node_local_to_unit, span_start, DIB};
use crate::llvm; use crate::llvm;
use crate::llvm::debuginfo::{ use crate::llvm::debuginfo::{
DIArray, DIBuilder, DIFile, DIFlags, DILexicalBlock, DISPFlags, DIScope, DIType, DIArray, DIBuilder, DIFile, DIFlags, DILexicalBlock, DISPFlags, DIScope, DIType, DIVariable,
}; };
use rustc::middle::codegen_fn_attrs::CodegenFnAttrFlags; use rustc::middle::codegen_fn_attrs::CodegenFnAttrFlags;
use rustc::ty::subst::{GenericArgKind, SubstsRef}; use rustc::ty::subst::{GenericArgKind, SubstsRef};
@ -143,33 +143,23 @@ pub fn finalize(cx: &CodegenCx<'_, '_>) {
}; };
} }
impl DebugInfoBuilderMethods<'tcx> for Builder<'a, 'll, 'tcx> { impl DebugInfoBuilderMethods for Builder<'a, 'll, 'tcx> {
fn declare_local( // FIXME(eddyb) find a common convention for all of the debuginfo-related
// names (choose between `dbg`, `debug`, `debuginfo`, `debug_info` etc.).
fn dbg_var_addr(
&mut self, &mut self,
dbg_context: &FunctionDebugContext<&'ll DIScope>, dbg_context: &FunctionDebugContext<&'ll DIScope>,
variable_name: ast::Name, dbg_var: &'ll DIVariable,
variable_type: Ty<'tcx>,
scope_metadata: &'ll DIScope, scope_metadata: &'ll DIScope,
variable_alloca: Self::Value, variable_alloca: Self::Value,
direct_offset: Size, direct_offset: Size,
indirect_offsets: &[Size], indirect_offsets: &[Size],
variable_kind: VariableKind,
span: Span, span: Span,
) { ) {
assert!(!dbg_context.source_locations_enabled); assert!(!dbg_context.source_locations_enabled);
let cx = self.cx(); let cx = self.cx();
let file = span_start(cx, span).file;
let file_metadata = file_metadata(cx, &file.name, dbg_context.defining_crate);
let loc = span_start(cx, span); let loc = span_start(cx, span);
let type_metadata = type_metadata(cx, variable_type, span);
let (argument_index, dwarf_tag) = match variable_kind {
ArgumentVariable(index) => (index as c_uint, DW_TAG_arg_variable),
LocalVariable => (0, DW_TAG_auto_variable),
};
let align = cx.align_of(variable_type);
// Convert the direct and indirect offsets to address ops. // Convert the direct and indirect offsets to address ops.
let op_deref = || unsafe { llvm::LLVMRustDIBuilderCreateOpDeref() }; let op_deref = || unsafe { llvm::LLVMRustDIBuilderCreateOpDeref() };
@ -188,32 +178,19 @@ impl DebugInfoBuilderMethods<'tcx> for Builder<'a, 'll, 'tcx> {
} }
} }
let name = SmallCStr::new(&variable_name.as_str()); // FIXME(eddyb) maybe this information could be extracted from `var`,
let metadata = unsafe { // to avoid having to pass it down in both places?
llvm::LLVMRustDIBuilderCreateVariable(
DIB(cx),
dwarf_tag,
scope_metadata,
name.as_ptr(),
file_metadata,
loc.line as c_uint,
type_metadata,
cx.sess().opts.optimize != config::OptLevel::No,
DIFlags::FlagZero,
argument_index,
align.bytes() as u32,
)
};
source_loc::set_debug_location( source_loc::set_debug_location(
self, self,
InternalDebugLocation::new(scope_metadata, loc.line, loc.col.to_usize()), InternalDebugLocation::new(scope_metadata, loc.line, loc.col.to_usize()),
); );
unsafe { unsafe {
let debug_loc = llvm::LLVMGetCurrentDebugLocation(self.llbuilder); let debug_loc = llvm::LLVMGetCurrentDebugLocation(self.llbuilder);
// FIXME(eddyb) replace `llvm.dbg.declare` with `llvm.dbg.addr`.
let instr = llvm::LLVMRustDIBuilderInsertDeclareAtEnd( let instr = llvm::LLVMRustDIBuilderInsertDeclareAtEnd(
DIB(cx), DIB(cx),
variable_alloca, variable_alloca,
metadata, dbg_var,
addr_ops.as_ptr(), addr_ops.as_ptr(),
addr_ops.len() as c_uint, addr_ops.len() as c_uint,
debug_loc, debug_loc,
@ -558,4 +535,45 @@ impl DebugInfoMethods<'tcx> for CodegenCx<'ll, 'tcx> {
fn debuginfo_finalize(&self) { fn debuginfo_finalize(&self) {
finalize(self) finalize(self)
} }
// FIXME(eddyb) find a common convention for all of the debuginfo-related
// names (choose between `dbg`, `debug`, `debuginfo`, `debug_info` etc.).
fn create_dbg_var(
&self,
dbg_context: &FunctionDebugContext<&'ll DIScope>,
variable_name: ast::Name,
variable_type: Ty<'tcx>,
scope_metadata: &'ll DIScope,
variable_kind: VariableKind,
span: Span,
) -> &'ll DIVariable {
let file = span_start(self, span).file;
let file_metadata = file_metadata(self, &file.name, dbg_context.defining_crate);
let loc = span_start(self, span);
let type_metadata = type_metadata(self, variable_type, span);
let (argument_index, dwarf_tag) = match variable_kind {
ArgumentVariable(index) => (index as c_uint, DW_TAG_arg_variable),
LocalVariable => (0, DW_TAG_auto_variable),
};
let align = self.align_of(variable_type);
let name = SmallCStr::new(&variable_name.as_str());
unsafe {
llvm::LLVMRustDIBuilderCreateVariable(
DIB(self),
dwarf_tag,
scope_metadata,
name.as_ptr(),
file_metadata,
loc.line as c_uint,
type_metadata,
self.sess().opts.optimize != config::OptLevel::No,
DIFlags::FlagZero,
argument_index,
align.bytes() as u32,
)
}
}
} }

View file

@ -226,15 +226,15 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
let (scope, span) = self.debug_loc(var.source_info); let (scope, span) = self.debug_loc(var.source_info);
if let Some(scope) = scope { if let Some(scope) = scope {
bx.declare_local( let dbg_var =
bx.create_dbg_var(debug_context, var.name, layout.ty, scope, kind, span);
bx.dbg_var_addr(
debug_context, debug_context,
var.name, dbg_var,
layout.ty,
scope, scope,
base.llval, base.llval,
direct_offset, direct_offset,
&indirect_offsets, &indirect_offsets,
kind,
span, span,
); );
} }

View file

@ -21,7 +21,10 @@ pub trait BackendTypes {
type Type: CodegenObject; type Type: CodegenObject;
type Funclet; type Funclet;
// FIXME(eddyb) find a common convention for all of the debuginfo-related
// names (choose between `Dbg`, `Debug`, `DebugInfo`, `DI` etc.).
type DIScope: Copy; type DIScope: Copy;
type DIVariable: Copy;
} }
pub trait Backend<'tcx>: pub trait Backend<'tcx>:

View file

@ -28,7 +28,7 @@ pub enum OverflowOp {
pub trait BuilderMethods<'a, 'tcx>: pub trait BuilderMethods<'a, 'tcx>:
HasCodegen<'tcx> HasCodegen<'tcx>
+ DebugInfoBuilderMethods<'tcx> + DebugInfoBuilderMethods
+ ArgAbiMethods<'tcx> + ArgAbiMethods<'tcx>
+ AbiBuilderMethods<'tcx> + AbiBuilderMethods<'tcx>
+ IntrinsicCallMethods<'tcx> + IntrinsicCallMethods<'tcx>

View file

@ -30,20 +30,32 @@ pub trait DebugInfoMethods<'tcx>: BackendTypes {
defining_crate: CrateNum, defining_crate: CrateNum,
) -> Self::DIScope; ) -> Self::DIScope;
fn debuginfo_finalize(&self); fn debuginfo_finalize(&self);
}
pub trait DebugInfoBuilderMethods<'tcx>: BackendTypes { // FIXME(eddyb) find a common convention for all of the debuginfo-related
fn declare_local( // names (choose between `dbg`, `debug`, `debuginfo`, `debug_info` etc.).
&mut self, fn create_dbg_var(
&self,
dbg_context: &FunctionDebugContext<Self::DIScope>, dbg_context: &FunctionDebugContext<Self::DIScope>,
variable_name: Name, variable_name: Name,
variable_type: Ty<'tcx>, variable_type: Ty<'tcx>,
scope_metadata: Self::DIScope, scope_metadata: Self::DIScope,
variable_kind: VariableKind,
span: Span,
) -> Self::DIVariable;
}
pub trait DebugInfoBuilderMethods: BackendTypes {
// FIXME(eddyb) find a common convention for all of the debuginfo-related
// names (choose between `dbg`, `debug`, `debuginfo`, `debug_info` etc.).
fn dbg_var_addr(
&mut self,
dbg_context: &FunctionDebugContext<Self::DIScope>,
dbg_var: Self::DIVariable,
scope_metadata: Self::DIScope,
variable_alloca: Self::Value, variable_alloca: Self::Value,
direct_offset: Size, direct_offset: Size,
// NB: each offset implies a deref (i.e. they're steps in a pointer chain). // NB: each offset implies a deref (i.e. they're steps in a pointer chain).
indirect_offsets: &[Size], indirect_offsets: &[Size],
variable_kind: VariableKind,
span: Span, span: Span,
); );
fn set_source_location( fn set_source_location(

View file

@ -93,5 +93,6 @@ pub trait HasCodegen<'tcx>:
Type = Self::Type, Type = Self::Type,
Funclet = Self::Funclet, Funclet = Self::Funclet,
DIScope = Self::DIScope, DIScope = Self::DIScope,
DIVariable = Self::DIVariable,
>; >;
} }