rustc_codegen_ssa: hide address ops from the declare_local interface.
This commit is contained in:
parent
c2e7743da8
commit
1e42072673
@ -1,7 +1,6 @@
|
||||
// See doc.rs for documentation.
|
||||
mod doc;
|
||||
|
||||
use rustc_codegen_ssa::mir::debuginfo::VariableAccess::*;
|
||||
use rustc_codegen_ssa::mir::debuginfo::VariableKind::*;
|
||||
|
||||
use self::utils::{DIB, span_start, create_DIArray, is_node_local_to_unit};
|
||||
@ -28,17 +27,18 @@ use rustc::util::nodemap::{DefIdMap, FxHashMap, FxHashSet};
|
||||
use rustc_data_structures::small_c_str::SmallCStr;
|
||||
use rustc_index::vec::IndexVec;
|
||||
use rustc_codegen_ssa::debuginfo::type_names;
|
||||
use rustc_codegen_ssa::mir::debuginfo::{FunctionDebugContext, DebugScope, VariableAccess,
|
||||
use rustc_codegen_ssa::mir::debuginfo::{FunctionDebugContext, DebugScope,
|
||||
VariableKind};
|
||||
|
||||
use libc::c_uint;
|
||||
use std::cell::RefCell;
|
||||
use std::ffi::{CStr, CString};
|
||||
|
||||
use smallvec::SmallVec;
|
||||
use syntax_pos::{self, BytePos, Span, Pos};
|
||||
use syntax::ast;
|
||||
use syntax::symbol::Symbol;
|
||||
use rustc::ty::layout::{self, LayoutOf, HasTyCtxt};
|
||||
use rustc::ty::layout::{self, LayoutOf, HasTyCtxt, Size};
|
||||
use rustc_codegen_ssa::traits::*;
|
||||
|
||||
pub mod gdb;
|
||||
@ -153,7 +153,9 @@ impl DebugInfoBuilderMethods<'tcx> for Builder<'a, 'll, 'tcx> {
|
||||
variable_name: ast::Name,
|
||||
variable_type: Ty<'tcx>,
|
||||
scope_metadata: &'ll DIScope,
|
||||
variable_access: VariableAccess<'_, &'ll Value>,
|
||||
variable_alloca: Self::Value,
|
||||
direct_offset: Size,
|
||||
indirect_offsets: &[Size],
|
||||
variable_kind: VariableKind,
|
||||
span: Span,
|
||||
) {
|
||||
@ -174,43 +176,55 @@ impl DebugInfoBuilderMethods<'tcx> for Builder<'a, 'll, 'tcx> {
|
||||
};
|
||||
let align = cx.align_of(variable_type);
|
||||
|
||||
let name = SmallCStr::new(&variable_name.as_str());
|
||||
match (variable_access, &[][..]) {
|
||||
(DirectVariable { alloca }, address_operations) |
|
||||
(IndirectVariable {alloca, address_operations}, _) => {
|
||||
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,
|
||||
)
|
||||
};
|
||||
source_loc::set_debug_location(self,
|
||||
InternalDebugLocation::new(scope_metadata, loc.line, loc.col.to_usize()));
|
||||
unsafe {
|
||||
let debug_loc = llvm::LLVMGetCurrentDebugLocation(self.llbuilder);
|
||||
let instr = llvm::LLVMRustDIBuilderInsertDeclareAtEnd(
|
||||
DIB(cx),
|
||||
alloca,
|
||||
metadata,
|
||||
address_operations.as_ptr(),
|
||||
address_operations.len() as c_uint,
|
||||
debug_loc,
|
||||
self.llbb());
|
||||
// Convert the direct and indirect offsets to address ops.
|
||||
let op_deref = || unsafe { llvm::LLVMRustDIBuilderCreateOpDeref() };
|
||||
let op_plus_uconst = || unsafe { llvm::LLVMRustDIBuilderCreateOpPlusUconst() };
|
||||
let mut addr_ops = SmallVec::<[_; 8]>::new();
|
||||
|
||||
llvm::LLVMSetInstDebugLocation(self.llbuilder, instr);
|
||||
}
|
||||
source_loc::set_debug_location(self, UnknownLocation);
|
||||
if direct_offset.bytes() > 0 {
|
||||
addr_ops.push(op_plus_uconst());
|
||||
addr_ops.push(direct_offset.bytes() as i64);
|
||||
}
|
||||
for &offset in indirect_offsets {
|
||||
addr_ops.push(op_deref());
|
||||
if offset.bytes() > 0 {
|
||||
addr_ops.push(op_plus_uconst());
|
||||
addr_ops.push(offset.bytes() as i64);
|
||||
}
|
||||
}
|
||||
|
||||
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,
|
||||
)
|
||||
};
|
||||
source_loc::set_debug_location(self,
|
||||
InternalDebugLocation::new(scope_metadata, loc.line, loc.col.to_usize()));
|
||||
unsafe {
|
||||
let debug_loc = llvm::LLVMGetCurrentDebugLocation(self.llbuilder);
|
||||
let instr = llvm::LLVMRustDIBuilderInsertDeclareAtEnd(
|
||||
DIB(cx),
|
||||
variable_alloca,
|
||||
metadata,
|
||||
addr_ops.as_ptr(),
|
||||
addr_ops.len() as c_uint,
|
||||
debug_loc,
|
||||
self.llbb());
|
||||
|
||||
llvm::LLVMSetInstDebugLocation(self.llbuilder, instr);
|
||||
}
|
||||
source_loc::set_debug_location(self, UnknownLocation);
|
||||
}
|
||||
|
||||
fn set_source_location(
|
||||
@ -571,13 +585,4 @@ impl DebugInfoMethods<'tcx> for CodegenCx<'ll, 'tcx> {
|
||||
fn debuginfo_finalize(&self) {
|
||||
finalize(self)
|
||||
}
|
||||
|
||||
fn debuginfo_upvar_ops_sequence(&self, byte_offset_of_var_in_env: u64) -> [i64; 4] {
|
||||
unsafe {
|
||||
[llvm::LLVMRustDIBuilderCreateOpDeref(),
|
||||
llvm::LLVMRustDIBuilderCreateOpPlusUconst(),
|
||||
byte_offset_of_var_in_env as i64,
|
||||
llvm::LLVMRustDIBuilderCreateOpDeref()]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -38,6 +38,7 @@ extern crate rustc_fs_util;
|
||||
extern crate rustc_driver as _;
|
||||
|
||||
#[macro_use] extern crate log;
|
||||
extern crate smallvec;
|
||||
extern crate syntax;
|
||||
extern crate syntax_pos;
|
||||
extern crate rustc_errors as errors;
|
||||
|
@ -3,7 +3,7 @@ use rustc::hir::def_id::CrateNum;
|
||||
use rustc::mir;
|
||||
use rustc::session::config::DebugInfo;
|
||||
use rustc::ty::{self, UpvarSubsts};
|
||||
use rustc::ty::layout::HasTyCtxt;
|
||||
use rustc::ty::layout::{HasTyCtxt, Size};
|
||||
use rustc_target::abi::{Variants, VariantIdx};
|
||||
use crate::traits::*;
|
||||
|
||||
@ -19,14 +19,6 @@ pub struct FunctionDebugContext<D> {
|
||||
pub defining_crate: CrateNum,
|
||||
}
|
||||
|
||||
pub enum VariableAccess<'a, V> {
|
||||
// The llptr given is an alloca containing the variable's value
|
||||
DirectVariable { alloca: V },
|
||||
// The llptr given is an alloca containing the start of some pointer chain
|
||||
// leading to the variable's content.
|
||||
IndirectVariable { alloca: V, address_operations: &'a [i64] }
|
||||
}
|
||||
|
||||
pub enum VariableKind {
|
||||
ArgumentVariable(usize /*index*/),
|
||||
LocalVariable,
|
||||
@ -188,8 +180,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
|
||||
});
|
||||
if let Some(scope) = scope {
|
||||
bx.declare_local(debug_context, name, place.layout.ty, scope,
|
||||
VariableAccess::DirectVariable { alloca: place.llval },
|
||||
kind, span);
|
||||
place.llval, Size::ZERO, &[], kind, span);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -310,30 +301,35 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
|
||||
}
|
||||
None => &closure_layout.fields,
|
||||
};
|
||||
let byte_offset_of_var_in_env = fields.offset(field).bytes();
|
||||
|
||||
let ops = bx.debuginfo_upvar_ops_sequence(byte_offset_of_var_in_env);
|
||||
|
||||
// The environment and the capture can each be indirect.
|
||||
let mut ops = if env_ref { &ops[..] } else { &ops[1..] };
|
||||
let mut direct_offset = Size::ZERO;
|
||||
let indirect_offsets = [
|
||||
fields.offset(field),
|
||||
Size::ZERO,
|
||||
];
|
||||
let mut indirect_offsets = &indirect_offsets[..];
|
||||
|
||||
if !env_ref {
|
||||
direct_offset = indirect_offsets[0];
|
||||
indirect_offsets = &indirect_offsets[1..];
|
||||
}
|
||||
|
||||
let ty = if let (true, &ty::Ref(_, ty, _)) = (by_ref, &ty.kind) {
|
||||
ty
|
||||
} else {
|
||||
ops = &ops[..ops.len() - 1];
|
||||
indirect_offsets = &indirect_offsets[..indirect_offsets.len() - 1];
|
||||
ty
|
||||
};
|
||||
|
||||
let variable_access = VariableAccess::IndirectVariable {
|
||||
alloca: place.llval,
|
||||
address_operations: &ops
|
||||
};
|
||||
bx.declare_local(
|
||||
debug_context,
|
||||
name,
|
||||
ty,
|
||||
var_scope,
|
||||
variable_access,
|
||||
place.llval,
|
||||
direct_offset,
|
||||
indirect_offsets,
|
||||
VariableKind::LocalVariable,
|
||||
var_span
|
||||
);
|
||||
|
@ -1,8 +1,9 @@
|
||||
use super::BackendTypes;
|
||||
use crate::mir::debuginfo::{FunctionDebugContext, VariableAccess, VariableKind};
|
||||
use crate::mir::debuginfo::{FunctionDebugContext, VariableKind};
|
||||
use rustc::hir::def_id::CrateNum;
|
||||
use rustc::mir;
|
||||
use rustc::ty::{self, Ty, Instance};
|
||||
use rustc::ty::layout::Size;
|
||||
use syntax::ast::Name;
|
||||
use syntax_pos::{SourceFile, Span};
|
||||
|
||||
@ -28,7 +29,6 @@ pub trait DebugInfoMethods<'tcx>: BackendTypes {
|
||||
defining_crate: CrateNum,
|
||||
) -> Self::DIScope;
|
||||
fn debuginfo_finalize(&self);
|
||||
fn debuginfo_upvar_ops_sequence(&self, byte_offset_of_var_in_env: u64) -> [i64; 4];
|
||||
}
|
||||
|
||||
pub trait DebugInfoBuilderMethods<'tcx>: BackendTypes {
|
||||
@ -38,7 +38,10 @@ pub trait DebugInfoBuilderMethods<'tcx>: BackendTypes {
|
||||
variable_name: Name,
|
||||
variable_type: Ty<'tcx>,
|
||||
scope_metadata: Self::DIScope,
|
||||
variable_access: VariableAccess<'_, Self::Value>,
|
||||
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,
|
||||
);
|
||||
|
Loading…
x
Reference in New Issue
Block a user