diff --git a/src/librustc_codegen_llvm/builder.rs b/src/librustc_codegen_llvm/builder.rs index c59b81eb4cc32..342ac437d3c24 100644 --- a/src/librustc_codegen_llvm/builder.rs +++ b/src/librustc_codegen_llvm/builder.rs @@ -57,6 +57,7 @@ impl BackendTypes for Builder<'_, 'll, 'tcx> { type Funclet = as BackendTypes>::Funclet; type DIScope = as BackendTypes>::DIScope; + type DIVariable = as BackendTypes>::DIVariable; } impl ty::layout::HasDataLayout for Builder<'_, '_, '_> { diff --git a/src/librustc_codegen_llvm/common.rs b/src/librustc_codegen_llvm/common.rs index 76f6eeb3f7907..1d6bfb321598c 100644 --- a/src/librustc_codegen_llvm/common.rs +++ b/src/librustc_codegen_llvm/common.rs @@ -91,6 +91,7 @@ impl BackendTypes for CodegenCx<'ll, 'tcx> { type Funclet = Funclet<'ll>; type DIScope = &'ll llvm::debuginfo::DIScope; + type DIVariable = &'ll llvm::debuginfo::DIVariable; } impl CodegenCx<'ll, 'tcx> { diff --git a/src/librustc_codegen_llvm/debuginfo/mod.rs b/src/librustc_codegen_llvm/debuginfo/mod.rs index 0462dcff42919..87af9b9c88da7 100644 --- a/src/librustc_codegen_llvm/debuginfo/mod.rs +++ b/src/librustc_codegen_llvm/debuginfo/mod.rs @@ -11,7 +11,7 @@ use self::utils::{create_DIArray, is_node_local_to_unit, span_start, DIB}; use crate::llvm; 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::ty::subst::{GenericArgKind, SubstsRef}; @@ -143,33 +143,23 @@ pub fn finalize(cx: &CodegenCx<'_, '_>) { }; } -impl DebugInfoBuilderMethods<'tcx> for Builder<'a, 'll, 'tcx> { - fn declare_local( +impl DebugInfoBuilderMethods for Builder<'a, 'll, 'tcx> { + // 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<&'ll DIScope>, - variable_name: ast::Name, - variable_type: Ty<'tcx>, + dbg_var: &'ll DIVariable, scope_metadata: &'ll DIScope, variable_alloca: Self::Value, direct_offset: Size, indirect_offsets: &[Size], - variable_kind: VariableKind, span: Span, ) { assert!(!dbg_context.source_locations_enabled); 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 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. 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()); - let metadata = unsafe { - 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, - ) - }; + // FIXME(eddyb) maybe this information could be extracted from `var`, + // to avoid having to pass it down in both places? source_loc::set_debug_location( self, InternalDebugLocation::new(scope_metadata, loc.line, loc.col.to_usize()), ); unsafe { let debug_loc = llvm::LLVMGetCurrentDebugLocation(self.llbuilder); + // FIXME(eddyb) replace `llvm.dbg.declare` with `llvm.dbg.addr`. let instr = llvm::LLVMRustDIBuilderInsertDeclareAtEnd( DIB(cx), variable_alloca, - metadata, + dbg_var, addr_ops.as_ptr(), addr_ops.len() as c_uint, debug_loc, @@ -558,4 +535,45 @@ impl DebugInfoMethods<'tcx> for CodegenCx<'ll, 'tcx> { fn debuginfo_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, + ) + } + } } diff --git a/src/librustc_codegen_ssa/mir/debuginfo.rs b/src/librustc_codegen_ssa/mir/debuginfo.rs index e0aec5d6dd512..1ee5fdba2a202 100644 --- a/src/librustc_codegen_ssa/mir/debuginfo.rs +++ b/src/librustc_codegen_ssa/mir/debuginfo.rs @@ -226,15 +226,15 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { let (scope, span) = self.debug_loc(var.source_info); 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, - var.name, - layout.ty, + dbg_var, scope, base.llval, direct_offset, &indirect_offsets, - kind, span, ); } diff --git a/src/librustc_codegen_ssa/traits/backend.rs b/src/librustc_codegen_ssa/traits/backend.rs index bc3a75250bf70..7b22961cd46e2 100644 --- a/src/librustc_codegen_ssa/traits/backend.rs +++ b/src/librustc_codegen_ssa/traits/backend.rs @@ -21,7 +21,10 @@ pub trait BackendTypes { type Type: CodegenObject; 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 DIVariable: Copy; } pub trait Backend<'tcx>: diff --git a/src/librustc_codegen_ssa/traits/builder.rs b/src/librustc_codegen_ssa/traits/builder.rs index 6f331e14a0d37..b3c830eef8698 100644 --- a/src/librustc_codegen_ssa/traits/builder.rs +++ b/src/librustc_codegen_ssa/traits/builder.rs @@ -28,7 +28,7 @@ pub enum OverflowOp { pub trait BuilderMethods<'a, 'tcx>: HasCodegen<'tcx> - + DebugInfoBuilderMethods<'tcx> + + DebugInfoBuilderMethods + ArgAbiMethods<'tcx> + AbiBuilderMethods<'tcx> + IntrinsicCallMethods<'tcx> diff --git a/src/librustc_codegen_ssa/traits/debuginfo.rs b/src/librustc_codegen_ssa/traits/debuginfo.rs index d2784f5b860f7..22a4e96b9e4bf 100644 --- a/src/librustc_codegen_ssa/traits/debuginfo.rs +++ b/src/librustc_codegen_ssa/traits/debuginfo.rs @@ -30,20 +30,32 @@ pub trait DebugInfoMethods<'tcx>: BackendTypes { defining_crate: CrateNum, ) -> Self::DIScope; fn debuginfo_finalize(&self); -} -pub trait DebugInfoBuilderMethods<'tcx>: BackendTypes { - fn declare_local( - &mut 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, variable_name: Name, variable_type: Ty<'tcx>, 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, + dbg_var: Self::DIVariable, + scope_metadata: Self::DIScope, variable_alloca: Self::Value, direct_offset: Size, // NB: each offset implies a deref (i.e. they're steps in a pointer chain). indirect_offsets: &[Size], - variable_kind: VariableKind, span: Span, ); fn set_source_location( diff --git a/src/librustc_codegen_ssa/traits/mod.rs b/src/librustc_codegen_ssa/traits/mod.rs index fff1b35507ce6..b8afadaadef38 100644 --- a/src/librustc_codegen_ssa/traits/mod.rs +++ b/src/librustc_codegen_ssa/traits/mod.rs @@ -93,5 +93,6 @@ pub trait HasCodegen<'tcx>: Type = Self::Type, Funclet = Self::Funclet, DIScope = Self::DIScope, + DIVariable = Self::DIVariable, >; }