rustc_codegen_ssa: hide address ops from the declare_local interface.
This commit is contained in:
parent
c2e7743da8
commit
1e42072673
4 changed files with 76 additions and 71 deletions
|
@ -1,7 +1,6 @@
|
||||||
// See doc.rs for documentation.
|
// See doc.rs for documentation.
|
||||||
mod doc;
|
mod doc;
|
||||||
|
|
||||||
use rustc_codegen_ssa::mir::debuginfo::VariableAccess::*;
|
|
||||||
use rustc_codegen_ssa::mir::debuginfo::VariableKind::*;
|
use rustc_codegen_ssa::mir::debuginfo::VariableKind::*;
|
||||||
|
|
||||||
use self::utils::{DIB, span_start, create_DIArray, is_node_local_to_unit};
|
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_data_structures::small_c_str::SmallCStr;
|
||||||
use rustc_index::vec::IndexVec;
|
use rustc_index::vec::IndexVec;
|
||||||
use rustc_codegen_ssa::debuginfo::type_names;
|
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};
|
VariableKind};
|
||||||
|
|
||||||
use libc::c_uint;
|
use libc::c_uint;
|
||||||
use std::cell::RefCell;
|
use std::cell::RefCell;
|
||||||
use std::ffi::{CStr, CString};
|
use std::ffi::{CStr, CString};
|
||||||
|
|
||||||
|
use smallvec::SmallVec;
|
||||||
use syntax_pos::{self, BytePos, Span, Pos};
|
use syntax_pos::{self, BytePos, Span, Pos};
|
||||||
use syntax::ast;
|
use syntax::ast;
|
||||||
use syntax::symbol::Symbol;
|
use syntax::symbol::Symbol;
|
||||||
use rustc::ty::layout::{self, LayoutOf, HasTyCtxt};
|
use rustc::ty::layout::{self, LayoutOf, HasTyCtxt, Size};
|
||||||
use rustc_codegen_ssa::traits::*;
|
use rustc_codegen_ssa::traits::*;
|
||||||
|
|
||||||
pub mod gdb;
|
pub mod gdb;
|
||||||
|
@ -153,7 +153,9 @@ impl DebugInfoBuilderMethods<'tcx> for Builder<'a, 'll, 'tcx> {
|
||||||
variable_name: ast::Name,
|
variable_name: ast::Name,
|
||||||
variable_type: Ty<'tcx>,
|
variable_type: Ty<'tcx>,
|
||||||
scope_metadata: &'ll DIScope,
|
scope_metadata: &'ll DIScope,
|
||||||
variable_access: VariableAccess<'_, &'ll Value>,
|
variable_alloca: Self::Value,
|
||||||
|
direct_offset: Size,
|
||||||
|
indirect_offsets: &[Size],
|
||||||
variable_kind: VariableKind,
|
variable_kind: VariableKind,
|
||||||
span: Span,
|
span: Span,
|
||||||
) {
|
) {
|
||||||
|
@ -174,43 +176,55 @@ impl DebugInfoBuilderMethods<'tcx> for Builder<'a, 'll, 'tcx> {
|
||||||
};
|
};
|
||||||
let align = cx.align_of(variable_type);
|
let align = cx.align_of(variable_type);
|
||||||
|
|
||||||
let name = SmallCStr::new(&variable_name.as_str());
|
// Convert the direct and indirect offsets to address ops.
|
||||||
match (variable_access, &[][..]) {
|
let op_deref = || unsafe { llvm::LLVMRustDIBuilderCreateOpDeref() };
|
||||||
(DirectVariable { alloca }, address_operations) |
|
let op_plus_uconst = || unsafe { llvm::LLVMRustDIBuilderCreateOpPlusUconst() };
|
||||||
(IndirectVariable {alloca, address_operations}, _) => {
|
let mut addr_ops = SmallVec::<[_; 8]>::new();
|
||||||
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());
|
|
||||||
|
|
||||||
llvm::LLVMSetInstDebugLocation(self.llbuilder, instr);
|
if direct_offset.bytes() > 0 {
|
||||||
}
|
addr_ops.push(op_plus_uconst());
|
||||||
source_loc::set_debug_location(self, UnknownLocation);
|
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(
|
fn set_source_location(
|
||||||
|
@ -571,13 +585,4 @@ impl DebugInfoMethods<'tcx> for CodegenCx<'ll, 'tcx> {
|
||||||
fn debuginfo_finalize(&self) {
|
fn debuginfo_finalize(&self) {
|
||||||
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 _;
|
extern crate rustc_driver as _;
|
||||||
|
|
||||||
#[macro_use] extern crate log;
|
#[macro_use] extern crate log;
|
||||||
|
extern crate smallvec;
|
||||||
extern crate syntax;
|
extern crate syntax;
|
||||||
extern crate syntax_pos;
|
extern crate syntax_pos;
|
||||||
extern crate rustc_errors as errors;
|
extern crate rustc_errors as errors;
|
||||||
|
|
|
@ -3,7 +3,7 @@ use rustc::hir::def_id::CrateNum;
|
||||||
use rustc::mir;
|
use rustc::mir;
|
||||||
use rustc::session::config::DebugInfo;
|
use rustc::session::config::DebugInfo;
|
||||||
use rustc::ty::{self, UpvarSubsts};
|
use rustc::ty::{self, UpvarSubsts};
|
||||||
use rustc::ty::layout::HasTyCtxt;
|
use rustc::ty::layout::{HasTyCtxt, Size};
|
||||||
use rustc_target::abi::{Variants, VariantIdx};
|
use rustc_target::abi::{Variants, VariantIdx};
|
||||||
use crate::traits::*;
|
use crate::traits::*;
|
||||||
|
|
||||||
|
@ -19,14 +19,6 @@ pub struct FunctionDebugContext<D> {
|
||||||
pub defining_crate: CrateNum,
|
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 {
|
pub enum VariableKind {
|
||||||
ArgumentVariable(usize /*index*/),
|
ArgumentVariable(usize /*index*/),
|
||||||
LocalVariable,
|
LocalVariable,
|
||||||
|
@ -188,8 +180,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
|
||||||
});
|
});
|
||||||
if let Some(scope) = scope {
|
if let Some(scope) = scope {
|
||||||
bx.declare_local(debug_context, name, place.layout.ty, scope,
|
bx.declare_local(debug_context, name, place.layout.ty, scope,
|
||||||
VariableAccess::DirectVariable { alloca: place.llval },
|
place.llval, Size::ZERO, &[], kind, span);
|
||||||
kind, span);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -310,30 +301,35 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
|
||||||
}
|
}
|
||||||
None => &closure_layout.fields,
|
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.
|
// 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) {
|
let ty = if let (true, &ty::Ref(_, ty, _)) = (by_ref, &ty.kind) {
|
||||||
ty
|
ty
|
||||||
} else {
|
} else {
|
||||||
ops = &ops[..ops.len() - 1];
|
indirect_offsets = &indirect_offsets[..indirect_offsets.len() - 1];
|
||||||
ty
|
ty
|
||||||
};
|
};
|
||||||
|
|
||||||
let variable_access = VariableAccess::IndirectVariable {
|
|
||||||
alloca: place.llval,
|
|
||||||
address_operations: &ops
|
|
||||||
};
|
|
||||||
bx.declare_local(
|
bx.declare_local(
|
||||||
debug_context,
|
debug_context,
|
||||||
name,
|
name,
|
||||||
ty,
|
ty,
|
||||||
var_scope,
|
var_scope,
|
||||||
variable_access,
|
place.llval,
|
||||||
|
direct_offset,
|
||||||
|
indirect_offsets,
|
||||||
VariableKind::LocalVariable,
|
VariableKind::LocalVariable,
|
||||||
var_span
|
var_span
|
||||||
);
|
);
|
||||||
|
|
|
@ -1,8 +1,9 @@
|
||||||
use super::BackendTypes;
|
use super::BackendTypes;
|
||||||
use crate::mir::debuginfo::{FunctionDebugContext, VariableAccess, VariableKind};
|
use crate::mir::debuginfo::{FunctionDebugContext, VariableKind};
|
||||||
use rustc::hir::def_id::CrateNum;
|
use rustc::hir::def_id::CrateNum;
|
||||||
use rustc::mir;
|
use rustc::mir;
|
||||||
use rustc::ty::{self, Ty, Instance};
|
use rustc::ty::{self, Ty, Instance};
|
||||||
|
use rustc::ty::layout::Size;
|
||||||
use syntax::ast::Name;
|
use syntax::ast::Name;
|
||||||
use syntax_pos::{SourceFile, Span};
|
use syntax_pos::{SourceFile, Span};
|
||||||
|
|
||||||
|
@ -28,7 +29,6 @@ pub trait DebugInfoMethods<'tcx>: BackendTypes {
|
||||||
defining_crate: CrateNum,
|
defining_crate: CrateNum,
|
||||||
) -> Self::DIScope;
|
) -> Self::DIScope;
|
||||||
fn debuginfo_finalize(&self);
|
fn debuginfo_finalize(&self);
|
||||||
fn debuginfo_upvar_ops_sequence(&self, byte_offset_of_var_in_env: u64) -> [i64; 4];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub trait DebugInfoBuilderMethods<'tcx>: BackendTypes {
|
pub trait DebugInfoBuilderMethods<'tcx>: BackendTypes {
|
||||||
|
@ -38,7 +38,10 @@ pub trait DebugInfoBuilderMethods<'tcx>: BackendTypes {
|
||||||
variable_name: Name,
|
variable_name: Name,
|
||||||
variable_type: Ty<'tcx>,
|
variable_type: Ty<'tcx>,
|
||||||
scope_metadata: Self::DIScope,
|
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,
|
variable_kind: VariableKind,
|
||||||
span: Span,
|
span: Span,
|
||||||
);
|
);
|
||||||
|
|
Loading…
Reference in a new issue