rustc_codegen_llvm: use safe references for Metadata and DI*.
This commit is contained in:
parent
6d0d82ce10
commit
eed48f560f
12 changed files with 410 additions and 376 deletions
|
@ -31,7 +31,7 @@ use super::ModuleKind;
|
||||||
use abi;
|
use abi;
|
||||||
use back::link;
|
use back::link;
|
||||||
use back::write::{self, OngoingCodegen};
|
use back::write::{self, OngoingCodegen};
|
||||||
use llvm::{ValueRef, Vector, get_param};
|
use llvm::{TypeKind, ValueRef, get_param};
|
||||||
use llvm;
|
use llvm;
|
||||||
use metadata;
|
use metadata;
|
||||||
use rustc::hir::def_id::{CrateNum, DefId, LOCAL_CRATE};
|
use rustc::hir::def_id::{CrateNum, DefId, LOCAL_CRATE};
|
||||||
|
@ -349,10 +349,10 @@ fn cast_shift_rhs<'ll, F, G>(op: hir::BinOpKind,
|
||||||
if op.is_shift() {
|
if op.is_shift() {
|
||||||
let mut rhs_llty = val_ty(rhs);
|
let mut rhs_llty = val_ty(rhs);
|
||||||
let mut lhs_llty = val_ty(lhs);
|
let mut lhs_llty = val_ty(lhs);
|
||||||
if rhs_llty.kind() == Vector {
|
if rhs_llty.kind() == TypeKind::Vector {
|
||||||
rhs_llty = rhs_llty.element_type()
|
rhs_llty = rhs_llty.element_type()
|
||||||
}
|
}
|
||||||
if lhs_llty.kind() == Vector {
|
if lhs_llty.kind() == TypeKind::Vector {
|
||||||
lhs_llty = lhs_llty.element_type()
|
lhs_llty = lhs_llty.element_type()
|
||||||
}
|
}
|
||||||
let rhs_sz = rhs_llty.int_width();
|
let rhs_sz = rhs_llty.int_width();
|
||||||
|
|
|
@ -13,10 +13,9 @@ use super::metadata::file_metadata;
|
||||||
use super::utils::{DIB, span_start};
|
use super::utils::{DIB, span_start};
|
||||||
|
|
||||||
use llvm;
|
use llvm;
|
||||||
use llvm::debuginfo::DIScope_opaque;
|
use llvm::debuginfo::DIScope;
|
||||||
use common::CodegenCx;
|
use common::CodegenCx;
|
||||||
use rustc::mir::{Mir, SourceScope};
|
use rustc::mir::{Mir, SourceScope};
|
||||||
use std::ptr::NonNull;
|
|
||||||
|
|
||||||
use libc::c_uint;
|
use libc::c_uint;
|
||||||
|
|
||||||
|
@ -28,15 +27,15 @@ use rustc_data_structures::indexed_vec::{Idx, IndexVec};
|
||||||
use syntax_pos::BytePos;
|
use syntax_pos::BytePos;
|
||||||
|
|
||||||
#[derive(Clone, Copy, Debug)]
|
#[derive(Clone, Copy, Debug)]
|
||||||
pub struct MirDebugScope {
|
pub struct MirDebugScope<'ll> {
|
||||||
pub scope_metadata: Option<NonNull<DIScope_opaque>>,
|
pub scope_metadata: Option<&'ll DIScope>,
|
||||||
// Start and end offsets of the file to which this DIScope belongs.
|
// Start and end offsets of the file to which this DIScope belongs.
|
||||||
// These are used to quickly determine whether some span refers to the same file.
|
// These are used to quickly determine whether some span refers to the same file.
|
||||||
pub file_start_pos: BytePos,
|
pub file_start_pos: BytePos,
|
||||||
pub file_end_pos: BytePos,
|
pub file_end_pos: BytePos,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl MirDebugScope {
|
impl MirDebugScope<'ll> {
|
||||||
pub fn is_valid(&self) -> bool {
|
pub fn is_valid(&self) -> bool {
|
||||||
!self.scope_metadata.is_none()
|
!self.scope_metadata.is_none()
|
||||||
}
|
}
|
||||||
|
@ -44,8 +43,8 @@ impl MirDebugScope {
|
||||||
|
|
||||||
/// Produce DIScope DIEs for each MIR Scope which has variables defined in it.
|
/// Produce DIScope DIEs for each MIR Scope which has variables defined in it.
|
||||||
/// If debuginfo is disabled, the returned vector is empty.
|
/// If debuginfo is disabled, the returned vector is empty.
|
||||||
pub fn create_mir_scopes(cx: &CodegenCx, mir: &Mir, debug_context: &FunctionDebugContext)
|
pub fn create_mir_scopes(cx: &CodegenCx<'ll, '_>, mir: &Mir, debug_context: &FunctionDebugContext<'ll>)
|
||||||
-> IndexVec<SourceScope, MirDebugScope> {
|
-> IndexVec<SourceScope, MirDebugScope<'ll>> {
|
||||||
let null_scope = MirDebugScope {
|
let null_scope = MirDebugScope {
|
||||||
scope_metadata: None,
|
scope_metadata: None,
|
||||||
file_start_pos: BytePos(0),
|
file_start_pos: BytePos(0),
|
||||||
|
@ -77,12 +76,12 @@ pub fn create_mir_scopes(cx: &CodegenCx, mir: &Mir, debug_context: &FunctionDebu
|
||||||
scopes
|
scopes
|
||||||
}
|
}
|
||||||
|
|
||||||
fn make_mir_scope(cx: &CodegenCx,
|
fn make_mir_scope(cx: &CodegenCx<'ll, '_>,
|
||||||
mir: &Mir,
|
mir: &Mir,
|
||||||
has_variables: &BitVector<SourceScope>,
|
has_variables: &BitVector<SourceScope>,
|
||||||
debug_context: &FunctionDebugContextData,
|
debug_context: &FunctionDebugContextData<'ll>,
|
||||||
scope: SourceScope,
|
scope: SourceScope,
|
||||||
scopes: &mut IndexVec<SourceScope, MirDebugScope>) {
|
scopes: &mut IndexVec<SourceScope, MirDebugScope<'ll>>) {
|
||||||
if scopes[scope].is_valid() {
|
if scopes[scope].is_valid() {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -95,7 +94,7 @@ fn make_mir_scope(cx: &CodegenCx,
|
||||||
// The root is the function itself.
|
// The root is the function itself.
|
||||||
let loc = span_start(cx, mir.span);
|
let loc = span_start(cx, mir.span);
|
||||||
scopes[scope] = MirDebugScope {
|
scopes[scope] = MirDebugScope {
|
||||||
scope_metadata: NonNull::new(debug_context.fn_metadata),
|
scope_metadata: Some(debug_context.fn_metadata),
|
||||||
file_start_pos: loc.file.start_pos,
|
file_start_pos: loc.file.start_pos,
|
||||||
file_end_pos: loc.file.end_pos,
|
file_end_pos: loc.file.end_pos,
|
||||||
};
|
};
|
||||||
|
@ -109,7 +108,7 @@ fn make_mir_scope(cx: &CodegenCx,
|
||||||
// However, we don't skip creating a nested scope if
|
// However, we don't skip creating a nested scope if
|
||||||
// our parent is the root, because we might want to
|
// our parent is the root, because we might want to
|
||||||
// put arguments in the root and not have shadowing.
|
// put arguments in the root and not have shadowing.
|
||||||
if parent_scope.scope_metadata.unwrap().as_ptr() != debug_context.fn_metadata {
|
if parent_scope.scope_metadata.unwrap() != debug_context.fn_metadata {
|
||||||
scopes[scope] = parent_scope;
|
scopes[scope] = parent_scope;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -121,9 +120,9 @@ fn make_mir_scope(cx: &CodegenCx,
|
||||||
debug_context.defining_crate);
|
debug_context.defining_crate);
|
||||||
|
|
||||||
let scope_metadata = unsafe {
|
let scope_metadata = unsafe {
|
||||||
NonNull::new(llvm::LLVMRustDIBuilderCreateLexicalBlock(
|
Some(llvm::LLVMRustDIBuilderCreateLexicalBlock(
|
||||||
DIB(cx),
|
DIB(cx),
|
||||||
parent_scope.scope_metadata.unwrap().as_ptr(),
|
parent_scope.scope_metadata.unwrap(),
|
||||||
file_metadata,
|
file_metadata,
|
||||||
loc.line as c_uint,
|
loc.line as c_uint,
|
||||||
loc.col.to_usize() as c_uint))
|
loc.col.to_usize() as c_uint))
|
||||||
|
|
|
@ -20,7 +20,7 @@ use super::{CrateDebugContext};
|
||||||
use abi;
|
use abi;
|
||||||
|
|
||||||
use llvm::{self, ValueRef};
|
use llvm::{self, ValueRef};
|
||||||
use llvm::debuginfo::{DIType, DIFile, DIScope_opaque, DIScope, DIDescriptor,
|
use llvm::debuginfo::{DIType, DIFile, DIScope, DIDescriptor,
|
||||||
DICompositeType, DILexicalBlock, DIFlags};
|
DICompositeType, DILexicalBlock, DIFlags};
|
||||||
|
|
||||||
use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
|
use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
|
||||||
|
@ -38,15 +38,34 @@ use rustc::util::common::path2cstr;
|
||||||
|
|
||||||
use libc::{c_uint, c_longlong};
|
use libc::{c_uint, c_longlong};
|
||||||
use std::ffi::CString;
|
use std::ffi::CString;
|
||||||
use std::fmt::Write;
|
use std::fmt::{self, Write};
|
||||||
|
use std::hash::{Hash, Hasher};
|
||||||
use std::iter;
|
use std::iter;
|
||||||
use std::ptr;
|
use std::ptr;
|
||||||
use std::ptr::NonNull;
|
|
||||||
use std::path::{Path, PathBuf};
|
use std::path::{Path, PathBuf};
|
||||||
use syntax::ast;
|
use syntax::ast;
|
||||||
use syntax::symbol::{Interner, InternedString, Symbol};
|
use syntax::symbol::{Interner, InternedString, Symbol};
|
||||||
use syntax_pos::{self, Span, FileName};
|
use syntax_pos::{self, Span, FileName};
|
||||||
|
|
||||||
|
impl PartialEq for llvm::Metadata {
|
||||||
|
fn eq(&self, other: &Self) -> bool {
|
||||||
|
self as *const _ == other as *const _
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Eq for llvm::Metadata {}
|
||||||
|
|
||||||
|
impl Hash for llvm::Metadata {
|
||||||
|
fn hash<H: Hasher>(&self, hasher: &mut H) {
|
||||||
|
(self as *const Self).hash(hasher);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl fmt::Debug for llvm::Metadata {
|
||||||
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||||
|
(self as *const Self).fmt(f)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// From DWARF 5.
|
// From DWARF 5.
|
||||||
// See http://www.dwarfstd.org/ShowIssue.php?issue=140129.1
|
// See http://www.dwarfstd.org/ShowIssue.php?issue=140129.1
|
||||||
|
@ -65,7 +84,7 @@ const DW_ATE_unsigned_char: c_uint = 0x08;
|
||||||
pub const UNKNOWN_LINE_NUMBER: c_uint = 0;
|
pub const UNKNOWN_LINE_NUMBER: c_uint = 0;
|
||||||
pub const UNKNOWN_COLUMN_NUMBER: c_uint = 0;
|
pub const UNKNOWN_COLUMN_NUMBER: c_uint = 0;
|
||||||
|
|
||||||
pub const NO_SCOPE_METADATA: Option<NonNull<DIScope_opaque>> = None;
|
pub const NO_SCOPE_METADATA: Option<&DIScope> = None;
|
||||||
|
|
||||||
#[derive(Copy, Debug, Hash, Eq, PartialEq, Clone)]
|
#[derive(Copy, Debug, Hash, Eq, PartialEq, Clone)]
|
||||||
pub struct UniqueTypeId(ast::Name);
|
pub struct UniqueTypeId(ast::Name);
|
||||||
|
@ -74,19 +93,19 @@ pub struct UniqueTypeId(ast::Name);
|
||||||
// created so far. The metadata nodes are indexed by UniqueTypeId, and, for
|
// created so far. The metadata nodes are indexed by UniqueTypeId, and, for
|
||||||
// faster lookup, also by Ty. The TypeMap is responsible for creating
|
// faster lookup, also by Ty. The TypeMap is responsible for creating
|
||||||
// UniqueTypeIds.
|
// UniqueTypeIds.
|
||||||
pub struct TypeMap<'tcx> {
|
pub struct TypeMap<'ll, 'tcx> {
|
||||||
// The UniqueTypeIds created so far
|
// The UniqueTypeIds created so far
|
||||||
unique_id_interner: Interner,
|
unique_id_interner: Interner,
|
||||||
// A map from UniqueTypeId to debuginfo metadata for that type. This is a 1:1 mapping.
|
// A map from UniqueTypeId to debuginfo metadata for that type. This is a 1:1 mapping.
|
||||||
unique_id_to_metadata: FxHashMap<UniqueTypeId, DIType>,
|
unique_id_to_metadata: FxHashMap<UniqueTypeId, &'ll DIType>,
|
||||||
// A map from types to debuginfo metadata. This is a N:1 mapping.
|
// A map from types to debuginfo metadata. This is a N:1 mapping.
|
||||||
type_to_metadata: FxHashMap<Ty<'tcx>, DIType>,
|
type_to_metadata: FxHashMap<Ty<'tcx>, &'ll DIType>,
|
||||||
// A map from types to UniqueTypeId. This is a N:1 mapping.
|
// A map from types to UniqueTypeId. This is a N:1 mapping.
|
||||||
type_to_unique_id: FxHashMap<Ty<'tcx>, UniqueTypeId>
|
type_to_unique_id: FxHashMap<Ty<'tcx>, UniqueTypeId>
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'tcx> TypeMap<'tcx> {
|
impl TypeMap<'ll, 'tcx> {
|
||||||
pub fn new() -> TypeMap<'tcx> {
|
pub fn new() -> Self {
|
||||||
TypeMap {
|
TypeMap {
|
||||||
unique_id_interner: Interner::new(),
|
unique_id_interner: Interner::new(),
|
||||||
type_to_metadata: FxHashMap(),
|
type_to_metadata: FxHashMap(),
|
||||||
|
@ -97,9 +116,11 @@ impl<'tcx> TypeMap<'tcx> {
|
||||||
|
|
||||||
// Adds a Ty to metadata mapping to the TypeMap. The method will fail if
|
// Adds a Ty to metadata mapping to the TypeMap. The method will fail if
|
||||||
// the mapping already exists.
|
// the mapping already exists.
|
||||||
fn register_type_with_metadata<'a>(&mut self,
|
fn register_type_with_metadata(
|
||||||
|
&mut self,
|
||||||
type_: Ty<'tcx>,
|
type_: Ty<'tcx>,
|
||||||
metadata: DIType) {
|
metadata: &'ll DIType,
|
||||||
|
) {
|
||||||
if self.type_to_metadata.insert(type_, metadata).is_some() {
|
if self.type_to_metadata.insert(type_, metadata).is_some() {
|
||||||
bug!("Type metadata for Ty '{}' is already in the TypeMap!", type_);
|
bug!("Type metadata for Ty '{}' is already in the TypeMap!", type_);
|
||||||
}
|
}
|
||||||
|
@ -107,20 +128,22 @@ impl<'tcx> TypeMap<'tcx> {
|
||||||
|
|
||||||
// Adds a UniqueTypeId to metadata mapping to the TypeMap. The method will
|
// Adds a UniqueTypeId to metadata mapping to the TypeMap. The method will
|
||||||
// fail if the mapping already exists.
|
// fail if the mapping already exists.
|
||||||
fn register_unique_id_with_metadata(&mut self,
|
fn register_unique_id_with_metadata(
|
||||||
|
&mut self,
|
||||||
unique_type_id: UniqueTypeId,
|
unique_type_id: UniqueTypeId,
|
||||||
metadata: DIType) {
|
metadata: &'ll DIType,
|
||||||
|
) {
|
||||||
if self.unique_id_to_metadata.insert(unique_type_id, metadata).is_some() {
|
if self.unique_id_to_metadata.insert(unique_type_id, metadata).is_some() {
|
||||||
bug!("Type metadata for unique id '{}' is already in the TypeMap!",
|
bug!("Type metadata for unique id '{}' is already in the TypeMap!",
|
||||||
self.get_unique_type_id_as_string(unique_type_id));
|
self.get_unique_type_id_as_string(unique_type_id));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn find_metadata_for_type(&self, type_: Ty<'tcx>) -> Option<DIType> {
|
fn find_metadata_for_type(&self, type_: Ty<'tcx>) -> Option<&'ll DIType> {
|
||||||
self.type_to_metadata.get(&type_).cloned()
|
self.type_to_metadata.get(&type_).cloned()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn find_metadata_for_unique_id(&self, unique_type_id: UniqueTypeId) -> Option<DIType> {
|
fn find_metadata_for_unique_id(&self, unique_type_id: UniqueTypeId) -> Option<&'ll DIType> {
|
||||||
self.unique_id_to_metadata.get(&unique_type_id).cloned()
|
self.unique_id_to_metadata.get(&unique_type_id).cloned()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -182,23 +205,23 @@ impl<'tcx> TypeMap<'tcx> {
|
||||||
// needed to generate the missing parts of the description. See the
|
// needed to generate the missing parts of the description. See the
|
||||||
// documentation section on Recursive Types at the top of this file for more
|
// documentation section on Recursive Types at the top of this file for more
|
||||||
// information.
|
// information.
|
||||||
enum RecursiveTypeDescription<'tcx> {
|
enum RecursiveTypeDescription<'ll, 'tcx> {
|
||||||
UnfinishedMetadata {
|
UnfinishedMetadata {
|
||||||
unfinished_type: Ty<'tcx>,
|
unfinished_type: Ty<'tcx>,
|
||||||
unique_type_id: UniqueTypeId,
|
unique_type_id: UniqueTypeId,
|
||||||
metadata_stub: DICompositeType,
|
metadata_stub: &'ll DICompositeType,
|
||||||
member_description_factory: MemberDescriptionFactory<'tcx>,
|
member_description_factory: MemberDescriptionFactory<'ll, 'tcx>,
|
||||||
},
|
},
|
||||||
FinalMetadata(DICompositeType)
|
FinalMetadata(&'ll DICompositeType)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn create_and_register_recursive_type_forward_declaration<'a, 'tcx>(
|
fn create_and_register_recursive_type_forward_declaration(
|
||||||
cx: &CodegenCx<'a, 'tcx>,
|
cx: &CodegenCx<'ll, 'tcx>,
|
||||||
unfinished_type: Ty<'tcx>,
|
unfinished_type: Ty<'tcx>,
|
||||||
unique_type_id: UniqueTypeId,
|
unique_type_id: UniqueTypeId,
|
||||||
metadata_stub: DICompositeType,
|
metadata_stub: &'ll DICompositeType,
|
||||||
member_description_factory: MemberDescriptionFactory<'tcx>)
|
member_description_factory: MemberDescriptionFactory<'ll, 'tcx>,
|
||||||
-> RecursiveTypeDescription<'tcx> {
|
) -> RecursiveTypeDescription<'ll, 'tcx> {
|
||||||
|
|
||||||
// Insert the stub into the TypeMap in order to allow for recursive references
|
// Insert the stub into the TypeMap in order to allow for recursive references
|
||||||
let mut type_map = debug_context(cx).type_map.borrow_mut();
|
let mut type_map = debug_context(cx).type_map.borrow_mut();
|
||||||
|
@ -213,11 +236,11 @@ fn create_and_register_recursive_type_forward_declaration<'a, 'tcx>(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'tcx> RecursiveTypeDescription<'tcx> {
|
impl RecursiveTypeDescription<'ll, 'tcx> {
|
||||||
// Finishes up the description of the type in question (mostly by providing
|
// Finishes up the description of the type in question (mostly by providing
|
||||||
// descriptions of the fields of the given type) and returns the final type
|
// descriptions of the fields of the given type) and returns the final type
|
||||||
// metadata.
|
// metadata.
|
||||||
fn finalize<'a>(&self, cx: &CodegenCx<'a, 'tcx>) -> MetadataCreationResult {
|
fn finalize(&self, cx: &CodegenCx<'ll, 'tcx>) -> MetadataCreationResult<'ll> {
|
||||||
match *self {
|
match *self {
|
||||||
FinalMetadata(metadata) => MetadataCreationResult::new(metadata, false),
|
FinalMetadata(metadata) => MetadataCreationResult::new(metadata, false),
|
||||||
UnfinishedMetadata {
|
UnfinishedMetadata {
|
||||||
|
@ -269,12 +292,13 @@ macro_rules! return_if_metadata_created_in_meantime {
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn fixed_vec_metadata<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>,
|
fn fixed_vec_metadata(
|
||||||
|
cx: &CodegenCx<'ll, 'tcx>,
|
||||||
unique_type_id: UniqueTypeId,
|
unique_type_id: UniqueTypeId,
|
||||||
array_or_slice_type: Ty<'tcx>,
|
array_or_slice_type: Ty<'tcx>,
|
||||||
element_type: Ty<'tcx>,
|
element_type: Ty<'tcx>,
|
||||||
span: Span)
|
span: Span,
|
||||||
-> MetadataCreationResult {
|
) -> MetadataCreationResult<'ll> {
|
||||||
let element_type_metadata = type_metadata(cx, element_type, span);
|
let element_type_metadata = type_metadata(cx, element_type, span);
|
||||||
|
|
||||||
return_if_metadata_created_in_meantime!(cx, unique_type_id);
|
return_if_metadata_created_in_meantime!(cx, unique_type_id);
|
||||||
|
@ -289,7 +313,7 @@ fn fixed_vec_metadata<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>,
|
||||||
};
|
};
|
||||||
|
|
||||||
let subrange = unsafe {
|
let subrange = unsafe {
|
||||||
NonNull::new(llvm::LLVMRustDIBuilderGetOrCreateSubrange(DIB(cx), 0, upper_bound))
|
Some(llvm::LLVMRustDIBuilderGetOrCreateSubrange(DIB(cx), 0, upper_bound))
|
||||||
};
|
};
|
||||||
|
|
||||||
let subscripts = create_DIArray(DIB(cx), &[subrange]);
|
let subscripts = create_DIArray(DIB(cx), &[subrange]);
|
||||||
|
@ -305,12 +329,13 @@ fn fixed_vec_metadata<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>,
|
||||||
return MetadataCreationResult::new(metadata, false);
|
return MetadataCreationResult::new(metadata, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn vec_slice_metadata<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>,
|
fn vec_slice_metadata(
|
||||||
|
cx: &CodegenCx<'ll, 'tcx>,
|
||||||
slice_ptr_type: Ty<'tcx>,
|
slice_ptr_type: Ty<'tcx>,
|
||||||
element_type: Ty<'tcx>,
|
element_type: Ty<'tcx>,
|
||||||
unique_type_id: UniqueTypeId,
|
unique_type_id: UniqueTypeId,
|
||||||
span: Span)
|
span: Span,
|
||||||
-> MetadataCreationResult {
|
) -> MetadataCreationResult<'ll> {
|
||||||
let data_ptr_type = cx.tcx.mk_imm_ptr(element_type);
|
let data_ptr_type = cx.tcx.mk_imm_ptr(element_type);
|
||||||
|
|
||||||
let data_ptr_metadata = type_metadata(cx, data_ptr_type, span);
|
let data_ptr_metadata = type_metadata(cx, data_ptr_type, span);
|
||||||
|
@ -354,12 +379,12 @@ fn vec_slice_metadata<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>,
|
||||||
MetadataCreationResult::new(metadata, false)
|
MetadataCreationResult::new(metadata, false)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn subroutine_type_metadata<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>,
|
fn subroutine_type_metadata(
|
||||||
|
cx: &CodegenCx<'ll, 'tcx>,
|
||||||
unique_type_id: UniqueTypeId,
|
unique_type_id: UniqueTypeId,
|
||||||
signature: ty::PolyFnSig<'tcx>,
|
signature: ty::PolyFnSig<'tcx>,
|
||||||
span: Span)
|
span: Span,
|
||||||
-> MetadataCreationResult
|
) -> MetadataCreationResult<'ll> {
|
||||||
{
|
|
||||||
let signature = cx.tcx.normalize_erasing_late_bound_regions(
|
let signature = cx.tcx.normalize_erasing_late_bound_regions(
|
||||||
ty::ParamEnv::reveal_all(),
|
ty::ParamEnv::reveal_all(),
|
||||||
&signature,
|
&signature,
|
||||||
|
@ -369,12 +394,12 @@ fn subroutine_type_metadata<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>,
|
||||||
// return type
|
// return type
|
||||||
match signature.output().sty {
|
match signature.output().sty {
|
||||||
ty::TyTuple(ref tys) if tys.is_empty() => None,
|
ty::TyTuple(ref tys) if tys.is_empty() => None,
|
||||||
_ => NonNull::new(type_metadata(cx, signature.output(), span))
|
_ => Some(type_metadata(cx, signature.output(), span))
|
||||||
}
|
}
|
||||||
).chain(
|
).chain(
|
||||||
// regular arguments
|
// regular arguments
|
||||||
signature.inputs().iter().map(|argument_type| {
|
signature.inputs().iter().map(|argument_type| {
|
||||||
NonNull::new(type_metadata(cx, argument_type, span))
|
Some(type_metadata(cx, argument_type, span))
|
||||||
})
|
})
|
||||||
).collect();
|
).collect();
|
||||||
|
|
||||||
|
@ -396,11 +421,12 @@ fn subroutine_type_metadata<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>,
|
||||||
// trait_type should be the actual trait (e.g., Trait). Where the trait is part
|
// trait_type should be the actual trait (e.g., Trait). Where the trait is part
|
||||||
// of a DST struct, there is no trait_object_type and the results of this
|
// of a DST struct, there is no trait_object_type and the results of this
|
||||||
// function will be a little bit weird.
|
// function will be a little bit weird.
|
||||||
fn trait_pointer_metadata<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>,
|
fn trait_pointer_metadata(
|
||||||
|
cx: &CodegenCx<'ll, 'tcx>,
|
||||||
trait_type: Ty<'tcx>,
|
trait_type: Ty<'tcx>,
|
||||||
trait_object_type: Option<Ty<'tcx>>,
|
trait_object_type: Option<Ty<'tcx>>,
|
||||||
unique_type_id: UniqueTypeId)
|
unique_type_id: UniqueTypeId,
|
||||||
-> DIType {
|
) -> &'ll DIType {
|
||||||
// The implementation provided here is a stub. It makes sure that the trait
|
// The implementation provided here is a stub. It makes sure that the trait
|
||||||
// type is assigned the correct name, size, namespace, and source location.
|
// type is assigned the correct name, size, namespace, and source location.
|
||||||
// But it does not describe the trait's methods.
|
// But it does not describe the trait's methods.
|
||||||
|
@ -408,7 +434,7 @@ fn trait_pointer_metadata<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>,
|
||||||
let containing_scope = match trait_type.sty {
|
let containing_scope = match trait_type.sty {
|
||||||
ty::TyDynamic(ref data, ..) => if let Some(principal) = data.principal() {
|
ty::TyDynamic(ref data, ..) => if let Some(principal) = data.principal() {
|
||||||
let def_id = principal.def_id();
|
let def_id = principal.def_id();
|
||||||
NonNull::new(get_namespace_for_item(cx, def_id))
|
Some(get_namespace_for_item(cx, def_id))
|
||||||
} else {
|
} else {
|
||||||
NO_SCOPE_METADATA
|
NO_SCOPE_METADATA
|
||||||
},
|
},
|
||||||
|
@ -463,10 +489,11 @@ fn trait_pointer_metadata<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>,
|
||||||
syntax_pos::DUMMY_SP)
|
syntax_pos::DUMMY_SP)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn type_metadata<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>,
|
pub fn type_metadata(
|
||||||
|
cx: &CodegenCx<'ll, 'tcx>,
|
||||||
t: Ty<'tcx>,
|
t: Ty<'tcx>,
|
||||||
usage_site_span: Span)
|
usage_site_span: Span,
|
||||||
-> DIType {
|
) -> &'ll DIType {
|
||||||
// Get the unique type id of this type.
|
// Get the unique type id of this type.
|
||||||
let unique_type_id = {
|
let unique_type_id = {
|
||||||
let mut type_map = debug_context(cx).type_map.borrow_mut();
|
let mut type_map = debug_context(cx).type_map.borrow_mut();
|
||||||
|
@ -683,9 +710,9 @@ pub fn type_metadata<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>,
|
||||||
metadata
|
metadata
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn file_metadata(cx: &CodegenCx,
|
pub fn file_metadata(cx: &CodegenCx<'ll, '_>,
|
||||||
file_name: &FileName,
|
file_name: &FileName,
|
||||||
defining_crate: CrateNum) -> DIFile {
|
defining_crate: CrateNum) -> &'ll DIFile {
|
||||||
debug!("file_metadata: file_name: {}, defining_crate: {}",
|
debug!("file_metadata: file_name: {}, defining_crate: {}",
|
||||||
file_name,
|
file_name,
|
||||||
defining_crate);
|
defining_crate);
|
||||||
|
@ -701,14 +728,14 @@ pub fn file_metadata(cx: &CodegenCx,
|
||||||
file_metadata_raw(cx, &file_name.to_string(), &directory.to_string_lossy())
|
file_metadata_raw(cx, &file_name.to_string(), &directory.to_string_lossy())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn unknown_file_metadata(cx: &CodegenCx) -> DIFile {
|
pub fn unknown_file_metadata(cx: &CodegenCx<'ll, '_>) -> &'ll DIFile {
|
||||||
file_metadata_raw(cx, "<unknown>", "")
|
file_metadata_raw(cx, "<unknown>", "")
|
||||||
}
|
}
|
||||||
|
|
||||||
fn file_metadata_raw(cx: &CodegenCx,
|
fn file_metadata_raw(cx: &CodegenCx<'ll, '_>,
|
||||||
file_name: &str,
|
file_name: &str,
|
||||||
directory: &str)
|
directory: &str)
|
||||||
-> DIFile {
|
-> &'ll DIFile {
|
||||||
let key = (Symbol::intern(file_name), Symbol::intern(directory));
|
let key = (Symbol::intern(file_name), Symbol::intern(directory));
|
||||||
|
|
||||||
if let Some(file_metadata) = debug_context(cx).created_files.borrow().get(&key) {
|
if let Some(file_metadata) = debug_context(cx).created_files.borrow().get(&key) {
|
||||||
|
@ -731,9 +758,7 @@ fn file_metadata_raw(cx: &CodegenCx,
|
||||||
file_metadata
|
file_metadata
|
||||||
}
|
}
|
||||||
|
|
||||||
fn basic_type_metadata<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>,
|
fn basic_type_metadata(cx: &CodegenCx<'ll, 'tcx>, t: Ty<'tcx>) -> &'ll DIType {
|
||||||
t: Ty<'tcx>) -> DIType {
|
|
||||||
|
|
||||||
debug!("basic_type_metadata: {:?}", t);
|
debug!("basic_type_metadata: {:?}", t);
|
||||||
|
|
||||||
let (name, encoding) = match t.sty {
|
let (name, encoding) = match t.sty {
|
||||||
|
@ -768,19 +793,22 @@ fn basic_type_metadata<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>,
|
||||||
return ty_metadata;
|
return ty_metadata;
|
||||||
}
|
}
|
||||||
|
|
||||||
fn foreign_type_metadata<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>,
|
fn foreign_type_metadata(
|
||||||
|
cx: &CodegenCx<'ll, 'tcx>,
|
||||||
t: Ty<'tcx>,
|
t: Ty<'tcx>,
|
||||||
unique_type_id: UniqueTypeId) -> DIType {
|
unique_type_id: UniqueTypeId,
|
||||||
|
) -> &'ll DIType {
|
||||||
debug!("foreign_type_metadata: {:?}", t);
|
debug!("foreign_type_metadata: {:?}", t);
|
||||||
|
|
||||||
let name = compute_debuginfo_type_name(cx, t, false);
|
let name = compute_debuginfo_type_name(cx, t, false);
|
||||||
create_struct_stub(cx, t, &name, unique_type_id, NO_SCOPE_METADATA)
|
create_struct_stub(cx, t, &name, unique_type_id, NO_SCOPE_METADATA)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn pointer_type_metadata<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>,
|
fn pointer_type_metadata(
|
||||||
|
cx: &CodegenCx<'ll, 'tcx>,
|
||||||
pointer_type: Ty<'tcx>,
|
pointer_type: Ty<'tcx>,
|
||||||
pointee_type_metadata: DIType)
|
pointee_type_metadata: &'ll DIType,
|
||||||
-> DIType {
|
) -> &'ll DIType {
|
||||||
let (pointer_size, pointer_align) = cx.size_and_align_of(pointer_type);
|
let (pointer_size, pointer_align) = cx.size_and_align_of(pointer_type);
|
||||||
let name = compute_debuginfo_type_name(cx, pointer_type, false);
|
let name = compute_debuginfo_type_name(cx, pointer_type, false);
|
||||||
let name = CString::new(name).unwrap();
|
let name = CString::new(name).unwrap();
|
||||||
|
@ -796,8 +824,8 @@ fn pointer_type_metadata<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>,
|
||||||
|
|
||||||
pub fn compile_unit_metadata(tcx: TyCtxt,
|
pub fn compile_unit_metadata(tcx: TyCtxt,
|
||||||
codegen_unit_name: &str,
|
codegen_unit_name: &str,
|
||||||
debug_context: &CrateDebugContext)
|
debug_context: &CrateDebugContext<'ll, '_>)
|
||||||
-> DIDescriptor {
|
-> &'ll DIDescriptor {
|
||||||
let mut name_in_debuginfo = match tcx.sess.local_crate_source_file {
|
let mut name_in_debuginfo = match tcx.sess.local_crate_source_file {
|
||||||
Some(ref path) => path.clone(),
|
Some(ref path) => path.clone(),
|
||||||
None => PathBuf::from(&*tcx.crate_name(LOCAL_CRATE).as_str()),
|
None => PathBuf::from(&*tcx.crate_name(LOCAL_CRATE).as_str()),
|
||||||
|
@ -872,13 +900,13 @@ pub fn compile_unit_metadata(tcx: TyCtxt,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
struct MetadataCreationResult {
|
struct MetadataCreationResult<'ll> {
|
||||||
metadata: DIType,
|
metadata: &'ll DIType,
|
||||||
already_stored_in_typemap: bool
|
already_stored_in_typemap: bool
|
||||||
}
|
}
|
||||||
|
|
||||||
impl MetadataCreationResult {
|
impl MetadataCreationResult<'ll> {
|
||||||
fn new(metadata: DIType, already_stored_in_typemap: bool) -> MetadataCreationResult {
|
fn new(metadata: &'ll DIType, already_stored_in_typemap: bool) -> Self {
|
||||||
MetadataCreationResult {
|
MetadataCreationResult {
|
||||||
metadata,
|
metadata,
|
||||||
already_stored_in_typemap,
|
already_stored_in_typemap,
|
||||||
|
@ -889,9 +917,9 @@ impl MetadataCreationResult {
|
||||||
// Description of a type member, which can either be a regular field (as in
|
// Description of a type member, which can either be a regular field (as in
|
||||||
// structs or tuples) or an enum variant.
|
// structs or tuples) or an enum variant.
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
struct MemberDescription {
|
struct MemberDescription<'ll> {
|
||||||
name: String,
|
name: String,
|
||||||
type_metadata: DIType,
|
type_metadata: &'ll DIType,
|
||||||
offset: Size,
|
offset: Size,
|
||||||
size: Size,
|
size: Size,
|
||||||
align: Align,
|
align: Align,
|
||||||
|
@ -902,17 +930,17 @@ struct MemberDescription {
|
||||||
// for some record-like type. MemberDescriptionFactories are used to defer the
|
// for some record-like type. MemberDescriptionFactories are used to defer the
|
||||||
// creation of type member descriptions in order to break cycles arising from
|
// creation of type member descriptions in order to break cycles arising from
|
||||||
// recursive type definitions.
|
// recursive type definitions.
|
||||||
enum MemberDescriptionFactory<'tcx> {
|
enum MemberDescriptionFactory<'ll, 'tcx> {
|
||||||
StructMDF(StructMemberDescriptionFactory<'tcx>),
|
StructMDF(StructMemberDescriptionFactory<'tcx>),
|
||||||
TupleMDF(TupleMemberDescriptionFactory<'tcx>),
|
TupleMDF(TupleMemberDescriptionFactory<'tcx>),
|
||||||
EnumMDF(EnumMemberDescriptionFactory<'tcx>),
|
EnumMDF(EnumMemberDescriptionFactory<'ll, 'tcx>),
|
||||||
UnionMDF(UnionMemberDescriptionFactory<'tcx>),
|
UnionMDF(UnionMemberDescriptionFactory<'tcx>),
|
||||||
VariantMDF(VariantMemberDescriptionFactory<'tcx>)
|
VariantMDF(VariantMemberDescriptionFactory<'ll, 'tcx>)
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'tcx> MemberDescriptionFactory<'tcx> {
|
impl MemberDescriptionFactory<'ll, 'tcx> {
|
||||||
fn create_member_descriptions<'a>(&self, cx: &CodegenCx<'a, 'tcx>)
|
fn create_member_descriptions(&self, cx: &CodegenCx<'ll, 'tcx>)
|
||||||
-> Vec<MemberDescription> {
|
-> Vec<MemberDescription<'ll>> {
|
||||||
match *self {
|
match *self {
|
||||||
StructMDF(ref this) => {
|
StructMDF(ref this) => {
|
||||||
this.create_member_descriptions(cx)
|
this.create_member_descriptions(cx)
|
||||||
|
@ -945,8 +973,8 @@ struct StructMemberDescriptionFactory<'tcx> {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'tcx> StructMemberDescriptionFactory<'tcx> {
|
impl<'tcx> StructMemberDescriptionFactory<'tcx> {
|
||||||
fn create_member_descriptions<'a>(&self, cx: &CodegenCx<'a, 'tcx>)
|
fn create_member_descriptions(&self, cx: &CodegenCx<'ll, 'tcx>)
|
||||||
-> Vec<MemberDescription> {
|
-> Vec<MemberDescription<'ll>> {
|
||||||
let layout = cx.layout_of(self.ty);
|
let layout = cx.layout_of(self.ty);
|
||||||
self.variant.fields.iter().enumerate().map(|(i, f)| {
|
self.variant.fields.iter().enumerate().map(|(i, f)| {
|
||||||
let name = if self.variant.ctor_kind == CtorKind::Fn {
|
let name = if self.variant.ctor_kind == CtorKind::Fn {
|
||||||
|
@ -969,11 +997,12 @@ impl<'tcx> StructMemberDescriptionFactory<'tcx> {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
fn prepare_struct_metadata<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>,
|
fn prepare_struct_metadata(
|
||||||
|
cx: &CodegenCx<'ll, 'tcx>,
|
||||||
struct_type: Ty<'tcx>,
|
struct_type: Ty<'tcx>,
|
||||||
unique_type_id: UniqueTypeId,
|
unique_type_id: UniqueTypeId,
|
||||||
span: Span)
|
span: Span,
|
||||||
-> RecursiveTypeDescription<'tcx> {
|
) -> RecursiveTypeDescription<'ll, 'tcx> {
|
||||||
let struct_name = compute_debuginfo_type_name(cx, struct_type, false);
|
let struct_name = compute_debuginfo_type_name(cx, struct_type, false);
|
||||||
|
|
||||||
let (struct_def_id, variant) = match struct_type.sty {
|
let (struct_def_id, variant) = match struct_type.sty {
|
||||||
|
@ -987,7 +1016,7 @@ fn prepare_struct_metadata<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>,
|
||||||
struct_type,
|
struct_type,
|
||||||
&struct_name,
|
&struct_name,
|
||||||
unique_type_id,
|
unique_type_id,
|
||||||
NonNull::new(containing_scope));
|
Some(containing_scope));
|
||||||
|
|
||||||
create_and_register_recursive_type_forward_declaration(
|
create_and_register_recursive_type_forward_declaration(
|
||||||
cx,
|
cx,
|
||||||
|
@ -1014,8 +1043,8 @@ struct TupleMemberDescriptionFactory<'tcx> {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'tcx> TupleMemberDescriptionFactory<'tcx> {
|
impl<'tcx> TupleMemberDescriptionFactory<'tcx> {
|
||||||
fn create_member_descriptions<'a>(&self, cx: &CodegenCx<'a, 'tcx>)
|
fn create_member_descriptions(&self, cx: &CodegenCx<'ll, 'tcx>)
|
||||||
-> Vec<MemberDescription> {
|
-> Vec<MemberDescription<'ll>> {
|
||||||
let layout = cx.layout_of(self.ty);
|
let layout = cx.layout_of(self.ty);
|
||||||
self.component_types.iter().enumerate().map(|(i, &component_type)| {
|
self.component_types.iter().enumerate().map(|(i, &component_type)| {
|
||||||
let (size, align) = cx.size_and_align_of(component_type);
|
let (size, align) = cx.size_and_align_of(component_type);
|
||||||
|
@ -1031,12 +1060,13 @@ impl<'tcx> TupleMemberDescriptionFactory<'tcx> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn prepare_tuple_metadata<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>,
|
fn prepare_tuple_metadata(
|
||||||
|
cx: &CodegenCx<'ll, 'tcx>,
|
||||||
tuple_type: Ty<'tcx>,
|
tuple_type: Ty<'tcx>,
|
||||||
component_types: &[Ty<'tcx>],
|
component_types: &[Ty<'tcx>],
|
||||||
unique_type_id: UniqueTypeId,
|
unique_type_id: UniqueTypeId,
|
||||||
span: Span)
|
span: Span,
|
||||||
-> RecursiveTypeDescription<'tcx> {
|
) -> RecursiveTypeDescription<'ll, 'tcx> {
|
||||||
let tuple_name = compute_debuginfo_type_name(cx, tuple_type, false);
|
let tuple_name = compute_debuginfo_type_name(cx, tuple_type, false);
|
||||||
|
|
||||||
create_and_register_recursive_type_forward_declaration(
|
create_and_register_recursive_type_forward_declaration(
|
||||||
|
@ -1067,8 +1097,8 @@ struct UnionMemberDescriptionFactory<'tcx> {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'tcx> UnionMemberDescriptionFactory<'tcx> {
|
impl<'tcx> UnionMemberDescriptionFactory<'tcx> {
|
||||||
fn create_member_descriptions<'a>(&self, cx: &CodegenCx<'a, 'tcx>)
|
fn create_member_descriptions(&self, cx: &CodegenCx<'ll, 'tcx>)
|
||||||
-> Vec<MemberDescription> {
|
-> Vec<MemberDescription<'ll>> {
|
||||||
self.variant.fields.iter().enumerate().map(|(i, f)| {
|
self.variant.fields.iter().enumerate().map(|(i, f)| {
|
||||||
let field = self.layout.field(cx, i);
|
let field = self.layout.field(cx, i);
|
||||||
let (size, align) = field.size_and_align();
|
let (size, align) = field.size_and_align();
|
||||||
|
@ -1084,11 +1114,12 @@ impl<'tcx> UnionMemberDescriptionFactory<'tcx> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn prepare_union_metadata<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>,
|
fn prepare_union_metadata(
|
||||||
|
cx: &CodegenCx<'ll, 'tcx>,
|
||||||
union_type: Ty<'tcx>,
|
union_type: Ty<'tcx>,
|
||||||
unique_type_id: UniqueTypeId,
|
unique_type_id: UniqueTypeId,
|
||||||
span: Span)
|
span: Span,
|
||||||
-> RecursiveTypeDescription<'tcx> {
|
) -> RecursiveTypeDescription<'ll, 'tcx> {
|
||||||
let union_name = compute_debuginfo_type_name(cx, union_type, false);
|
let union_name = compute_debuginfo_type_name(cx, union_type, false);
|
||||||
|
|
||||||
let (union_def_id, variant) = match union_type.sty {
|
let (union_def_id, variant) = match union_type.sty {
|
||||||
|
@ -1126,17 +1157,17 @@ fn prepare_union_metadata<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>,
|
||||||
// the members of this union; so for every variant of the given enum, this
|
// the members of this union; so for every variant of the given enum, this
|
||||||
// factory will produce one MemberDescription (all with no name and a fixed
|
// factory will produce one MemberDescription (all with no name and a fixed
|
||||||
// offset of zero bytes).
|
// offset of zero bytes).
|
||||||
struct EnumMemberDescriptionFactory<'tcx> {
|
struct EnumMemberDescriptionFactory<'ll, 'tcx> {
|
||||||
enum_type: Ty<'tcx>,
|
enum_type: Ty<'tcx>,
|
||||||
layout: TyLayout<'tcx>,
|
layout: TyLayout<'tcx>,
|
||||||
discriminant_type_metadata: Option<DIType>,
|
discriminant_type_metadata: Option<&'ll DIType>,
|
||||||
containing_scope: DIScope,
|
containing_scope: &'ll DIScope,
|
||||||
span: Span,
|
span: Span,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'tcx> EnumMemberDescriptionFactory<'tcx> {
|
impl EnumMemberDescriptionFactory<'ll, 'tcx> {
|
||||||
fn create_member_descriptions<'a>(&self, cx: &CodegenCx<'a, 'tcx>)
|
fn create_member_descriptions(&self, cx: &CodegenCx<'ll, 'tcx>)
|
||||||
-> Vec<MemberDescription> {
|
-> Vec<MemberDescription<'ll>> {
|
||||||
let adt = &self.enum_type.ty_adt_def().unwrap();
|
let adt = &self.enum_type.ty_adt_def().unwrap();
|
||||||
match self.layout.variants {
|
match self.layout.variants {
|
||||||
layout::Variants::Single { .. } if adt.variants.is_empty() => vec![],
|
layout::Variants::Single { .. } if adt.variants.is_empty() => vec![],
|
||||||
|
@ -1261,17 +1292,17 @@ impl<'tcx> EnumMemberDescriptionFactory<'tcx> {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Creates MemberDescriptions for the fields of a single enum variant.
|
// Creates MemberDescriptions for the fields of a single enum variant.
|
||||||
struct VariantMemberDescriptionFactory<'tcx> {
|
struct VariantMemberDescriptionFactory<'ll, 'tcx> {
|
||||||
// Cloned from the layout::Struct describing the variant.
|
// Cloned from the layout::Struct describing the variant.
|
||||||
offsets: Vec<layout::Size>,
|
offsets: Vec<layout::Size>,
|
||||||
args: Vec<(String, Ty<'tcx>)>,
|
args: Vec<(String, Ty<'tcx>)>,
|
||||||
discriminant_type_metadata: Option<DIType>,
|
discriminant_type_metadata: Option<&'ll DIType>,
|
||||||
span: Span,
|
span: Span,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'tcx> VariantMemberDescriptionFactory<'tcx> {
|
impl VariantMemberDescriptionFactory<'ll, 'tcx> {
|
||||||
fn create_member_descriptions<'a>(&self, cx: &CodegenCx<'a, 'tcx>)
|
fn create_member_descriptions(&self, cx: &CodegenCx<'ll, 'tcx>)
|
||||||
-> Vec<MemberDescription> {
|
-> Vec<MemberDescription<'ll>> {
|
||||||
self.args.iter().enumerate().map(|(i, &(ref name, ty))| {
|
self.args.iter().enumerate().map(|(i, &(ref name, ty))| {
|
||||||
let (size, align) = cx.size_and_align_of(ty);
|
let (size, align) = cx.size_and_align_of(ty);
|
||||||
MemberDescription {
|
MemberDescription {
|
||||||
|
@ -1290,8 +1321,8 @@ impl<'tcx> VariantMemberDescriptionFactory<'tcx> {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Copy, Clone)]
|
#[derive(Copy, Clone)]
|
||||||
enum EnumDiscriminantInfo {
|
enum EnumDiscriminantInfo<'ll> {
|
||||||
RegularDiscriminant(DIType),
|
RegularDiscriminant(&'ll DIType),
|
||||||
OptimizedDiscriminant,
|
OptimizedDiscriminant,
|
||||||
NoDiscriminant
|
NoDiscriminant
|
||||||
}
|
}
|
||||||
|
@ -1300,13 +1331,14 @@ enum EnumDiscriminantInfo {
|
||||||
// of the variant, and (3) a MemberDescriptionFactory for producing the
|
// of the variant, and (3) a MemberDescriptionFactory for producing the
|
||||||
// descriptions of the fields of the variant. This is a rudimentary version of a
|
// descriptions of the fields of the variant. This is a rudimentary version of a
|
||||||
// full RecursiveTypeDescription.
|
// full RecursiveTypeDescription.
|
||||||
fn describe_enum_variant<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>,
|
fn describe_enum_variant(
|
||||||
|
cx: &CodegenCx<'ll, 'tcx>,
|
||||||
layout: layout::TyLayout<'tcx>,
|
layout: layout::TyLayout<'tcx>,
|
||||||
variant: &'tcx ty::VariantDef,
|
variant: &'tcx ty::VariantDef,
|
||||||
discriminant_info: EnumDiscriminantInfo,
|
discriminant_info: EnumDiscriminantInfo<'ll>,
|
||||||
containing_scope: DIScope,
|
containing_scope: &'ll DIScope,
|
||||||
span: Span)
|
span: Span,
|
||||||
-> (DICompositeType, MemberDescriptionFactory<'tcx>) {
|
) -> (&'ll DICompositeType, MemberDescriptionFactory<'ll, 'tcx>) {
|
||||||
let variant_name = variant.name.as_str();
|
let variant_name = variant.name.as_str();
|
||||||
let unique_type_id = debug_context(cx).type_map
|
let unique_type_id = debug_context(cx).type_map
|
||||||
.borrow_mut()
|
.borrow_mut()
|
||||||
|
@ -1319,7 +1351,7 @@ fn describe_enum_variant<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>,
|
||||||
layout.ty,
|
layout.ty,
|
||||||
&variant_name,
|
&variant_name,
|
||||||
unique_type_id,
|
unique_type_id,
|
||||||
NonNull::new(containing_scope));
|
Some(containing_scope));
|
||||||
|
|
||||||
// If this is not a univariant enum, there is also the discriminant field.
|
// If this is not a univariant enum, there is also the discriminant field.
|
||||||
let (discr_offset, discr_arg) = match discriminant_info {
|
let (discr_offset, discr_arg) = match discriminant_info {
|
||||||
|
@ -1360,12 +1392,13 @@ fn describe_enum_variant<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>,
|
||||||
(metadata_stub, member_description_factory)
|
(metadata_stub, member_description_factory)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn prepare_enum_metadata<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>,
|
fn prepare_enum_metadata(
|
||||||
|
cx: &CodegenCx<'ll, 'tcx>,
|
||||||
enum_type: Ty<'tcx>,
|
enum_type: Ty<'tcx>,
|
||||||
enum_def_id: DefId,
|
enum_def_id: DefId,
|
||||||
unique_type_id: UniqueTypeId,
|
unique_type_id: UniqueTypeId,
|
||||||
span: Span)
|
span: Span,
|
||||||
-> RecursiveTypeDescription<'tcx> {
|
) -> RecursiveTypeDescription<'ll, 'tcx> {
|
||||||
let enum_name = compute_debuginfo_type_name(cx, enum_type, false);
|
let enum_name = compute_debuginfo_type_name(cx, enum_type, false);
|
||||||
|
|
||||||
let containing_scope = get_namespace_for_item(cx, enum_def_id);
|
let containing_scope = get_namespace_for_item(cx, enum_def_id);
|
||||||
|
@ -1384,7 +1417,7 @@ fn prepare_enum_metadata<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>,
|
||||||
let token = v.name.as_str();
|
let token = v.name.as_str();
|
||||||
let name = CString::new(token.as_bytes()).unwrap();
|
let name = CString::new(token.as_bytes()).unwrap();
|
||||||
unsafe {
|
unsafe {
|
||||||
NonNull::new(llvm::LLVMRustDIBuilderCreateEnumerator(
|
Some(llvm::LLVMRustDIBuilderCreateEnumerator(
|
||||||
DIB(cx),
|
DIB(cx),
|
||||||
name.as_ptr(),
|
name.as_ptr(),
|
||||||
// FIXME: what if enumeration has i128 discriminant?
|
// FIXME: what if enumeration has i128 discriminant?
|
||||||
|
@ -1491,18 +1524,19 @@ fn prepare_enum_metadata<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>,
|
||||||
/// results in a LLVM struct.
|
/// results in a LLVM struct.
|
||||||
///
|
///
|
||||||
/// Examples of Rust types to use this are: structs, tuples, boxes, vecs, and enums.
|
/// Examples of Rust types to use this are: structs, tuples, boxes, vecs, and enums.
|
||||||
fn composite_type_metadata<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>,
|
fn composite_type_metadata(
|
||||||
|
cx: &CodegenCx<'ll, 'tcx>,
|
||||||
composite_type: Ty<'tcx>,
|
composite_type: Ty<'tcx>,
|
||||||
composite_type_name: &str,
|
composite_type_name: &str,
|
||||||
composite_type_unique_id: UniqueTypeId,
|
composite_type_unique_id: UniqueTypeId,
|
||||||
member_descriptions: &[MemberDescription],
|
member_descriptions: &[MemberDescription<'ll>],
|
||||||
containing_scope: Option<NonNull<DIScope_opaque>>,
|
containing_scope: Option<&'ll DIScope>,
|
||||||
|
|
||||||
// Ignore source location information as long as it
|
// Ignore source location information as long as it
|
||||||
// can't be reconstructed for non-local crates.
|
// can't be reconstructed for non-local crates.
|
||||||
_file_metadata: DIFile,
|
_file_metadata: &'ll DIFile,
|
||||||
_definition_span: Span)
|
_definition_span: Span,
|
||||||
-> DICompositeType {
|
) -> &'ll DICompositeType {
|
||||||
// Create the (empty) struct metadata node ...
|
// Create the (empty) struct metadata node ...
|
||||||
let composite_type_metadata = create_struct_stub(cx,
|
let composite_type_metadata = create_struct_stub(cx,
|
||||||
composite_type,
|
composite_type,
|
||||||
|
@ -1517,9 +1551,9 @@ fn composite_type_metadata<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>,
|
||||||
return composite_type_metadata;
|
return composite_type_metadata;
|
||||||
}
|
}
|
||||||
|
|
||||||
fn set_members_of_composite_type(cx: &CodegenCx,
|
fn set_members_of_composite_type(cx: &CodegenCx<'ll, '_>,
|
||||||
composite_type_metadata: DICompositeType,
|
composite_type_metadata: &'ll DICompositeType,
|
||||||
member_descriptions: &[MemberDescription]) {
|
member_descriptions: &[MemberDescription<'ll>]) {
|
||||||
// In some rare cases LLVM metadata uniquing would lead to an existing type
|
// In some rare cases LLVM metadata uniquing would lead to an existing type
|
||||||
// description being used instead of a new one created in
|
// description being used instead of a new one created in
|
||||||
// create_struct_stub. This would cause a hard to trace assertion in
|
// create_struct_stub. This would cause a hard to trace assertion in
|
||||||
|
@ -1543,7 +1577,7 @@ fn set_members_of_composite_type(cx: &CodegenCx,
|
||||||
let member_name = member_description.name.as_bytes();
|
let member_name = member_description.name.as_bytes();
|
||||||
let member_name = CString::new(member_name).unwrap();
|
let member_name = CString::new(member_name).unwrap();
|
||||||
unsafe {
|
unsafe {
|
||||||
NonNull::new(llvm::LLVMRustDIBuilderCreateMemberType(
|
Some(llvm::LLVMRustDIBuilderCreateMemberType(
|
||||||
DIB(cx),
|
DIB(cx),
|
||||||
composite_type_metadata,
|
composite_type_metadata,
|
||||||
member_name.as_ptr(),
|
member_name.as_ptr(),
|
||||||
|
@ -1568,12 +1602,13 @@ fn set_members_of_composite_type(cx: &CodegenCx,
|
||||||
// A convenience wrapper around LLVMRustDIBuilderCreateStructType(). Does not do
|
// A convenience wrapper around LLVMRustDIBuilderCreateStructType(). Does not do
|
||||||
// any caching, does not add any fields to the struct. This can be done later
|
// any caching, does not add any fields to the struct. This can be done later
|
||||||
// with set_members_of_composite_type().
|
// with set_members_of_composite_type().
|
||||||
fn create_struct_stub<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>,
|
fn create_struct_stub(
|
||||||
|
cx: &CodegenCx<'ll, 'tcx>,
|
||||||
struct_type: Ty<'tcx>,
|
struct_type: Ty<'tcx>,
|
||||||
struct_type_name: &str,
|
struct_type_name: &str,
|
||||||
unique_type_id: UniqueTypeId,
|
unique_type_id: UniqueTypeId,
|
||||||
containing_scope: Option<NonNull<DIScope_opaque>>)
|
containing_scope: Option<&'ll DIScope>,
|
||||||
-> DICompositeType {
|
) -> &'ll DICompositeType {
|
||||||
let (struct_size, struct_align) = cx.size_and_align_of(struct_type);
|
let (struct_size, struct_align) = cx.size_and_align_of(struct_type);
|
||||||
|
|
||||||
let name = CString::new(struct_type_name).unwrap();
|
let name = CString::new(struct_type_name).unwrap();
|
||||||
|
@ -1605,12 +1640,13 @@ fn create_struct_stub<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>,
|
||||||
return metadata_stub;
|
return metadata_stub;
|
||||||
}
|
}
|
||||||
|
|
||||||
fn create_union_stub<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>,
|
fn create_union_stub(
|
||||||
|
cx: &CodegenCx<'ll, 'tcx>,
|
||||||
union_type: Ty<'tcx>,
|
union_type: Ty<'tcx>,
|
||||||
union_type_name: &str,
|
union_type_name: &str,
|
||||||
unique_type_id: UniqueTypeId,
|
unique_type_id: UniqueTypeId,
|
||||||
containing_scope: DIScope)
|
containing_scope: &'ll DIScope,
|
||||||
-> DICompositeType {
|
) -> &'ll DICompositeType {
|
||||||
let (union_size, union_align) = cx.size_and_align_of(union_type);
|
let (union_size, union_align) = cx.size_and_align_of(union_type);
|
||||||
|
|
||||||
let name = CString::new(union_type_name).unwrap();
|
let name = CString::new(union_type_name).unwrap();
|
||||||
|
@ -1632,7 +1668,7 @@ fn create_union_stub<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>,
|
||||||
union_size.bits(),
|
union_size.bits(),
|
||||||
union_align.abi_bits() as u32,
|
union_align.abi_bits() as u32,
|
||||||
DIFlags::FlagZero,
|
DIFlags::FlagZero,
|
||||||
NonNull::new(empty_array),
|
Some(empty_array),
|
||||||
0, // RuntimeLang
|
0, // RuntimeLang
|
||||||
unique_type_id.as_ptr())
|
unique_type_id.as_ptr())
|
||||||
};
|
};
|
||||||
|
@ -1686,7 +1722,7 @@ pub fn create_global_var_metadata(cx: &CodegenCx,
|
||||||
|
|
||||||
unsafe {
|
unsafe {
|
||||||
llvm::LLVMRustDIBuilderCreateStaticVariable(DIB(cx),
|
llvm::LLVMRustDIBuilderCreateStaticVariable(DIB(cx),
|
||||||
NonNull::new(var_scope),
|
Some(var_scope),
|
||||||
var_name.as_ptr(),
|
var_name.as_ptr(),
|
||||||
// If null, linkage_name field is omitted,
|
// If null, linkage_name field is omitted,
|
||||||
// which is what we want for no_mangle statics
|
// which is what we want for no_mangle statics
|
||||||
|
@ -1704,11 +1740,12 @@ pub fn create_global_var_metadata(cx: &CodegenCx,
|
||||||
}
|
}
|
||||||
|
|
||||||
// Creates an "extension" of an existing DIScope into another file.
|
// Creates an "extension" of an existing DIScope into another file.
|
||||||
pub fn extend_scope_to_file(cx: &CodegenCx,
|
pub fn extend_scope_to_file(
|
||||||
scope_metadata: DIScope,
|
cx: &CodegenCx<'ll, '_>,
|
||||||
|
scope_metadata: &'ll DIScope,
|
||||||
file: &syntax_pos::FileMap,
|
file: &syntax_pos::FileMap,
|
||||||
defining_crate: CrateNum)
|
defining_crate: CrateNum,
|
||||||
-> DILexicalBlock {
|
) -> &'ll DILexicalBlock {
|
||||||
let file_metadata = file_metadata(cx, &file.name, defining_crate);
|
let file_metadata = file_metadata(cx, &file.name, defining_crate);
|
||||||
unsafe {
|
unsafe {
|
||||||
llvm::LLVMRustDIBuilderCreateLexicalBlockFile(
|
llvm::LLVMRustDIBuilderCreateLexicalBlockFile(
|
||||||
|
@ -1754,7 +1791,7 @@ pub fn create_vtable_metadata<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>,
|
||||||
None,
|
None,
|
||||||
empty_array,
|
empty_array,
|
||||||
0,
|
0,
|
||||||
NonNull::new(type_metadata),
|
Some(type_metadata),
|
||||||
name.as_ptr()
|
name.as_ptr()
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
|
@ -39,7 +39,6 @@ use rustc::util::nodemap::{DefIdMap, FxHashMap, FxHashSet};
|
||||||
use libc::c_uint;
|
use libc::c_uint;
|
||||||
use std::cell::{Cell, RefCell};
|
use std::cell::{Cell, RefCell};
|
||||||
use std::ffi::CString;
|
use std::ffi::CString;
|
||||||
use std::ptr::NonNull;
|
|
||||||
|
|
||||||
use syntax_pos::{self, Span, Pos};
|
use syntax_pos::{self, Span, Pos};
|
||||||
use syntax::ast;
|
use syntax::ast;
|
||||||
|
@ -71,15 +70,15 @@ pub struct CrateDebugContext<'a, 'tcx> {
|
||||||
llcontext: &'a llvm::Context,
|
llcontext: &'a llvm::Context,
|
||||||
llmod: &'a llvm::Module,
|
llmod: &'a llvm::Module,
|
||||||
builder: &'a DIBuilder,
|
builder: &'a DIBuilder,
|
||||||
created_files: RefCell<FxHashMap<(Symbol, Symbol), DIFile>>,
|
created_files: RefCell<FxHashMap<(Symbol, Symbol), &'a DIFile>>,
|
||||||
created_enum_disr_types: RefCell<FxHashMap<(DefId, layout::Primitive), DIType>>,
|
created_enum_disr_types: RefCell<FxHashMap<(DefId, layout::Primitive), &'a DIType>>,
|
||||||
|
|
||||||
type_map: RefCell<TypeMap<'tcx>>,
|
type_map: RefCell<TypeMap<'a, 'tcx>>,
|
||||||
namespace_map: RefCell<DefIdMap<DIScope>>,
|
namespace_map: RefCell<DefIdMap<&'a DIScope>>,
|
||||||
|
|
||||||
// This collection is used to assert that composite types (structs, enums,
|
// This collection is used to assert that composite types (structs, enums,
|
||||||
// ...) have their members only set once:
|
// ...) have their members only set once:
|
||||||
composite_types_completed: RefCell<FxHashSet<DIType>>,
|
composite_types_completed: RefCell<FxHashSet<&'a DIType>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, 'tcx> CrateDebugContext<'a, 'tcx> {
|
impl<'a, 'tcx> CrateDebugContext<'a, 'tcx> {
|
||||||
|
@ -101,14 +100,14 @@ impl<'a, 'tcx> CrateDebugContext<'a, 'tcx> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub enum FunctionDebugContext {
|
pub enum FunctionDebugContext<'ll> {
|
||||||
RegularContext(FunctionDebugContextData),
|
RegularContext(FunctionDebugContextData<'ll>),
|
||||||
DebugInfoDisabled,
|
DebugInfoDisabled,
|
||||||
FunctionWithoutDebugInfo,
|
FunctionWithoutDebugInfo,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl FunctionDebugContext {
|
impl FunctionDebugContext<'ll> {
|
||||||
pub fn get_ref<'a>(&'a self, span: Span) -> &'a FunctionDebugContextData {
|
pub fn get_ref<'a>(&'a self, span: Span) -> &'a FunctionDebugContextData<'ll> {
|
||||||
match *self {
|
match *self {
|
||||||
FunctionDebugContext::RegularContext(ref data) => data,
|
FunctionDebugContext::RegularContext(ref data) => data,
|
||||||
FunctionDebugContext::DebugInfoDisabled => {
|
FunctionDebugContext::DebugInfoDisabled => {
|
||||||
|
@ -130,8 +129,8 @@ impl FunctionDebugContext {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct FunctionDebugContextData {
|
pub struct FunctionDebugContextData<'ll> {
|
||||||
fn_metadata: DISubprogram,
|
fn_metadata: &'ll DISubprogram,
|
||||||
source_locations_enabled: Cell<bool>,
|
source_locations_enabled: Cell<bool>,
|
||||||
pub defining_crate: CrateNum,
|
pub defining_crate: CrateNum,
|
||||||
}
|
}
|
||||||
|
@ -201,11 +200,13 @@ pub fn finalize(cx: &CodegenCx) {
|
||||||
/// for debug info creation. The function may also return another variant of the
|
/// for debug info creation. The function may also return another variant of the
|
||||||
/// FunctionDebugContext enum which indicates why no debuginfo should be created
|
/// FunctionDebugContext enum which indicates why no debuginfo should be created
|
||||||
/// for the function.
|
/// for the function.
|
||||||
pub fn create_function_debug_context<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>,
|
pub fn create_function_debug_context(
|
||||||
|
cx: &CodegenCx<'ll, 'tcx>,
|
||||||
instance: Instance<'tcx>,
|
instance: Instance<'tcx>,
|
||||||
sig: ty::FnSig<'tcx>,
|
sig: ty::FnSig<'tcx>,
|
||||||
llfn: ValueRef,
|
llfn: ValueRef,
|
||||||
mir: &mir::Mir) -> FunctionDebugContext {
|
mir: &mir::Mir,
|
||||||
|
) -> FunctionDebugContext<'ll> {
|
||||||
if cx.sess().opts.debuginfo == NoDebugInfo {
|
if cx.sess().opts.debuginfo == NoDebugInfo {
|
||||||
return FunctionDebugContext::DebugInfoDisabled;
|
return FunctionDebugContext::DebugInfoDisabled;
|
||||||
}
|
}
|
||||||
|
@ -302,8 +303,10 @@ pub fn create_function_debug_context<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>,
|
||||||
|
|
||||||
return FunctionDebugContext::RegularContext(fn_debug_context);
|
return FunctionDebugContext::RegularContext(fn_debug_context);
|
||||||
|
|
||||||
fn get_function_signature<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>,
|
fn get_function_signature(
|
||||||
sig: ty::FnSig<'tcx>) -> DIArray {
|
cx: &CodegenCx<'ll, 'tcx>,
|
||||||
|
sig: ty::FnSig<'tcx>,
|
||||||
|
) -> &'ll DIArray {
|
||||||
if cx.sess().opts.debuginfo == LimitedDebugInfo {
|
if cx.sess().opts.debuginfo == LimitedDebugInfo {
|
||||||
return create_DIArray(DIB(cx), &[]);
|
return create_DIArray(DIB(cx), &[]);
|
||||||
}
|
}
|
||||||
|
@ -313,7 +316,7 @@ pub fn create_function_debug_context<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>,
|
||||||
// Return type -- llvm::DIBuilder wants this at index 0
|
// Return type -- llvm::DIBuilder wants this at index 0
|
||||||
signature.push(match sig.output().sty {
|
signature.push(match sig.output().sty {
|
||||||
ty::TyTuple(ref tys) if tys.is_empty() => None,
|
ty::TyTuple(ref tys) if tys.is_empty() => None,
|
||||||
_ => NonNull::new(type_metadata(cx, sig.output(), syntax_pos::DUMMY_SP))
|
_ => Some(type_metadata(cx, sig.output(), syntax_pos::DUMMY_SP))
|
||||||
});
|
});
|
||||||
|
|
||||||
let inputs = if sig.abi == Abi::RustCall {
|
let inputs = if sig.abi == Abi::RustCall {
|
||||||
|
@ -342,11 +345,11 @@ pub fn create_function_debug_context<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>,
|
||||||
}
|
}
|
||||||
_ => t
|
_ => t
|
||||||
};
|
};
|
||||||
NonNull::new(type_metadata(cx, t, syntax_pos::DUMMY_SP))
|
Some(type_metadata(cx, t, syntax_pos::DUMMY_SP))
|
||||||
}));
|
}));
|
||||||
} else {
|
} else {
|
||||||
signature.extend(inputs.iter().map(|t| {
|
signature.extend(inputs.iter().map(|t| {
|
||||||
NonNull::new(type_metadata(cx, t, syntax_pos::DUMMY_SP))
|
Some(type_metadata(cx, t, syntax_pos::DUMMY_SP))
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -354,7 +357,7 @@ pub fn create_function_debug_context<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>,
|
||||||
if let ty::TyTuple(args) = sig.inputs()[sig.inputs().len() - 1].sty {
|
if let ty::TyTuple(args) = sig.inputs()[sig.inputs().len() - 1].sty {
|
||||||
signature.extend(
|
signature.extend(
|
||||||
args.iter().map(|argument_type| {
|
args.iter().map(|argument_type| {
|
||||||
NonNull::new(type_metadata(cx, argument_type, syntax_pos::DUMMY_SP))
|
Some(type_metadata(cx, argument_type, syntax_pos::DUMMY_SP))
|
||||||
})
|
})
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -363,13 +366,13 @@ pub fn create_function_debug_context<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>,
|
||||||
return create_DIArray(DIB(cx), &signature[..]);
|
return create_DIArray(DIB(cx), &signature[..]);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_template_parameters<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>,
|
fn get_template_parameters(
|
||||||
|
cx: &CodegenCx<'ll, 'tcx>,
|
||||||
generics: &ty::Generics,
|
generics: &ty::Generics,
|
||||||
substs: &Substs<'tcx>,
|
substs: &Substs<'tcx>,
|
||||||
file_metadata: DIFile,
|
file_metadata: &'ll DIFile,
|
||||||
name_to_append_suffix_to: &mut String)
|
name_to_append_suffix_to: &mut String,
|
||||||
-> DIArray
|
) -> &'ll DIArray {
|
||||||
{
|
|
||||||
if substs.types().next().is_none() {
|
if substs.types().next().is_none() {
|
||||||
return create_DIArray(DIB(cx), &[]);
|
return create_DIArray(DIB(cx), &[]);
|
||||||
}
|
}
|
||||||
|
@ -399,14 +402,15 @@ pub fn create_function_debug_context<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>,
|
||||||
type_metadata(cx, actual_type, syntax_pos::DUMMY_SP);
|
type_metadata(cx, actual_type, syntax_pos::DUMMY_SP);
|
||||||
let name = CString::new(name.as_str().as_bytes()).unwrap();
|
let name = CString::new(name.as_str().as_bytes()).unwrap();
|
||||||
Some(unsafe {
|
Some(unsafe {
|
||||||
NonNull::new(llvm::LLVMRustDIBuilderCreateTemplateTypeParameter(
|
Some(llvm::LLVMRustDIBuilderCreateTemplateTypeParameter(
|
||||||
DIB(cx),
|
DIB(cx),
|
||||||
None,
|
None,
|
||||||
name.as_ptr(),
|
name.as_ptr(),
|
||||||
actual_type_metadata,
|
actual_type_metadata,
|
||||||
file_metadata,
|
file_metadata,
|
||||||
0,
|
0,
|
||||||
0))
|
0,
|
||||||
|
))
|
||||||
})
|
})
|
||||||
} else {
|
} else {
|
||||||
None
|
None
|
||||||
|
@ -429,9 +433,10 @@ pub fn create_function_debug_context<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>,
|
||||||
names
|
names
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_containing_scope<'cx, 'tcx>(cx: &CodegenCx<'cx, 'tcx>,
|
fn get_containing_scope(
|
||||||
instance: Instance<'tcx>)
|
cx: &CodegenCx<'ll, 'tcx>,
|
||||||
-> DIScope {
|
instance: Instance<'tcx>,
|
||||||
|
) -> &'ll DIScope {
|
||||||
// First, let's see if this is a method within an inherent impl. Because
|
// First, let's see if this is a method within an inherent impl. Because
|
||||||
// if yes, we want to make the result subroutine DIE a child of the
|
// if yes, we want to make the result subroutine DIE a child of the
|
||||||
// subroutine's self-type.
|
// subroutine's self-type.
|
||||||
|
@ -473,10 +478,10 @@ pub fn create_function_debug_context<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>,
|
||||||
|
|
||||||
pub fn declare_local(
|
pub fn declare_local(
|
||||||
bx: &Builder<'a, 'll, 'tcx>,
|
bx: &Builder<'a, 'll, 'tcx>,
|
||||||
dbg_context: &FunctionDebugContext,
|
dbg_context: &FunctionDebugContext<'ll>,
|
||||||
variable_name: ast::Name,
|
variable_name: ast::Name,
|
||||||
variable_type: Ty<'tcx>,
|
variable_type: Ty<'tcx>,
|
||||||
scope_metadata: DIScope,
|
scope_metadata: &'ll DIScope,
|
||||||
variable_access: VariableAccess,
|
variable_access: VariableAccess,
|
||||||
variable_kind: VariableKind,
|
variable_kind: VariableKind,
|
||||||
span: Span,
|
span: Span,
|
||||||
|
|
|
@ -22,7 +22,6 @@ use rustc::hir::map::DefPathData;
|
||||||
use common::CodegenCx;
|
use common::CodegenCx;
|
||||||
|
|
||||||
use std::ffi::CString;
|
use std::ffi::CString;
|
||||||
use std::ptr::NonNull;
|
|
||||||
|
|
||||||
pub fn mangled_name_of_instance<'a, 'tcx>(
|
pub fn mangled_name_of_instance<'a, 'tcx>(
|
||||||
cx: &CodegenCx<'a, 'tcx>,
|
cx: &CodegenCx<'a, 'tcx>,
|
||||||
|
@ -32,17 +31,17 @@ pub fn mangled_name_of_instance<'a, 'tcx>(
|
||||||
tcx.symbol_name(instance)
|
tcx.symbol_name(instance)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn item_namespace(cx: &CodegenCx, def_id: DefId) -> DIScope {
|
pub fn item_namespace(cx: &CodegenCx<'ll, '_>, def_id: DefId) -> &'ll DIScope {
|
||||||
if let Some(&scope) = debug_context(cx).namespace_map.borrow().get(&def_id) {
|
if let Some(&scope) = debug_context(cx).namespace_map.borrow().get(&def_id) {
|
||||||
return scope;
|
return scope;
|
||||||
}
|
}
|
||||||
|
|
||||||
let def_key = cx.tcx.def_key(def_id);
|
let def_key = cx.tcx.def_key(def_id);
|
||||||
let parent_scope = def_key.parent.and_then(|parent| {
|
let parent_scope = def_key.parent.map(|parent| {
|
||||||
NonNull::new(item_namespace(cx, DefId {
|
item_namespace(cx, DefId {
|
||||||
krate: def_id.krate,
|
krate: def_id.krate,
|
||||||
index: parent
|
index: parent
|
||||||
}))
|
})
|
||||||
});
|
});
|
||||||
|
|
||||||
let namespace_name = match def_key.disambiguated_data.data {
|
let namespace_name = match def_key.disambiguated_data.data {
|
||||||
|
|
|
@ -15,7 +15,7 @@ use super::metadata::UNKNOWN_COLUMN_NUMBER;
|
||||||
use super::FunctionDebugContext;
|
use super::FunctionDebugContext;
|
||||||
|
|
||||||
use llvm;
|
use llvm;
|
||||||
use llvm::debuginfo::{DIScope_opaque, DIScope};
|
use llvm::debuginfo::DIScope;
|
||||||
use builder::Builder;
|
use builder::Builder;
|
||||||
|
|
||||||
use libc::c_uint;
|
use libc::c_uint;
|
||||||
|
@ -26,7 +26,10 @@ use syntax_pos::{Span, Pos};
|
||||||
///
|
///
|
||||||
/// Maps to a call to llvm::LLVMSetCurrentDebugLocation(...).
|
/// Maps to a call to llvm::LLVMSetCurrentDebugLocation(...).
|
||||||
pub fn set_source_location(
|
pub fn set_source_location(
|
||||||
debug_context: &FunctionDebugContext, bx: &Builder, scope: Option<NonNull<DIScope_opaque>>, span: Span
|
debug_context: &FunctionDebugContext<'ll>,
|
||||||
|
bx: &Builder<'_, 'll, '_>,
|
||||||
|
scope: Option<&'ll DIScope>,
|
||||||
|
span: Span,
|
||||||
) {
|
) {
|
||||||
let function_debug_context = match *debug_context {
|
let function_debug_context = match *debug_context {
|
||||||
FunctionDebugContext::DebugInfoDisabled => return,
|
FunctionDebugContext::DebugInfoDisabled => return,
|
||||||
|
@ -40,7 +43,7 @@ pub fn set_source_location(
|
||||||
let dbg_loc = if function_debug_context.source_locations_enabled.get() {
|
let dbg_loc = if function_debug_context.source_locations_enabled.get() {
|
||||||
debug!("set_source_location: {}", bx.sess().codemap().span_to_string(span));
|
debug!("set_source_location: {}", bx.sess().codemap().span_to_string(span));
|
||||||
let loc = span_start(bx.cx, span);
|
let loc = span_start(bx.cx, span);
|
||||||
InternalDebugLocation::new(scope.unwrap().as_ptr(), loc.line, loc.col.to_usize())
|
InternalDebugLocation::new(scope.unwrap(), loc.line, loc.col.to_usize())
|
||||||
} else {
|
} else {
|
||||||
UnknownLocation
|
UnknownLocation
|
||||||
};
|
};
|
||||||
|
@ -53,7 +56,7 @@ pub fn set_source_location(
|
||||||
/// they are disabled when beginning to codegen a new function. This functions
|
/// they are disabled when beginning to codegen a new function. This functions
|
||||||
/// switches source location emitting on and must therefore be called before the
|
/// switches source location emitting on and must therefore be called before the
|
||||||
/// first real statement/expression of the function is codegened.
|
/// first real statement/expression of the function is codegened.
|
||||||
pub fn start_emitting_source_locations(dbg_context: &FunctionDebugContext) {
|
pub fn start_emitting_source_locations(dbg_context: &FunctionDebugContext<'ll>) {
|
||||||
match *dbg_context {
|
match *dbg_context {
|
||||||
FunctionDebugContext::RegularContext(ref data) => {
|
FunctionDebugContext::RegularContext(ref data) => {
|
||||||
data.source_locations_enabled.set(true)
|
data.source_locations_enabled.set(true)
|
||||||
|
@ -64,13 +67,13 @@ pub fn start_emitting_source_locations(dbg_context: &FunctionDebugContext) {
|
||||||
|
|
||||||
|
|
||||||
#[derive(Copy, Clone, PartialEq)]
|
#[derive(Copy, Clone, PartialEq)]
|
||||||
pub enum InternalDebugLocation {
|
pub enum InternalDebugLocation<'ll> {
|
||||||
KnownLocation { scope: DIScope, line: usize, col: usize },
|
KnownLocation { scope: &'ll DIScope, line: usize, col: usize },
|
||||||
UnknownLocation
|
UnknownLocation
|
||||||
}
|
}
|
||||||
|
|
||||||
impl InternalDebugLocation {
|
impl InternalDebugLocation<'ll> {
|
||||||
pub fn new(scope: DIScope, line: usize, col: usize) -> InternalDebugLocation {
|
pub fn new(scope: &'ll DIScope, line: usize, col: usize) -> Self {
|
||||||
KnownLocation {
|
KnownLocation {
|
||||||
scope,
|
scope,
|
||||||
line,
|
line,
|
||||||
|
@ -79,7 +82,7 @@ impl InternalDebugLocation {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn set_debug_location(bx: &Builder, debug_location: InternalDebugLocation) {
|
pub fn set_debug_location(bx: &Builder<'_, 'll, '_>, debug_location: InternalDebugLocation<'ll>) {
|
||||||
let metadata_node = match debug_location {
|
let metadata_node = match debug_location {
|
||||||
KnownLocation { scope, line, col } => {
|
KnownLocation { scope, line, col } => {
|
||||||
// For MSVC, set the column number to zero.
|
// For MSVC, set the column number to zero.
|
||||||
|
|
|
@ -17,10 +17,9 @@ use rustc::hir::def_id::DefId;
|
||||||
use rustc::ty::DefIdTree;
|
use rustc::ty::DefIdTree;
|
||||||
|
|
||||||
use llvm;
|
use llvm;
|
||||||
use llvm::debuginfo::{DIScope, DIBuilder, DIDescriptor_opaque, DIArray};
|
use llvm::debuginfo::{DIScope, DIBuilder, DIDescriptor, DIArray};
|
||||||
use common::{CodegenCx};
|
use common::{CodegenCx};
|
||||||
|
|
||||||
use std::ptr::NonNull;
|
|
||||||
use syntax_pos::{self, Span};
|
use syntax_pos::{self, Span};
|
||||||
|
|
||||||
pub fn is_node_local_to_unit(cx: &CodegenCx, def_id: DefId) -> bool
|
pub fn is_node_local_to_unit(cx: &CodegenCx, def_id: DefId) -> bool
|
||||||
|
@ -37,7 +36,7 @@ pub fn is_node_local_to_unit(cx: &CodegenCx, def_id: DefId) -> bool
|
||||||
}
|
}
|
||||||
|
|
||||||
#[allow(non_snake_case)]
|
#[allow(non_snake_case)]
|
||||||
pub fn create_DIArray(builder: &DIBuilder, arr: &[Option<NonNull<DIDescriptor_opaque>>]) -> DIArray {
|
pub fn create_DIArray(builder: &'ll DIBuilder, arr: &[Option<&'ll DIDescriptor>]) -> &'ll DIArray {
|
||||||
return unsafe {
|
return unsafe {
|
||||||
llvm::LLVMRustDIBuilderGetOrCreateArray(builder, arr.as_ptr(), arr.len() as u32)
|
llvm::LLVMRustDIBuilderGetOrCreateArray(builder, arr.as_ptr(), arr.len() as u32)
|
||||||
};
|
};
|
||||||
|
@ -49,7 +48,7 @@ pub fn span_start(cx: &CodegenCx, span: Span) -> syntax_pos::Loc {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn debug_context(cx: &'a CodegenCx<'ll, 'tcx>) -> &'a CrateDebugContext<'a, 'tcx> {
|
pub fn debug_context(cx: &'a CodegenCx<'ll, 'tcx>) -> &'a CrateDebugContext<'ll, 'tcx> {
|
||||||
cx.dbg_cx.as_ref().unwrap()
|
cx.dbg_cx.as_ref().unwrap()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -59,7 +58,7 @@ pub fn DIB(cx: &CodegenCx<'ll, '_>) -> &'ll DIBuilder {
|
||||||
cx.dbg_cx.as_ref().unwrap().builder
|
cx.dbg_cx.as_ref().unwrap().builder
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_namespace_for_item(cx: &CodegenCx, def_id: DefId) -> DIScope {
|
pub fn get_namespace_for_item(cx: &CodegenCx<'ll, '_>, def_id: DefId) -> &'ll DIScope {
|
||||||
item_namespace(cx, cx.tcx.parent(def_id)
|
item_namespace(cx, cx.tcx.parent(def_id)
|
||||||
.expect("get_namespace_for_item: missing parent?"))
|
.expect("get_namespace_for_item: missing parent?"))
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,7 +12,7 @@
|
||||||
|
|
||||||
use intrinsics::{self, Intrinsic};
|
use intrinsics::{self, Intrinsic};
|
||||||
use llvm;
|
use llvm;
|
||||||
use llvm::{ValueRef};
|
use llvm::{TypeKind, ValueRef};
|
||||||
use abi::{Abi, FnType, LlvmType, PassMode};
|
use abi::{Abi, FnType, LlvmType, PassMode};
|
||||||
use mir::place::PlaceRef;
|
use mir::place::PlaceRef;
|
||||||
use mir::operand::{OperandRef, OperandValue};
|
use mir::operand::{OperandRef, OperandValue};
|
||||||
|
@ -1060,7 +1060,7 @@ fn generic_simd_intrinsic(
|
||||||
found `{}` with length {}",
|
found `{}` with length {}",
|
||||||
in_len, in_ty,
|
in_len, in_ty,
|
||||||
ret_ty, out_len);
|
ret_ty, out_len);
|
||||||
require!(llret_ty.element_type().kind() == llvm::Integer,
|
require!(llret_ty.element_type().kind() == TypeKind::Integer,
|
||||||
"expected return type with integer elements, found `{}` with non-integer `{}`",
|
"expected return type with integer elements, found `{}` with non-integer `{}`",
|
||||||
ret_ty,
|
ret_ty,
|
||||||
ret_ty.simd_type(tcx));
|
ret_ty.simd_type(tcx));
|
||||||
|
|
|
@ -15,9 +15,9 @@
|
||||||
// https://reviews.llvm.org/D26769
|
// https://reviews.llvm.org/D26769
|
||||||
|
|
||||||
use super::debuginfo::{
|
use super::debuginfo::{
|
||||||
DIBuilder, DIDescriptor_opaque, DIDescriptor, DIFile, DILexicalBlock, DISubprogram, DIType_opaque,
|
DIBuilder, DIDescriptor, DIFile, DILexicalBlock, DISubprogram, DIType,
|
||||||
DIType, DIBasicType, DIDerivedType, DICompositeType, DIScope_opaque, DIScope, DIVariable,
|
DIBasicType, DIDerivedType, DICompositeType, DIScope, DIVariable,
|
||||||
DIGlobalVariable, DIArray_opaque, DIArray, DISubrange, DITemplateTypeParameter, DIEnumerator,
|
DIGlobalVariable, DIArray, DISubrange, DITemplateTypeParameter, DIEnumerator,
|
||||||
DINameSpace, DIFlags,
|
DINameSpace, DIFlags,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -380,8 +380,7 @@ extern { pub type Context; }
|
||||||
extern { pub type Type; }
|
extern { pub type Type; }
|
||||||
extern { pub type Value_opaque; }
|
extern { pub type Value_opaque; }
|
||||||
pub type ValueRef = *mut Value_opaque;
|
pub type ValueRef = *mut Value_opaque;
|
||||||
extern { pub type Metadata_opaque; }
|
extern { pub type Metadata; }
|
||||||
pub type MetadataRef = *mut Metadata_opaque;
|
|
||||||
extern { pub type BasicBlock_opaque; }
|
extern { pub type BasicBlock_opaque; }
|
||||||
pub type BasicBlockRef = *mut BasicBlock_opaque;
|
pub type BasicBlockRef = *mut BasicBlock_opaque;
|
||||||
extern { pub type Builder; }
|
extern { pub type Builder; }
|
||||||
|
@ -431,28 +430,23 @@ pub type InlineAsmDiagHandler = unsafe extern "C" fn(SMDiagnosticRef, *const c_v
|
||||||
|
|
||||||
|
|
||||||
pub mod debuginfo {
|
pub mod debuginfo {
|
||||||
use super::Metadata_opaque;
|
use super::Metadata;
|
||||||
|
|
||||||
extern { pub type DIBuilder; }
|
extern { pub type DIBuilder; }
|
||||||
|
|
||||||
pub type DIDescriptor_opaque = Metadata_opaque;
|
pub type DIDescriptor = Metadata;
|
||||||
pub type DIDescriptor = *mut DIDescriptor_opaque;
|
pub type DIScope = DIDescriptor;
|
||||||
pub type DIScope_opaque = DIDescriptor_opaque;
|
|
||||||
pub type DIScope = *mut DIScope_opaque;
|
|
||||||
pub type DILocation = DIDescriptor;
|
|
||||||
pub type DIFile = DIScope;
|
pub type DIFile = DIScope;
|
||||||
pub type DILexicalBlock = DIScope;
|
pub type DILexicalBlock = DIScope;
|
||||||
pub type DISubprogram = DIScope;
|
pub type DISubprogram = DIScope;
|
||||||
pub type DINameSpace = DIScope;
|
pub type DINameSpace = DIScope;
|
||||||
pub type DIType_opaque = DIDescriptor_opaque;
|
pub type DIType = DIDescriptor;
|
||||||
pub type DIType = *mut DIType_opaque;
|
|
||||||
pub type DIBasicType = DIType;
|
pub type DIBasicType = DIType;
|
||||||
pub type DIDerivedType = DIType;
|
pub type DIDerivedType = DIType;
|
||||||
pub type DICompositeType = DIDerivedType;
|
pub type DICompositeType = DIDerivedType;
|
||||||
pub type DIVariable = DIDescriptor;
|
pub type DIVariable = DIDescriptor;
|
||||||
pub type DIGlobalVariable = DIDescriptor;
|
pub type DIGlobalVariable = DIDescriptor;
|
||||||
pub type DIArray_opaque = DIDescriptor_opaque;
|
pub type DIArray = DIDescriptor;
|
||||||
pub type DIArray = *mut DIArray_opaque;
|
|
||||||
pub type DISubrange = DIDescriptor;
|
pub type DISubrange = DIDescriptor;
|
||||||
pub type DIEnumerator = DIDescriptor;
|
pub type DIEnumerator = DIDescriptor;
|
||||||
pub type DITemplateTypeParameter = DIDescriptor;
|
pub type DITemplateTypeParameter = DIDescriptor;
|
||||||
|
@ -1366,7 +1360,7 @@ extern "C" {
|
||||||
|
|
||||||
pub fn LLVMRustAddModuleFlag(M: &Module, name: *const c_char, value: u32);
|
pub fn LLVMRustAddModuleFlag(M: &Module, name: *const c_char, value: u32);
|
||||||
|
|
||||||
pub fn LLVMRustMetadataAsValue(C: &Context, MD: MetadataRef) -> ValueRef;
|
pub fn LLVMRustMetadataAsValue(C: &'a Context, MD: &'a Metadata) -> ValueRef;
|
||||||
|
|
||||||
pub fn LLVMRustDIBuilderCreate(M: &Module) -> &DIBuilder;
|
pub fn LLVMRustDIBuilderCreate(M: &Module) -> &DIBuilder;
|
||||||
|
|
||||||
|
@ -1374,149 +1368,149 @@ extern "C" {
|
||||||
|
|
||||||
pub fn LLVMRustDIBuilderFinalize(Builder: &DIBuilder);
|
pub fn LLVMRustDIBuilderFinalize(Builder: &DIBuilder);
|
||||||
|
|
||||||
pub fn LLVMRustDIBuilderCreateCompileUnit(Builder: &DIBuilder,
|
pub fn LLVMRustDIBuilderCreateCompileUnit(Builder: &'a DIBuilder,
|
||||||
Lang: c_uint,
|
Lang: c_uint,
|
||||||
File: DIFile,
|
File: &'a DIFile,
|
||||||
Producer: *const c_char,
|
Producer: *const c_char,
|
||||||
isOptimized: bool,
|
isOptimized: bool,
|
||||||
Flags: *const c_char,
|
Flags: *const c_char,
|
||||||
RuntimeVer: c_uint,
|
RuntimeVer: c_uint,
|
||||||
SplitName: *const c_char)
|
SplitName: *const c_char)
|
||||||
-> DIDescriptor;
|
-> &'a DIDescriptor;
|
||||||
|
|
||||||
pub fn LLVMRustDIBuilderCreateFile(Builder: &DIBuilder,
|
pub fn LLVMRustDIBuilderCreateFile(Builder: &DIBuilder,
|
||||||
Filename: *const c_char,
|
Filename: *const c_char,
|
||||||
Directory: *const c_char)
|
Directory: *const c_char)
|
||||||
-> DIFile;
|
-> &DIFile;
|
||||||
|
|
||||||
pub fn LLVMRustDIBuilderCreateSubroutineType(Builder: &DIBuilder,
|
pub fn LLVMRustDIBuilderCreateSubroutineType(Builder: &'a DIBuilder,
|
||||||
File: DIFile,
|
File: &'a DIFile,
|
||||||
ParameterTypes: DIArray)
|
ParameterTypes: &'a DIArray)
|
||||||
-> DICompositeType;
|
-> &'a DICompositeType;
|
||||||
|
|
||||||
pub fn LLVMRustDIBuilderCreateFunction(Builder: &DIBuilder,
|
pub fn LLVMRustDIBuilderCreateFunction(Builder: &'a DIBuilder,
|
||||||
Scope: DIDescriptor,
|
Scope: &'a DIDescriptor,
|
||||||
Name: *const c_char,
|
Name: *const c_char,
|
||||||
LinkageName: *const c_char,
|
LinkageName: *const c_char,
|
||||||
File: DIFile,
|
File: &'a DIFile,
|
||||||
LineNo: c_uint,
|
LineNo: c_uint,
|
||||||
Ty: DIType,
|
Ty: &'a DIType,
|
||||||
isLocalToUnit: bool,
|
isLocalToUnit: bool,
|
||||||
isDefinition: bool,
|
isDefinition: bool,
|
||||||
ScopeLine: c_uint,
|
ScopeLine: c_uint,
|
||||||
Flags: DIFlags,
|
Flags: DIFlags,
|
||||||
isOptimized: bool,
|
isOptimized: bool,
|
||||||
Fn: ValueRef,
|
Fn: ValueRef,
|
||||||
TParam: DIArray,
|
TParam: &'a DIArray,
|
||||||
Decl: Option<NonNull<DIDescriptor_opaque>>)
|
Decl: Option<&'a DIDescriptor>)
|
||||||
-> DISubprogram;
|
-> &'a DISubprogram;
|
||||||
|
|
||||||
pub fn LLVMRustDIBuilderCreateBasicType(Builder: &DIBuilder,
|
pub fn LLVMRustDIBuilderCreateBasicType(Builder: &DIBuilder,
|
||||||
Name: *const c_char,
|
Name: *const c_char,
|
||||||
SizeInBits: u64,
|
SizeInBits: u64,
|
||||||
AlignInBits: u32,
|
AlignInBits: u32,
|
||||||
Encoding: c_uint)
|
Encoding: c_uint)
|
||||||
-> DIBasicType;
|
-> &DIBasicType;
|
||||||
|
|
||||||
pub fn LLVMRustDIBuilderCreatePointerType(Builder: &DIBuilder,
|
pub fn LLVMRustDIBuilderCreatePointerType(Builder: &'a DIBuilder,
|
||||||
PointeeTy: DIType,
|
PointeeTy: &'a DIType,
|
||||||
SizeInBits: u64,
|
SizeInBits: u64,
|
||||||
AlignInBits: u32,
|
AlignInBits: u32,
|
||||||
Name: *const c_char)
|
Name: *const c_char)
|
||||||
-> DIDerivedType;
|
-> &'a DIDerivedType;
|
||||||
|
|
||||||
pub fn LLVMRustDIBuilderCreateStructType(Builder: &DIBuilder,
|
pub fn LLVMRustDIBuilderCreateStructType(Builder: &'a DIBuilder,
|
||||||
Scope: Option<NonNull<DIDescriptor_opaque>>,
|
Scope: Option<&'a DIDescriptor>,
|
||||||
Name: *const c_char,
|
Name: *const c_char,
|
||||||
File: DIFile,
|
File: &'a DIFile,
|
||||||
LineNumber: c_uint,
|
LineNumber: c_uint,
|
||||||
SizeInBits: u64,
|
SizeInBits: u64,
|
||||||
AlignInBits: u32,
|
AlignInBits: u32,
|
||||||
Flags: DIFlags,
|
Flags: DIFlags,
|
||||||
DerivedFrom: Option<NonNull<DIType_opaque>>,
|
DerivedFrom: Option<&'a DIType>,
|
||||||
Elements: DIArray,
|
Elements: &'a DIArray,
|
||||||
RunTimeLang: c_uint,
|
RunTimeLang: c_uint,
|
||||||
VTableHolder: Option<NonNull<DIType_opaque>>,
|
VTableHolder: Option<&'a DIType>,
|
||||||
UniqueId: *const c_char)
|
UniqueId: *const c_char)
|
||||||
-> DICompositeType;
|
-> &'a DICompositeType;
|
||||||
|
|
||||||
pub fn LLVMRustDIBuilderCreateMemberType(Builder: &DIBuilder,
|
pub fn LLVMRustDIBuilderCreateMemberType(Builder: &'a DIBuilder,
|
||||||
Scope: DIDescriptor,
|
Scope: &'a DIDescriptor,
|
||||||
Name: *const c_char,
|
Name: *const c_char,
|
||||||
File: DIFile,
|
File: &'a DIFile,
|
||||||
LineNo: c_uint,
|
LineNo: c_uint,
|
||||||
SizeInBits: u64,
|
SizeInBits: u64,
|
||||||
AlignInBits: u32,
|
AlignInBits: u32,
|
||||||
OffsetInBits: u64,
|
OffsetInBits: u64,
|
||||||
Flags: DIFlags,
|
Flags: DIFlags,
|
||||||
Ty: DIType)
|
Ty: &'a DIType)
|
||||||
-> DIDerivedType;
|
-> &'a DIDerivedType;
|
||||||
|
|
||||||
pub fn LLVMRustDIBuilderCreateLexicalBlock(Builder: &DIBuilder,
|
pub fn LLVMRustDIBuilderCreateLexicalBlock(Builder: &'a DIBuilder,
|
||||||
Scope: DIScope,
|
Scope: &'a DIScope,
|
||||||
File: DIFile,
|
File: &'a DIFile,
|
||||||
Line: c_uint,
|
Line: c_uint,
|
||||||
Col: c_uint)
|
Col: c_uint)
|
||||||
-> DILexicalBlock;
|
-> &'a DILexicalBlock;
|
||||||
|
|
||||||
pub fn LLVMRustDIBuilderCreateLexicalBlockFile(Builder: &DIBuilder,
|
pub fn LLVMRustDIBuilderCreateLexicalBlockFile(Builder: &'a DIBuilder,
|
||||||
Scope: DIScope,
|
Scope: &'a DIScope,
|
||||||
File: DIFile)
|
File: &'a DIFile)
|
||||||
-> DILexicalBlock;
|
-> &'a DILexicalBlock;
|
||||||
|
|
||||||
pub fn LLVMRustDIBuilderCreateStaticVariable(Builder: &DIBuilder,
|
pub fn LLVMRustDIBuilderCreateStaticVariable(Builder: &'a DIBuilder,
|
||||||
Context: Option<NonNull<DIScope_opaque>>,
|
Context: Option<&'a DIScope>,
|
||||||
Name: *const c_char,
|
Name: *const c_char,
|
||||||
LinkageName: *const c_char,
|
LinkageName: *const c_char,
|
||||||
File: DIFile,
|
File: &'a DIFile,
|
||||||
LineNo: c_uint,
|
LineNo: c_uint,
|
||||||
Ty: DIType,
|
Ty: &'a DIType,
|
||||||
isLocalToUnit: bool,
|
isLocalToUnit: bool,
|
||||||
Val: ValueRef,
|
Val: ValueRef,
|
||||||
Decl: Option<NonNull<DIDescriptor_opaque>>,
|
Decl: Option<&'a DIDescriptor>,
|
||||||
AlignInBits: u32)
|
AlignInBits: u32)
|
||||||
-> DIGlobalVariable;
|
-> &'a DIGlobalVariable;
|
||||||
|
|
||||||
pub fn LLVMRustDIBuilderCreateVariable(Builder: &DIBuilder,
|
pub fn LLVMRustDIBuilderCreateVariable(Builder: &'a DIBuilder,
|
||||||
Tag: c_uint,
|
Tag: c_uint,
|
||||||
Scope: DIDescriptor,
|
Scope: &'a DIDescriptor,
|
||||||
Name: *const c_char,
|
Name: *const c_char,
|
||||||
File: DIFile,
|
File: &'a DIFile,
|
||||||
LineNo: c_uint,
|
LineNo: c_uint,
|
||||||
Ty: DIType,
|
Ty: &'a DIType,
|
||||||
AlwaysPreserve: bool,
|
AlwaysPreserve: bool,
|
||||||
Flags: DIFlags,
|
Flags: DIFlags,
|
||||||
ArgNo: c_uint,
|
ArgNo: c_uint,
|
||||||
AlignInBits: u32)
|
AlignInBits: u32)
|
||||||
-> DIVariable;
|
-> &'a DIVariable;
|
||||||
|
|
||||||
pub fn LLVMRustDIBuilderCreateArrayType(Builder: &DIBuilder,
|
pub fn LLVMRustDIBuilderCreateArrayType(Builder: &'a DIBuilder,
|
||||||
Size: u64,
|
Size: u64,
|
||||||
AlignInBits: u32,
|
AlignInBits: u32,
|
||||||
Ty: DIType,
|
Ty: &'a DIType,
|
||||||
Subscripts: DIArray)
|
Subscripts: &'a DIArray)
|
||||||
-> DIType;
|
-> &'a DIType;
|
||||||
|
|
||||||
pub fn LLVMRustDIBuilderCreateVectorType(Builder: &DIBuilder,
|
pub fn LLVMRustDIBuilderCreateVectorType(Builder: &'a DIBuilder,
|
||||||
Size: u64,
|
Size: u64,
|
||||||
AlignInBits: u32,
|
AlignInBits: u32,
|
||||||
Ty: DIType,
|
Ty: &'a DIType,
|
||||||
Subscripts: DIArray)
|
Subscripts: &'a DIArray)
|
||||||
-> DIType;
|
-> &'a DIType;
|
||||||
|
|
||||||
pub fn LLVMRustDIBuilderGetOrCreateSubrange(Builder: &DIBuilder,
|
pub fn LLVMRustDIBuilderGetOrCreateSubrange(Builder: &DIBuilder,
|
||||||
Lo: i64,
|
Lo: i64,
|
||||||
Count: i64)
|
Count: i64)
|
||||||
-> DISubrange;
|
-> &DISubrange;
|
||||||
|
|
||||||
pub fn LLVMRustDIBuilderGetOrCreateArray(Builder: &DIBuilder,
|
pub fn LLVMRustDIBuilderGetOrCreateArray(Builder: &'a DIBuilder,
|
||||||
Ptr: *const Option<NonNull<DIDescriptor_opaque>>,
|
Ptr: *const Option<&'a DIDescriptor>,
|
||||||
Count: c_uint)
|
Count: c_uint)
|
||||||
-> DIArray;
|
-> &'a DIArray;
|
||||||
|
|
||||||
pub fn LLVMRustDIBuilderInsertDeclareAtEnd(Builder: &DIBuilder,
|
pub fn LLVMRustDIBuilderInsertDeclareAtEnd(Builder: &'a DIBuilder,
|
||||||
Val: ValueRef,
|
Val: ValueRef,
|
||||||
VarInfo: DIVariable,
|
VarInfo: &'a DIVariable,
|
||||||
AddrOps: *const i64,
|
AddrOps: *const i64,
|
||||||
AddrOpsCount: c_uint,
|
AddrOpsCount: c_uint,
|
||||||
DL: ValueRef,
|
DL: ValueRef,
|
||||||
|
@ -1526,60 +1520,61 @@ extern "C" {
|
||||||
pub fn LLVMRustDIBuilderCreateEnumerator(Builder: &DIBuilder,
|
pub fn LLVMRustDIBuilderCreateEnumerator(Builder: &DIBuilder,
|
||||||
Name: *const c_char,
|
Name: *const c_char,
|
||||||
Val: u64)
|
Val: u64)
|
||||||
-> DIEnumerator;
|
-> &DIEnumerator;
|
||||||
|
|
||||||
pub fn LLVMRustDIBuilderCreateEnumerationType(Builder: &DIBuilder,
|
pub fn LLVMRustDIBuilderCreateEnumerationType(Builder: &'a DIBuilder,
|
||||||
Scope: DIScope,
|
Scope: &'a DIScope,
|
||||||
Name: *const c_char,
|
Name: *const c_char,
|
||||||
File: DIFile,
|
File: &'a DIFile,
|
||||||
LineNumber: c_uint,
|
LineNumber: c_uint,
|
||||||
SizeInBits: u64,
|
SizeInBits: u64,
|
||||||
AlignInBits: u32,
|
AlignInBits: u32,
|
||||||
Elements: DIArray,
|
Elements: &'a DIArray,
|
||||||
ClassType: DIType)
|
ClassType: &'a DIType)
|
||||||
-> DIType;
|
-> &'a DIType;
|
||||||
|
|
||||||
pub fn LLVMRustDIBuilderCreateUnionType(Builder: &DIBuilder,
|
pub fn LLVMRustDIBuilderCreateUnionType(Builder: &'a DIBuilder,
|
||||||
Scope: DIScope,
|
Scope: &'a DIScope,
|
||||||
Name: *const c_char,
|
Name: *const c_char,
|
||||||
File: DIFile,
|
File: &'a DIFile,
|
||||||
LineNumber: c_uint,
|
LineNumber: c_uint,
|
||||||
SizeInBits: u64,
|
SizeInBits: u64,
|
||||||
AlignInBits: u32,
|
AlignInBits: u32,
|
||||||
Flags: DIFlags,
|
Flags: DIFlags,
|
||||||
Elements: Option<NonNull<DIArray_opaque>>,
|
Elements: Option<&'a DIArray>,
|
||||||
RunTimeLang: c_uint,
|
RunTimeLang: c_uint,
|
||||||
UniqueId: *const c_char)
|
UniqueId: *const c_char)
|
||||||
-> DIType;
|
-> &'a DIType;
|
||||||
|
|
||||||
pub fn LLVMSetUnnamedAddr(GlobalVar: ValueRef, UnnamedAddr: Bool);
|
pub fn LLVMSetUnnamedAddr(GlobalVar: ValueRef, UnnamedAddr: Bool);
|
||||||
|
|
||||||
pub fn LLVMRustDIBuilderCreateTemplateTypeParameter(Builder: &DIBuilder,
|
pub fn LLVMRustDIBuilderCreateTemplateTypeParameter(Builder: &'a DIBuilder,
|
||||||
Scope: Option<NonNull<DIScope_opaque>>,
|
Scope: Option<&'a DIScope>,
|
||||||
Name: *const c_char,
|
Name: *const c_char,
|
||||||
Ty: DIType,
|
Ty: &'a DIType,
|
||||||
File: DIFile,
|
File: &'a DIFile,
|
||||||
LineNo: c_uint,
|
LineNo: c_uint,
|
||||||
ColumnNo: c_uint)
|
ColumnNo: c_uint)
|
||||||
-> DITemplateTypeParameter;
|
-> &'a DITemplateTypeParameter;
|
||||||
|
|
||||||
|
|
||||||
pub fn LLVMRustDIBuilderCreateNameSpace(Builder: &DIBuilder,
|
pub fn LLVMRustDIBuilderCreateNameSpace(Builder: &'a DIBuilder,
|
||||||
Scope: Option<NonNull<DIScope_opaque>>,
|
Scope: Option<&'a DIScope>,
|
||||||
Name: *const c_char,
|
Name: *const c_char,
|
||||||
File: DIFile,
|
File: &'a DIFile,
|
||||||
LineNo: c_uint)
|
LineNo: c_uint)
|
||||||
-> DINameSpace;
|
-> &'a DINameSpace;
|
||||||
pub fn LLVMRustDICompositeTypeSetTypeArray(Builder: &DIBuilder,
|
|
||||||
CompositeType: DIType,
|
pub fn LLVMRustDICompositeTypeSetTypeArray(Builder: &'a DIBuilder,
|
||||||
TypeArray: DIArray);
|
CompositeType: &'a DIType,
|
||||||
|
TypeArray: &'a DIArray);
|
||||||
|
|
||||||
|
|
||||||
pub fn LLVMRustDIBuilderCreateDebugLocation(Context: &Context,
|
pub fn LLVMRustDIBuilderCreateDebugLocation(Context: &'a Context,
|
||||||
Line: c_uint,
|
Line: c_uint,
|
||||||
Column: c_uint,
|
Column: c_uint,
|
||||||
Scope: DIScope,
|
Scope: &'a DIScope,
|
||||||
InlinedAt: Option<NonNull<Metadata_opaque>>)
|
InlinedAt: Option<&'a Metadata>)
|
||||||
-> ValueRef;
|
-> ValueRef;
|
||||||
pub fn LLVMRustDIBuilderCreateOpDeref() -> i64;
|
pub fn LLVMRustDIBuilderCreateOpDeref() -> i64;
|
||||||
pub fn LLVMRustDIBuilderCreateOpPlusUconst() -> i64;
|
pub fn LLVMRustDIBuilderCreateOpPlusUconst() -> i64;
|
||||||
|
|
|
@ -16,7 +16,6 @@
|
||||||
|
|
||||||
pub use self::IntPredicate::*;
|
pub use self::IntPredicate::*;
|
||||||
pub use self::RealPredicate::*;
|
pub use self::RealPredicate::*;
|
||||||
pub use self::TypeKind::*;
|
|
||||||
pub use self::AtomicRmwBinOp::*;
|
pub use self::AtomicRmwBinOp::*;
|
||||||
pub use self::MetadataType::*;
|
pub use self::MetadataType::*;
|
||||||
pub use self::CodeGenOptSize::*;
|
pub use self::CodeGenOptSize::*;
|
||||||
|
|
|
@ -11,7 +11,7 @@
|
||||||
use common::{C_i32, C_null};
|
use common::{C_i32, C_null};
|
||||||
use libc::c_uint;
|
use libc::c_uint;
|
||||||
use llvm::{self, ValueRef, BasicBlockRef};
|
use llvm::{self, ValueRef, BasicBlockRef};
|
||||||
use llvm::debuginfo::DIScope_opaque;
|
use llvm::debuginfo::DIScope;
|
||||||
use rustc::ty::{self, Ty, TypeFoldable, UpvarSubsts};
|
use rustc::ty::{self, Ty, TypeFoldable, UpvarSubsts};
|
||||||
use rustc::ty::layout::{LayoutOf, TyLayout};
|
use rustc::ty::layout::{LayoutOf, TyLayout};
|
||||||
use rustc::mir::{self, Mir};
|
use rustc::mir::{self, Mir};
|
||||||
|
@ -29,7 +29,6 @@ use syntax_pos::{DUMMY_SP, NO_EXPANSION, BytePos, Span};
|
||||||
use syntax::symbol::keywords;
|
use syntax::symbol::keywords;
|
||||||
|
|
||||||
use std::iter;
|
use std::iter;
|
||||||
use std::ptr::NonNull;
|
|
||||||
|
|
||||||
use rustc_data_structures::bitvec::BitVector;
|
use rustc_data_structures::bitvec::BitVector;
|
||||||
use rustc_data_structures::indexed_vec::{IndexVec, Idx};
|
use rustc_data_structures::indexed_vec::{IndexVec, Idx};
|
||||||
|
@ -48,7 +47,7 @@ pub struct FunctionCx<'a, 'll: 'a, 'tcx: 'll> {
|
||||||
|
|
||||||
mir: &'a mir::Mir<'tcx>,
|
mir: &'a mir::Mir<'tcx>,
|
||||||
|
|
||||||
debug_context: debuginfo::FunctionDebugContext,
|
debug_context: FunctionDebugContext<'ll>,
|
||||||
|
|
||||||
llfn: ValueRef,
|
llfn: ValueRef,
|
||||||
|
|
||||||
|
@ -100,7 +99,7 @@ pub struct FunctionCx<'a, 'll: 'a, 'tcx: 'll> {
|
||||||
locals: IndexVec<mir::Local, LocalRef<'tcx>>,
|
locals: IndexVec<mir::Local, LocalRef<'tcx>>,
|
||||||
|
|
||||||
/// Debug information for MIR scopes.
|
/// Debug information for MIR scopes.
|
||||||
scopes: IndexVec<mir::SourceScope, debuginfo::MirDebugScope>,
|
scopes: IndexVec<mir::SourceScope, debuginfo::MirDebugScope<'ll>>,
|
||||||
|
|
||||||
/// If this function is being monomorphized, this contains the type substitutions used.
|
/// If this function is being monomorphized, this contains the type substitutions used.
|
||||||
param_substs: &'tcx Substs<'tcx>,
|
param_substs: &'tcx Substs<'tcx>,
|
||||||
|
@ -117,12 +116,12 @@ impl FunctionCx<'a, 'll, 'tcx> {
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn set_debug_loc(&mut self, bx: &Builder, source_info: mir::SourceInfo) {
|
pub fn set_debug_loc(&mut self, bx: &Builder<'_, 'll, '_>, source_info: mir::SourceInfo) {
|
||||||
let (scope, span) = self.debug_loc(source_info);
|
let (scope, span) = self.debug_loc(source_info);
|
||||||
debuginfo::set_source_location(&self.debug_context, bx, scope, span);
|
debuginfo::set_source_location(&self.debug_context, bx, scope, span);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn debug_loc(&mut self, source_info: mir::SourceInfo) -> (Option<NonNull<DIScope_opaque>>, Span) {
|
pub fn debug_loc(&mut self, source_info: mir::SourceInfo) -> (Option<&'ll DIScope>, Span) {
|
||||||
// Bail out if debug info emission is not enabled.
|
// Bail out if debug info emission is not enabled.
|
||||||
match self.debug_context {
|
match self.debug_context {
|
||||||
FunctionDebugContext::DebugInfoDisabled |
|
FunctionDebugContext::DebugInfoDisabled |
|
||||||
|
@ -162,14 +161,14 @@ impl FunctionCx<'a, 'll, 'tcx> {
|
||||||
// corresponding to span's containing source scope. If so, we need to create a DIScope
|
// corresponding to span's containing source scope. If so, we need to create a DIScope
|
||||||
// "extension" into that file.
|
// "extension" into that file.
|
||||||
fn scope_metadata_for_loc(&self, scope_id: mir::SourceScope, pos: BytePos)
|
fn scope_metadata_for_loc(&self, scope_id: mir::SourceScope, pos: BytePos)
|
||||||
-> Option<NonNull<DIScope_opaque>> {
|
-> Option<&'ll DIScope> {
|
||||||
let scope_metadata = self.scopes[scope_id].scope_metadata;
|
let scope_metadata = self.scopes[scope_id].scope_metadata;
|
||||||
if pos < self.scopes[scope_id].file_start_pos ||
|
if pos < self.scopes[scope_id].file_start_pos ||
|
||||||
pos >= self.scopes[scope_id].file_end_pos {
|
pos >= self.scopes[scope_id].file_end_pos {
|
||||||
let cm = self.cx.sess().codemap();
|
let cm = self.cx.sess().codemap();
|
||||||
let defining_crate = self.debug_context.get_ref(DUMMY_SP).defining_crate;
|
let defining_crate = self.debug_context.get_ref(DUMMY_SP).defining_crate;
|
||||||
NonNull::new(debuginfo::extend_scope_to_file(self.cx,
|
Some(debuginfo::extend_scope_to_file(self.cx,
|
||||||
scope_metadata.unwrap().as_ptr(),
|
scope_metadata.unwrap(),
|
||||||
&cm.lookup_char_pos(pos).file,
|
&cm.lookup_char_pos(pos).file,
|
||||||
defining_crate))
|
defining_crate))
|
||||||
} else {
|
} else {
|
||||||
|
@ -281,7 +280,7 @@ pub fn codegen_mir(
|
||||||
span: decl.source_info.span,
|
span: decl.source_info.span,
|
||||||
scope: decl.visibility_scope,
|
scope: decl.visibility_scope,
|
||||||
});
|
});
|
||||||
declare_local(&bx, &fx.debug_context, name, layout.ty, scope.unwrap().as_ptr(),
|
declare_local(&bx, &fx.debug_context, name, layout.ty, scope.unwrap(),
|
||||||
VariableAccess::DirectVariable { alloca: place.llval },
|
VariableAccess::DirectVariable { alloca: place.llval },
|
||||||
VariableKind::LocalVariable, span);
|
VariableKind::LocalVariable, span);
|
||||||
}
|
}
|
||||||
|
@ -416,7 +415,7 @@ fn create_funclets(
|
||||||
fn arg_local_refs(
|
fn arg_local_refs(
|
||||||
bx: &Builder<'a, 'll, 'tcx>,
|
bx: &Builder<'a, 'll, 'tcx>,
|
||||||
fx: &FunctionCx<'a, 'll, 'tcx>,
|
fx: &FunctionCx<'a, 'll, 'tcx>,
|
||||||
scopes: &IndexVec<mir::SourceScope, debuginfo::MirDebugScope>,
|
scopes: &IndexVec<mir::SourceScope, debuginfo::MirDebugScope<'ll>>,
|
||||||
memory_locals: &BitVector<mir::Local>,
|
memory_locals: &BitVector<mir::Local>,
|
||||||
) -> Vec<LocalRef<'tcx>> {
|
) -> Vec<LocalRef<'tcx>> {
|
||||||
let mir = fx.mir;
|
let mir = fx.mir;
|
||||||
|
@ -473,7 +472,7 @@ fn arg_local_refs(
|
||||||
bx,
|
bx,
|
||||||
&fx.debug_context,
|
&fx.debug_context,
|
||||||
arg_decl.name.unwrap_or(keywords::Invalid.name()),
|
arg_decl.name.unwrap_or(keywords::Invalid.name()),
|
||||||
arg_ty, scope.as_ptr(),
|
arg_ty, scope,
|
||||||
variable_access,
|
variable_access,
|
||||||
VariableKind::ArgumentVariable(arg_index + 1),
|
VariableKind::ArgumentVariable(arg_index + 1),
|
||||||
DUMMY_SP
|
DUMMY_SP
|
||||||
|
@ -552,7 +551,7 @@ fn arg_local_refs(
|
||||||
&fx.debug_context,
|
&fx.debug_context,
|
||||||
arg_decl.name.unwrap_or(keywords::Invalid.name()),
|
arg_decl.name.unwrap_or(keywords::Invalid.name()),
|
||||||
arg.layout.ty,
|
arg.layout.ty,
|
||||||
scope.as_ptr(),
|
scope,
|
||||||
variable_access,
|
variable_access,
|
||||||
VariableKind::ArgumentVariable(arg_index + 1),
|
VariableKind::ArgumentVariable(arg_index + 1),
|
||||||
DUMMY_SP
|
DUMMY_SP
|
||||||
|
@ -603,7 +602,7 @@ fn arg_local_refs(
|
||||||
&fx.debug_context,
|
&fx.debug_context,
|
||||||
decl.debug_name,
|
decl.debug_name,
|
||||||
ty,
|
ty,
|
||||||
scope.as_ptr(),
|
scope,
|
||||||
variable_access,
|
variable_access,
|
||||||
VariableKind::LocalVariable,
|
VariableKind::LocalVariable,
|
||||||
DUMMY_SP
|
DUMMY_SP
|
||||||
|
|
|
@ -14,7 +14,6 @@ pub use llvm::Type;
|
||||||
|
|
||||||
use llvm;
|
use llvm;
|
||||||
use llvm::{Bool, False, True, TypeKind};
|
use llvm::{Bool, False, True, TypeKind};
|
||||||
use llvm::{Float, Double, X86_FP80, PPC_FP128, FP128};
|
|
||||||
|
|
||||||
use context::CodegenCx;
|
use context::CodegenCx;
|
||||||
|
|
||||||
|
@ -265,10 +264,10 @@ impl Type {
|
||||||
|
|
||||||
pub fn float_width(&self) -> usize {
|
pub fn float_width(&self) -> usize {
|
||||||
match self.kind() {
|
match self.kind() {
|
||||||
Float => 32,
|
TypeKind::Float => 32,
|
||||||
Double => 64,
|
TypeKind::Double => 64,
|
||||||
X86_FP80 => 80,
|
TypeKind::X86_FP80 => 80,
|
||||||
FP128 | PPC_FP128 => 128,
|
TypeKind::FP128 | TypeKind::PPC_FP128 => 128,
|
||||||
_ => bug!("llvm_float_width called on a non-float type")
|
_ => bug!("llvm_float_width called on a non-float type")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue