rustc_codegen_llvm: use safe references for Type.

This commit is contained in:
Irina Popa 2018-07-02 17:52:53 +03:00
parent 249d5acaec
commit d04e66d114
26 changed files with 568 additions and 533 deletions

View File

@ -103,11 +103,11 @@ impl ArgAttributesExt for ArgAttributes {
} }
pub trait LlvmType { pub trait LlvmType {
fn llvm_type(&self, cx: &CodegenCx) -> Type; fn llvm_type(&self, cx: &CodegenCx<'ll, '_>) -> &'ll Type;
} }
impl LlvmType for Reg { impl LlvmType for Reg {
fn llvm_type(&self, cx: &CodegenCx) -> Type { fn llvm_type(&self, cx: &CodegenCx<'ll, '_>) -> &'ll Type {
match self.kind { match self.kind {
RegKind::Integer => Type::ix(cx, self.size.bits()), RegKind::Integer => Type::ix(cx, self.size.bits()),
RegKind::Float => { RegKind::Float => {
@ -118,14 +118,14 @@ impl LlvmType for Reg {
} }
} }
RegKind::Vector => { RegKind::Vector => {
Type::vector(&Type::i8(cx), self.size.bytes()) Type::vector(Type::i8(cx), self.size.bytes())
} }
} }
} }
} }
impl LlvmType for CastTarget { impl LlvmType for CastTarget {
fn llvm_type(&self, cx: &CodegenCx) -> Type { fn llvm_type(&self, cx: &CodegenCx<'ll, '_>) -> &'ll Type {
let rest_ll_unit = self.rest.unit.llvm_type(cx); let rest_ll_unit = self.rest.unit.llvm_type(cx);
let (rest_count, rem_bytes) = if self.rest.unit.size.bytes() == 0 { let (rest_count, rem_bytes) = if self.rest.unit.size.bytes() == 0 {
(0, 0) (0, 0)
@ -142,7 +142,7 @@ impl LlvmType for CastTarget {
// Simplify to array when all chunks are the same size and type // Simplify to array when all chunks are the same size and type
if rem_bytes == 0 { if rem_bytes == 0 {
return Type::array(&rest_ll_unit, rest_count); return Type::array(rest_ll_unit, rest_count);
} }
} }
@ -165,15 +165,15 @@ impl LlvmType for CastTarget {
} }
pub trait ArgTypeExt<'a, 'tcx> { pub trait ArgTypeExt<'a, 'tcx> {
fn memory_ty(&self, cx: &CodegenCx<'a, 'tcx>) -> Type; fn memory_ty(&self, cx: &CodegenCx<'a, 'tcx>) -> &'a Type;
fn store(&self, bx: &Builder<'a, 'tcx>, val: ValueRef, dst: PlaceRef<'tcx>); fn store(&self, bx: &Builder<'a, 'll, 'tcx>, val: ValueRef, dst: PlaceRef<'tcx>);
fn store_fn_arg(&self, bx: &Builder<'a, 'tcx>, idx: &mut usize, dst: PlaceRef<'tcx>); fn store_fn_arg(&self, bx: &Builder<'a, 'll, 'tcx>, idx: &mut usize, dst: PlaceRef<'tcx>);
} }
impl<'a, 'tcx> ArgTypeExt<'a, 'tcx> for ArgType<'tcx, Ty<'tcx>> { impl<'a, 'tcx> ArgTypeExt<'a, 'tcx> for ArgType<'tcx, Ty<'tcx>> {
/// Get the LLVM type for a place of the original Rust type of /// Get the LLVM type for a place of the original Rust type of
/// this argument/return, i.e. the result of `type_of::type_of`. /// this argument/return, i.e. the result of `type_of::type_of`.
fn memory_ty(&self, cx: &CodegenCx<'a, 'tcx>) -> Type { fn memory_ty(&self, cx: &CodegenCx<'a, 'tcx>) -> &'a Type {
self.layout.llvm_type(cx) self.layout.llvm_type(cx)
} }
@ -181,7 +181,7 @@ impl<'a, 'tcx> ArgTypeExt<'a, 'tcx> for ArgType<'tcx, Ty<'tcx>> {
/// place for the original Rust type of this argument/return. /// place for the original Rust type of this argument/return.
/// Can be used for both storing formal arguments into Rust variables /// Can be used for both storing formal arguments into Rust variables
/// or results of call/invoke instructions into their destinations. /// or results of call/invoke instructions into their destinations.
fn store(&self, bx: &Builder<'a, 'tcx>, val: ValueRef, dst: PlaceRef<'tcx>) { fn store(&self, bx: &Builder<'a, 'll, 'tcx>, val: ValueRef, dst: PlaceRef<'tcx>) {
if self.is_ignore() { if self.is_ignore() {
return; return;
} }
@ -234,7 +234,7 @@ impl<'a, 'tcx> ArgTypeExt<'a, 'tcx> for ArgType<'tcx, Ty<'tcx>> {
} }
} }
fn store_fn_arg(&self, bx: &Builder<'a, 'tcx>, idx: &mut usize, dst: PlaceRef<'tcx>) { fn store_fn_arg(&self, bx: &Builder<'a, 'll, 'tcx>, idx: &mut usize, dst: PlaceRef<'tcx>) {
let mut next = || { let mut next = || {
let val = llvm::get_param(bx.llfn(), *idx as c_uint); let val = llvm::get_param(bx.llfn(), *idx as c_uint);
*idx += 1; *idx += 1;
@ -270,10 +270,10 @@ pub trait FnTypeExt<'a, 'tcx> {
fn adjust_for_abi(&mut self, fn adjust_for_abi(&mut self,
cx: &CodegenCx<'a, 'tcx>, cx: &CodegenCx<'a, 'tcx>,
abi: Abi); abi: Abi);
fn llvm_type(&self, cx: &CodegenCx<'a, 'tcx>) -> Type; fn llvm_type(&self, cx: &CodegenCx<'a, 'tcx>) -> &'a Type;
fn llvm_cconv(&self) -> llvm::CallConv; fn llvm_cconv(&self) -> llvm::CallConv;
fn apply_attrs_llfn(&self, llfn: ValueRef); fn apply_attrs_llfn(&self, llfn: ValueRef);
fn apply_attrs_callsite(&self, bx: &Builder<'a, 'tcx>, callsite: ValueRef); fn apply_attrs_callsite(&self, bx: &Builder<'a, 'll, 'tcx>, callsite: ValueRef);
} }
impl<'a, 'tcx> FnTypeExt<'a, 'tcx> for FnType<'tcx, Ty<'tcx>> { impl<'a, 'tcx> FnTypeExt<'a, 'tcx> for FnType<'tcx, Ty<'tcx>> {
@ -564,7 +564,7 @@ impl<'a, 'tcx> FnTypeExt<'a, 'tcx> for FnType<'tcx, Ty<'tcx>> {
} }
} }
fn llvm_type(&self, cx: &CodegenCx<'a, 'tcx>) -> Type { fn llvm_type(&self, cx: &CodegenCx<'a, 'tcx>) -> &'a Type {
let args_capacity: usize = self.args.iter().map(|arg| let args_capacity: usize = self.args.iter().map(|arg|
if arg.pad.is_some() { 1 } else { 0 } + if arg.pad.is_some() { 1 } else { 0 } +
if let PassMode::Pair(_, _) = arg.mode { 2 } else { 1 } if let PassMode::Pair(_, _) = arg.mode { 2 } else { 1 }
@ -606,9 +606,9 @@ impl<'a, 'tcx> FnTypeExt<'a, 'tcx> for FnType<'tcx, Ty<'tcx>> {
} }
if self.variadic { if self.variadic {
Type::variadic_func(&llargument_tys, &llreturn_ty) Type::variadic_func(&llargument_tys, llreturn_ty)
} else { } else {
Type::func(&llargument_tys, &llreturn_ty) Type::func(&llargument_tys, llreturn_ty)
} }
} }
@ -659,7 +659,7 @@ impl<'a, 'tcx> FnTypeExt<'a, 'tcx> for FnType<'tcx, Ty<'tcx>> {
} }
} }
fn apply_attrs_callsite(&self, bx: &Builder<'a, 'tcx>, callsite: ValueRef) { fn apply_attrs_callsite(&self, bx: &Builder<'a, 'll, 'tcx>, callsite: ValueRef) {
let mut i = 0; let mut i = 0;
let mut apply = |attrs: &ArgAttributes| { let mut apply = |attrs: &ArgAttributes| {
attrs.apply_callsite(llvm::AttributePlace::Argument(i), callsite); attrs.apply_callsite(llvm::AttributePlace::Argument(i), callsite);

View File

@ -24,8 +24,8 @@ use syntax::ast::AsmDialect;
use libc::{c_uint, c_char}; use libc::{c_uint, c_char};
// Take an inline assembly expression and splat it out via LLVM // Take an inline assembly expression and splat it out via LLVM
pub fn codegen_inline_asm<'a, 'tcx>( pub fn codegen_inline_asm(
bx: &Builder<'a, 'tcx>, bx: &Builder<'a, 'll, 'tcx>,
ia: &hir::InlineAsm, ia: &hir::InlineAsm,
outputs: Vec<PlaceRef<'tcx>>, outputs: Vec<PlaceRef<'tcx>>,
mut inputs: Vec<ValueRef> mut inputs: Vec<ValueRef>

View File

@ -831,7 +831,7 @@ unsafe fn embed_bitcode(cgcx: &CodegenContext,
let llconst = C_bytes_in_context(llcx, bitcode.unwrap_or(&[])); let llconst = C_bytes_in_context(llcx, bitcode.unwrap_or(&[]));
let llglobal = llvm::LLVMAddGlobal( let llglobal = llvm::LLVMAddGlobal(
llmod, llmod,
val_ty(llconst).to_ref(), val_ty(llconst),
"rustc.embedded.module\0".as_ptr() as *const _, "rustc.embedded.module\0".as_ptr() as *const _,
); );
llvm::LLVMSetInitializer(llglobal, llconst); llvm::LLVMSetInitializer(llglobal, llconst);
@ -851,7 +851,7 @@ unsafe fn embed_bitcode(cgcx: &CodegenContext,
let llconst = C_bytes_in_context(llcx, &[]); let llconst = C_bytes_in_context(llcx, &[]);
let llglobal = llvm::LLVMAddGlobal( let llglobal = llvm::LLVMAddGlobal(
llmod, llmod,
val_ty(llconst).to_ref(), val_ty(llconst),
"rustc.embedded.cmdline\0".as_ptr() as *const _, "rustc.embedded.cmdline\0".as_ptr() as *const _,
); );
llvm::LLVMSetInitializer(llglobal, llconst); llvm::LLVMSetInitializer(llglobal, llconst);
@ -2380,7 +2380,7 @@ fn create_msvc_imps(cgcx: &CodegenContext, llcx: &llvm::Context, llmod: &llvm::M
.collect::<Vec<_>>(); .collect::<Vec<_>>();
for (imp_name, val) in globals { for (imp_name, val) in globals {
let imp = llvm::LLVMAddGlobal(llmod, let imp = llvm::LLVMAddGlobal(llmod,
i8p_ty.to_ref(), i8p_ty,
imp_name.as_ptr() as *const _); imp_name.as_ptr() as *const _);
llvm::LLVMSetInitializer(imp, consts::ptrcast(val, i8p_ty)); llvm::LLVMSetInitializer(imp, consts::ptrcast(val, i8p_ty));
llvm::LLVMRustSetLinkage(imp, llvm::Linkage::ExternalLinkage); llvm::LLVMRustSetLinkage(imp, llvm::Linkage::ExternalLinkage);

View File

@ -19,9 +19,9 @@
//! //!
//! * There's no way to find out the Ty type of a ValueRef. Doing so //! * There's no way to find out the Ty type of a ValueRef. Doing so
//! would be "trying to get the eggs out of an omelette" (credit: //! would be "trying to get the eggs out of an omelette" (credit:
//! pcwalton). You can, instead, find out its TypeRef by calling val_ty, //! pcwalton). You can, instead, find out its llvm::Type by calling val_ty,
//! but one TypeRef corresponds to many `Ty`s; for instance, tup(int, int, //! but one llvm::Type corresponds to many `Ty`s; for instance, tup(int, int,
//! int) and rec(x=int, y=int, z=int) will have the same TypeRef. //! int) and rec(x=int, y=int, z=int) will have the same llvm::Type.
use super::ModuleLlvm; use super::ModuleLlvm;
use super::ModuleSource; use super::ModuleSource;
@ -91,14 +91,14 @@ use mir::operand::OperandValue;
use rustc_codegen_utils::check_for_rustc_errors_attr; use rustc_codegen_utils::check_for_rustc_errors_attr;
pub struct StatRecorder<'a, 'tcx: 'a> { pub struct StatRecorder<'a, 'll: 'a, 'tcx: 'll> {
cx: &'a CodegenCx<'a, 'tcx>, cx: &'a CodegenCx<'ll, 'tcx>,
name: Option<String>, name: Option<String>,
istart: usize, istart: usize,
} }
impl<'a, 'tcx> StatRecorder<'a, 'tcx> { impl StatRecorder<'a, 'll, 'tcx> {
pub fn new(cx: &'a CodegenCx<'a, 'tcx>, name: String) -> StatRecorder<'a, 'tcx> { pub fn new(cx: &'a CodegenCx<'ll, 'tcx>, name: String) -> Self {
let istart = cx.stats.borrow().n_llvm_insns; let istart = cx.stats.borrow().n_llvm_insns;
StatRecorder { StatRecorder {
cx, cx,
@ -108,7 +108,7 @@ impl<'a, 'tcx> StatRecorder<'a, 'tcx> {
} }
} }
impl<'a, 'tcx> Drop for StatRecorder<'a, 'tcx> { impl Drop for StatRecorder<'a, 'll, 'tcx> {
fn drop(&mut self) { fn drop(&mut self) {
if self.cx.sess().codegen_stats() { if self.cx.sess().codegen_stats() {
let mut stats = self.cx.stats.borrow_mut(); let mut stats = self.cx.stats.borrow_mut();
@ -155,12 +155,12 @@ pub fn bin_op_to_fcmp_predicate(op: hir::BinOpKind) -> llvm::RealPredicate {
} }
} }
pub fn compare_simd_types<'a, 'tcx>( pub fn compare_simd_types(
bx: &Builder<'a, 'tcx>, bx: &Builder<'a, 'll, 'tcx>,
lhs: ValueRef, lhs: ValueRef,
rhs: ValueRef, rhs: ValueRef,
t: Ty<'tcx>, t: Ty<'tcx>,
ret_ty: Type, ret_ty: &'ll Type,
op: hir::BinOpKind op: hir::BinOpKind
) -> ValueRef { ) -> ValueRef {
let signed = match t.sty { let signed = match t.sty {
@ -216,8 +216,8 @@ pub fn unsized_info<'cx, 'tcx>(cx: &CodegenCx<'cx, 'tcx>,
} }
/// Coerce `src` to `dst_ty`. `src_ty` must be a thin pointer. /// Coerce `src` to `dst_ty`. `src_ty` must be a thin pointer.
pub fn unsize_thin_ptr<'a, 'tcx>( pub fn unsize_thin_ptr(
bx: &Builder<'a, 'tcx>, bx: &Builder<'a, 'll, 'tcx>,
src: ValueRef, src: ValueRef,
src_ty: Ty<'tcx>, src_ty: Ty<'tcx>,
dst_ty: Ty<'tcx> dst_ty: Ty<'tcx>
@ -271,9 +271,11 @@ pub fn unsize_thin_ptr<'a, 'tcx>(
/// Coerce `src`, which is a reference to a value of type `src_ty`, /// Coerce `src`, which is a reference to a value of type `src_ty`,
/// to a value of type `dst_ty` and store the result in `dst` /// to a value of type `dst_ty` and store the result in `dst`
pub fn coerce_unsized_into<'a, 'tcx>(bx: &Builder<'a, 'tcx>, pub fn coerce_unsized_into(
src: PlaceRef<'tcx>, bx: &Builder<'a, 'll, 'tcx>,
dst: PlaceRef<'tcx>) { src: PlaceRef<'tcx>,
dst: PlaceRef<'tcx>
) {
let src_ty = src.layout.ty; let src_ty = src.layout.ty;
let dst_ty = dst.layout.ty; let dst_ty = dst.layout.ty;
let coerce_ptr = || { let coerce_ptr = || {
@ -334,14 +336,14 @@ pub fn cast_shift_expr_rhs(
cast_shift_rhs(op, lhs, rhs, |a, b| cx.trunc(a, b), |a, b| cx.zext(a, b)) cast_shift_rhs(op, lhs, rhs, |a, b| cx.trunc(a, b), |a, b| cx.zext(a, b))
} }
fn cast_shift_rhs<F, G>(op: hir::BinOpKind, fn cast_shift_rhs<'ll, F, G>(op: hir::BinOpKind,
lhs: ValueRef, lhs: ValueRef,
rhs: ValueRef, rhs: ValueRef,
trunc: F, trunc: F,
zext: G) zext: G)
-> ValueRef -> ValueRef
where F: FnOnce(ValueRef, Type) -> ValueRef, where F: FnOnce(ValueRef, &'ll Type) -> ValueRef,
G: FnOnce(ValueRef, Type) -> ValueRef G: FnOnce(ValueRef, &'ll Type) -> ValueRef
{ {
// Shifts may have any size int on the rhs // Shifts may have any size int on the rhs
if op.is_shift() { if op.is_shift() {
@ -378,7 +380,7 @@ pub fn wants_msvc_seh(sess: &Session) -> bool {
sess.target.target.options.is_like_msvc sess.target.target.options.is_like_msvc
} }
pub fn call_assume<'a, 'tcx>(bx: &Builder<'a, 'tcx>, val: ValueRef) { pub fn call_assume(bx: &Builder<'a, 'll, 'tcx>, val: ValueRef) {
let assume_intrinsic = bx.cx.get_intrinsic("llvm.assume"); let assume_intrinsic = bx.cx.get_intrinsic("llvm.assume");
bx.call(assume_intrinsic, &[val], None); bx.call(assume_intrinsic, &[val], None);
} }
@ -430,8 +432,8 @@ pub fn call_memcpy(bx: &Builder,
bx.call(memcpy, &[dst_ptr, src_ptr, size, align, volatile], None); bx.call(memcpy, &[dst_ptr, src_ptr, size, align, volatile], None);
} }
pub fn memcpy_ty<'a, 'tcx>( pub fn memcpy_ty(
bx: &Builder<'a, 'tcx>, bx: &Builder<'a, 'll, 'tcx>,
dst: ValueRef, dst: ValueRef,
src: ValueRef, src: ValueRef,
layout: TyLayout<'tcx>, layout: TyLayout<'tcx>,
@ -446,12 +448,14 @@ pub fn memcpy_ty<'a, 'tcx>(
call_memcpy(bx, dst, src, C_usize(bx.cx, size), align, flags); call_memcpy(bx, dst, src, C_usize(bx.cx, size), align, flags);
} }
pub fn call_memset<'a, 'tcx>(bx: &Builder<'a, 'tcx>, pub fn call_memset(
ptr: ValueRef, bx: &Builder<'a, 'll, 'tcx>,
fill_byte: ValueRef, ptr: ValueRef,
size: ValueRef, fill_byte: ValueRef,
align: ValueRef, size: ValueRef,
volatile: bool) -> ValueRef { align: ValueRef,
volatile: bool,
) -> ValueRef {
let ptr_width = &bx.cx.sess().target.target.target_pointer_width; let ptr_width = &bx.cx.sess().target.target.target_pointer_width;
let intrinsic_key = format!("llvm.memset.p0i8.i{}", ptr_width); let intrinsic_key = format!("llvm.memset.p0i8.i{}", ptr_width);
let llintrinsicfn = bx.cx.get_intrinsic(&intrinsic_key); let llintrinsicfn = bx.cx.get_intrinsic(&intrinsic_key);
@ -553,7 +557,7 @@ fn maybe_create_entry_wrapper(cx: &CodegenCx) {
rust_main: ValueRef, rust_main: ValueRef,
rust_main_def_id: DefId, rust_main_def_id: DefId,
use_start_lang_item: bool) { use_start_lang_item: bool) {
let llfty = Type::func(&[Type::c_int(cx), Type::i8p(cx).ptr_to()], &Type::c_int(cx)); let llfty = Type::func(&[Type::c_int(cx), Type::i8p(cx).ptr_to()], Type::c_int(cx));
let main_ret_ty = cx.tcx.fn_sig(rust_main_def_id).output(); let main_ret_ty = cx.tcx.fn_sig(rust_main_def_id).output();
// Given that `main()` has no arguments, // Given that `main()` has no arguments,
@ -656,7 +660,7 @@ fn write_metadata<'a, 'gcx>(tcx: TyCtxt<'a, 'gcx, 'gcx>,
let name = exported_symbols::metadata_symbol_name(tcx); let name = exported_symbols::metadata_symbol_name(tcx);
let buf = CString::new(name).unwrap(); let buf = CString::new(name).unwrap();
let llglobal = unsafe { let llglobal = unsafe {
llvm::LLVMAddGlobal(metadata_llmod, val_ty(llconst).to_ref(), buf.as_ptr()) llvm::LLVMAddGlobal(metadata_llmod, val_ty(llconst), buf.as_ptr())
}; };
unsafe { unsafe {
llvm::LLVMSetInitializer(llglobal, llconst); llvm::LLVMSetInitializer(llglobal, llconst);
@ -1206,7 +1210,7 @@ fn compile_codegen_unit<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
// Run replace-all-uses-with for statics that need it // Run replace-all-uses-with for statics that need it
for &(old_g, new_g) in cx.statics_to_rauw.borrow().iter() { for &(old_g, new_g) in cx.statics_to_rauw.borrow().iter() {
unsafe { unsafe {
let bitcast = llvm::LLVMConstPointerCast(new_g, llvm::LLVMTypeOf(old_g)); let bitcast = llvm::LLVMConstPointerCast(new_g, val_ty(old_g));
llvm::LLVMReplaceAllUsesWith(old_g, bitcast); llvm::LLVMReplaceAllUsesWith(old_g, bitcast);
llvm::LLVMDeleteGlobal(old_g); llvm::LLVMDeleteGlobal(old_g);
} }
@ -1221,7 +1225,7 @@ fn compile_codegen_unit<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
unsafe { unsafe {
let g = llvm::LLVMAddGlobal(cx.llmod, let g = llvm::LLVMAddGlobal(cx.llmod,
val_ty(array).to_ref(), val_ty(array),
name.as_ptr()); name.as_ptr());
llvm::LLVMSetInitializer(g, array); llvm::LLVMSetInitializer(g, array);
llvm::LLVMRustSetLinkage(g, llvm::Linkage::AppendingLinkage); llvm::LLVMRustSetLinkage(g, llvm::Linkage::AppendingLinkage);

View File

@ -31,12 +31,12 @@ use syntax_pos::Span;
// All Builders must have an llfn associated with them // All Builders must have an llfn associated with them
#[must_use] #[must_use]
pub struct Builder<'a, 'tcx: 'a> { pub struct Builder<'a, 'll: 'a, 'tcx: 'll> {
pub llbuilder: BuilderRef, pub llbuilder: BuilderRef,
pub cx: &'a CodegenCx<'a, 'tcx>, pub cx: &'a CodegenCx<'ll, 'tcx>,
} }
impl<'a, 'tcx> Drop for Builder<'a, 'tcx> { impl Drop for Builder<'a, 'll, 'tcx> {
fn drop(&mut self) { fn drop(&mut self) {
unsafe { unsafe {
llvm::LLVMDisposeBuilder(self.llbuilder); llvm::LLVMDisposeBuilder(self.llbuilder);
@ -59,8 +59,8 @@ bitflags! {
} }
} }
impl<'a, 'tcx> Builder<'a, 'tcx> { impl Builder<'a, 'll, 'tcx> {
pub fn new_block<'b>(cx: &'a CodegenCx<'a, 'tcx>, llfn: ValueRef, name: &'b str) -> Self { pub fn new_block<'b>(cx: &'a CodegenCx<'ll, 'tcx>, llfn: ValueRef, name: &'b str) -> Self {
let bx = Builder::with_cx(cx); let bx = Builder::with_cx(cx);
let llbb = unsafe { let llbb = unsafe {
let name = CString::new(name).unwrap(); let name = CString::new(name).unwrap();
@ -74,7 +74,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
bx bx
} }
pub fn with_cx(cx: &'a CodegenCx<'a, 'tcx>) -> Self { pub fn with_cx(cx: &'a CodegenCx<'ll, 'tcx>) -> Self {
// Create a fresh builder from the crate context. // Create a fresh builder from the crate context.
let llbuilder = unsafe { let llbuilder = unsafe {
llvm::LLVMCreateBuilderInContext(cx.llcx) llvm::LLVMCreateBuilderInContext(cx.llcx)
@ -85,7 +85,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
} }
} }
pub fn build_sibling_block<'b>(&self, name: &'b str) -> Builder<'a, 'tcx> { pub fn build_sibling_block<'b>(&self, name: &'b str) -> Builder<'a, 'll, 'tcx> {
Builder::new_block(self.cx, self.llfn(), name) Builder::new_block(self.cx, self.llfn(), name)
} }
@ -504,7 +504,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
} }
} }
pub fn alloca(&self, ty: Type, name: &str, align: Align) -> ValueRef { pub fn alloca(&self, ty: &'ll Type, name: &str, align: Align) -> ValueRef {
let bx = Builder::with_cx(self.cx); let bx = Builder::with_cx(self.cx);
bx.position_at_start(unsafe { bx.position_at_start(unsafe {
llvm::LLVMGetFirstBasicBlock(self.llfn()) llvm::LLVMGetFirstBasicBlock(self.llfn())
@ -512,14 +512,14 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
bx.dynamic_alloca(ty, name, align) bx.dynamic_alloca(ty, name, align)
} }
pub fn dynamic_alloca(&self, ty: Type, name: &str, align: Align) -> ValueRef { pub fn dynamic_alloca(&self, ty: &'ll Type, name: &str, align: Align) -> ValueRef {
self.count_insn("alloca"); self.count_insn("alloca");
unsafe { unsafe {
let alloca = if name.is_empty() { let alloca = if name.is_empty() {
llvm::LLVMBuildAlloca(self.llbuilder, ty.to_ref(), noname()) llvm::LLVMBuildAlloca(self.llbuilder, ty, noname())
} else { } else {
let name = CString::new(name).unwrap(); let name = CString::new(name).unwrap();
llvm::LLVMBuildAlloca(self.llbuilder, ty.to_ref(), llvm::LLVMBuildAlloca(self.llbuilder, ty,
name.as_ptr()) name.as_ptr())
}; };
llvm::LLVMSetAlignment(alloca, align.abi() as c_uint); llvm::LLVMSetAlignment(alloca, align.abi() as c_uint);
@ -678,136 +678,136 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
} }
/* Casts */ /* Casts */
pub fn trunc(&self, val: ValueRef, dest_ty: Type) -> ValueRef { pub fn trunc(&self, val: ValueRef, dest_ty: &'ll Type) -> ValueRef {
self.count_insn("trunc"); self.count_insn("trunc");
unsafe { unsafe {
llvm::LLVMBuildTrunc(self.llbuilder, val, dest_ty.to_ref(), noname()) llvm::LLVMBuildTrunc(self.llbuilder, val, dest_ty, noname())
} }
} }
pub fn zext(&self, val: ValueRef, dest_ty: Type) -> ValueRef { pub fn zext(&self, val: ValueRef, dest_ty: &'ll Type) -> ValueRef {
self.count_insn("zext"); self.count_insn("zext");
unsafe { unsafe {
llvm::LLVMBuildZExt(self.llbuilder, val, dest_ty.to_ref(), noname()) llvm::LLVMBuildZExt(self.llbuilder, val, dest_ty, noname())
} }
} }
pub fn sext(&self, val: ValueRef, dest_ty: Type) -> ValueRef { pub fn sext(&self, val: ValueRef, dest_ty: &'ll Type) -> ValueRef {
self.count_insn("sext"); self.count_insn("sext");
unsafe { unsafe {
llvm::LLVMBuildSExt(self.llbuilder, val, dest_ty.to_ref(), noname()) llvm::LLVMBuildSExt(self.llbuilder, val, dest_ty, noname())
} }
} }
pub fn fptoui(&self, val: ValueRef, dest_ty: Type) -> ValueRef { pub fn fptoui(&self, val: ValueRef, dest_ty: &'ll Type) -> ValueRef {
self.count_insn("fptoui"); self.count_insn("fptoui");
unsafe { unsafe {
llvm::LLVMBuildFPToUI(self.llbuilder, val, dest_ty.to_ref(), noname()) llvm::LLVMBuildFPToUI(self.llbuilder, val, dest_ty, noname())
} }
} }
pub fn fptosi(&self, val: ValueRef, dest_ty: Type) -> ValueRef { pub fn fptosi(&self, val: ValueRef, dest_ty: &'ll Type) -> ValueRef {
self.count_insn("fptosi"); self.count_insn("fptosi");
unsafe { unsafe {
llvm::LLVMBuildFPToSI(self.llbuilder, val, dest_ty.to_ref(),noname()) llvm::LLVMBuildFPToSI(self.llbuilder, val, dest_ty,noname())
} }
} }
pub fn uitofp(&self, val: ValueRef, dest_ty: Type) -> ValueRef { pub fn uitofp(&self, val: ValueRef, dest_ty: &'ll Type) -> ValueRef {
self.count_insn("uitofp"); self.count_insn("uitofp");
unsafe { unsafe {
llvm::LLVMBuildUIToFP(self.llbuilder, val, dest_ty.to_ref(), noname()) llvm::LLVMBuildUIToFP(self.llbuilder, val, dest_ty, noname())
} }
} }
pub fn sitofp(&self, val: ValueRef, dest_ty: Type) -> ValueRef { pub fn sitofp(&self, val: ValueRef, dest_ty: &'ll Type) -> ValueRef {
self.count_insn("sitofp"); self.count_insn("sitofp");
unsafe { unsafe {
llvm::LLVMBuildSIToFP(self.llbuilder, val, dest_ty.to_ref(), noname()) llvm::LLVMBuildSIToFP(self.llbuilder, val, dest_ty, noname())
} }
} }
pub fn fptrunc(&self, val: ValueRef, dest_ty: Type) -> ValueRef { pub fn fptrunc(&self, val: ValueRef, dest_ty: &'ll Type) -> ValueRef {
self.count_insn("fptrunc"); self.count_insn("fptrunc");
unsafe { unsafe {
llvm::LLVMBuildFPTrunc(self.llbuilder, val, dest_ty.to_ref(), noname()) llvm::LLVMBuildFPTrunc(self.llbuilder, val, dest_ty, noname())
} }
} }
pub fn fpext(&self, val: ValueRef, dest_ty: Type) -> ValueRef { pub fn fpext(&self, val: ValueRef, dest_ty: &'ll Type) -> ValueRef {
self.count_insn("fpext"); self.count_insn("fpext");
unsafe { unsafe {
llvm::LLVMBuildFPExt(self.llbuilder, val, dest_ty.to_ref(), noname()) llvm::LLVMBuildFPExt(self.llbuilder, val, dest_ty, noname())
} }
} }
pub fn ptrtoint(&self, val: ValueRef, dest_ty: Type) -> ValueRef { pub fn ptrtoint(&self, val: ValueRef, dest_ty: &'ll Type) -> ValueRef {
self.count_insn("ptrtoint"); self.count_insn("ptrtoint");
unsafe { unsafe {
llvm::LLVMBuildPtrToInt(self.llbuilder, val, dest_ty.to_ref(), noname()) llvm::LLVMBuildPtrToInt(self.llbuilder, val, dest_ty, noname())
} }
} }
pub fn inttoptr(&self, val: ValueRef, dest_ty: Type) -> ValueRef { pub fn inttoptr(&self, val: ValueRef, dest_ty: &'ll Type) -> ValueRef {
self.count_insn("inttoptr"); self.count_insn("inttoptr");
unsafe { unsafe {
llvm::LLVMBuildIntToPtr(self.llbuilder, val, dest_ty.to_ref(), noname()) llvm::LLVMBuildIntToPtr(self.llbuilder, val, dest_ty, noname())
} }
} }
pub fn bitcast(&self, val: ValueRef, dest_ty: Type) -> ValueRef { pub fn bitcast(&self, val: ValueRef, dest_ty: &'ll Type) -> ValueRef {
self.count_insn("bitcast"); self.count_insn("bitcast");
unsafe { unsafe {
llvm::LLVMBuildBitCast(self.llbuilder, val, dest_ty.to_ref(), noname()) llvm::LLVMBuildBitCast(self.llbuilder, val, dest_ty, noname())
} }
} }
pub fn zext_or_bitcast(&self, val: ValueRef, dest_ty: Type) -> ValueRef { pub fn zext_or_bitcast(&self, val: ValueRef, dest_ty: &'ll Type) -> ValueRef {
self.count_insn("zextorbitcast"); self.count_insn("zextorbitcast");
unsafe { unsafe {
llvm::LLVMBuildZExtOrBitCast(self.llbuilder, val, dest_ty.to_ref(), noname()) llvm::LLVMBuildZExtOrBitCast(self.llbuilder, val, dest_ty, noname())
} }
} }
pub fn sext_or_bitcast(&self, val: ValueRef, dest_ty: Type) -> ValueRef { pub fn sext_or_bitcast(&self, val: ValueRef, dest_ty: &'ll Type) -> ValueRef {
self.count_insn("sextorbitcast"); self.count_insn("sextorbitcast");
unsafe { unsafe {
llvm::LLVMBuildSExtOrBitCast(self.llbuilder, val, dest_ty.to_ref(), noname()) llvm::LLVMBuildSExtOrBitCast(self.llbuilder, val, dest_ty, noname())
} }
} }
pub fn trunc_or_bitcast(&self, val: ValueRef, dest_ty: Type) -> ValueRef { pub fn trunc_or_bitcast(&self, val: ValueRef, dest_ty: &'ll Type) -> ValueRef {
self.count_insn("truncorbitcast"); self.count_insn("truncorbitcast");
unsafe { unsafe {
llvm::LLVMBuildTruncOrBitCast(self.llbuilder, val, dest_ty.to_ref(), noname()) llvm::LLVMBuildTruncOrBitCast(self.llbuilder, val, dest_ty, noname())
} }
} }
pub fn cast(&self, op: Opcode, val: ValueRef, dest_ty: Type) -> ValueRef { pub fn cast(&self, op: Opcode, val: ValueRef, dest_ty: &'ll Type) -> ValueRef {
self.count_insn("cast"); self.count_insn("cast");
unsafe { unsafe {
llvm::LLVMBuildCast(self.llbuilder, op, val, dest_ty.to_ref(), noname()) llvm::LLVMBuildCast(self.llbuilder, op, val, dest_ty, noname())
} }
} }
pub fn pointercast(&self, val: ValueRef, dest_ty: Type) -> ValueRef { pub fn pointercast(&self, val: ValueRef, dest_ty: &'ll Type) -> ValueRef {
self.count_insn("pointercast"); self.count_insn("pointercast");
unsafe { unsafe {
llvm::LLVMBuildPointerCast(self.llbuilder, val, dest_ty.to_ref(), noname()) llvm::LLVMBuildPointerCast(self.llbuilder, val, dest_ty, noname())
} }
} }
pub fn intcast(&self, val: ValueRef, dest_ty: Type, is_signed: bool) -> ValueRef { pub fn intcast(&self, val: ValueRef, dest_ty: &'ll Type, is_signed: bool) -> ValueRef {
self.count_insn("intcast"); self.count_insn("intcast");
unsafe { unsafe {
llvm::LLVMRustBuildIntCast(self.llbuilder, val, dest_ty.to_ref(), is_signed) llvm::LLVMRustBuildIntCast(self.llbuilder, val, dest_ty, is_signed)
} }
} }
pub fn fpcast(&self, val: ValueRef, dest_ty: Type) -> ValueRef { pub fn fpcast(&self, val: ValueRef, dest_ty: &'ll Type) -> ValueRef {
self.count_insn("fpcast"); self.count_insn("fpcast");
unsafe { unsafe {
llvm::LLVMBuildFPCast(self.llbuilder, val, dest_ty.to_ref(), noname()) llvm::LLVMBuildFPCast(self.llbuilder, val, dest_ty, noname())
} }
} }
@ -828,14 +828,14 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
} }
/* Miscellaneous instructions */ /* Miscellaneous instructions */
pub fn empty_phi(&self, ty: Type) -> ValueRef { pub fn empty_phi(&self, ty: &'ll Type) -> ValueRef {
self.count_insn("emptyphi"); self.count_insn("emptyphi");
unsafe { unsafe {
llvm::LLVMBuildPhi(self.llbuilder, ty.to_ref(), noname()) llvm::LLVMBuildPhi(self.llbuilder, ty, noname())
} }
} }
pub fn phi(&self, ty: Type, vals: &[ValueRef], bbs: &[BasicBlockRef]) -> ValueRef { pub fn phi(&self, ty: &'ll Type, vals: &[ValueRef], bbs: &[BasicBlockRef]) -> ValueRef {
assert_eq!(vals.len(), bbs.len()); assert_eq!(vals.len(), bbs.len());
let phi = self.empty_phi(ty); let phi = self.empty_phi(ty);
self.count_insn("addincoming"); self.count_insn("addincoming");
@ -865,7 +865,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
self.count_insn("inlineasm"); self.count_insn("inlineasm");
let comment_text = CString::new(comment_text).unwrap(); let comment_text = CString::new(comment_text).unwrap();
let asm = unsafe { let asm = unsafe {
llvm::LLVMConstInlineAsm(Type::func(&[], &Type::void(self.cx)).to_ref(), llvm::LLVMConstInlineAsm(Type::func(&[], Type::void(self.cx)),
comment_text.as_ptr(), noname(), False, comment_text.as_ptr(), noname(), False,
False) False)
}; };
@ -874,7 +874,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
} }
pub fn inline_asm_call(&self, asm: *const c_char, cons: *const c_char, pub fn inline_asm_call(&self, asm: *const c_char, cons: *const c_char,
inputs: &[ValueRef], output: Type, inputs: &[ValueRef], output: &'ll Type,
volatile: bool, alignstack: bool, volatile: bool, alignstack: bool,
dia: AsmDialect) -> ValueRef { dia: AsmDialect) -> ValueRef {
self.count_insn("inlineasm"); self.count_insn("inlineasm");
@ -890,10 +890,10 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
}).collect::<Vec<_>>(); }).collect::<Vec<_>>();
debug!("Asm Output Type: {:?}", output); debug!("Asm Output Type: {:?}", output);
let fty = Type::func(&argtys[..], &output); let fty = Type::func(&argtys[..], output);
unsafe { unsafe {
let v = llvm::LLVMRustInlineAsm( let v = llvm::LLVMRustInlineAsm(
fty.to_ref(), asm, cons, volatile, alignstack, dia); fty, asm, cons, volatile, alignstack, dia);
self.call(v, inputs, None) self.call(v, inputs, None)
} }
} }
@ -946,10 +946,10 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
} }
} }
pub fn va_arg(&self, list: ValueRef, ty: Type) -> ValueRef { pub fn va_arg(&self, list: ValueRef, ty: &'ll Type) -> ValueRef {
self.count_insn("vaarg"); self.count_insn("vaarg");
unsafe { unsafe {
llvm::LLVMBuildVAArg(self.llbuilder, list, ty.to_ref(), noname()) llvm::LLVMBuildVAArg(self.llbuilder, list, ty, noname())
} }
} }
@ -977,9 +977,9 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
pub fn vector_splat(&self, num_elts: usize, elt: ValueRef) -> ValueRef { pub fn vector_splat(&self, num_elts: usize, elt: ValueRef) -> ValueRef {
unsafe { unsafe {
let elt_ty = val_ty(elt); let elt_ty = val_ty(elt);
let undef = llvm::LLVMGetUndef(Type::vector(&elt_ty, num_elts as u64).to_ref()); let undef = llvm::LLVMGetUndef(Type::vector(elt_ty, num_elts as u64));
let vec = self.insert_element(undef, elt, C_i32(self.cx, 0)); let vec = self.insert_element(undef, elt, C_i32(self.cx, 0));
let vec_i32_ty = Type::vector(&Type::i32(self.cx), num_elts as u64); let vec_i32_ty = Type::vector(Type::i32(self.cx), num_elts as u64);
self.shuffle_vector(vec, undef, C_null(vec_i32_ty)) self.shuffle_vector(vec, undef, C_null(vec_i32_ty))
} }
} }
@ -1164,11 +1164,11 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
} }
} }
pub fn landing_pad(&self, ty: Type, pers_fn: ValueRef, pub fn landing_pad(&self, ty: &'ll Type, pers_fn: ValueRef,
num_clauses: usize) -> ValueRef { num_clauses: usize) -> ValueRef {
self.count_insn("landingpad"); self.count_insn("landingpad");
unsafe { unsafe {
llvm::LLVMBuildLandingPad(self.llbuilder, ty.to_ref(), pers_fn, llvm::LLVMBuildLandingPad(self.llbuilder, ty, pers_fn,
num_clauses as c_uint, noname()) num_clauses as c_uint, noname())
} }
} }

View File

@ -112,41 +112,42 @@ impl Funclet {
} }
} }
pub fn val_ty(v: ValueRef) -> Type { // TODO: use proper lifetime in return type
pub fn val_ty(v: ValueRef) -> &'static Type {
unsafe { unsafe {
Type::from_ref(llvm::LLVMTypeOf(v)) llvm::LLVMTypeOf(&*v)
} }
} }
// LLVM constant constructors. // LLVM constant constructors.
pub fn C_null(t: Type) -> ValueRef { pub fn C_null(t: &Type) -> ValueRef {
unsafe { unsafe {
llvm::LLVMConstNull(t.to_ref()) llvm::LLVMConstNull(t)
} }
} }
pub fn C_undef(t: Type) -> ValueRef { pub fn C_undef(t: &Type) -> ValueRef {
unsafe { unsafe {
llvm::LLVMGetUndef(t.to_ref()) llvm::LLVMGetUndef(t)
} }
} }
pub fn C_int(t: Type, i: i64) -> ValueRef { pub fn C_int(t: &Type, i: i64) -> ValueRef {
unsafe { unsafe {
llvm::LLVMConstInt(t.to_ref(), i as u64, True) llvm::LLVMConstInt(t, i as u64, True)
} }
} }
pub fn C_uint(t: Type, i: u64) -> ValueRef { pub fn C_uint(t: &Type, i: u64) -> ValueRef {
unsafe { unsafe {
llvm::LLVMConstInt(t.to_ref(), i, False) llvm::LLVMConstInt(t, i, False)
} }
} }
pub fn C_uint_big(t: Type, u: u128) -> ValueRef { pub fn C_uint_big(t: &Type, u: u128) -> ValueRef {
unsafe { unsafe {
let words = [u as u64, (u >> 64) as u64]; let words = [u as u64, (u >> 64) as u64];
llvm::LLVMConstIntOfArbitraryPrecision(t.to_ref(), 2, words.as_ptr()) llvm::LLVMConstIntOfArbitraryPrecision(t, 2, words.as_ptr())
} }
} }
@ -233,9 +234,9 @@ pub fn C_struct_in_context(llcx: &llvm::Context, elts: &[ValueRef], packed: bool
} }
} }
pub fn C_array(ty: Type, elts: &[ValueRef]) -> ValueRef { pub fn C_array(ty: &Type, elts: &[ValueRef]) -> ValueRef {
unsafe { unsafe {
return llvm::LLVMConstArray(ty.to_ref(), elts.as_ptr(), elts.len() as c_uint); return llvm::LLVMConstArray(ty, elts.as_ptr(), elts.len() as c_uint);
} }
} }
@ -345,8 +346,8 @@ pub fn langcall(tcx: TyCtxt,
// all shifts). For 32- and 64-bit types, this matches the semantics // all shifts). For 32- and 64-bit types, this matches the semantics
// of Java. (See related discussion on #1877 and #10183.) // of Java. (See related discussion on #1877 and #10183.)
pub fn build_unchecked_lshift<'a, 'tcx>( pub fn build_unchecked_lshift(
bx: &Builder<'a, 'tcx>, bx: &Builder<'a, 'll, 'tcx>,
lhs: ValueRef, lhs: ValueRef,
rhs: ValueRef rhs: ValueRef
) -> ValueRef { ) -> ValueRef {
@ -356,8 +357,8 @@ pub fn build_unchecked_lshift<'a, 'tcx>(
bx.shl(lhs, rhs) bx.shl(lhs, rhs)
} }
pub fn build_unchecked_rshift<'a, 'tcx>( pub fn build_unchecked_rshift(
bx: &Builder<'a, 'tcx>, lhs_t: Ty<'tcx>, lhs: ValueRef, rhs: ValueRef bx: &Builder<'a, 'll, 'tcx>, lhs_t: Ty<'tcx>, lhs: ValueRef, rhs: ValueRef
) -> ValueRef { ) -> ValueRef {
let rhs = base::cast_shift_expr_rhs(bx, hir::BinOpKind::Shr, lhs, rhs); let rhs = base::cast_shift_expr_rhs(bx, hir::BinOpKind::Shr, lhs, rhs);
// #1877, #10183: Ensure that input is always valid // #1877, #10183: Ensure that input is always valid
@ -370,15 +371,15 @@ pub fn build_unchecked_rshift<'a, 'tcx>(
} }
} }
fn shift_mask_rhs<'a, 'tcx>(bx: &Builder<'a, 'tcx>, rhs: ValueRef) -> ValueRef { fn shift_mask_rhs(bx: &Builder<'a, 'll, 'tcx>, rhs: ValueRef) -> ValueRef {
let rhs_llty = val_ty(rhs); let rhs_llty = val_ty(rhs);
bx.and(rhs, shift_mask_val(bx, rhs_llty, rhs_llty, false)) bx.and(rhs, shift_mask_val(bx, rhs_llty, rhs_llty, false))
} }
pub fn shift_mask_val<'a, 'tcx>( pub fn shift_mask_val(
bx: &Builder<'a, 'tcx>, bx: &Builder<'a, 'll, 'tcx>,
llty: Type, llty: &'ll Type,
mask_llty: Type, mask_llty: &'ll Type,
invert: bool invert: bool
) -> ValueRef { ) -> ValueRef {
let kind = llty.kind(); let kind = llty.kind();

View File

@ -31,15 +31,15 @@ use rustc::hir::{self, CodegenFnAttrs, CodegenFnAttrFlags};
use std::ffi::{CStr, CString}; use std::ffi::{CStr, CString};
pub fn ptrcast(val: ValueRef, ty: Type) -> ValueRef { pub fn ptrcast(val: ValueRef, ty: &Type) -> ValueRef {
unsafe { unsafe {
llvm::LLVMConstPointerCast(val, ty.to_ref()) llvm::LLVMConstPointerCast(val, ty)
} }
} }
pub fn bitcast(val: ValueRef, ty: Type) -> ValueRef { pub fn bitcast(val: ValueRef, ty: &Type) -> ValueRef {
unsafe { unsafe {
llvm::LLVMConstBitCast(val, ty.to_ref()) llvm::LLVMConstBitCast(val, ty)
} }
} }
@ -294,7 +294,7 @@ pub fn codegen_static<'a, 'tcx>(
let mut val_llty = val_ty(v); let mut val_llty = val_ty(v);
let v = if val_llty == Type::i1(cx) { let v = if val_llty == Type::i1(cx) {
val_llty = Type::i8(cx); val_llty = Type::i8(cx);
llvm::LLVMConstZExt(v, val_llty.to_ref()) llvm::LLVMConstZExt(v, val_llty)
} else { } else {
v v
}; };
@ -316,7 +316,7 @@ pub fn codegen_static<'a, 'tcx>(
let visibility = llvm::LLVMRustGetVisibility(g); let visibility = llvm::LLVMRustGetVisibility(g);
let new_g = llvm::LLVMRustGetOrInsertGlobal( let new_g = llvm::LLVMRustGetOrInsertGlobal(
cx.llmod, name_string.as_ptr(), val_llty.to_ref()); cx.llmod, name_string.as_ptr(), val_llty);
llvm::LLVMRustSetLinkage(new_g, linkage); llvm::LLVMRustSetLinkage(new_g, linkage);
llvm::LLVMRustSetVisibility(new_g, visibility); llvm::LLVMRustSetVisibility(new_g, visibility);
@ -411,7 +411,7 @@ pub fn codegen_static<'a, 'tcx>(
if attrs.flags.contains(CodegenFnAttrFlags::USED) { if attrs.flags.contains(CodegenFnAttrFlags::USED) {
// This static will be stored in the llvm.used variable which is an array of i8* // This static will be stored in the llvm.used variable which is an array of i8*
let cast = llvm::LLVMConstPointerCast(g, Type::i8p(cx).to_ref()); let cast = llvm::LLVMConstPointerCast(g, Type::i8p(cx));
cx.used_statics.borrow_mut().push(cast); cx.used_statics.borrow_mut().push(cast);
} }
} }

View File

@ -89,10 +89,10 @@ pub struct CodegenCx<'a, 'tcx: 'a> {
/// See http://llvm.org/docs/LangRef.html#the-llvm-used-global-variable for details /// See http://llvm.org/docs/LangRef.html#the-llvm-used-global-variable for details
pub used_statics: RefCell<Vec<ValueRef>>, pub used_statics: RefCell<Vec<ValueRef>>,
pub lltypes: RefCell<FxHashMap<(Ty<'tcx>, Option<usize>), Type>>, pub lltypes: RefCell<FxHashMap<(Ty<'tcx>, Option<usize>), &'a Type>>,
pub scalar_lltypes: RefCell<FxHashMap<Ty<'tcx>, Type>>, pub scalar_lltypes: RefCell<FxHashMap<Ty<'tcx>, &'a Type>>,
pub pointee_infos: RefCell<FxHashMap<(Ty<'tcx>, Size), Option<PointeeInfo>>>, pub pointee_infos: RefCell<FxHashMap<(Ty<'tcx>, Size), Option<PointeeInfo>>>,
pub isize_ty: Type, pub isize_ty: &'a Type,
pub dbg_cx: Option<debuginfo::CrateDebugContext<'a, 'tcx>>, pub dbg_cx: Option<debuginfo::CrateDebugContext<'a, 'tcx>>,
@ -373,7 +373,7 @@ impl<'b, 'tcx> CodegenCx<'b, 'tcx> {
} else { } else {
"rust_eh_personality" "rust_eh_personality"
}; };
let fty = Type::variadic_func(&[], &Type::i32(self)); let fty = Type::variadic_func(&[], Type::i32(self));
declare::declare_cfn(self, name, fty) declare::declare_cfn(self, name, fty)
} }
}; };
@ -439,25 +439,25 @@ impl<'b, 'tcx> CodegenCx<'b, 'tcx> {
} }
} }
impl<'a, 'tcx> ty::layout::HasDataLayout for &'a CodegenCx<'a, 'tcx> { impl ty::layout::HasDataLayout for &'a CodegenCx<'ll, 'tcx> {
fn data_layout(&self) -> &ty::layout::TargetDataLayout { fn data_layout(&self) -> &ty::layout::TargetDataLayout {
&self.tcx.data_layout &self.tcx.data_layout
} }
} }
impl<'a, 'tcx> HasTargetSpec for &'a CodegenCx<'a, 'tcx> { impl HasTargetSpec for &'a CodegenCx<'ll, 'tcx> {
fn target_spec(&self) -> &Target { fn target_spec(&self) -> &Target {
&self.tcx.sess.target.target &self.tcx.sess.target.target
} }
} }
impl<'a, 'tcx> ty::layout::HasTyCtxt<'tcx> for &'a CodegenCx<'a, 'tcx> { impl ty::layout::HasTyCtxt<'tcx> for &'a CodegenCx<'ll, 'tcx> {
fn tcx<'b>(&'b self) -> TyCtxt<'b, 'tcx, 'tcx> { fn tcx<'b>(&'b self) -> TyCtxt<'b, 'tcx, 'tcx> {
self.tcx self.tcx
} }
} }
impl<'a, 'tcx> LayoutOf for &'a CodegenCx<'a, 'tcx> { impl LayoutOf for &'a CodegenCx<'ll, 'tcx> {
type Ty = Ty<'tcx>; type Ty = Ty<'tcx>;
type TyLayout = TyLayout<'tcx>; type TyLayout = TyLayout<'tcx>;
@ -475,7 +475,7 @@ fn declare_intrinsic(cx: &CodegenCx, key: &str) -> Option<ValueRef> {
macro_rules! ifn { macro_rules! ifn {
($name:expr, fn() -> $ret:expr) => ( ($name:expr, fn() -> $ret:expr) => (
if key == $name { if key == $name {
let f = declare::declare_cfn(cx, $name, Type::func(&[], &$ret)); let f = declare::declare_cfn(cx, $name, Type::func(&[], $ret));
llvm::SetUnnamedAddr(f, false); llvm::SetUnnamedAddr(f, false);
cx.intrinsics.borrow_mut().insert($name, f.clone()); cx.intrinsics.borrow_mut().insert($name, f.clone());
return Some(f); return Some(f);
@ -483,7 +483,7 @@ fn declare_intrinsic(cx: &CodegenCx, key: &str) -> Option<ValueRef> {
); );
($name:expr, fn(...) -> $ret:expr) => ( ($name:expr, fn(...) -> $ret:expr) => (
if key == $name { if key == $name {
let f = declare::declare_cfn(cx, $name, Type::variadic_func(&[], &$ret)); let f = declare::declare_cfn(cx, $name, Type::variadic_func(&[], $ret));
llvm::SetUnnamedAddr(f, false); llvm::SetUnnamedAddr(f, false);
cx.intrinsics.borrow_mut().insert($name, f.clone()); cx.intrinsics.borrow_mut().insert($name, f.clone());
return Some(f); return Some(f);
@ -491,7 +491,7 @@ fn declare_intrinsic(cx: &CodegenCx, key: &str) -> Option<ValueRef> {
); );
($name:expr, fn($($arg:expr),*) -> $ret:expr) => ( ($name:expr, fn($($arg:expr),*) -> $ret:expr) => (
if key == $name { if key == $name {
let f = declare::declare_cfn(cx, $name, Type::func(&[$($arg),*], &$ret)); let f = declare::declare_cfn(cx, $name, Type::func(&[$($arg),*], $ret));
llvm::SetUnnamedAddr(f, false); llvm::SetUnnamedAddr(f, false);
cx.intrinsics.borrow_mut().insert($name, f.clone()); cx.intrinsics.borrow_mut().insert($name, f.clone());
return Some(f); return Some(f);
@ -513,14 +513,14 @@ fn declare_intrinsic(cx: &CodegenCx, key: &str) -> Option<ValueRef> {
let t_f32 = Type::f32(cx); let t_f32 = Type::f32(cx);
let t_f64 = Type::f64(cx); let t_f64 = Type::f64(cx);
let t_v2f32 = Type::vector(&t_f32, 2); let t_v2f32 = Type::vector(t_f32, 2);
let t_v4f32 = Type::vector(&t_f32, 4); let t_v4f32 = Type::vector(t_f32, 4);
let t_v8f32 = Type::vector(&t_f32, 8); let t_v8f32 = Type::vector(t_f32, 8);
let t_v16f32 = Type::vector(&t_f32, 16); let t_v16f32 = Type::vector(t_f32, 16);
let t_v2f64 = Type::vector(&t_f64, 2); let t_v2f64 = Type::vector(t_f64, 2);
let t_v4f64 = Type::vector(&t_f64, 4); let t_v4f64 = Type::vector(t_f64, 4);
let t_v8f64 = Type::vector(&t_f64, 8); let t_v8f64 = Type::vector(t_f64, 8);
ifn!("llvm.memcpy.p0i8.p0i8.i16", fn(i8p, i8p, t_i16, t_i32, i1) -> void); ifn!("llvm.memcpy.p0i8.p0i8.i16", fn(i8p, i8p, t_i16, t_i32, i1) -> void);
ifn!("llvm.memcpy.p0i8.p0i8.i32", fn(i8p, i8p, t_i32, t_i32, i1) -> void); ifn!("llvm.memcpy.p0i8.p0i8.i32", fn(i8p, i8p, t_i32, t_i32, i1) -> void);

View File

@ -54,7 +54,7 @@ pub fn get_or_insert_gdb_debug_scripts_section_global(cx: &CodegenCx)
let section_contents = b"\x01gdb_load_rust_pretty_printers.py\0"; let section_contents = b"\x01gdb_load_rust_pretty_printers.py\0";
unsafe { unsafe {
let llvm_type = Type::array(&Type::i8(cx), let llvm_type = Type::array(Type::i8(cx),
section_contents.len() as u64); section_contents.len() as u64);
let section_var = declare::define_global(cx, section_var_name, let section_var = declare::define_global(cx, section_var_name,

View File

@ -471,14 +471,16 @@ pub fn create_function_debug_context<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>,
} }
} }
pub fn declare_local<'a, 'tcx>(bx: &Builder<'a, 'tcx>, pub fn declare_local(
dbg_context: &FunctionDebugContext, bx: &Builder<'a, 'll, 'tcx>,
variable_name: ast::Name, dbg_context: &FunctionDebugContext,
variable_type: Ty<'tcx>, variable_name: ast::Name,
scope_metadata: DIScope, variable_type: Ty<'tcx>,
variable_access: VariableAccess, scope_metadata: DIScope,
variable_kind: VariableKind, variable_access: VariableAccess,
span: Span) { variable_kind: VariableKind,
span: Span,
) {
assert!(!dbg_context.get_ref(span).source_locations_enabled.get()); assert!(!dbg_context.get_ref(span).source_locations_enabled.get());
let cx = bx.cx; let cx = bx.cx;

View File

@ -49,8 +49,7 @@ pub fn span_start(cx: &CodegenCx, span: Span) -> syntax_pos::Loc {
} }
#[inline] #[inline]
pub fn debug_context<'a, 'tcx>(cx: &'a CodegenCx<'a, 'tcx>) pub fn debug_context(cx: &'a CodegenCx<'ll, 'tcx>) -> &'a CrateDebugContext<'a, 'tcx> {
-> &'a CrateDebugContext<'a, 'tcx> {
cx.dbg_cx.as_ref().unwrap() cx.dbg_cx.as_ref().unwrap()
} }

View File

@ -40,13 +40,13 @@ use std::ffi::CString;
/// ///
/// If theres a value with the same name already declared, the function will /// If theres a value with the same name already declared, the function will
/// return its ValueRef instead. /// return its ValueRef instead.
pub fn declare_global(cx: &CodegenCx, name: &str, ty: Type) -> llvm::ValueRef { pub fn declare_global(cx: &CodegenCx, name: &str, ty: &Type) -> llvm::ValueRef {
debug!("declare_global(name={:?})", name); debug!("declare_global(name={:?})", name);
let namebuf = CString::new(name).unwrap_or_else(|_|{ let namebuf = CString::new(name).unwrap_or_else(|_|{
bug!("name {:?} contains an interior null byte", name) bug!("name {:?} contains an interior null byte", name)
}); });
unsafe { unsafe {
llvm::LLVMRustGetOrInsertGlobal(cx.llmod, namebuf.as_ptr(), ty.to_ref()) llvm::LLVMRustGetOrInsertGlobal(cx.llmod, namebuf.as_ptr(), ty)
} }
} }
@ -55,13 +55,13 @@ pub fn declare_global(cx: &CodegenCx, name: &str, ty: Type) -> llvm::ValueRef {
/// ///
/// If theres a value with the same name already declared, the function will /// If theres a value with the same name already declared, the function will
/// update the declaration and return existing ValueRef instead. /// update the declaration and return existing ValueRef instead.
fn declare_raw_fn(cx: &CodegenCx, name: &str, callconv: llvm::CallConv, ty: Type) -> ValueRef { fn declare_raw_fn(cx: &CodegenCx, name: &str, callconv: llvm::CallConv, ty: &Type) -> ValueRef {
debug!("declare_raw_fn(name={:?}, ty={:?})", name, ty); debug!("declare_raw_fn(name={:?}, ty={:?})", name, ty);
let namebuf = CString::new(name).unwrap_or_else(|_|{ let namebuf = CString::new(name).unwrap_or_else(|_|{
bug!("name {:?} contains an interior null byte", name) bug!("name {:?} contains an interior null byte", name)
}); });
let llfn = unsafe { let llfn = unsafe {
llvm::LLVMRustGetOrInsertFunction(cx.llmod, namebuf.as_ptr(), ty.to_ref()) llvm::LLVMRustGetOrInsertFunction(cx.llmod, namebuf.as_ptr(), ty)
}; };
llvm::SetFunctionCallConv(llfn, callconv); llvm::SetFunctionCallConv(llfn, callconv);
@ -115,7 +115,7 @@ fn declare_raw_fn(cx: &CodegenCx, name: &str, callconv: llvm::CallConv, ty: Type
/// ///
/// If theres a value with the same name already declared, the function will /// If theres a value with the same name already declared, the function will
/// update the declaration and return existing ValueRef instead. /// update the declaration and return existing ValueRef instead.
pub fn declare_cfn(cx: &CodegenCx, name: &str, fn_type: Type) -> ValueRef { pub fn declare_cfn(cx: &CodegenCx, name: &str, fn_type: &Type) -> ValueRef {
declare_raw_fn(cx, name, llvm::CCallConv, fn_type) declare_raw_fn(cx, name, llvm::CCallConv, fn_type)
} }
@ -154,7 +154,7 @@ pub fn declare_fn<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>, name: &str,
/// return None if the name already has a definition associated with it. In that /// return None if the name already has a definition associated with it. In that
/// case an error should be reported to the user, because it usually happens due /// case an error should be reported to the user, because it usually happens due
/// to users fault (e.g. misuse of #[no_mangle] or #[export_name] attributes). /// to users fault (e.g. misuse of #[no_mangle] or #[export_name] attributes).
pub fn define_global(cx: &CodegenCx, name: &str, ty: Type) -> Option<ValueRef> { pub fn define_global(cx: &CodegenCx, name: &str, ty: &Type) -> Option<ValueRef> {
if get_defined_value(cx, name).is_some() { if get_defined_value(cx, name).is_some() {
None None
} else { } else {

View File

@ -23,7 +23,7 @@ use rustc::ty::layout::LayoutOf;
use rustc::ty::{self, Ty}; use rustc::ty::{self, Ty};
use value::Value; use value::Value;
pub fn size_and_align_of_dst<'a, 'tcx>(bx: &Builder<'a, 'tcx>, t: Ty<'tcx>, info: ValueRef) pub fn size_and_align_of_dst(bx: &Builder<'a, 'll, 'tcx>, t: Ty<'tcx>, info: ValueRef)
-> (ValueRef, ValueRef) { -> (ValueRef, ValueRef) {
debug!("calculate size of DST: {}; with lost info: {:?}", debug!("calculate size of DST: {}; with lost info: {:?}",
t, Value(info)); t, Value(info));

View File

@ -85,12 +85,14 @@ fn get_simple_intrinsic(cx: &CodegenCx, name: &str) -> Option<ValueRef> {
/// Remember to add all intrinsics here, in librustc_typeck/check/mod.rs, /// Remember to add all intrinsics here, in librustc_typeck/check/mod.rs,
/// and in libcore/intrinsics.rs; if you need access to any llvm intrinsics, /// and in libcore/intrinsics.rs; if you need access to any llvm intrinsics,
/// add them to librustc_codegen_llvm/context.rs /// add them to librustc_codegen_llvm/context.rs
pub fn codegen_intrinsic_call<'a, 'tcx>(bx: &Builder<'a, 'tcx>, pub fn codegen_intrinsic_call(
callee_ty: Ty<'tcx>, bx: &Builder<'a, 'll, 'tcx>,
fn_ty: &FnType<'tcx, Ty<'tcx>>, callee_ty: Ty<'tcx>,
args: &[OperandRef<'tcx>], fn_ty: &FnType<'tcx, Ty<'tcx>>,
llresult: ValueRef, args: &[OperandRef<'tcx>],
span: Span) { llresult: ValueRef,
span: Span,
) {
let cx = bx.cx; let cx = bx.cx;
let tcx = cx.tcx; let tcx = cx.tcx;
@ -545,7 +547,7 @@ pub fn codegen_intrinsic_call<'a, 'tcx>(bx: &Builder<'a, 'tcx>,
assert_eq!(x.len(), 1); assert_eq!(x.len(), 1);
x.into_iter().next().unwrap() x.into_iter().next().unwrap()
} }
fn ty_to_type(cx: &CodegenCx, t: &intrinsics::Type) -> Vec<Type> { fn ty_to_type(cx: &CodegenCx<'ll, '_>, t: &intrinsics::Type) -> Vec<&'ll Type> {
use intrinsics::Type::*; use intrinsics::Type::*;
match *t { match *t {
Void => vec![Type::void(cx)], Void => vec![Type::void(cx)],
@ -567,7 +569,7 @@ pub fn codegen_intrinsic_call<'a, 'tcx>(bx: &Builder<'a, 'tcx>,
Vector(ref t, ref llvm_elem, length) => { Vector(ref t, ref llvm_elem, length) => {
let t = llvm_elem.as_ref().unwrap_or(t); let t = llvm_elem.as_ref().unwrap_or(t);
let elem = one(ty_to_type(cx, t)); let elem = one(ty_to_type(cx, t));
vec![Type::vector(&elem, length as u64)] vec![Type::vector(elem, length as u64)]
} }
Aggregate(false, ref contents) => { Aggregate(false, ref contents) => {
let elems = contents.iter() let elems = contents.iter()
@ -587,10 +589,11 @@ pub fn codegen_intrinsic_call<'a, 'tcx>(bx: &Builder<'a, 'tcx>,
// qux` to be converted into `foo, bar, baz, qux`, integer // qux` to be converted into `foo, bar, baz, qux`, integer
// arguments to be truncated as needed and pointers to be // arguments to be truncated as needed and pointers to be
// cast. // cast.
fn modify_as_needed<'a, 'tcx>(bx: &Builder<'a, 'tcx>, fn modify_as_needed(
t: &intrinsics::Type, bx: &Builder<'a, 'll, 'tcx>,
arg: &OperandRef<'tcx>) t: &intrinsics::Type,
-> Vec<ValueRef> arg: &OperandRef<'tcx>,
) -> Vec<ValueRef>
{ {
match *t { match *t {
intrinsics::Type::Aggregate(true, ref contents) => { intrinsics::Type::Aggregate(true, ref contents) => {
@ -616,7 +619,7 @@ pub fn codegen_intrinsic_call<'a, 'tcx>(bx: &Builder<'a, 'tcx>,
} }
intrinsics::Type::Vector(_, Some(ref llvm_elem), length) => { intrinsics::Type::Vector(_, Some(ref llvm_elem), length) => {
let llvm_elem = one(ty_to_type(bx.cx, llvm_elem)); let llvm_elem = one(ty_to_type(bx.cx, llvm_elem));
vec![bx.bitcast(arg.immediate(), Type::vector(&llvm_elem, length as u64))] vec![bx.bitcast(arg.immediate(), Type::vector(llvm_elem, length as u64))]
} }
intrinsics::Type::Integer(_, width, llvm_width) if width != llvm_width => { intrinsics::Type::Integer(_, width, llvm_width) if width != llvm_width => {
// the LLVM intrinsic uses a smaller integer // the LLVM intrinsic uses a smaller integer
@ -644,7 +647,7 @@ pub fn codegen_intrinsic_call<'a, 'tcx>(bx: &Builder<'a, 'tcx>,
intrinsics::IntrinsicDef::Named(name) => { intrinsics::IntrinsicDef::Named(name) => {
let f = declare::declare_cfn(cx, let f = declare::declare_cfn(cx,
name, name,
Type::func(&inputs, &outputs)); Type::func(&inputs, outputs));
bx.call(f, &llargs, None) bx.call(f, &llargs, None)
} }
}; };
@ -677,14 +680,15 @@ pub fn codegen_intrinsic_call<'a, 'tcx>(bx: &Builder<'a, 'tcx>,
} }
} }
fn copy_intrinsic<'a, 'tcx>(bx: &Builder<'a, 'tcx>, fn copy_intrinsic(
allow_overlap: bool, bx: &Builder<'a, 'll, 'tcx>,
volatile: bool, allow_overlap: bool,
ty: Ty<'tcx>, volatile: bool,
dst: ValueRef, ty: Ty<'tcx>,
src: ValueRef, dst: ValueRef,
count: ValueRef) src: ValueRef,
-> ValueRef { count: ValueRef,
) -> ValueRef {
let cx = bx.cx; let cx = bx.cx;
let (size, align) = cx.size_and_align_of(ty); let (size, align) = cx.size_and_align_of(ty);
let size = C_usize(cx, size.bytes()); let size = C_usize(cx, size.bytes());
@ -712,8 +716,8 @@ fn copy_intrinsic<'a, 'tcx>(bx: &Builder<'a, 'tcx>,
None) None)
} }
fn memset_intrinsic<'a, 'tcx>( fn memset_intrinsic(
bx: &Builder<'a, 'tcx>, bx: &Builder<'a, 'll, 'tcx>,
volatile: bool, volatile: bool,
ty: Ty<'tcx>, ty: Ty<'tcx>,
dst: ValueRef, dst: ValueRef,
@ -728,8 +732,8 @@ fn memset_intrinsic<'a, 'tcx>(
call_memset(bx, dst, val, bx.mul(size, count), align, volatile) call_memset(bx, dst, val, bx.mul(size, count), align, volatile)
} }
fn try_intrinsic<'a, 'tcx>( fn try_intrinsic(
bx: &Builder<'a, 'tcx>, bx: &Builder<'a, 'll, 'tcx>,
cx: &CodegenCx, cx: &CodegenCx,
func: ValueRef, func: ValueRef,
data: ValueRef, data: ValueRef,
@ -754,12 +758,14 @@ fn try_intrinsic<'a, 'tcx>(
// instructions are meant to work for all targets, as of the time of this // instructions are meant to work for all targets, as of the time of this
// writing, however, LLVM does not recommend the usage of these new instructions // writing, however, LLVM does not recommend the usage of these new instructions
// as the old ones are still more optimized. // as the old ones are still more optimized.
fn codegen_msvc_try<'a, 'tcx>(bx: &Builder<'a, 'tcx>, fn codegen_msvc_try(
cx: &CodegenCx, bx: &Builder<'a, 'll, 'tcx>,
func: ValueRef, cx: &CodegenCx,
data: ValueRef, func: ValueRef,
local_ptr: ValueRef, data: ValueRef,
dest: ValueRef) { local_ptr: ValueRef,
dest: ValueRef,
) {
let llfn = get_rust_try_fn(cx, &mut |bx| { let llfn = get_rust_try_fn(cx, &mut |bx| {
let cx = bx.cx; let cx = bx.cx;
@ -862,12 +868,14 @@ fn codegen_msvc_try<'a, 'tcx>(bx: &Builder<'a, 'tcx>,
// function calling it, and that function may already have other personality // function calling it, and that function may already have other personality
// functions in play. By calling a shim we're guaranteed that our shim will have // functions in play. By calling a shim we're guaranteed that our shim will have
// the right personality function. // the right personality function.
fn codegen_gnu_try<'a, 'tcx>(bx: &Builder<'a, 'tcx>, fn codegen_gnu_try(
cx: &CodegenCx, bx: &Builder<'a, 'll, 'tcx>,
func: ValueRef, cx: &CodegenCx,
data: ValueRef, func: ValueRef,
local_ptr: ValueRef, data: ValueRef,
dest: ValueRef) { local_ptr: ValueRef,
dest: ValueRef,
) {
let llfn = get_rust_try_fn(cx, &mut |bx| { let llfn = get_rust_try_fn(cx, &mut |bx| {
let cx = bx.cx; let cx = bx.cx;
@ -922,12 +930,13 @@ fn codegen_gnu_try<'a, 'tcx>(bx: &Builder<'a, 'tcx>,
// Helper function to give a Block to a closure to codegen a shim function. // Helper function to give a Block to a closure to codegen a shim function.
// This is currently primarily used for the `try` intrinsic functions above. // This is currently primarily used for the `try` intrinsic functions above.
fn gen_fn<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>, fn gen_fn<'ll, 'tcx>(
name: &str, cx: &CodegenCx<'ll, 'tcx>,
inputs: Vec<Ty<'tcx>>, name: &str,
output: Ty<'tcx>, inputs: Vec<Ty<'tcx>>,
codegen: &mut dyn for<'b> FnMut(Builder<'b, 'tcx>)) output: Ty<'tcx>,
-> ValueRef { codegen: &mut dyn FnMut(Builder<'_, 'll, 'tcx>),
) -> ValueRef {
let rust_fn_ty = cx.tcx.mk_fn_ptr(ty::Binder::bind(cx.tcx.mk_fn_sig( let rust_fn_ty = cx.tcx.mk_fn_ptr(ty::Binder::bind(cx.tcx.mk_fn_sig(
inputs.into_iter(), inputs.into_iter(),
output, output,
@ -945,9 +954,10 @@ fn gen_fn<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>,
// catch exceptions. // catch exceptions.
// //
// This function is only generated once and is then cached. // This function is only generated once and is then cached.
fn get_rust_try_fn<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>, fn get_rust_try_fn<'ll, 'tcx>(
codegen: &mut dyn for<'b> FnMut(Builder<'b, 'tcx>)) cx: &CodegenCx<'ll, 'tcx>,
-> ValueRef { codegen: &mut dyn FnMut(Builder<'_, 'll, 'tcx>),
) -> ValueRef {
if let Some(llfn) = cx.rust_try_fn.get() { if let Some(llfn) = cx.rust_try_fn.get() {
return llfn; return llfn;
} }
@ -972,13 +982,13 @@ fn span_invalid_monomorphization_error(a: &Session, b: Span, c: &str) {
span_err!(a, b, E0511, "{}", c); span_err!(a, b, E0511, "{}", c);
} }
fn generic_simd_intrinsic<'a, 'tcx>( fn generic_simd_intrinsic(
bx: &Builder<'a, 'tcx>, bx: &Builder<'a, 'll, 'tcx>,
name: &str, name: &str,
callee_ty: Ty<'tcx>, callee_ty: Ty<'tcx>,
args: &[OperandRef<'tcx>], args: &[OperandRef<'tcx>],
ret_ty: Ty<'tcx>, ret_ty: Ty<'tcx>,
llret_ty: Type, llret_ty: &'ll Type,
span: Span span: Span
) -> Result<ValueRef, ()> { ) -> Result<ValueRef, ()> {
// macros for error handling: // macros for error handling:
@ -1145,19 +1155,20 @@ fn generic_simd_intrinsic<'a, 'tcx>(
} }
// truncate the mask to a vector of i1s // truncate the mask to a vector of i1s
let i1 = Type::i1(bx.cx); let i1 = Type::i1(bx.cx);
let i1xn = Type::vector(&i1, m_len as u64); let i1xn = Type::vector(i1, m_len as u64);
let m_i1s = bx.trunc(args[0].immediate(), i1xn); let m_i1s = bx.trunc(args[0].immediate(), i1xn);
return Ok(bx.select(m_i1s, args[1].immediate(), args[2].immediate())); return Ok(bx.select(m_i1s, args[1].immediate(), args[2].immediate()));
} }
fn simd_simple_float_intrinsic<'a, 'tcx>(name: &str, fn simd_simple_float_intrinsic(
in_elem: &::rustc::ty::TyS, name: &str,
in_ty: &::rustc::ty::TyS, in_elem: &::rustc::ty::TyS,
in_len: usize, in_ty: &::rustc::ty::TyS,
bx: &Builder<'a, 'tcx>, in_len: usize,
span: Span, bx: &Builder<'a, 'll, 'tcx>,
args: &[OperandRef<'tcx>]) span: Span,
-> Result<ValueRef, ()> { args: &[OperandRef<'tcx>],
) -> Result<ValueRef, ()> {
macro_rules! emit_error { macro_rules! emit_error {
($msg: tt) => { ($msg: tt) => {
emit_error!($msg, ) emit_error!($msg, )
@ -1283,8 +1294,8 @@ fn generic_simd_intrinsic<'a, 'tcx>(
} }
} }
fn llvm_vector_ty(cx: &CodegenCx, elem_ty: ty::Ty, vec_len: usize, fn llvm_vector_ty(cx: &CodegenCx<'ll, '_>, elem_ty: ty::Ty, vec_len: usize,
mut no_pointers: usize) -> Type { mut no_pointers: usize) -> &'ll Type {
// FIXME: use cx.layout_of(ty).llvm_type() ? // FIXME: use cx.layout_of(ty).llvm_type() ?
let mut elem_ty = match elem_ty.sty { let mut elem_ty = match elem_ty.sty {
ty::TyInt(v) => Type::int_from_ty(cx, v), ty::TyInt(v) => Type::int_from_ty(cx, v),
@ -1296,7 +1307,7 @@ fn generic_simd_intrinsic<'a, 'tcx>(
elem_ty = elem_ty.ptr_to(); elem_ty = elem_ty.ptr_to();
no_pointers -= 1; no_pointers -= 1;
} }
Type::vector(&elem_ty, vec_len as u64) Type::vector(elem_ty, vec_len as u64)
} }
@ -1379,7 +1390,7 @@ fn generic_simd_intrinsic<'a, 'tcx>(
// Truncate the mask vector to a vector of i1s: // Truncate the mask vector to a vector of i1s:
let (mask, mask_ty) = { let (mask, mask_ty) = {
let i1 = Type::i1(bx.cx); let i1 = Type::i1(bx.cx);
let i1xn = Type::vector(&i1, in_len as u64); let i1xn = Type::vector(i1, in_len as u64);
(bx.trunc(args[2].immediate(), i1xn), i1xn) (bx.trunc(args[2].immediate(), i1xn), i1xn)
}; };
@ -1395,7 +1406,7 @@ fn generic_simd_intrinsic<'a, 'tcx>(
llvm_elem_vec_str, llvm_pointer_vec_str); llvm_elem_vec_str, llvm_pointer_vec_str);
let f = declare::declare_cfn(bx.cx, &llvm_intrinsic, let f = declare::declare_cfn(bx.cx, &llvm_intrinsic,
Type::func(&[llvm_pointer_vec_ty, alignment_ty, mask_ty, Type::func(&[llvm_pointer_vec_ty, alignment_ty, mask_ty,
llvm_elem_vec_ty], &llvm_elem_vec_ty)); llvm_elem_vec_ty], llvm_elem_vec_ty));
llvm::SetUnnamedAddr(f, false); llvm::SetUnnamedAddr(f, false);
let v = bx.call(f, &[args[1].immediate(), alignment, mask, args[0].immediate()], let v = bx.call(f, &[args[1].immediate(), alignment, mask, args[0].immediate()],
None); None);
@ -1476,7 +1487,7 @@ fn generic_simd_intrinsic<'a, 'tcx>(
// Truncate the mask vector to a vector of i1s: // Truncate the mask vector to a vector of i1s:
let (mask, mask_ty) = { let (mask, mask_ty) = {
let i1 = Type::i1(bx.cx); let i1 = Type::i1(bx.cx);
let i1xn = Type::vector(&i1, in_len as u64); let i1xn = Type::vector(i1, in_len as u64);
(bx.trunc(args[2].immediate(), i1xn), i1xn) (bx.trunc(args[2].immediate(), i1xn), i1xn)
}; };
@ -1496,7 +1507,7 @@ fn generic_simd_intrinsic<'a, 'tcx>(
Type::func(&[llvm_elem_vec_ty, Type::func(&[llvm_elem_vec_ty,
llvm_pointer_vec_ty, llvm_pointer_vec_ty,
alignment_ty, alignment_ty,
mask_ty], &ret_t)); mask_ty], ret_t));
llvm::SetUnnamedAddr(f, false); llvm::SetUnnamedAddr(f, false);
let v = bx.call(f, &[args[0].immediate(), args[1].immediate(), alignment, mask], let v = bx.call(f, &[args[0].immediate(), args[1].immediate(), alignment, mask],
None); None);
@ -1629,7 +1640,7 @@ unsupported {} from `{}` with element `{}` of size `{}` to `{}`"#,
// boolean reductions operate on vectors of i1s: // boolean reductions operate on vectors of i1s:
let i1 = Type::i1(bx.cx); let i1 = Type::i1(bx.cx);
let i1xn = Type::vector(&i1, in_len as u64); let i1xn = Type::vector(i1, in_len as u64);
bx.trunc(args[0].immediate(), i1xn) bx.trunc(args[0].immediate(), i1xn)
}; };
return match in_elem.sty { return match in_elem.sty {

View File

@ -377,8 +377,7 @@ pub enum ThreadLocalMode {
// Opaque pointer types // Opaque pointer types
extern { pub type Module; } extern { pub type Module; }
extern { pub type Context; } extern { pub type Context; }
extern { pub type Type_opaque; } extern { pub type Type; }
pub type TypeRef = *mut Type_opaque;
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_opaque; }
@ -517,55 +516,55 @@ extern "C" {
pub fn LLVMRustAppendModuleInlineAsm(M: &Module, Asm: *const c_char); pub fn LLVMRustAppendModuleInlineAsm(M: &Module, Asm: *const c_char);
/// See llvm::LLVMTypeKind::getTypeID. /// See llvm::LLVMTypeKind::getTypeID.
pub fn LLVMRustGetTypeKind(Ty: TypeRef) -> TypeKind; pub fn LLVMRustGetTypeKind(Ty: &Type) -> TypeKind;
// Operations on integer types // Operations on integer types
pub fn LLVMInt1TypeInContext(C: &Context) -> TypeRef; pub fn LLVMInt1TypeInContext(C: &Context) -> &Type;
pub fn LLVMInt8TypeInContext(C: &Context) -> TypeRef; pub fn LLVMInt8TypeInContext(C: &Context) -> &Type;
pub fn LLVMInt16TypeInContext(C: &Context) -> TypeRef; pub fn LLVMInt16TypeInContext(C: &Context) -> &Type;
pub fn LLVMInt32TypeInContext(C: &Context) -> TypeRef; pub fn LLVMInt32TypeInContext(C: &Context) -> &Type;
pub fn LLVMInt64TypeInContext(C: &Context) -> TypeRef; pub fn LLVMInt64TypeInContext(C: &Context) -> &Type;
pub fn LLVMIntTypeInContext(C: &Context, NumBits: c_uint) -> TypeRef; pub fn LLVMIntTypeInContext(C: &Context, NumBits: c_uint) -> &Type;
pub fn LLVMGetIntTypeWidth(IntegerTy: TypeRef) -> c_uint; pub fn LLVMGetIntTypeWidth(IntegerTy: &Type) -> c_uint;
// Operations on real types // Operations on real types
pub fn LLVMFloatTypeInContext(C: &Context) -> TypeRef; pub fn LLVMFloatTypeInContext(C: &Context) -> &Type;
pub fn LLVMDoubleTypeInContext(C: &Context) -> TypeRef; pub fn LLVMDoubleTypeInContext(C: &Context) -> &Type;
// Operations on function types // Operations on function types
pub fn LLVMFunctionType(ReturnType: TypeRef, pub fn LLVMFunctionType(ReturnType: &'a Type,
ParamTypes: *const TypeRef, ParamTypes: *const &'a Type,
ParamCount: c_uint, ParamCount: c_uint,
IsVarArg: Bool) IsVarArg: Bool)
-> TypeRef; -> &'a Type;
pub fn LLVMGetReturnType(FunctionTy: TypeRef) -> TypeRef; pub fn LLVMGetReturnType(FunctionTy: &Type) -> &Type;
pub fn LLVMCountParamTypes(FunctionTy: TypeRef) -> c_uint; pub fn LLVMCountParamTypes(FunctionTy: &Type) -> c_uint;
pub fn LLVMGetParamTypes(FunctionTy: TypeRef, Dest: *mut TypeRef); pub fn LLVMGetParamTypes(FunctionTy: &'a Type, Dest: *mut &'a Type);
// Operations on struct types // Operations on struct types
pub fn LLVMStructTypeInContext(C: &Context, pub fn LLVMStructTypeInContext(C: &'a Context,
ElementTypes: *const TypeRef, ElementTypes: *const &'a Type,
ElementCount: c_uint, ElementCount: c_uint,
Packed: Bool) Packed: Bool)
-> TypeRef; -> &'a Type;
pub fn LLVMIsPackedStruct(StructTy: TypeRef) -> Bool; pub fn LLVMIsPackedStruct(StructTy: &Type) -> Bool;
// Operations on array, pointer, and vector types (sequence types) // Operations on array, pointer, and vector types (sequence types)
pub fn LLVMRustArrayType(ElementType: TypeRef, ElementCount: u64) -> TypeRef; pub fn LLVMRustArrayType(ElementType: &Type, ElementCount: u64) -> &Type;
pub fn LLVMPointerType(ElementType: TypeRef, AddressSpace: c_uint) -> TypeRef; pub fn LLVMPointerType(ElementType: &Type, AddressSpace: c_uint) -> &Type;
pub fn LLVMVectorType(ElementType: TypeRef, ElementCount: c_uint) -> TypeRef; pub fn LLVMVectorType(ElementType: &Type, ElementCount: c_uint) -> &Type;
pub fn LLVMGetElementType(Ty: TypeRef) -> TypeRef; pub fn LLVMGetElementType(Ty: &Type) -> &Type;
pub fn LLVMGetVectorSize(VectorTy: TypeRef) -> c_uint; pub fn LLVMGetVectorSize(VectorTy: &Type) -> c_uint;
// Operations on other types // Operations on other types
pub fn LLVMVoidTypeInContext(C: &Context) -> TypeRef; pub fn LLVMVoidTypeInContext(C: &Context) -> &Type;
pub fn LLVMX86MMXTypeInContext(C: &Context) -> TypeRef; pub fn LLVMX86MMXTypeInContext(C: &Context) -> &Type;
pub fn LLVMRustMetadataTypeInContext(C: &Context) -> TypeRef; pub fn LLVMRustMetadataTypeInContext(C: &Context) -> &Type;
// Operations on all values // Operations on all values
pub fn LLVMTypeOf(Val: ValueRef) -> TypeRef; pub fn LLVMTypeOf(Val: &Value_opaque) -> &Type;
pub fn LLVMGetValueName(Val: ValueRef) -> *const c_char; pub fn LLVMGetValueName(Val: ValueRef) -> *const c_char;
pub fn LLVMSetValueName(Val: ValueRef, Name: *const c_char); pub fn LLVMSetValueName(Val: ValueRef, Name: *const c_char);
pub fn LLVMReplaceAllUsesWith(OldVal: ValueRef, NewVal: ValueRef); pub fn LLVMReplaceAllUsesWith(OldVal: ValueRef, NewVal: ValueRef);
@ -580,10 +579,10 @@ extern "C" {
pub fn LLVMGetOperand(Val: ValueRef, Index: c_uint) -> ValueRef; pub fn LLVMGetOperand(Val: ValueRef, Index: c_uint) -> ValueRef;
// Operations on constants of any type // Operations on constants of any type
pub fn LLVMConstNull(Ty: TypeRef) -> ValueRef; pub fn LLVMConstNull(Ty: &Type) -> ValueRef;
pub fn LLVMConstICmp(Pred: IntPredicate, V1: ValueRef, V2: ValueRef) -> ValueRef; pub fn LLVMConstICmp(Pred: IntPredicate, V1: ValueRef, V2: ValueRef) -> ValueRef;
pub fn LLVMConstFCmp(Pred: RealPredicate, V1: ValueRef, V2: ValueRef) -> ValueRef; pub fn LLVMConstFCmp(Pred: RealPredicate, V1: ValueRef, V2: ValueRef) -> ValueRef;
pub fn LLVMGetUndef(Ty: TypeRef) -> ValueRef; pub fn LLVMGetUndef(Ty: &Type) -> ValueRef;
// Operations on metadata // Operations on metadata
pub fn LLVMMDStringInContext(C: &Context, Str: *const c_char, SLen: c_uint) -> ValueRef; pub fn LLVMMDStringInContext(C: &Context, Str: *const c_char, SLen: c_uint) -> ValueRef;
@ -591,8 +590,8 @@ extern "C" {
pub fn LLVMAddNamedMetadataOperand(M: &Module, Name: *const c_char, Val: ValueRef); pub fn LLVMAddNamedMetadataOperand(M: &Module, Name: *const c_char, Val: ValueRef);
// Operations on scalar constants // Operations on scalar constants
pub fn LLVMConstInt(IntTy: TypeRef, N: c_ulonglong, SignExtend: Bool) -> ValueRef; pub fn LLVMConstInt(IntTy: &Type, N: c_ulonglong, SignExtend: Bool) -> ValueRef;
pub fn LLVMConstIntOfArbitraryPrecision(IntTy: TypeRef, Wn: c_uint, Ws: *const u64) -> ValueRef; pub fn LLVMConstIntOfArbitraryPrecision(IntTy: &Type, Wn: c_uint, Ws: *const u64) -> ValueRef;
pub fn LLVMConstIntGetZExtValue(ConstantVal: ValueRef) -> c_ulonglong; pub fn LLVMConstIntGetZExtValue(ConstantVal: ValueRef) -> c_ulonglong;
pub fn LLVMConstIntGetSExtValue(ConstantVal: ValueRef) -> c_longlong; pub fn LLVMConstIntGetSExtValue(ConstantVal: ValueRef) -> c_longlong;
pub fn LLVMRustConstInt128Get(ConstantVal: ValueRef, SExt: bool, pub fn LLVMRustConstInt128Get(ConstantVal: ValueRef, SExt: bool,
@ -612,14 +611,14 @@ extern "C" {
Packed: Bool) Packed: Bool)
-> ValueRef; -> ValueRef;
pub fn LLVMConstArray(ElementTy: TypeRef, pub fn LLVMConstArray(ElementTy: &Type,
ConstantVals: *const ValueRef, ConstantVals: *const ValueRef,
Length: c_uint) Length: c_uint)
-> ValueRef; -> ValueRef;
pub fn LLVMConstVector(ScalarConstantVals: *const ValueRef, Size: c_uint) -> ValueRef; pub fn LLVMConstVector(ScalarConstantVals: *const ValueRef, Size: c_uint) -> ValueRef;
// Constant expressions // Constant expressions
pub fn LLVMSizeOf(Ty: TypeRef) -> ValueRef; pub fn LLVMSizeOf(Ty: &Type) -> ValueRef;
pub fn LLVMConstNeg(ConstantVal: ValueRef) -> ValueRef; pub fn LLVMConstNeg(ConstantVal: ValueRef) -> ValueRef;
pub fn LLVMConstFNeg(ConstantVal: ValueRef) -> ValueRef; pub fn LLVMConstFNeg(ConstantVal: ValueRef) -> ValueRef;
pub fn LLVMConstNot(ConstantVal: ValueRef) -> ValueRef; pub fn LLVMConstNot(ConstantVal: ValueRef) -> ValueRef;
@ -651,23 +650,23 @@ extern "C" {
ConstantIndices: *const ValueRef, ConstantIndices: *const ValueRef,
NumIndices: c_uint, NumIndices: c_uint,
) -> ValueRef; ) -> ValueRef;
pub fn LLVMConstTrunc(ConstantVal: ValueRef, ToType: TypeRef) -> ValueRef; pub fn LLVMConstTrunc(ConstantVal: ValueRef, ToType: &Type) -> ValueRef;
pub fn LLVMConstZExt(ConstantVal: ValueRef, ToType: TypeRef) -> ValueRef; pub fn LLVMConstZExt(ConstantVal: ValueRef, ToType: &Type) -> ValueRef;
pub fn LLVMConstUIToFP(ConstantVal: ValueRef, ToType: TypeRef) -> ValueRef; pub fn LLVMConstUIToFP(ConstantVal: ValueRef, ToType: &Type) -> ValueRef;
pub fn LLVMConstSIToFP(ConstantVal: ValueRef, ToType: TypeRef) -> ValueRef; pub fn LLVMConstSIToFP(ConstantVal: ValueRef, ToType: &Type) -> ValueRef;
pub fn LLVMConstFPToUI(ConstantVal: ValueRef, ToType: TypeRef) -> ValueRef; pub fn LLVMConstFPToUI(ConstantVal: ValueRef, ToType: &Type) -> ValueRef;
pub fn LLVMConstFPToSI(ConstantVal: ValueRef, ToType: TypeRef) -> ValueRef; pub fn LLVMConstFPToSI(ConstantVal: ValueRef, ToType: &Type) -> ValueRef;
pub fn LLVMConstPtrToInt(ConstantVal: ValueRef, ToType: TypeRef) -> ValueRef; pub fn LLVMConstPtrToInt(ConstantVal: ValueRef, ToType: &Type) -> ValueRef;
pub fn LLVMConstIntToPtr(ConstantVal: ValueRef, ToType: TypeRef) -> ValueRef; pub fn LLVMConstIntToPtr(ConstantVal: ValueRef, ToType: &Type) -> ValueRef;
pub fn LLVMConstBitCast(ConstantVal: ValueRef, ToType: TypeRef) -> ValueRef; pub fn LLVMConstBitCast(ConstantVal: ValueRef, ToType: &Type) -> ValueRef;
pub fn LLVMConstPointerCast(ConstantVal: ValueRef, ToType: TypeRef) -> ValueRef; pub fn LLVMConstPointerCast(ConstantVal: ValueRef, ToType: &Type) -> ValueRef;
pub fn LLVMConstIntCast(ConstantVal: ValueRef, ToType: TypeRef, isSigned: Bool) -> ValueRef; pub fn LLVMConstIntCast(ConstantVal: ValueRef, ToType: &Type, isSigned: Bool) -> ValueRef;
pub fn LLVMConstFPCast(ConstantVal: ValueRef, ToType: TypeRef) -> ValueRef; pub fn LLVMConstFPCast(ConstantVal: ValueRef, ToType: &Type) -> ValueRef;
pub fn LLVMConstExtractValue(AggConstant: ValueRef, pub fn LLVMConstExtractValue(AggConstant: ValueRef,
IdxList: *const c_uint, IdxList: *const c_uint,
NumIdx: c_uint) NumIdx: c_uint)
-> ValueRef; -> ValueRef;
pub fn LLVMConstInlineAsm(Ty: TypeRef, pub fn LLVMConstInlineAsm(Ty: &Type,
AsmString: *const c_char, AsmString: *const c_char,
Constraints: *const c_char, Constraints: *const c_char,
HasSideEffects: Bool, HasSideEffects: Bool,
@ -690,9 +689,9 @@ extern "C" {
// Operations on global variables // Operations on global variables
pub fn LLVMIsAGlobalVariable(GlobalVar: ValueRef) -> ValueRef; pub fn LLVMIsAGlobalVariable(GlobalVar: ValueRef) -> ValueRef;
pub fn LLVMAddGlobal(M: &Module, Ty: TypeRef, Name: *const c_char) -> ValueRef; pub fn LLVMAddGlobal(M: &Module, Ty: &Type, Name: *const c_char) -> ValueRef;
pub fn LLVMGetNamedGlobal(M: &Module, Name: *const c_char) -> ValueRef; pub fn LLVMGetNamedGlobal(M: &Module, Name: *const c_char) -> ValueRef;
pub fn LLVMRustGetOrInsertGlobal(M: &Module, Name: *const c_char, T: TypeRef) -> ValueRef; pub fn LLVMRustGetOrInsertGlobal(M: &Module, Name: *const c_char, T: &Type) -> ValueRef;
pub fn LLVMGetFirstGlobal(M: &Module) -> ValueRef; pub fn LLVMGetFirstGlobal(M: &Module) -> ValueRef;
pub fn LLVMGetNextGlobal(GlobalVar: ValueRef) -> ValueRef; pub fn LLVMGetNextGlobal(GlobalVar: ValueRef) -> ValueRef;
pub fn LLVMDeleteGlobal(GlobalVar: ValueRef); pub fn LLVMDeleteGlobal(GlobalVar: ValueRef);
@ -706,13 +705,13 @@ extern "C" {
pub fn LLVMSetTailCall(CallInst: ValueRef, IsTailCall: Bool); pub fn LLVMSetTailCall(CallInst: ValueRef, IsTailCall: Bool);
// Operations on functions // Operations on functions
pub fn LLVMAddFunction(M: &Module, Name: *const c_char, FunctionTy: TypeRef) -> ValueRef; pub fn LLVMAddFunction(M: &Module, Name: *const c_char, FunctionTy: &Type) -> ValueRef;
pub fn LLVMGetNamedFunction(M: &Module, Name: *const c_char) -> ValueRef; pub fn LLVMGetNamedFunction(M: &Module, Name: *const c_char) -> ValueRef;
pub fn LLVMGetFirstFunction(M: &Module) -> ValueRef; pub fn LLVMGetFirstFunction(M: &Module) -> ValueRef;
pub fn LLVMGetNextFunction(Fn: ValueRef) -> ValueRef; pub fn LLVMGetNextFunction(Fn: ValueRef) -> ValueRef;
pub fn LLVMRustGetOrInsertFunction(M: &Module, pub fn LLVMRustGetOrInsertFunction(M: &Module,
Name: *const c_char, Name: *const c_char,
FunctionTy: TypeRef) FunctionTy: &Type)
-> ValueRef; -> ValueRef;
pub fn LLVMSetFunctionCallConv(Fn: ValueRef, CC: c_uint); pub fn LLVMSetFunctionCallConv(Fn: ValueRef, CC: c_uint);
pub fn LLVMRustAddAlignmentAttr(Fn: ValueRef, index: c_uint, bytes: u32); pub fn LLVMRustAddAlignmentAttr(Fn: ValueRef, index: c_uint, bytes: u32);
@ -801,7 +800,7 @@ extern "C" {
Name: *const c_char) Name: *const c_char)
-> ValueRef; -> ValueRef;
pub fn LLVMBuildLandingPad(B: BuilderRef, pub fn LLVMBuildLandingPad(B: BuilderRef,
Ty: TypeRef, Ty: &Type,
PersFn: ValueRef, PersFn: ValueRef,
NumClauses: c_uint, NumClauses: c_uint,
Name: *const c_char) Name: *const c_char)
@ -989,7 +988,7 @@ extern "C" {
pub fn LLVMRustSetHasUnsafeAlgebra(Instr: ValueRef); pub fn LLVMRustSetHasUnsafeAlgebra(Instr: ValueRef);
// Memory // Memory
pub fn LLVMBuildAlloca(B: BuilderRef, Ty: TypeRef, Name: *const c_char) -> ValueRef; pub fn LLVMBuildAlloca(B: BuilderRef, Ty: &Type, Name: *const c_char) -> ValueRef;
pub fn LLVMBuildFree(B: BuilderRef, PointerVal: ValueRef) -> ValueRef; pub fn LLVMBuildFree(B: BuilderRef, PointerVal: ValueRef) -> ValueRef;
pub fn LLVMBuildLoad(B: BuilderRef, PointerVal: ValueRef, Name: *const c_char) -> ValueRef; pub fn LLVMBuildLoad(B: BuilderRef, PointerVal: ValueRef, Name: *const c_char) -> ValueRef;
@ -1024,98 +1023,98 @@ extern "C" {
// Casts // Casts
pub fn LLVMBuildTrunc(B: BuilderRef, pub fn LLVMBuildTrunc(B: BuilderRef,
Val: ValueRef, Val: ValueRef,
DestTy: TypeRef, DestTy: &Type,
Name: *const c_char) Name: *const c_char)
-> ValueRef; -> ValueRef;
pub fn LLVMBuildZExt(B: BuilderRef, pub fn LLVMBuildZExt(B: BuilderRef,
Val: ValueRef, Val: ValueRef,
DestTy: TypeRef, DestTy: &Type,
Name: *const c_char) Name: *const c_char)
-> ValueRef; -> ValueRef;
pub fn LLVMBuildSExt(B: BuilderRef, pub fn LLVMBuildSExt(B: BuilderRef,
Val: ValueRef, Val: ValueRef,
DestTy: TypeRef, DestTy: &Type,
Name: *const c_char) Name: *const c_char)
-> ValueRef; -> ValueRef;
pub fn LLVMBuildFPToUI(B: BuilderRef, pub fn LLVMBuildFPToUI(B: BuilderRef,
Val: ValueRef, Val: ValueRef,
DestTy: TypeRef, DestTy: &Type,
Name: *const c_char) Name: *const c_char)
-> ValueRef; -> ValueRef;
pub fn LLVMBuildFPToSI(B: BuilderRef, pub fn LLVMBuildFPToSI(B: BuilderRef,
Val: ValueRef, Val: ValueRef,
DestTy: TypeRef, DestTy: &Type,
Name: *const c_char) Name: *const c_char)
-> ValueRef; -> ValueRef;
pub fn LLVMBuildUIToFP(B: BuilderRef, pub fn LLVMBuildUIToFP(B: BuilderRef,
Val: ValueRef, Val: ValueRef,
DestTy: TypeRef, DestTy: &Type,
Name: *const c_char) Name: *const c_char)
-> ValueRef; -> ValueRef;
pub fn LLVMBuildSIToFP(B: BuilderRef, pub fn LLVMBuildSIToFP(B: BuilderRef,
Val: ValueRef, Val: ValueRef,
DestTy: TypeRef, DestTy: &Type,
Name: *const c_char) Name: *const c_char)
-> ValueRef; -> ValueRef;
pub fn LLVMBuildFPTrunc(B: BuilderRef, pub fn LLVMBuildFPTrunc(B: BuilderRef,
Val: ValueRef, Val: ValueRef,
DestTy: TypeRef, DestTy: &Type,
Name: *const c_char) Name: *const c_char)
-> ValueRef; -> ValueRef;
pub fn LLVMBuildFPExt(B: BuilderRef, pub fn LLVMBuildFPExt(B: BuilderRef,
Val: ValueRef, Val: ValueRef,
DestTy: TypeRef, DestTy: &Type,
Name: *const c_char) Name: *const c_char)
-> ValueRef; -> ValueRef;
pub fn LLVMBuildPtrToInt(B: BuilderRef, pub fn LLVMBuildPtrToInt(B: BuilderRef,
Val: ValueRef, Val: ValueRef,
DestTy: TypeRef, DestTy: &Type,
Name: *const c_char) Name: *const c_char)
-> ValueRef; -> ValueRef;
pub fn LLVMBuildIntToPtr(B: BuilderRef, pub fn LLVMBuildIntToPtr(B: BuilderRef,
Val: ValueRef, Val: ValueRef,
DestTy: TypeRef, DestTy: &Type,
Name: *const c_char) Name: *const c_char)
-> ValueRef; -> ValueRef;
pub fn LLVMBuildBitCast(B: BuilderRef, pub fn LLVMBuildBitCast(B: BuilderRef,
Val: ValueRef, Val: ValueRef,
DestTy: TypeRef, DestTy: &Type,
Name: *const c_char) Name: *const c_char)
-> ValueRef; -> ValueRef;
pub fn LLVMBuildZExtOrBitCast(B: BuilderRef, pub fn LLVMBuildZExtOrBitCast(B: BuilderRef,
Val: ValueRef, Val: ValueRef,
DestTy: TypeRef, DestTy: &Type,
Name: *const c_char) Name: *const c_char)
-> ValueRef; -> ValueRef;
pub fn LLVMBuildSExtOrBitCast(B: BuilderRef, pub fn LLVMBuildSExtOrBitCast(B: BuilderRef,
Val: ValueRef, Val: ValueRef,
DestTy: TypeRef, DestTy: &Type,
Name: *const c_char) Name: *const c_char)
-> ValueRef; -> ValueRef;
pub fn LLVMBuildTruncOrBitCast(B: BuilderRef, pub fn LLVMBuildTruncOrBitCast(B: BuilderRef,
Val: ValueRef, Val: ValueRef,
DestTy: TypeRef, DestTy: &Type,
Name: *const c_char) Name: *const c_char)
-> ValueRef; -> ValueRef;
pub fn LLVMBuildCast(B: BuilderRef, pub fn LLVMBuildCast(B: BuilderRef,
Op: Opcode, Op: Opcode,
Val: ValueRef, Val: ValueRef,
DestTy: TypeRef, DestTy: &Type,
Name: *const c_char) Name: *const c_char)
-> ValueRef; -> ValueRef;
pub fn LLVMBuildPointerCast(B: BuilderRef, pub fn LLVMBuildPointerCast(B: BuilderRef,
Val: ValueRef, Val: ValueRef,
DestTy: TypeRef, DestTy: &Type,
Name: *const c_char) Name: *const c_char)
-> ValueRef; -> ValueRef;
pub fn LLVMRustBuildIntCast(B: BuilderRef, pub fn LLVMRustBuildIntCast(B: BuilderRef,
Val: ValueRef, Val: ValueRef,
DestTy: TypeRef, DestTy: &Type,
IsSized: bool) IsSized: bool)
-> ValueRef; -> ValueRef;
pub fn LLVMBuildFPCast(B: BuilderRef, pub fn LLVMBuildFPCast(B: BuilderRef,
Val: ValueRef, Val: ValueRef,
DestTy: TypeRef, DestTy: &Type,
Name: *const c_char) Name: *const c_char)
-> ValueRef; -> ValueRef;
@ -1134,7 +1133,7 @@ extern "C" {
-> ValueRef; -> ValueRef;
// Miscellaneous instructions // Miscellaneous instructions
pub fn LLVMBuildPhi(B: BuilderRef, Ty: TypeRef, Name: *const c_char) -> ValueRef; pub fn LLVMBuildPhi(B: BuilderRef, Ty: &Type, Name: *const c_char) -> ValueRef;
pub fn LLVMRustBuildCall(B: BuilderRef, pub fn LLVMRustBuildCall(B: BuilderRef,
Fn: ValueRef, Fn: ValueRef,
Args: *const ValueRef, Args: *const ValueRef,
@ -1150,7 +1149,7 @@ extern "C" {
-> ValueRef; -> ValueRef;
pub fn LLVMBuildVAArg(B: BuilderRef, pub fn LLVMBuildVAArg(B: BuilderRef,
list: ValueRef, list: ValueRef,
Ty: TypeRef, Ty: &Type,
Name: *const c_char) Name: *const c_char)
-> ValueRef; -> ValueRef;
pub fn LLVMBuildExtractElement(B: BuilderRef, pub fn LLVMBuildExtractElement(B: BuilderRef,
@ -1347,15 +1346,15 @@ extern "C" {
/// Print the pass timings since static dtors aren't picking them up. /// Print the pass timings since static dtors aren't picking them up.
pub fn LLVMRustPrintPassTimings(); pub fn LLVMRustPrintPassTimings();
pub fn LLVMStructCreateNamed(C: &Context, Name: *const c_char) -> TypeRef; pub fn LLVMStructCreateNamed(C: &Context, Name: *const c_char) -> &Type;
pub fn LLVMStructSetBody(StructTy: TypeRef, pub fn LLVMStructSetBody(StructTy: &'a Type,
ElementTypes: *const TypeRef, ElementTypes: *const &'a Type,
ElementCount: c_uint, ElementCount: c_uint,
Packed: Bool); Packed: Bool);
/// Prepares inline assembly. /// Prepares inline assembly.
pub fn LLVMRustInlineAsm(Ty: TypeRef, pub fn LLVMRustInlineAsm(Ty: &Type,
AsmString: *const c_char, AsmString: *const c_char,
Constraints: *const c_char, Constraints: *const c_char,
SideEffects: Bool, SideEffects: Bool,
@ -1587,7 +1586,7 @@ extern "C" {
pub fn LLVMRustDIBuilderCreateOpDeref() -> i64; pub fn LLVMRustDIBuilderCreateOpDeref() -> i64;
pub fn LLVMRustDIBuilderCreateOpPlusUconst() -> i64; pub fn LLVMRustDIBuilderCreateOpPlusUconst() -> i64;
pub fn LLVMRustWriteTypeToString(Type: TypeRef, s: RustStringRef); pub fn LLVMRustWriteTypeToString(Type: &Type, s: RustStringRef);
pub fn LLVMRustWriteValueToString(value_ref: ValueRef, s: RustStringRef); pub fn LLVMRustWriteValueToString(value_ref: ValueRef, s: RustStringRef);
pub fn LLVMIsAConstantInt(value_ref: ValueRef) -> ValueRef; pub fn LLVMIsAConstantInt(value_ref: ValueRef) -> ValueRef;

View File

@ -33,7 +33,7 @@ impl<'a, 'tcx> VirtualIndex {
VirtualIndex(index as u64 + 3) VirtualIndex(index as u64 + 3)
} }
pub fn get_fn(self, bx: &Builder<'a, 'tcx>, pub fn get_fn(self, bx: &Builder<'a, 'll, 'tcx>,
llvtable: ValueRef, llvtable: ValueRef,
fn_ty: &FnType<'tcx, Ty<'tcx>>) -> ValueRef { fn_ty: &FnType<'tcx, Ty<'tcx>>) -> ValueRef {
// Load the data pointer from the object. // Load the data pointer from the object.
@ -48,7 +48,7 @@ impl<'a, 'tcx> VirtualIndex {
ptr ptr
} }
pub fn get_usize(self, bx: &Builder<'a, 'tcx>, llvtable: ValueRef) -> ValueRef { pub fn get_usize(self, bx: &Builder<'a, 'll, 'tcx>, llvtable: ValueRef) -> ValueRef {
// Load the data pointer from the object. // Load the data pointer from the object.
debug!("get_int({:?}, {:?})", Value(llvtable), self); debug!("get_int({:?}, {:?})", Value(llvtable), self);

View File

@ -22,7 +22,7 @@ use rustc::ty::layout::LayoutOf;
use type_of::LayoutLlvmExt; use type_of::LayoutLlvmExt;
use super::FunctionCx; use super::FunctionCx;
pub fn non_ssa_locals<'a, 'tcx>(fx: &FunctionCx<'a, 'tcx>) -> BitVector<mir::Local> { pub fn non_ssa_locals(fx: &FunctionCx<'a, 'll, 'tcx>) -> BitVector<mir::Local> {
let mir = fx.mir; let mir = fx.mir;
let mut analyzer = LocalAnalyzer::new(fx); let mut analyzer = LocalAnalyzer::new(fx);
@ -51,8 +51,8 @@ pub fn non_ssa_locals<'a, 'tcx>(fx: &FunctionCx<'a, 'tcx>) -> BitVector<mir::Loc
analyzer.non_ssa_locals analyzer.non_ssa_locals
} }
struct LocalAnalyzer<'mir, 'a: 'mir, 'tcx: 'a> { struct LocalAnalyzer<'mir, 'a: 'mir, 'll: 'a, 'tcx: 'll> {
fx: &'mir FunctionCx<'a, 'tcx>, fx: &'mir FunctionCx<'a, 'll, 'tcx>,
dominators: Dominators<mir::BasicBlock>, dominators: Dominators<mir::BasicBlock>,
non_ssa_locals: BitVector<mir::Local>, non_ssa_locals: BitVector<mir::Local>,
// The location of the first visited direct assignment to each // The location of the first visited direct assignment to each
@ -60,8 +60,8 @@ struct LocalAnalyzer<'mir, 'a: 'mir, 'tcx: 'a> {
first_assignment: IndexVec<mir::Local, Location> first_assignment: IndexVec<mir::Local, Location>
} }
impl<'mir, 'a, 'tcx> LocalAnalyzer<'mir, 'a, 'tcx> { impl LocalAnalyzer<'mir, 'a, 'll, 'tcx> {
fn new(fx: &'mir FunctionCx<'a, 'tcx>) -> LocalAnalyzer<'mir, 'a, 'tcx> { fn new(fx: &'mir FunctionCx<'a, 'll, 'tcx>) -> Self {
let invalid_location = let invalid_location =
mir::BasicBlock::new(fx.mir.basic_blocks().len()).start_location(); mir::BasicBlock::new(fx.mir.basic_blocks().len()).start_location();
let mut analyzer = LocalAnalyzer { let mut analyzer = LocalAnalyzer {
@ -102,7 +102,7 @@ impl<'mir, 'a, 'tcx> LocalAnalyzer<'mir, 'a, 'tcx> {
} }
} }
impl<'mir, 'a, 'tcx> Visitor<'tcx> for LocalAnalyzer<'mir, 'a, 'tcx> { impl Visitor<'tcx> for LocalAnalyzer<'mir, 'a, 'll, 'tcx> {
fn visit_assign(&mut self, fn visit_assign(&mut self,
block: mir::BasicBlock, block: mir::BasicBlock,
place: &mir::Place<'tcx>, place: &mir::Place<'tcx>,

View File

@ -33,7 +33,7 @@ use super::place::PlaceRef;
use super::operand::OperandRef; use super::operand::OperandRef;
use super::operand::OperandValue::{Pair, Ref, Immediate}; use super::operand::OperandValue::{Pair, Ref, Immediate};
impl<'a, 'tcx> FunctionCx<'a, 'tcx> { impl FunctionCx<'a, 'll, 'tcx> {
pub fn codegen_block(&mut self, bb: mir::BasicBlock) { pub fn codegen_block(&mut self, bb: mir::BasicBlock) {
let mut bx = self.build_block(bb); let mut bx = self.build_block(bb);
let data = &self.mir[bb]; let data = &self.mir[bb];
@ -48,7 +48,7 @@ impl<'a, 'tcx> FunctionCx<'a, 'tcx> {
} }
fn codegen_terminator(&mut self, fn codegen_terminator(&mut self,
mut bx: Builder<'a, 'tcx>, mut bx: Builder<'a, 'll, 'tcx>,
bb: mir::BasicBlock, bb: mir::BasicBlock,
terminator: &mir::Terminator<'tcx>) terminator: &mir::Terminator<'tcx>)
{ {
@ -110,7 +110,7 @@ impl<'a, 'tcx> FunctionCx<'a, 'tcx> {
let do_call = | let do_call = |
this: &mut Self, this: &mut Self,
bx: Builder<'a, 'tcx>, bx: Builder<'a, 'll, 'tcx>,
fn_ty: FnType<'tcx, Ty<'tcx>>, fn_ty: FnType<'tcx, Ty<'tcx>>,
fn_ptr: ValueRef, fn_ptr: ValueRef,
llargs: &[ValueRef], llargs: &[ValueRef],
@ -627,7 +627,7 @@ impl<'a, 'tcx> FunctionCx<'a, 'tcx> {
} }
fn codegen_argument(&mut self, fn codegen_argument(&mut self,
bx: &Builder<'a, 'tcx>, bx: &Builder<'a, 'll, 'tcx>,
op: OperandRef<'tcx>, op: OperandRef<'tcx>,
llargs: &mut Vec<ValueRef>, llargs: &mut Vec<ValueRef>,
arg: &ArgType<'tcx, Ty<'tcx>>) { arg: &ArgType<'tcx, Ty<'tcx>>) {
@ -706,7 +706,7 @@ impl<'a, 'tcx> FunctionCx<'a, 'tcx> {
} }
fn codegen_arguments_untupled(&mut self, fn codegen_arguments_untupled(&mut self,
bx: &Builder<'a, 'tcx>, bx: &Builder<'a, 'll, 'tcx>,
operand: &mir::Operand<'tcx>, operand: &mir::Operand<'tcx>,
llargs: &mut Vec<ValueRef>, llargs: &mut Vec<ValueRef>,
args: &[ArgType<'tcx, Ty<'tcx>>]) { args: &[ArgType<'tcx, Ty<'tcx>>]) {
@ -728,7 +728,7 @@ impl<'a, 'tcx> FunctionCx<'a, 'tcx> {
} }
} }
fn get_personality_slot(&mut self, bx: &Builder<'a, 'tcx>) -> PlaceRef<'tcx> { fn get_personality_slot(&mut self, bx: &Builder<'a, 'll, 'tcx>) -> PlaceRef<'tcx> {
let cx = bx.cx; let cx = bx.cx;
if let Some(slot) = self.personality_slot { if let Some(slot) = self.personality_slot {
slot slot
@ -777,7 +777,7 @@ impl<'a, 'tcx> FunctionCx<'a, 'tcx> {
bx.llbb() bx.llbb()
} }
fn landing_pad_type(&self) -> Type { fn landing_pad_type(&self) -> &'ll Type {
let cx = self.cx; let cx = self.cx;
Type::struct_(cx, &[Type::i8p(cx), Type::i32(cx)], false) Type::struct_(cx, &[Type::i8p(cx), Type::i32(cx)], false)
} }
@ -791,17 +791,17 @@ impl<'a, 'tcx> FunctionCx<'a, 'tcx> {
}) })
} }
pub fn new_block(&self, name: &str) -> Builder<'a, 'tcx> { pub fn new_block(&self, name: &str) -> Builder<'a, 'll, 'tcx> {
Builder::new_block(self.cx, self.llfn, name) Builder::new_block(self.cx, self.llfn, name)
} }
pub fn build_block(&self, bb: mir::BasicBlock) -> Builder<'a, 'tcx> { pub fn build_block(&self, bb: mir::BasicBlock) -> Builder<'a, 'll, 'tcx> {
let bx = Builder::with_cx(self.cx); let bx = Builder::with_cx(self.cx);
bx.position_at_end(self.blocks[bb]); bx.position_at_end(self.blocks[bb]);
bx bx
} }
fn make_return_dest(&mut self, bx: &Builder<'a, 'tcx>, fn make_return_dest(&mut self, bx: &Builder<'a, 'll, 'tcx>,
dest: &mir::Place<'tcx>, fn_ret: &ArgType<'tcx, Ty<'tcx>>, dest: &mir::Place<'tcx>, fn_ret: &ArgType<'tcx, Ty<'tcx>>,
llargs: &mut Vec<ValueRef>, is_intrinsic: bool) llargs: &mut Vec<ValueRef>, is_intrinsic: bool)
-> ReturnDest<'tcx> { -> ReturnDest<'tcx> {
@ -857,7 +857,7 @@ impl<'a, 'tcx> FunctionCx<'a, 'tcx> {
} }
} }
fn codegen_transmute(&mut self, bx: &Builder<'a, 'tcx>, fn codegen_transmute(&mut self, bx: &Builder<'a, 'll, 'tcx>,
src: &mir::Operand<'tcx>, src: &mir::Operand<'tcx>,
dst: &mir::Place<'tcx>) { dst: &mir::Place<'tcx>) {
if let mir::Place::Local(index) = *dst { if let mir::Place::Local(index) = *dst {
@ -884,7 +884,7 @@ impl<'a, 'tcx> FunctionCx<'a, 'tcx> {
} }
} }
fn codegen_transmute_into(&mut self, bx: &Builder<'a, 'tcx>, fn codegen_transmute_into(&mut self, bx: &Builder<'a, 'll, 'tcx>,
src: &mir::Operand<'tcx>, src: &mir::Operand<'tcx>,
dst: PlaceRef<'tcx>) { dst: PlaceRef<'tcx>) {
let src = self.codegen_operand(bx, src); let src = self.codegen_operand(bx, src);
@ -897,7 +897,7 @@ impl<'a, 'tcx> FunctionCx<'a, 'tcx> {
// Stores the return value of a function call into it's final location. // Stores the return value of a function call into it's final location.
fn store_return(&mut self, fn store_return(&mut self,
bx: &Builder<'a, 'tcx>, bx: &Builder<'a, 'll, 'tcx>,
dest: ReturnDest<'tcx>, dest: ReturnDest<'tcx>,
ret_ty: &ArgType<'tcx, Ty<'tcx>>, ret_ty: &ArgType<'tcx, Ty<'tcx>>,
llval: ValueRef) { llval: ValueRef) {

View File

@ -33,7 +33,7 @@ use super::FunctionCx;
pub fn scalar_to_llvm(cx: &CodegenCx, pub fn scalar_to_llvm(cx: &CodegenCx,
cv: Scalar, cv: Scalar,
layout: &layout::Scalar, layout: &layout::Scalar,
llty: Type) -> ValueRef { llty: &Type) -> ValueRef {
let bitsize = if layout.is_bool() { 1 } else { layout.value.size(cx).bits() }; let bitsize = if layout.is_bool() { 1 } else { layout.value.size(cx).bits() };
match cv { match cv {
Scalar::Bits { defined, .. } if (defined as u64) < bitsize || defined == 0 => { Scalar::Bits { defined, .. } if (defined as u64) < bitsize || defined == 0 => {
@ -42,7 +42,7 @@ pub fn scalar_to_llvm(cx: &CodegenCx,
Scalar::Bits { bits, .. } => { Scalar::Bits { bits, .. } => {
let llval = C_uint_big(Type::ix(cx, bitsize), bits); let llval = C_uint_big(Type::ix(cx, bitsize), bits);
if layout.value == layout::Pointer { if layout.value == layout::Pointer {
unsafe { llvm::LLVMConstIntToPtr(llval, llty.to_ref()) } unsafe { llvm::LLVMConstIntToPtr(llval, llty) }
} else { } else {
consts::bitcast(llval, llty) consts::bitcast(llval, llty)
} }
@ -73,7 +73,7 @@ pub fn scalar_to_llvm(cx: &CodegenCx,
1, 1,
) }; ) };
if layout.value != layout::Pointer { if layout.value != layout::Pointer {
unsafe { llvm::LLVMConstPtrToInt(llval, llty.to_ref()) } unsafe { llvm::LLVMConstPtrToInt(llval, llty) }
} else { } else {
consts::bitcast(llval, llty) consts::bitcast(llval, llty)
} }
@ -135,10 +135,10 @@ pub fn codegen_static_initializer<'a, 'tcx>(
Ok((const_alloc_to_llvm(cx, alloc), alloc)) Ok((const_alloc_to_llvm(cx, alloc), alloc))
} }
impl<'a, 'tcx> FunctionCx<'a, 'tcx> { impl FunctionCx<'a, 'll, 'tcx> {
fn fully_evaluate( fn fully_evaluate(
&mut self, &mut self,
bx: &Builder<'a, 'tcx>, bx: &Builder<'a, 'll, 'tcx>,
constant: &'tcx ty::Const<'tcx>, constant: &'tcx ty::Const<'tcx>,
) -> Result<&'tcx ty::Const<'tcx>, Lrc<ConstEvalErr<'tcx>>> { ) -> Result<&'tcx ty::Const<'tcx>, Lrc<ConstEvalErr<'tcx>>> {
match constant.val { match constant.val {
@ -158,7 +158,7 @@ impl<'a, 'tcx> FunctionCx<'a, 'tcx> {
pub fn eval_mir_constant( pub fn eval_mir_constant(
&mut self, &mut self,
bx: &Builder<'a, 'tcx>, bx: &Builder<'a, 'll, 'tcx>,
constant: &mir::Constant<'tcx>, constant: &mir::Constant<'tcx>,
) -> Result<&'tcx ty::Const<'tcx>, Lrc<ConstEvalErr<'tcx>>> { ) -> Result<&'tcx ty::Const<'tcx>, Lrc<ConstEvalErr<'tcx>>> {
let c = self.monomorphize(&constant.literal); let c = self.monomorphize(&constant.literal);
@ -168,7 +168,7 @@ impl<'a, 'tcx> FunctionCx<'a, 'tcx> {
/// process constant containing SIMD shuffle indices /// process constant containing SIMD shuffle indices
pub fn simd_shuffle_indices( pub fn simd_shuffle_indices(
&mut self, &mut self,
bx: &Builder<'a, 'tcx>, bx: &Builder<'a, 'll, 'tcx>,
span: Span, span: Span,
ty: Ty<'tcx>, ty: Ty<'tcx>,
constant: Result<&'tcx ty::Const<'tcx>, Lrc<ConstEvalErr<'tcx>>>, constant: Result<&'tcx ty::Const<'tcx>, Lrc<ConstEvalErr<'tcx>>>,

View File

@ -43,7 +43,7 @@ use rustc::mir::traversal;
use self::operand::{OperandRef, OperandValue}; use self::operand::{OperandRef, OperandValue};
/// Master context for codegenning from MIR. /// Master context for codegenning from MIR.
pub struct FunctionCx<'a, 'tcx:'a> { pub struct FunctionCx<'a, 'll: 'a, 'tcx: 'll> {
instance: Instance<'tcx>, instance: Instance<'tcx>,
mir: &'a mir::Mir<'tcx>, mir: &'a mir::Mir<'tcx>,
@ -52,7 +52,7 @@ pub struct FunctionCx<'a, 'tcx:'a> {
llfn: ValueRef, llfn: ValueRef,
cx: &'a CodegenCx<'a, 'tcx>, cx: &'a CodegenCx<'ll, 'tcx>,
fn_ty: FnType<'tcx, Ty<'tcx>>, fn_ty: FnType<'tcx, Ty<'tcx>>,
@ -106,7 +106,7 @@ pub struct FunctionCx<'a, 'tcx:'a> {
param_substs: &'tcx Substs<'tcx>, param_substs: &'tcx Substs<'tcx>,
} }
impl<'a, 'tcx> FunctionCx<'a, 'tcx> { impl FunctionCx<'a, 'll, 'tcx> {
pub fn monomorphize<T>(&self, value: &T) -> T pub fn monomorphize<T>(&self, value: &T) -> T
where T: TypeFoldable<'tcx> where T: TypeFoldable<'tcx>
{ {
@ -198,8 +198,8 @@ impl<'a, 'tcx> LocalRef<'tcx> {
/////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////
pub fn codegen_mir<'a, 'tcx: 'a>( pub fn codegen_mir(
cx: &'a CodegenCx<'a, 'tcx>, cx: &'a CodegenCx<'ll, 'tcx>,
llfn: ValueRef, llfn: ValueRef,
mir: &'a Mir<'tcx>, mir: &'a Mir<'tcx>,
instance: Instance<'tcx>, instance: Instance<'tcx>,
@ -344,9 +344,9 @@ pub fn codegen_mir<'a, 'tcx: 'a>(
} }
} }
fn create_funclets<'a, 'tcx>( fn create_funclets(
mir: &'a Mir<'tcx>, mir: &'a Mir<'tcx>,
bx: &Builder<'a, 'tcx>, bx: &Builder<'a, 'll, 'tcx>,
cleanup_kinds: &IndexVec<mir::BasicBlock, CleanupKind>, cleanup_kinds: &IndexVec<mir::BasicBlock, CleanupKind>,
block_bxs: &IndexVec<mir::BasicBlock, BasicBlockRef>) block_bxs: &IndexVec<mir::BasicBlock, BasicBlockRef>)
-> (IndexVec<mir::BasicBlock, Option<BasicBlockRef>>, -> (IndexVec<mir::BasicBlock, Option<BasicBlockRef>>,
@ -413,11 +413,12 @@ fn create_funclets<'a, 'tcx>(
/// Produce, for each argument, a `ValueRef` pointing at the /// Produce, for each argument, a `ValueRef` pointing at the
/// argument's value. As arguments are places, these are always /// argument's value. As arguments are places, these are always
/// indirect. /// indirect.
fn arg_local_refs<'a, 'tcx>(bx: &Builder<'a, 'tcx>, fn arg_local_refs(
fx: &FunctionCx<'a, 'tcx>, bx: &Builder<'a, 'll, 'tcx>,
scopes: &IndexVec<mir::SourceScope, debuginfo::MirDebugScope>, fx: &FunctionCx<'a, 'll, 'tcx>,
memory_locals: &BitVector<mir::Local>) scopes: &IndexVec<mir::SourceScope, debuginfo::MirDebugScope>,
-> Vec<LocalRef<'tcx>> { memory_locals: &BitVector<mir::Local>,
) -> Vec<LocalRef<'tcx>> {
let mir = fx.mir; let mir = fx.mir;
let tcx = bx.tcx(); let tcx = bx.tcx();
let mut idx = 0; let mut idx = 0;

View File

@ -92,7 +92,7 @@ impl<'a, 'tcx> OperandRef<'tcx> {
} }
} }
pub fn from_const(bx: &Builder<'a, 'tcx>, pub fn from_const(bx: &Builder<'a, 'll, 'tcx>,
val: &'tcx ty::Const<'tcx>) val: &'tcx ty::Const<'tcx>)
-> Result<OperandRef<'tcx>, Lrc<ConstEvalErr<'tcx>>> { -> Result<OperandRef<'tcx>, Lrc<ConstEvalErr<'tcx>>> {
let layout = bx.cx.layout_of(val.ty); let layout = bx.cx.layout_of(val.ty);
@ -174,7 +174,7 @@ impl<'a, 'tcx> OperandRef<'tcx> {
/// If this operand is a `Pair`, we return an aggregate with the two values. /// If this operand is a `Pair`, we return an aggregate with the two values.
/// For other cases, see `immediate`. /// For other cases, see `immediate`.
pub fn immediate_or_packed_pair(self, bx: &Builder<'a, 'tcx>) -> ValueRef { pub fn immediate_or_packed_pair(self, bx: &Builder<'a, 'll, 'tcx>) -> ValueRef {
if let OperandValue::Pair(a, b) = self.val { if let OperandValue::Pair(a, b) = self.val {
let llty = self.layout.llvm_type(bx.cx); let llty = self.layout.llvm_type(bx.cx);
debug!("Operand::immediate_or_packed_pair: packing {:?} into {:?}", debug!("Operand::immediate_or_packed_pair: packing {:?} into {:?}",
@ -190,7 +190,7 @@ impl<'a, 'tcx> OperandRef<'tcx> {
} }
/// If the type is a pair, we return a `Pair`, otherwise, an `Immediate`. /// If the type is a pair, we return a `Pair`, otherwise, an `Immediate`.
pub fn from_immediate_or_packed_pair(bx: &Builder<'a, 'tcx>, pub fn from_immediate_or_packed_pair(bx: &Builder<'a, 'll, 'tcx>,
llval: ValueRef, llval: ValueRef,
layout: TyLayout<'tcx>) layout: TyLayout<'tcx>)
-> OperandRef<'tcx> { -> OperandRef<'tcx> {
@ -208,7 +208,7 @@ impl<'a, 'tcx> OperandRef<'tcx> {
OperandRef { val, layout } OperandRef { val, layout }
} }
pub fn extract_field(&self, bx: &Builder<'a, 'tcx>, i: usize) -> OperandRef<'tcx> { pub fn extract_field(&self, bx: &Builder<'a, 'll, 'tcx>, i: usize) -> OperandRef<'tcx> {
let field = self.layout.field(bx.cx, i); let field = self.layout.field(bx.cx, i);
let offset = self.layout.fields.offset(i); let offset = self.layout.fields.offset(i);
@ -267,23 +267,23 @@ impl<'a, 'tcx> OperandRef<'tcx> {
} }
impl<'a, 'tcx> OperandValue { impl<'a, 'tcx> OperandValue {
pub fn store(self, bx: &Builder<'a, 'tcx>, dest: PlaceRef<'tcx>) { pub fn store(self, bx: &Builder<'a, 'll, 'tcx>, dest: PlaceRef<'tcx>) {
self.store_with_flags(bx, dest, MemFlags::empty()); self.store_with_flags(bx, dest, MemFlags::empty());
} }
pub fn volatile_store(self, bx: &Builder<'a, 'tcx>, dest: PlaceRef<'tcx>) { pub fn volatile_store(self, bx: &Builder<'a, 'll, 'tcx>, dest: PlaceRef<'tcx>) {
self.store_with_flags(bx, dest, MemFlags::VOLATILE); self.store_with_flags(bx, dest, MemFlags::VOLATILE);
} }
pub fn unaligned_volatile_store(self, bx: &Builder<'a, 'tcx>, dest: PlaceRef<'tcx>) { pub fn unaligned_volatile_store(self, bx: &Builder<'a, 'll, 'tcx>, dest: PlaceRef<'tcx>) {
self.store_with_flags(bx, dest, MemFlags::VOLATILE | MemFlags::UNALIGNED); self.store_with_flags(bx, dest, MemFlags::VOLATILE | MemFlags::UNALIGNED);
} }
pub fn nontemporal_store(self, bx: &Builder<'a, 'tcx>, dest: PlaceRef<'tcx>) { pub fn nontemporal_store(self, bx: &Builder<'a, 'll, 'tcx>, dest: PlaceRef<'tcx>) {
self.store_with_flags(bx, dest, MemFlags::NONTEMPORAL); self.store_with_flags(bx, dest, MemFlags::NONTEMPORAL);
} }
fn store_with_flags(self, bx: &Builder<'a, 'tcx>, dest: PlaceRef<'tcx>, flags: MemFlags) { fn store_with_flags(self, bx: &Builder<'a, 'll, 'tcx>, dest: PlaceRef<'tcx>, flags: MemFlags) {
debug!("OperandRef::store: operand={:?}, dest={:?}", self, dest); debug!("OperandRef::store: operand={:?}, dest={:?}", self, dest);
// Avoid generating stores of zero-sized values, because the only way to have a zero-sized // Avoid generating stores of zero-sized values, because the only way to have a zero-sized
// value is through `undef`, and store itself is useless. // value is through `undef`, and store itself is useless.
@ -310,9 +310,9 @@ impl<'a, 'tcx> OperandValue {
} }
} }
impl<'a, 'tcx> FunctionCx<'a, 'tcx> { impl FunctionCx<'a, 'll, 'tcx> {
fn maybe_codegen_consume_direct(&mut self, fn maybe_codegen_consume_direct(&mut self,
bx: &Builder<'a, 'tcx>, bx: &Builder<'a, 'll, 'tcx>,
place: &mir::Place<'tcx>) place: &mir::Place<'tcx>)
-> Option<OperandRef<'tcx>> -> Option<OperandRef<'tcx>>
{ {
@ -360,7 +360,7 @@ impl<'a, 'tcx> FunctionCx<'a, 'tcx> {
} }
pub fn codegen_consume(&mut self, pub fn codegen_consume(&mut self,
bx: &Builder<'a, 'tcx>, bx: &Builder<'a, 'll, 'tcx>,
place: &mir::Place<'tcx>) place: &mir::Place<'tcx>)
-> OperandRef<'tcx> -> OperandRef<'tcx>
{ {
@ -384,7 +384,7 @@ impl<'a, 'tcx> FunctionCx<'a, 'tcx> {
} }
pub fn codegen_operand(&mut self, pub fn codegen_operand(&mut self,
bx: &Builder<'a, 'tcx>, bx: &Builder<'a, 'll, 'tcx>,
operand: &mir::Operand<'tcx>) operand: &mir::Operand<'tcx>)
-> OperandRef<'tcx> -> OperandRef<'tcx>
{ {

View File

@ -56,7 +56,7 @@ impl<'a, 'tcx> PlaceRef<'tcx> {
} }
pub fn from_const_alloc( pub fn from_const_alloc(
bx: &Builder<'a, 'tcx>, bx: &Builder<'a, 'll, 'tcx>,
layout: TyLayout<'tcx>, layout: TyLayout<'tcx>,
alloc: &mir::interpret::Allocation, alloc: &mir::interpret::Allocation,
offset: Size, offset: Size,
@ -73,7 +73,7 @@ impl<'a, 'tcx> PlaceRef<'tcx> {
PlaceRef::new_sized(llval, layout, alloc.align) PlaceRef::new_sized(llval, layout, alloc.align)
} }
pub fn alloca(bx: &Builder<'a, 'tcx>, layout: TyLayout<'tcx>, name: &str) pub fn alloca(bx: &Builder<'a, 'll, 'tcx>, layout: TyLayout<'tcx>, name: &str)
-> PlaceRef<'tcx> { -> PlaceRef<'tcx> {
debug!("alloca({:?}: {:?})", name, layout); debug!("alloca({:?}: {:?})", name, layout);
let tmp = bx.alloca(layout.llvm_type(bx.cx), name, layout.align); let tmp = bx.alloca(layout.llvm_type(bx.cx), name, layout.align);
@ -98,7 +98,7 @@ impl<'a, 'tcx> PlaceRef<'tcx> {
!self.llextra.is_null() !self.llextra.is_null()
} }
pub fn load(&self, bx: &Builder<'a, 'tcx>) -> OperandRef<'tcx> { pub fn load(&self, bx: &Builder<'a, 'll, 'tcx>) -> OperandRef<'tcx> {
debug!("PlaceRef::load: {:?}", self); debug!("PlaceRef::load: {:?}", self);
assert!(!self.has_extra()); assert!(!self.has_extra());
@ -162,7 +162,7 @@ impl<'a, 'tcx> PlaceRef<'tcx> {
} }
/// Access a field, at a point when the value's case is known. /// Access a field, at a point when the value's case is known.
pub fn project_field(self, bx: &Builder<'a, 'tcx>, ix: usize) -> PlaceRef<'tcx> { pub fn project_field(self, bx: &Builder<'a, 'll, 'tcx>, ix: usize) -> PlaceRef<'tcx> {
let cx = bx.cx; let cx = bx.cx;
let field = self.layout.field(cx, ix); let field = self.layout.field(cx, ix);
let offset = self.layout.fields.offset(ix); let offset = self.layout.fields.offset(ix);
@ -266,7 +266,7 @@ impl<'a, 'tcx> PlaceRef<'tcx> {
} }
/// Obtain the actual discriminant of a value. /// Obtain the actual discriminant of a value.
pub fn codegen_get_discr(self, bx: &Builder<'a, 'tcx>, cast_to: Ty<'tcx>) -> ValueRef { pub fn codegen_get_discr(self, bx: &Builder<'a, 'll, 'tcx>, cast_to: Ty<'tcx>) -> ValueRef {
let cast_to = bx.cx.layout_of(cast_to).immediate_llvm_type(bx.cx); let cast_to = bx.cx.layout_of(cast_to).immediate_llvm_type(bx.cx);
if self.layout.abi == layout::Abi::Uninhabited { if self.layout.abi == layout::Abi::Uninhabited {
return C_undef(cast_to); return C_undef(cast_to);
@ -330,7 +330,7 @@ impl<'a, 'tcx> PlaceRef<'tcx> {
/// Set the discriminant for a new value of the given case of the given /// Set the discriminant for a new value of the given case of the given
/// representation. /// representation.
pub fn codegen_set_discr(&self, bx: &Builder<'a, 'tcx>, variant_index: usize) { pub fn codegen_set_discr(&self, bx: &Builder<'a, 'll, 'tcx>, variant_index: usize) {
if self.layout.for_variant(bx.cx, variant_index).abi == layout::Abi::Uninhabited { if self.layout.for_variant(bx.cx, variant_index).abi == layout::Abi::Uninhabited {
return; return;
} }
@ -384,7 +384,7 @@ impl<'a, 'tcx> PlaceRef<'tcx> {
} }
} }
pub fn project_index(&self, bx: &Builder<'a, 'tcx>, llindex: ValueRef) pub fn project_index(&self, bx: &Builder<'a, 'll, 'tcx>, llindex: ValueRef)
-> PlaceRef<'tcx> { -> PlaceRef<'tcx> {
PlaceRef { PlaceRef {
llval: bx.inbounds_gep(self.llval, &[C_usize(bx.cx, 0), llindex]), llval: bx.inbounds_gep(self.llval, &[C_usize(bx.cx, 0), llindex]),
@ -394,7 +394,7 @@ impl<'a, 'tcx> PlaceRef<'tcx> {
} }
} }
pub fn project_downcast(&self, bx: &Builder<'a, 'tcx>, variant_index: usize) pub fn project_downcast(&self, bx: &Builder<'a, 'll, 'tcx>, variant_index: usize)
-> PlaceRef<'tcx> { -> PlaceRef<'tcx> {
let mut downcast = *self; let mut downcast = *self;
downcast.layout = self.layout.for_variant(bx.cx, variant_index); downcast.layout = self.layout.for_variant(bx.cx, variant_index);
@ -406,18 +406,18 @@ impl<'a, 'tcx> PlaceRef<'tcx> {
downcast downcast
} }
pub fn storage_live(&self, bx: &Builder<'a, 'tcx>) { pub fn storage_live(&self, bx: &Builder<'a, 'll, 'tcx>) {
bx.lifetime_start(self.llval, self.layout.size); bx.lifetime_start(self.llval, self.layout.size);
} }
pub fn storage_dead(&self, bx: &Builder<'a, 'tcx>) { pub fn storage_dead(&self, bx: &Builder<'a, 'll, 'tcx>) {
bx.lifetime_end(self.llval, self.layout.size); bx.lifetime_end(self.llval, self.layout.size);
} }
} }
impl<'a, 'tcx> FunctionCx<'a, 'tcx> { impl FunctionCx<'a, 'll, 'tcx> {
pub fn codegen_place(&mut self, pub fn codegen_place(&mut self,
bx: &Builder<'a, 'tcx>, bx: &Builder<'a, 'll, 'tcx>,
place: &mir::Place<'tcx>) place: &mir::Place<'tcx>)
-> PlaceRef<'tcx> { -> PlaceRef<'tcx> {
debug!("codegen_place(place={:?})", place); debug!("codegen_place(place={:?})", place);

View File

@ -32,12 +32,12 @@ use super::{FunctionCx, LocalRef};
use super::operand::{OperandRef, OperandValue}; use super::operand::{OperandRef, OperandValue};
use super::place::PlaceRef; use super::place::PlaceRef;
impl<'a, 'tcx> FunctionCx<'a, 'tcx> { impl FunctionCx<'a, 'll, 'tcx> {
pub fn codegen_rvalue(&mut self, pub fn codegen_rvalue(&mut self,
bx: Builder<'a, 'tcx>, bx: Builder<'a, 'll, 'tcx>,
dest: PlaceRef<'tcx>, dest: PlaceRef<'tcx>,
rvalue: &mir::Rvalue<'tcx>) rvalue: &mir::Rvalue<'tcx>)
-> Builder<'a, 'tcx> -> Builder<'a, 'll, 'tcx>
{ {
debug!("codegen_rvalue(dest.llval={:?}, rvalue={:?})", debug!("codegen_rvalue(dest.llval={:?}, rvalue={:?})",
Value(dest.llval), rvalue); Value(dest.llval), rvalue);
@ -176,9 +176,9 @@ impl<'a, 'tcx> FunctionCx<'a, 'tcx> {
} }
pub fn codegen_rvalue_operand(&mut self, pub fn codegen_rvalue_operand(&mut self,
bx: Builder<'a, 'tcx>, bx: Builder<'a, 'll, 'tcx>,
rvalue: &mir::Rvalue<'tcx>) rvalue: &mir::Rvalue<'tcx>)
-> (Builder<'a, 'tcx>, OperandRef<'tcx>) -> (Builder<'a, 'll, 'tcx>, OperandRef<'tcx>)
{ {
assert!(self.rvalue_creates_operand(rvalue), "cannot codegen {:?} to operand", rvalue); assert!(self.rvalue_creates_operand(rvalue), "cannot codegen {:?} to operand", rvalue);
@ -512,7 +512,7 @@ impl<'a, 'tcx> FunctionCx<'a, 'tcx> {
} }
fn evaluate_array_len(&mut self, fn evaluate_array_len(&mut self,
bx: &Builder<'a, 'tcx>, bx: &Builder<'a, 'll, 'tcx>,
place: &mir::Place<'tcx>) -> ValueRef place: &mir::Place<'tcx>) -> ValueRef
{ {
// ZST are passed as operands and require special handling // ZST are passed as operands and require special handling
@ -531,7 +531,7 @@ impl<'a, 'tcx> FunctionCx<'a, 'tcx> {
} }
pub fn codegen_scalar_binop(&mut self, pub fn codegen_scalar_binop(&mut self,
bx: &Builder<'a, 'tcx>, bx: &Builder<'a, 'll, 'tcx>,
op: mir::BinOp, op: mir::BinOp,
lhs: ValueRef, lhs: ValueRef,
rhs: ValueRef, rhs: ValueRef,
@ -597,7 +597,7 @@ impl<'a, 'tcx> FunctionCx<'a, 'tcx> {
} }
pub fn codegen_fat_ptr_binop(&mut self, pub fn codegen_fat_ptr_binop(&mut self,
bx: &Builder<'a, 'tcx>, bx: &Builder<'a, 'll, 'tcx>,
op: mir::BinOp, op: mir::BinOp,
lhs_addr: ValueRef, lhs_addr: ValueRef,
lhs_extra: ValueRef, lhs_extra: ValueRef,
@ -644,7 +644,7 @@ impl<'a, 'tcx> FunctionCx<'a, 'tcx> {
} }
pub fn codegen_scalar_checked_binop(&mut self, pub fn codegen_scalar_checked_binop(&mut self,
bx: &Builder<'a, 'tcx>, bx: &Builder<'a, 'll, 'tcx>,
op: mir::BinOp, op: mir::BinOp,
lhs: ValueRef, lhs: ValueRef,
rhs: ValueRef, rhs: ValueRef,
@ -796,11 +796,11 @@ fn get_overflow_intrinsic(oop: OverflowOp, bx: &Builder, ty: Ty) -> ValueRef {
bx.cx.get_intrinsic(&name) bx.cx.get_intrinsic(&name)
} }
fn cast_int_to_float(bx: &Builder, fn cast_int_to_float(bx: &Builder<'_, 'll, '_>,
signed: bool, signed: bool,
x: ValueRef, x: ValueRef,
int_ty: Type, int_ty: &'ll Type,
float_ty: Type) -> ValueRef { float_ty: &'ll Type) -> ValueRef {
// Most integer types, even i128, fit into [-f32::MAX, f32::MAX] after rounding. // Most integer types, even i128, fit into [-f32::MAX, f32::MAX] after rounding.
// It's only u128 -> f32 that can cause overflows (i.e., should yield infinity). // It's only u128 -> f32 that can cause overflows (i.e., should yield infinity).
// LLVM's uitofp produces undef in those cases, so we manually check for that case. // LLVM's uitofp produces undef in those cases, so we manually check for that case.
@ -826,11 +826,11 @@ fn cast_int_to_float(bx: &Builder,
} }
} }
fn cast_float_to_int(bx: &Builder, fn cast_float_to_int(bx: &Builder<'_, 'll, '_>,
signed: bool, signed: bool,
x: ValueRef, x: ValueRef,
float_ty: Type, float_ty: &'ll Type,
int_ty: Type) -> ValueRef { int_ty: &'ll Type) -> ValueRef {
let fptosui_result = if signed { let fptosui_result = if signed {
bx.fptosi(x, int_ty) bx.fptosi(x, int_ty)
} else { } else {
@ -859,14 +859,14 @@ fn cast_float_to_int(bx: &Builder,
// On the other hand, f_max works even if int_ty::MAX is greater than float_ty::MAX. Because // On the other hand, f_max works even if int_ty::MAX is greater than float_ty::MAX. Because
// we're rounding towards zero, we just get float_ty::MAX (which is always an integer). // we're rounding towards zero, we just get float_ty::MAX (which is always an integer).
// This already happens today with u128::MAX = 2^128 - 1 > f32::MAX. // This already happens today with u128::MAX = 2^128 - 1 > f32::MAX.
fn compute_clamp_bounds<F: Float>(signed: bool, int_ty: Type) -> (u128, u128) { fn compute_clamp_bounds<F: Float>(signed: bool, int_ty: &Type) -> (u128, u128) {
let rounded_min = F::from_i128_r(int_min(signed, int_ty), Round::TowardZero); let rounded_min = F::from_i128_r(int_min(signed, int_ty), Round::TowardZero);
assert_eq!(rounded_min.status, Status::OK); assert_eq!(rounded_min.status, Status::OK);
let rounded_max = F::from_u128_r(int_max(signed, int_ty), Round::TowardZero); let rounded_max = F::from_u128_r(int_max(signed, int_ty), Round::TowardZero);
assert!(rounded_max.value.is_finite()); assert!(rounded_max.value.is_finite());
(rounded_min.value.to_bits(), rounded_max.value.to_bits()) (rounded_min.value.to_bits(), rounded_max.value.to_bits())
} }
fn int_max(signed: bool, int_ty: Type) -> u128 { fn int_max(signed: bool, int_ty: &Type) -> u128 {
let shift_amount = 128 - int_ty.int_width(); let shift_amount = 128 - int_ty.int_width();
if signed { if signed {
i128::MAX as u128 >> shift_amount i128::MAX as u128 >> shift_amount
@ -874,7 +874,7 @@ fn cast_float_to_int(bx: &Builder,
u128::MAX >> shift_amount u128::MAX >> shift_amount
} }
} }
fn int_min(signed: bool, int_ty: Type) -> i128 { fn int_min(signed: bool, int_ty: &Type) -> i128 {
if signed { if signed {
i128::MIN >> (128 - int_ty.int_width()) i128::MIN >> (128 - int_ty.int_width())
} else { } else {

View File

@ -16,11 +16,11 @@ use builder::Builder;
use super::FunctionCx; use super::FunctionCx;
use super::LocalRef; use super::LocalRef;
impl<'a, 'tcx> FunctionCx<'a, 'tcx> { impl FunctionCx<'a, 'll, 'tcx> {
pub fn codegen_statement(&mut self, pub fn codegen_statement(&mut self,
bx: Builder<'a, 'tcx>, bx: Builder<'a, 'll, 'tcx>,
statement: &mir::Statement<'tcx>) statement: &mir::Statement<'tcx>)
-> Builder<'a, 'tcx> { -> Builder<'a, 'll, 'tcx> {
debug!("codegen_statement(statement={:?})", statement); debug!("codegen_statement(statement={:?})", statement);
self.set_debug_loc(&bx, statement.source_info); self.set_debug_loc(&bx, statement.source_info);

View File

@ -10,8 +10,10 @@
#![allow(non_upper_case_globals)] #![allow(non_upper_case_globals)]
pub use llvm::Type;
use llvm; use llvm;
use llvm::{TypeRef, Bool, False, True, TypeKind}; use llvm::{Bool, False, True, TypeKind};
use llvm::{Float, Double, X86_FP80, PPC_FP128, FP128}; use llvm::{Float, Double, X86_FP80, PPC_FP128, FP128};
use context::CodegenCx; use context::CodegenCx;
@ -21,121 +23,125 @@ use rustc::ty::layout::{self, Align, Size};
use std::ffi::CString; use std::ffi::CString;
use std::fmt; use std::fmt;
use std::mem;
use libc::c_uint; use libc::c_uint;
#[derive(Clone, Copy, PartialEq)] impl PartialEq for Type {
#[repr(C)] fn eq(&self, other: &Self) -> bool {
pub struct Type { self as *const _ == other as *const _
rf: TypeRef }
} }
impl fmt::Debug for Type { impl fmt::Debug for Type {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
f.write_str(&llvm::build_string(|s| unsafe { f.write_str(&llvm::build_string(|s| unsafe {
llvm::LLVMRustWriteTypeToString(self.to_ref(), s); llvm::LLVMRustWriteTypeToString(self, s);
}).expect("non-UTF8 type description from LLVM")) }).expect("non-UTF8 type description from LLVM"))
} }
} }
macro_rules! ty {
($e:expr) => ( Type::from_ref(unsafe { $e }))
}
/// Wrapper for LLVM TypeRef
impl Type { impl Type {
#[inline(always)] pub fn void(cx: &CodegenCx<'ll, '_>) -> &'ll Type {
pub fn from_ref(r: TypeRef) -> Type { unsafe {
Type { llvm::LLVMVoidTypeInContext(cx.llcx)
rf: r
} }
} }
#[inline(always)] // So it doesn't kill --opt-level=0 builds of the compiler pub fn metadata(cx: &CodegenCx<'ll, '_>) -> &'ll Type {
pub fn to_ref(&self) -> TypeRef { unsafe {
self.rf llvm::LLVMRustMetadataTypeInContext(cx.llcx)
}
} }
pub fn to_ref_slice(slice: &[Type]) -> &[TypeRef] { pub fn i1(cx: &CodegenCx<'ll, '_>) -> &'ll Type {
unsafe { mem::transmute(slice) } unsafe {
llvm::LLVMInt1TypeInContext(cx.llcx)
}
} }
pub fn void(cx: &CodegenCx) -> Type { pub fn i8(cx: &CodegenCx<'ll, '_>) -> &'ll Type {
ty!(llvm::LLVMVoidTypeInContext(cx.llcx)) unsafe {
llvm::LLVMInt8TypeInContext(cx.llcx)
}
} }
pub fn metadata(cx: &CodegenCx) -> Type { pub fn i8_llcx(llcx: &llvm::Context) -> &Type {
ty!(llvm::LLVMRustMetadataTypeInContext(cx.llcx)) unsafe {
llvm::LLVMInt8TypeInContext(llcx)
}
} }
pub fn i1(cx: &CodegenCx) -> Type { pub fn i16(cx: &CodegenCx<'ll, '_>) -> &'ll Type {
ty!(llvm::LLVMInt1TypeInContext(cx.llcx)) unsafe {
llvm::LLVMInt16TypeInContext(cx.llcx)
}
} }
pub fn i8(cx: &CodegenCx) -> Type { pub fn i32(cx: &CodegenCx<'ll, '_>) -> &'ll Type {
ty!(llvm::LLVMInt8TypeInContext(cx.llcx)) unsafe {
llvm::LLVMInt32TypeInContext(cx.llcx)
}
} }
pub fn i8_llcx(llcx: &llvm::Context) -> Type { pub fn i64(cx: &CodegenCx<'ll, '_>) -> &'ll Type {
ty!(llvm::LLVMInt8TypeInContext(llcx)) unsafe {
llvm::LLVMInt64TypeInContext(cx.llcx)
}
} }
pub fn i16(cx: &CodegenCx) -> Type { pub fn i128(cx: &CodegenCx<'ll, '_>) -> &'ll Type {
ty!(llvm::LLVMInt16TypeInContext(cx.llcx)) unsafe {
} llvm::LLVMIntTypeInContext(cx.llcx, 128)
}
pub fn i32(cx: &CodegenCx) -> Type {
ty!(llvm::LLVMInt32TypeInContext(cx.llcx))
}
pub fn i64(cx: &CodegenCx) -> Type {
ty!(llvm::LLVMInt64TypeInContext(cx.llcx))
}
pub fn i128(cx: &CodegenCx) -> Type {
ty!(llvm::LLVMIntTypeInContext(cx.llcx, 128))
} }
// Creates an integer type with the given number of bits, e.g. i24 // Creates an integer type with the given number of bits, e.g. i24
pub fn ix(cx: &CodegenCx, num_bits: u64) -> Type { pub fn ix(cx: &CodegenCx<'ll, '_>, num_bits: u64) -> &'ll Type {
ty!(llvm::LLVMIntTypeInContext(cx.llcx, num_bits as c_uint)) unsafe {
llvm::LLVMIntTypeInContext(cx.llcx, num_bits as c_uint)
}
} }
// Creates an integer type with the given number of bits, e.g. i24 // Creates an integer type with the given number of bits, e.g. i24
pub fn ix_llcx(llcx: &llvm::Context, num_bits: u64) -> Type { pub fn ix_llcx(llcx: &llvm::Context, num_bits: u64) -> &Type {
ty!(llvm::LLVMIntTypeInContext(llcx, num_bits as c_uint)) unsafe {
llvm::LLVMIntTypeInContext(llcx, num_bits as c_uint)
}
} }
pub fn f32(cx: &CodegenCx) -> Type { pub fn f32(cx: &CodegenCx<'ll, '_>) -> &'ll Type {
ty!(llvm::LLVMFloatTypeInContext(cx.llcx)) unsafe {
llvm::LLVMFloatTypeInContext(cx.llcx)
}
} }
pub fn f64(cx: &CodegenCx) -> Type { pub fn f64(cx: &CodegenCx<'ll, '_>) -> &'ll Type {
ty!(llvm::LLVMDoubleTypeInContext(cx.llcx)) unsafe {
llvm::LLVMDoubleTypeInContext(cx.llcx)
}
} }
pub fn bool(cx: &CodegenCx) -> Type { pub fn bool(cx: &CodegenCx<'ll, '_>) -> &'ll Type {
Type::i8(cx) Type::i8(cx)
} }
pub fn char(cx: &CodegenCx) -> Type { pub fn char(cx: &CodegenCx<'ll, '_>) -> &'ll Type {
Type::i32(cx) Type::i32(cx)
} }
pub fn i8p(cx: &CodegenCx) -> Type { pub fn i8p(cx: &CodegenCx<'ll, '_>) -> &'ll Type {
Type::i8(cx).ptr_to() Type::i8(cx).ptr_to()
} }
pub fn i8p_llcx(llcx: &llvm::Context) -> Type { pub fn i8p_llcx(llcx: &llvm::Context) -> &Type {
Type::i8_llcx(llcx).ptr_to() Type::i8_llcx(llcx).ptr_to()
} }
pub fn isize(cx: &CodegenCx) -> Type { pub fn isize(cx: &CodegenCx<'ll, '_>) -> &'ll Type {
cx.isize_ty cx.isize_ty
} }
pub fn c_int(cx: &CodegenCx) -> Type { pub fn c_int(cx: &CodegenCx<'ll, '_>) -> &'ll Type {
match &cx.tcx.sess.target.target.target_c_int_width[..] { match &cx.tcx.sess.target.target.target_c_int_width[..] {
"16" => Type::i16(cx), "16" => Type::i16(cx),
"32" => Type::i32(cx), "32" => Type::i32(cx),
@ -144,7 +150,7 @@ impl Type {
} }
} }
pub fn int_from_ty(cx: &CodegenCx, t: ast::IntTy) -> Type { pub fn int_from_ty(cx: &CodegenCx<'ll, '_>, t: ast::IntTy) -> &'ll Type {
match t { match t {
ast::IntTy::Isize => cx.isize_ty, ast::IntTy::Isize => cx.isize_ty,
ast::IntTy::I8 => Type::i8(cx), ast::IntTy::I8 => Type::i8(cx),
@ -155,7 +161,7 @@ impl Type {
} }
} }
pub fn uint_from_ty(cx: &CodegenCx, t: ast::UintTy) -> Type { pub fn uint_from_ty(cx: &CodegenCx<'ll, '_>, t: ast::UintTy) -> &'ll Type {
match t { match t {
ast::UintTy::Usize => cx.isize_ty, ast::UintTy::Usize => cx.isize_ty,
ast::UintTy::U8 => Type::i8(cx), ast::UintTy::U8 => Type::i8(cx),
@ -166,83 +172,93 @@ impl Type {
} }
} }
pub fn float_from_ty(cx: &CodegenCx, t: ast::FloatTy) -> Type { pub fn float_from_ty(cx: &CodegenCx<'ll, '_>, t: ast::FloatTy) -> &'ll Type {
match t { match t {
ast::FloatTy::F32 => Type::f32(cx), ast::FloatTy::F32 => Type::f32(cx),
ast::FloatTy::F64 => Type::f64(cx), ast::FloatTy::F64 => Type::f64(cx),
} }
} }
pub fn func(args: &[Type], ret: &Type) -> Type { pub fn func(args: &[&'ll Type], ret: &'ll Type) -> &'ll Type {
let slice: &[TypeRef] = Type::to_ref_slice(args); unsafe {
ty!(llvm::LLVMFunctionType(ret.to_ref(), slice.as_ptr(), llvm::LLVMFunctionType(ret, args.as_ptr(),
args.len() as c_uint, False)) args.len() as c_uint, False)
}
} }
pub fn variadic_func(args: &[Type], ret: &Type) -> Type { pub fn variadic_func(args: &[&'ll Type], ret: &'ll Type) -> &'ll Type {
let slice: &[TypeRef] = Type::to_ref_slice(args); unsafe {
ty!(llvm::LLVMFunctionType(ret.to_ref(), slice.as_ptr(), llvm::LLVMFunctionType(ret, args.as_ptr(),
args.len() as c_uint, True)) args.len() as c_uint, True)
}
} }
pub fn struct_(cx: &CodegenCx, els: &[Type], packed: bool) -> Type { pub fn struct_(cx: &CodegenCx<'ll, '_>, els: &[&'ll Type], packed: bool) -> &'ll Type {
let els: &[TypeRef] = Type::to_ref_slice(els); unsafe {
ty!(llvm::LLVMStructTypeInContext(cx.llcx, els.as_ptr(), llvm::LLVMStructTypeInContext(cx.llcx, els.as_ptr(),
els.len() as c_uint, els.len() as c_uint,
packed as Bool)) packed as Bool)
}
} }
pub fn named_struct(cx: &CodegenCx, name: &str) -> Type { pub fn named_struct(cx: &CodegenCx<'ll, '_>, name: &str) -> &'ll Type {
let name = CString::new(name).unwrap(); let name = CString::new(name).unwrap();
ty!(llvm::LLVMStructCreateNamed(cx.llcx, name.as_ptr())) unsafe {
llvm::LLVMStructCreateNamed(cx.llcx, name.as_ptr())
}
} }
pub fn array(ty: &Type, len: u64) -> Type { pub fn array(ty: &Type, len: u64) -> &Type {
ty!(llvm::LLVMRustArrayType(ty.to_ref(), len)) unsafe {
llvm::LLVMRustArrayType(ty, len)
}
} }
pub fn vector(ty: &Type, len: u64) -> Type { pub fn vector(ty: &Type, len: u64) -> &Type {
ty!(llvm::LLVMVectorType(ty.to_ref(), len as c_uint)) unsafe {
llvm::LLVMVectorType(ty, len as c_uint)
}
} }
pub fn kind(&self) -> TypeKind { pub fn kind(&self) -> TypeKind {
unsafe { unsafe {
llvm::LLVMRustGetTypeKind(self.to_ref()) llvm::LLVMRustGetTypeKind(self)
} }
} }
pub fn set_struct_body(&mut self, els: &[Type], packed: bool) { pub fn set_struct_body(&'ll self, els: &[&'ll Type], packed: bool) {
let slice: &[TypeRef] = Type::to_ref_slice(els);
unsafe { unsafe {
llvm::LLVMStructSetBody(self.to_ref(), slice.as_ptr(), llvm::LLVMStructSetBody(self, els.as_ptr(),
els.len() as c_uint, packed as Bool) els.len() as c_uint, packed as Bool)
} }
} }
pub fn ptr_to(&self) -> Type { pub fn ptr_to(&self) -> &Type {
ty!(llvm::LLVMPointerType(self.to_ref(), 0)) unsafe {
llvm::LLVMPointerType(self, 0)
}
} }
pub fn element_type(&self) -> Type { pub fn element_type(&self) -> &Type {
unsafe { unsafe {
Type::from_ref(llvm::LLVMGetElementType(self.to_ref())) llvm::LLVMGetElementType(self)
} }
} }
/// Return the number of elements in `self` if it is a LLVM vector type. /// Return the number of elements in `self` if it is a LLVM vector type.
pub fn vector_length(&self) -> usize { pub fn vector_length(&self) -> usize {
unsafe { unsafe {
llvm::LLVMGetVectorSize(self.to_ref()) as usize llvm::LLVMGetVectorSize(self) as usize
} }
} }
pub fn func_params(&self) -> Vec<Type> { pub fn func_params(&self) -> Vec<&Type> {
unsafe { unsafe {
let n_args = llvm::LLVMCountParamTypes(self.to_ref()) as usize; let n_args = llvm::LLVMCountParamTypes(self) as usize;
let mut args = vec![Type { rf: 0 as *mut _ }; n_args]; let mut args = Vec::with_capacity(n_args);
llvm::LLVMGetParamTypes(self.to_ref(), llvm::LLVMGetParamTypes(self, args.as_mut_ptr());
args.as_mut_ptr() as *mut TypeRef); args.set_len(n_args);
args args
} }
} }
@ -260,11 +276,11 @@ impl Type {
/// Retrieve the bit width of the integer type `self`. /// Retrieve the bit width of the integer type `self`.
pub fn int_width(&self) -> u64 { pub fn int_width(&self) -> u64 {
unsafe { unsafe {
llvm::LLVMGetIntTypeWidth(self.to_ref()) as u64 llvm::LLVMGetIntTypeWidth(self) as u64
} }
} }
pub fn from_integer(cx: &CodegenCx, i: layout::Integer) -> Type { pub fn from_integer(cx: &CodegenCx<'ll, '_>, i: layout::Integer) -> &'ll Type {
use rustc::ty::layout::Integer::*; use rustc::ty::layout::Integer::*;
match i { match i {
I8 => Type::i8(cx), I8 => Type::i8(cx),
@ -277,7 +293,7 @@ impl Type {
/// Return a LLVM type that has at most the required alignment, /// Return a LLVM type that has at most the required alignment,
/// as a conservative approximation for unknown pointee types. /// as a conservative approximation for unknown pointee types.
pub fn pointee_for_abi_align(cx: &CodegenCx, align: Align) -> Type { pub fn pointee_for_abi_align(cx: &CodegenCx<'ll, '_>, align: Align) -> &'ll Type {
// FIXME(eddyb) We could find a better approximation if ity.align < align. // FIXME(eddyb) We could find a better approximation if ity.align < align.
let ity = layout::Integer::approximate_abi_align(cx, align); let ity = layout::Integer::approximate_abi_align(cx, align);
Type::from_integer(cx, ity) Type::from_integer(cx, ity)
@ -285,15 +301,17 @@ impl Type {
/// Return a LLVM type that has at most the required alignment, /// Return a LLVM type that has at most the required alignment,
/// and exactly the required size, as a best-effort padding array. /// and exactly the required size, as a best-effort padding array.
pub fn padding_filler(cx: &CodegenCx, size: Size, align: Align) -> Type { pub fn padding_filler(cx: &CodegenCx<'ll, '_>, size: Size, align: Align) -> &'ll Type {
let unit = layout::Integer::approximate_abi_align(cx, align); let unit = layout::Integer::approximate_abi_align(cx, align);
let size = size.bytes(); let size = size.bytes();
let unit_size = unit.size().bytes(); let unit_size = unit.size().bytes();
assert_eq!(size % unit_size, 0); assert_eq!(size % unit_size, 0);
Type::array(&Type::from_integer(cx, unit), size / unit_size) Type::array(Type::from_integer(cx, unit), size / unit_size)
} }
pub fn x86_mmx(cx: &CodegenCx) -> Type { pub fn x86_mmx(cx: &CodegenCx<'ll, '_>) -> &'ll Type {
ty!(llvm::LLVMX86MMXTypeInContext(cx.llcx)) unsafe {
llvm::LLVMX86MMXTypeInContext(cx.llcx)
}
} }
} }

View File

@ -23,8 +23,8 @@ use std::fmt::Write;
fn uncached_llvm_type<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>, fn uncached_llvm_type<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>,
layout: TyLayout<'tcx>, layout: TyLayout<'tcx>,
defer: &mut Option<(Type, TyLayout<'tcx>)>) defer: &mut Option<(&'a Type, TyLayout<'tcx>)>)
-> Type { -> &'a Type {
match layout.abi { match layout.abi {
layout::Abi::Scalar(_) => bug!("handled elsewhere"), layout::Abi::Scalar(_) => bug!("handled elsewhere"),
layout::Abi::Vector { ref element, count } => { layout::Abi::Vector { ref element, count } => {
@ -42,7 +42,7 @@ fn uncached_llvm_type<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>,
return Type::x86_mmx(cx) return Type::x86_mmx(cx)
} else { } else {
let element = layout.scalar_llvm_type_at(cx, element, Size::ZERO); let element = layout.scalar_llvm_type_at(cx, element, Size::ZERO);
return Type::vector(&element, count); return Type::vector(element, count);
} }
} }
layout::Abi::ScalarPair(..) => { layout::Abi::ScalarPair(..) => {
@ -96,7 +96,7 @@ fn uncached_llvm_type<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>,
} }
} }
layout::FieldPlacement::Array { count, .. } => { layout::FieldPlacement::Array { count, .. } => {
Type::array(&layout.field(cx, 0).llvm_type(cx), count) Type::array(layout.field(cx, 0).llvm_type(cx), count)
} }
layout::FieldPlacement::Arbitrary { .. } => { layout::FieldPlacement::Arbitrary { .. } => {
match name { match name {
@ -116,14 +116,14 @@ fn uncached_llvm_type<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>,
fn struct_llfields<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>, fn struct_llfields<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>,
layout: TyLayout<'tcx>) layout: TyLayout<'tcx>)
-> (Vec<Type>, bool) { -> (Vec<&'a Type>, bool) {
debug!("struct_llfields: {:#?}", layout); debug!("struct_llfields: {:#?}", layout);
let field_count = layout.fields.count(); let field_count = layout.fields.count();
let mut packed = false; let mut packed = false;
let mut offset = Size::ZERO; let mut offset = Size::ZERO;
let mut prev_align = layout.align; let mut prev_align = layout.align;
let mut result: Vec<Type> = Vec::with_capacity(1 + field_count * 2); let mut result: Vec<_> = Vec::with_capacity(1 + field_count * 2);
for i in layout.fields.index_by_increasing_offset() { for i in layout.fields.index_by_increasing_offset() {
let field = layout.field(cx, i); let field = layout.field(cx, i);
packed |= layout.align.abi() < field.align.abi(); packed |= layout.align.abi() < field.align.abi();
@ -201,12 +201,12 @@ pub struct PointeeInfo {
pub trait LayoutLlvmExt<'tcx> { pub trait LayoutLlvmExt<'tcx> {
fn is_llvm_immediate(&self) -> bool; fn is_llvm_immediate(&self) -> bool;
fn is_llvm_scalar_pair<'a>(&self) -> bool; fn is_llvm_scalar_pair<'a>(&self) -> bool;
fn llvm_type<'a>(&self, cx: &CodegenCx<'a, 'tcx>) -> Type; fn llvm_type<'a>(&self, cx: &CodegenCx<'a, 'tcx>) -> &'a Type;
fn immediate_llvm_type<'a>(&self, cx: &CodegenCx<'a, 'tcx>) -> Type; fn immediate_llvm_type<'a>(&self, cx: &CodegenCx<'a, 'tcx>) -> &'a Type;
fn scalar_llvm_type_at<'a>(&self, cx: &CodegenCx<'a, 'tcx>, fn scalar_llvm_type_at<'a>(&self, cx: &CodegenCx<'a, 'tcx>,
scalar: &layout::Scalar, offset: Size) -> Type; scalar: &layout::Scalar, offset: Size) -> &'a Type;
fn scalar_pair_element_llvm_type<'a>(&self, cx: &CodegenCx<'a, 'tcx>, fn scalar_pair_element_llvm_type<'a>(&self, cx: &CodegenCx<'a, 'tcx>,
index: usize, immediate: bool) -> Type; index: usize, immediate: bool) -> &'a Type;
fn llvm_field_index(&self, index: usize) -> u64; fn llvm_field_index(&self, index: usize) -> u64;
fn pointee_info_at<'a>(&self, cx: &CodegenCx<'a, 'tcx>, offset: Size) fn pointee_info_at<'a>(&self, cx: &CodegenCx<'a, 'tcx>, offset: Size)
-> Option<PointeeInfo>; -> Option<PointeeInfo>;
@ -244,7 +244,7 @@ impl<'tcx> LayoutLlvmExt<'tcx> for TyLayout<'tcx> {
/// with the inner-most trailing unsized field using the "minimal unit" /// with the inner-most trailing unsized field using the "minimal unit"
/// of that field's type - this is useful for taking the address of /// of that field's type - this is useful for taking the address of
/// that field and ensuring the struct has the right alignment. /// that field and ensuring the struct has the right alignment.
fn llvm_type<'a>(&self, cx: &CodegenCx<'a, 'tcx>) -> Type { fn llvm_type<'a>(&self, cx: &CodegenCx<'a, 'tcx>) -> &'a Type {
if let layout::Abi::Scalar(ref scalar) = self.abi { if let layout::Abi::Scalar(ref scalar) = self.abi {
// Use a different cache for scalars because pointers to DSTs // Use a different cache for scalars because pointers to DSTs
// can be either fat or thin (data pointers of fat pointers). // can be either fat or thin (data pointers of fat pointers).
@ -304,7 +304,7 @@ impl<'tcx> LayoutLlvmExt<'tcx> for TyLayout<'tcx> {
cx.lltypes.borrow_mut().insert((self.ty, variant_index), llty); cx.lltypes.borrow_mut().insert((self.ty, variant_index), llty);
if let Some((mut llty, layout)) = defer { if let Some((llty, layout)) = defer {
let (llfields, packed) = struct_llfields(cx, layout); let (llfields, packed) = struct_llfields(cx, layout);
llty.set_struct_body(&llfields, packed) llty.set_struct_body(&llfields, packed)
} }
@ -312,7 +312,7 @@ impl<'tcx> LayoutLlvmExt<'tcx> for TyLayout<'tcx> {
llty llty
} }
fn immediate_llvm_type<'a>(&self, cx: &CodegenCx<'a, 'tcx>) -> Type { fn immediate_llvm_type<'a>(&self, cx: &CodegenCx<'a, 'tcx>) -> &'a Type {
if let layout::Abi::Scalar(ref scalar) = self.abi { if let layout::Abi::Scalar(ref scalar) = self.abi {
if scalar.is_bool() { if scalar.is_bool() {
return Type::i1(cx); return Type::i1(cx);
@ -322,7 +322,7 @@ impl<'tcx> LayoutLlvmExt<'tcx> for TyLayout<'tcx> {
} }
fn scalar_llvm_type_at<'a>(&self, cx: &CodegenCx<'a, 'tcx>, fn scalar_llvm_type_at<'a>(&self, cx: &CodegenCx<'a, 'tcx>,
scalar: &layout::Scalar, offset: Size) -> Type { scalar: &layout::Scalar, offset: Size) -> &'a Type {
match scalar.value { match scalar.value {
layout::Int(i, _) => Type::from_integer(cx, i), layout::Int(i, _) => Type::from_integer(cx, i),
layout::Float(FloatTy::F32) => Type::f32(cx), layout::Float(FloatTy::F32) => Type::f32(cx),
@ -340,7 +340,7 @@ impl<'tcx> LayoutLlvmExt<'tcx> for TyLayout<'tcx> {
} }
fn scalar_pair_element_llvm_type<'a>(&self, cx: &CodegenCx<'a, 'tcx>, fn scalar_pair_element_llvm_type<'a>(&self, cx: &CodegenCx<'a, 'tcx>,
index: usize, immediate: bool) -> Type { index: usize, immediate: bool) -> &'a Type {
// HACK(eddyb) special-case fat pointers until LLVM removes // HACK(eddyb) special-case fat pointers until LLVM removes
// pointee types, to avoid bitcasting every `OperandRef::deref`. // pointee types, to avoid bitcasting every `OperandRef::deref`.
match self.ty.sty { match self.ty.sty {