rustc_codegen_llvm: use safe references for Metadata and DI*.

This commit is contained in:
Irina Popa 2018-07-04 16:36:49 +03:00
parent 6d0d82ce10
commit eed48f560f
12 changed files with 410 additions and 376 deletions

View file

@ -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();

View file

@ -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))

View file

@ -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()
); );

View file

@ -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,

View file

@ -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 {

View file

@ -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.

View file

@ -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?"))
} }

View file

@ -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));

View file

@ -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;

View file

@ -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::*;

View file

@ -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

View file

@ -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")
} }
} }