}
pub trait LlvmType {
- fn llvm_type(&self, cx: &CodegenCx) -> Type;
+ fn llvm_type(&self, cx: &CodegenCx<'ll, '_>) -> &'ll Type;
}
impl LlvmType for Reg {
- fn llvm_type(&self, cx: &CodegenCx) -> Type {
+ fn llvm_type(&self, cx: &CodegenCx<'ll, '_>) -> &'ll Type {
match self.kind {
RegKind::Integer => Type::ix(cx, self.size.bits()),
RegKind::Float => {
}
}
RegKind::Vector => {
- Type::vector(&Type::i8(cx), self.size.bytes())
+ Type::vector(Type::i8(cx), self.size.bytes())
}
}
}
}
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_count, rem_bytes) = if self.rest.unit.size.bytes() == 0 {
(0, 0)
// Simplify to array when all chunks are the same size and type
if rem_bytes == 0 {
- return Type::array(&rest_ll_unit, rest_count);
+ return Type::array(rest_ll_unit, rest_count);
}
}
}
pub trait ArgTypeExt<'a, 'tcx> {
- fn memory_ty(&self, cx: &CodegenCx<'a, 'tcx>) -> Type;
- fn store(&self, bx: &Builder<'a, 'tcx>, val: ValueRef, dst: PlaceRef<'tcx>);
- fn store_fn_arg(&self, bx: &Builder<'a, 'tcx>, idx: &mut usize, dst: PlaceRef<'tcx>);
+ fn memory_ty(&self, cx: &CodegenCx<'a, 'tcx>) -> &'a Type;
+ fn store(&self, bx: &Builder<'a, 'll, 'tcx>, val: ValueRef, 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>> {
/// 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`.
- fn memory_ty(&self, cx: &CodegenCx<'a, 'tcx>) -> Type {
+ fn memory_ty(&self, cx: &CodegenCx<'a, 'tcx>) -> &'a Type {
self.layout.llvm_type(cx)
}
/// place for the original Rust type of this argument/return.
/// Can be used for both storing formal arguments into Rust variables
/// 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() {
return;
}
}
}
- 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 val = llvm::get_param(bx.llfn(), *idx as c_uint);
*idx += 1;
fn adjust_for_abi(&mut self,
cx: &CodegenCx<'a, 'tcx>,
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 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>> {
}
}
- 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|
if arg.pad.is_some() { 1 } else { 0 } +
if let PassMode::Pair(_, _) = arg.mode { 2 } else { 1 }
}
if self.variadic {
- Type::variadic_func(&llargument_tys, &llreturn_ty)
+ Type::variadic_func(&llargument_tys, llreturn_ty)
} else {
- Type::func(&llargument_tys, &llreturn_ty)
+ Type::func(&llargument_tys, llreturn_ty)
}
}
}
}
- 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 apply = |attrs: &ArgAttributes| {
attrs.apply_callsite(llvm::AttributePlace::Argument(i), callsite);
use libc::{c_uint, c_char};
// Take an inline assembly expression and splat it out via LLVM
-pub fn codegen_inline_asm<'a, 'tcx>(
- bx: &Builder<'a, 'tcx>,
+pub fn codegen_inline_asm(
+ bx: &Builder<'a, 'll, 'tcx>,
ia: &hir::InlineAsm,
outputs: Vec<PlaceRef<'tcx>>,
mut inputs: Vec<ValueRef>
let llconst = C_bytes_in_context(llcx, bitcode.unwrap_or(&[]));
let llglobal = llvm::LLVMAddGlobal(
llmod,
- val_ty(llconst).to_ref(),
+ val_ty(llconst),
"rustc.embedded.module\0".as_ptr() as *const _,
);
llvm::LLVMSetInitializer(llglobal, llconst);
let llconst = C_bytes_in_context(llcx, &[]);
let llglobal = llvm::LLVMAddGlobal(
llmod,
- val_ty(llconst).to_ref(),
+ val_ty(llconst),
"rustc.embedded.cmdline\0".as_ptr() as *const _,
);
llvm::LLVMSetInitializer(llglobal, llconst);
.collect::<Vec<_>>();
for (imp_name, val) in globals {
let imp = llvm::LLVMAddGlobal(llmod,
- i8p_ty.to_ref(),
+ i8p_ty,
imp_name.as_ptr() as *const _);
llvm::LLVMSetInitializer(imp, consts::ptrcast(val, i8p_ty));
llvm::LLVMRustSetLinkage(imp, llvm::Linkage::ExternalLinkage);
//!
//! * 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:
-//! pcwalton). You can, instead, find out its TypeRef by calling val_ty,
-//! but one TypeRef corresponds to many `Ty`s; for instance, tup(int, int,
-//! int) and rec(x=int, y=int, z=int) will have the same TypeRef.
+//! pcwalton). You can, instead, find out its llvm::Type by calling val_ty,
+//! 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 llvm::Type.
use super::ModuleLlvm;
use super::ModuleSource;
use rustc_codegen_utils::check_for_rustc_errors_attr;
-pub struct StatRecorder<'a, 'tcx: 'a> {
- cx: &'a CodegenCx<'a, 'tcx>,
+pub struct StatRecorder<'a, 'll: 'a, 'tcx: 'll> {
+ cx: &'a CodegenCx<'ll, 'tcx>,
name: Option<String>,
istart: usize,
}
-impl<'a, 'tcx> StatRecorder<'a, 'tcx> {
- pub fn new(cx: &'a CodegenCx<'a, 'tcx>, name: String) -> StatRecorder<'a, 'tcx> {
+impl StatRecorder<'a, 'll, 'tcx> {
+ pub fn new(cx: &'a CodegenCx<'ll, 'tcx>, name: String) -> Self {
let istart = cx.stats.borrow().n_llvm_insns;
StatRecorder {
cx,
}
}
-impl<'a, 'tcx> Drop for StatRecorder<'a, 'tcx> {
+impl Drop for StatRecorder<'a, 'll, 'tcx> {
fn drop(&mut self) {
if self.cx.sess().codegen_stats() {
let mut stats = self.cx.stats.borrow_mut();
}
}
-pub fn compare_simd_types<'a, 'tcx>(
- bx: &Builder<'a, 'tcx>,
+pub fn compare_simd_types(
+ bx: &Builder<'a, 'll, 'tcx>,
lhs: ValueRef,
rhs: ValueRef,
t: Ty<'tcx>,
- ret_ty: Type,
+ ret_ty: &'ll Type,
op: hir::BinOpKind
) -> ValueRef {
let signed = match t.sty {
}
/// Coerce `src` to `dst_ty`. `src_ty` must be a thin pointer.
-pub fn unsize_thin_ptr<'a, 'tcx>(
- bx: &Builder<'a, 'tcx>,
+pub fn unsize_thin_ptr(
+ bx: &Builder<'a, 'll, 'tcx>,
src: ValueRef,
src_ty: Ty<'tcx>,
dst_ty: Ty<'tcx>
/// 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`
-pub fn coerce_unsized_into<'a, 'tcx>(bx: &Builder<'a, 'tcx>,
- src: PlaceRef<'tcx>,
- dst: PlaceRef<'tcx>) {
+pub fn coerce_unsized_into(
+ bx: &Builder<'a, 'll, 'tcx>,
+ src: PlaceRef<'tcx>,
+ dst: PlaceRef<'tcx>
+) {
let src_ty = src.layout.ty;
let dst_ty = dst.layout.ty;
let coerce_ptr = || {
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,
rhs: ValueRef,
trunc: F,
zext: G)
-> ValueRef
- where F: FnOnce(ValueRef, Type) -> ValueRef,
- G: FnOnce(ValueRef, Type) -> ValueRef
+ where F: FnOnce(ValueRef, &'ll Type) -> ValueRef,
+ G: FnOnce(ValueRef, &'ll Type) -> ValueRef
{
// Shifts may have any size int on the rhs
if op.is_shift() {
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");
bx.call(assume_intrinsic, &[val], None);
}
bx.call(memcpy, &[dst_ptr, src_ptr, size, align, volatile], None);
}
-pub fn memcpy_ty<'a, 'tcx>(
- bx: &Builder<'a, 'tcx>,
+pub fn memcpy_ty(
+ bx: &Builder<'a, 'll, 'tcx>,
dst: ValueRef,
src: ValueRef,
layout: TyLayout<'tcx>,
call_memcpy(bx, dst, src, C_usize(bx.cx, size), align, flags);
}
-pub fn call_memset<'a, 'tcx>(bx: &Builder<'a, 'tcx>,
- ptr: ValueRef,
- fill_byte: ValueRef,
- size: ValueRef,
- align: ValueRef,
- volatile: bool) -> ValueRef {
+pub fn call_memset(
+ bx: &Builder<'a, 'll, 'tcx>,
+ ptr: ValueRef,
+ fill_byte: ValueRef,
+ size: ValueRef,
+ align: ValueRef,
+ volatile: bool,
+) -> ValueRef {
let ptr_width = &bx.cx.sess().target.target.target_pointer_width;
let intrinsic_key = format!("llvm.memset.p0i8.i{}", ptr_width);
let llintrinsicfn = bx.cx.get_intrinsic(&intrinsic_key);
rust_main: ValueRef,
rust_main_def_id: DefId,
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();
// Given that `main()` has no arguments,
let name = exported_symbols::metadata_symbol_name(tcx);
let buf = CString::new(name).unwrap();
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 {
llvm::LLVMSetInitializer(llglobal, llconst);
// Run replace-all-uses-with for statics that need it
for &(old_g, new_g) in cx.statics_to_rauw.borrow().iter() {
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::LLVMDeleteGlobal(old_g);
}
unsafe {
let g = llvm::LLVMAddGlobal(cx.llmod,
- val_ty(array).to_ref(),
+ val_ty(array),
name.as_ptr());
llvm::LLVMSetInitializer(g, array);
llvm::LLVMRustSetLinkage(g, llvm::Linkage::AppendingLinkage);
// All Builders must have an llfn associated with them
#[must_use]
-pub struct Builder<'a, 'tcx: 'a> {
+pub struct Builder<'a, 'll: 'a, 'tcx: 'll> {
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) {
unsafe {
llvm::LLVMDisposeBuilder(self.llbuilder);
}
}
-impl<'a, 'tcx> Builder<'a, 'tcx> {
- pub fn new_block<'b>(cx: &'a CodegenCx<'a, 'tcx>, llfn: ValueRef, name: &'b str) -> Self {
+impl Builder<'a, 'll, 'tcx> {
+ pub fn new_block<'b>(cx: &'a CodegenCx<'ll, 'tcx>, llfn: ValueRef, name: &'b str) -> Self {
let bx = Builder::with_cx(cx);
let llbb = unsafe {
let name = CString::new(name).unwrap();
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.
let llbuilder = unsafe {
llvm::LLVMCreateBuilderInContext(cx.llcx)
}
}
- 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)
}
}
}
- 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);
bx.position_at_start(unsafe {
llvm::LLVMGetFirstBasicBlock(self.llfn())
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");
unsafe {
let alloca = if name.is_empty() {
- llvm::LLVMBuildAlloca(self.llbuilder, ty.to_ref(), noname())
+ llvm::LLVMBuildAlloca(self.llbuilder, ty, noname())
} else {
let name = CString::new(name).unwrap();
- llvm::LLVMBuildAlloca(self.llbuilder, ty.to_ref(),
+ llvm::LLVMBuildAlloca(self.llbuilder, ty,
name.as_ptr())
};
llvm::LLVMSetAlignment(alloca, align.abi() as c_uint);
}
/* 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");
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");
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");
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");
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");
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");
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");
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");
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");
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");
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");
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");
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");
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");
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");
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");
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");
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");
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");
unsafe {
- llvm::LLVMBuildFPCast(self.llbuilder, val, dest_ty.to_ref(), noname())
+ llvm::LLVMBuildFPCast(self.llbuilder, val, dest_ty, noname())
}
}
}
/* Miscellaneous instructions */
- pub fn empty_phi(&self, ty: Type) -> ValueRef {
+ pub fn empty_phi(&self, ty: &'ll Type) -> ValueRef {
self.count_insn("emptyphi");
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());
let phi = self.empty_phi(ty);
self.count_insn("addincoming");
self.count_insn("inlineasm");
let comment_text = CString::new(comment_text).unwrap();
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,
False)
};
}
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,
dia: AsmDialect) -> ValueRef {
self.count_insn("inlineasm");
}).collect::<Vec<_>>();
debug!("Asm Output Type: {:?}", output);
- let fty = Type::func(&argtys[..], &output);
+ let fty = Type::func(&argtys[..], output);
unsafe {
let v = llvm::LLVMRustInlineAsm(
- fty.to_ref(), asm, cons, volatile, alignstack, dia);
+ fty, asm, cons, volatile, alignstack, dia);
self.call(v, inputs, None)
}
}
}
}
- 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");
unsafe {
- llvm::LLVMBuildVAArg(self.llbuilder, list, ty.to_ref(), noname())
+ llvm::LLVMBuildVAArg(self.llbuilder, list, ty, noname())
}
}
pub fn vector_splat(&self, num_elts: usize, elt: ValueRef) -> ValueRef {
unsafe {
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_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))
}
}
}
}
- 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 {
self.count_insn("landingpad");
unsafe {
- llvm::LLVMBuildLandingPad(self.llbuilder, ty.to_ref(), pers_fn,
+ llvm::LLVMBuildLandingPad(self.llbuilder, ty, pers_fn,
num_clauses as c_uint, noname())
}
}
}
}
-pub fn val_ty(v: ValueRef) -> Type {
+// TODO: use proper lifetime in return type
+pub fn val_ty(v: ValueRef) -> &'static Type {
unsafe {
- Type::from_ref(llvm::LLVMTypeOf(v))
+ llvm::LLVMTypeOf(&*v)
}
}
// LLVM constant constructors.
-pub fn C_null(t: Type) -> ValueRef {
+pub fn C_null(t: &Type) -> ValueRef {
unsafe {
- llvm::LLVMConstNull(t.to_ref())
+ llvm::LLVMConstNull(t)
}
}
-pub fn C_undef(t: Type) -> ValueRef {
+pub fn C_undef(t: &Type) -> ValueRef {
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 {
- 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 {
- 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 {
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())
}
}
}
}
-pub fn C_array(ty: Type, elts: &[ValueRef]) -> ValueRef {
+pub fn C_array(ty: &Type, elts: &[ValueRef]) -> ValueRef {
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);
}
}
// all shifts). For 32- and 64-bit types, this matches the semantics
// of Java. (See related discussion on #1877 and #10183.)
-pub fn build_unchecked_lshift<'a, 'tcx>(
- bx: &Builder<'a, 'tcx>,
+pub fn build_unchecked_lshift(
+ bx: &Builder<'a, 'll, 'tcx>,
lhs: ValueRef,
rhs: ValueRef
) -> ValueRef {
bx.shl(lhs, rhs)
}
-pub fn build_unchecked_rshift<'a, 'tcx>(
- bx: &Builder<'a, 'tcx>, lhs_t: Ty<'tcx>, lhs: ValueRef, rhs: ValueRef
+pub fn build_unchecked_rshift(
+ bx: &Builder<'a, 'll, 'tcx>, lhs_t: Ty<'tcx>, lhs: ValueRef, rhs: ValueRef
) -> ValueRef {
let rhs = base::cast_shift_expr_rhs(bx, hir::BinOpKind::Shr, lhs, rhs);
// #1877, #10183: Ensure that input is always valid
}
}
-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);
bx.and(rhs, shift_mask_val(bx, rhs_llty, rhs_llty, false))
}
-pub fn shift_mask_val<'a, 'tcx>(
- bx: &Builder<'a, 'tcx>,
- llty: Type,
- mask_llty: Type,
+pub fn shift_mask_val(
+ bx: &Builder<'a, 'll, 'tcx>,
+ llty: &'ll Type,
+ mask_llty: &'ll Type,
invert: bool
) -> ValueRef {
let kind = llty.kind();
use std::ffi::{CStr, CString};
-pub fn ptrcast(val: ValueRef, ty: Type) -> ValueRef {
+pub fn ptrcast(val: ValueRef, ty: &Type) -> ValueRef {
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 {
- llvm::LLVMConstBitCast(val, ty.to_ref())
+ llvm::LLVMConstBitCast(val, ty)
}
}
let mut val_llty = val_ty(v);
let v = if val_llty == Type::i1(cx) {
val_llty = Type::i8(cx);
- llvm::LLVMConstZExt(v, val_llty.to_ref())
+ llvm::LLVMConstZExt(v, val_llty)
} else {
v
};
let visibility = llvm::LLVMRustGetVisibility(g);
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::LLVMRustSetVisibility(new_g, visibility);
if attrs.flags.contains(CodegenFnAttrFlags::USED) {
// 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);
}
}
/// See http://llvm.org/docs/LangRef.html#the-llvm-used-global-variable for details
pub used_statics: RefCell<Vec<ValueRef>>,
- pub lltypes: RefCell<FxHashMap<(Ty<'tcx>, Option<usize>), Type>>,
- pub scalar_lltypes: RefCell<FxHashMap<Ty<'tcx>, Type>>,
+ pub lltypes: RefCell<FxHashMap<(Ty<'tcx>, Option<usize>), &'a Type>>,
+ pub scalar_lltypes: RefCell<FxHashMap<Ty<'tcx>, &'a Type>>,
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>>,
} else {
"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)
}
};
}
}
-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 {
&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 {
&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> {
self.tcx
}
}
-impl<'a, 'tcx> LayoutOf for &'a CodegenCx<'a, 'tcx> {
+impl LayoutOf for &'a CodegenCx<'ll, 'tcx> {
type Ty = Ty<'tcx>;
type TyLayout = TyLayout<'tcx>;
macro_rules! ifn {
($name:expr, fn() -> $ret:expr) => (
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);
cx.intrinsics.borrow_mut().insert($name, f.clone());
return Some(f);
);
($name:expr, fn(...) -> $ret:expr) => (
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);
cx.intrinsics.borrow_mut().insert($name, f.clone());
return Some(f);
);
($name:expr, fn($($arg:expr),*) -> $ret:expr) => (
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);
cx.intrinsics.borrow_mut().insert($name, f.clone());
return Some(f);
let t_f32 = Type::f32(cx);
let t_f64 = Type::f64(cx);
- let t_v2f32 = Type::vector(&t_f32, 2);
- let t_v4f32 = Type::vector(&t_f32, 4);
- let t_v8f32 = Type::vector(&t_f32, 8);
- let t_v16f32 = Type::vector(&t_f32, 16);
+ let t_v2f32 = Type::vector(t_f32, 2);
+ let t_v4f32 = Type::vector(t_f32, 4);
+ let t_v8f32 = Type::vector(t_f32, 8);
+ let t_v16f32 = Type::vector(t_f32, 16);
- let t_v2f64 = Type::vector(&t_f64, 2);
- let t_v4f64 = Type::vector(&t_f64, 4);
- let t_v8f64 = Type::vector(&t_f64, 8);
+ let t_v2f64 = Type::vector(t_f64, 2);
+ let t_v4f64 = Type::vector(t_f64, 4);
+ 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.i32", fn(i8p, i8p, t_i32, t_i32, i1) -> void);
let section_contents = b"\x01gdb_load_rust_pretty_printers.py\0";
unsafe {
- let llvm_type = Type::array(&Type::i8(cx),
+ let llvm_type = Type::array(Type::i8(cx),
section_contents.len() as u64);
let section_var = declare::define_global(cx, section_var_name,
}
}
-pub fn declare_local<'a, 'tcx>(bx: &Builder<'a, 'tcx>,
- dbg_context: &FunctionDebugContext,
- variable_name: ast::Name,
- variable_type: Ty<'tcx>,
- scope_metadata: DIScope,
- variable_access: VariableAccess,
- variable_kind: VariableKind,
- span: Span) {
+pub fn declare_local(
+ bx: &Builder<'a, 'll, 'tcx>,
+ dbg_context: &FunctionDebugContext,
+ variable_name: ast::Name,
+ variable_type: Ty<'tcx>,
+ scope_metadata: DIScope,
+ variable_access: VariableAccess,
+ variable_kind: VariableKind,
+ span: Span,
+) {
assert!(!dbg_context.get_ref(span).source_locations_enabled.get());
let cx = bx.cx;
}
#[inline]
-pub fn debug_context<'a, 'tcx>(cx: &'a CodegenCx<'a, 'tcx>)
- -> &'a CrateDebugContext<'a, 'tcx> {
+pub fn debug_context(cx: &'a CodegenCx<'ll, 'tcx>) -> &'a CrateDebugContext<'a, 'tcx> {
cx.dbg_cx.as_ref().unwrap()
}
///
/// If there’s a value with the same name already declared, the function will
/// 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);
let namebuf = CString::new(name).unwrap_or_else(|_|{
bug!("name {:?} contains an interior null byte", name)
});
unsafe {
- llvm::LLVMRustGetOrInsertGlobal(cx.llmod, namebuf.as_ptr(), ty.to_ref())
+ llvm::LLVMRustGetOrInsertGlobal(cx.llmod, namebuf.as_ptr(), ty)
}
}
///
/// If there’s a value with the same name already declared, the function will
/// 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);
let namebuf = CString::new(name).unwrap_or_else(|_|{
bug!("name {:?} contains an interior null byte", name)
});
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);
///
/// If there’s a value with the same name already declared, the function will
/// 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)
}
/// 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
/// to user’s 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() {
None
} else {
use rustc::ty::{self, Ty};
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) {
debug!("calculate size of DST: {}; with lost info: {:?}",
t, Value(info));
/// 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,
/// add them to librustc_codegen_llvm/context.rs
-pub fn codegen_intrinsic_call<'a, 'tcx>(bx: &Builder<'a, 'tcx>,
- callee_ty: Ty<'tcx>,
- fn_ty: &FnType<'tcx, Ty<'tcx>>,
- args: &[OperandRef<'tcx>],
- llresult: ValueRef,
- span: Span) {
+pub fn codegen_intrinsic_call(
+ bx: &Builder<'a, 'll, 'tcx>,
+ callee_ty: Ty<'tcx>,
+ fn_ty: &FnType<'tcx, Ty<'tcx>>,
+ args: &[OperandRef<'tcx>],
+ llresult: ValueRef,
+ span: Span,
+) {
let cx = bx.cx;
let tcx = cx.tcx;
assert_eq!(x.len(), 1);
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::*;
match *t {
Void => vec![Type::void(cx)],
Vector(ref t, ref llvm_elem, length) => {
let t = llvm_elem.as_ref().unwrap_or(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) => {
let elems = contents.iter()
// qux` to be converted into `foo, bar, baz, qux`, integer
// arguments to be truncated as needed and pointers to be
// cast.
- fn modify_as_needed<'a, 'tcx>(bx: &Builder<'a, 'tcx>,
- t: &intrinsics::Type,
- arg: &OperandRef<'tcx>)
- -> Vec<ValueRef>
+ fn modify_as_needed(
+ bx: &Builder<'a, 'll, 'tcx>,
+ t: &intrinsics::Type,
+ arg: &OperandRef<'tcx>,
+ ) -> Vec<ValueRef>
{
match *t {
intrinsics::Type::Aggregate(true, ref contents) => {
}
intrinsics::Type::Vector(_, Some(ref llvm_elem), length) => {
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 => {
// the LLVM intrinsic uses a smaller integer
intrinsics::IntrinsicDef::Named(name) => {
let f = declare::declare_cfn(cx,
name,
- Type::func(&inputs, &outputs));
+ Type::func(&inputs, outputs));
bx.call(f, &llargs, None)
}
};
}
}
-fn copy_intrinsic<'a, 'tcx>(bx: &Builder<'a, 'tcx>,
- allow_overlap: bool,
- volatile: bool,
- ty: Ty<'tcx>,
- dst: ValueRef,
- src: ValueRef,
- count: ValueRef)
- -> ValueRef {
+fn copy_intrinsic(
+ bx: &Builder<'a, 'll, 'tcx>,
+ allow_overlap: bool,
+ volatile: bool,
+ ty: Ty<'tcx>,
+ dst: ValueRef,
+ src: ValueRef,
+ count: ValueRef,
+) -> ValueRef {
let cx = bx.cx;
let (size, align) = cx.size_and_align_of(ty);
let size = C_usize(cx, size.bytes());
None)
}
-fn memset_intrinsic<'a, 'tcx>(
- bx: &Builder<'a, 'tcx>,
+fn memset_intrinsic(
+ bx: &Builder<'a, 'll, 'tcx>,
volatile: bool,
ty: Ty<'tcx>,
dst: ValueRef,
call_memset(bx, dst, val, bx.mul(size, count), align, volatile)
}
-fn try_intrinsic<'a, 'tcx>(
- bx: &Builder<'a, 'tcx>,
+fn try_intrinsic(
+ bx: &Builder<'a, 'll, 'tcx>,
cx: &CodegenCx,
func: ValueRef,
data: ValueRef,
// 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
// as the old ones are still more optimized.
-fn codegen_msvc_try<'a, 'tcx>(bx: &Builder<'a, 'tcx>,
- cx: &CodegenCx,
- func: ValueRef,
- data: ValueRef,
- local_ptr: ValueRef,
- dest: ValueRef) {
+fn codegen_msvc_try(
+ bx: &Builder<'a, 'll, 'tcx>,
+ cx: &CodegenCx,
+ func: ValueRef,
+ data: ValueRef,
+ local_ptr: ValueRef,
+ dest: ValueRef,
+) {
let llfn = get_rust_try_fn(cx, &mut |bx| {
let cx = bx.cx;
// 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
// the right personality function.
-fn codegen_gnu_try<'a, 'tcx>(bx: &Builder<'a, 'tcx>,
- cx: &CodegenCx,
- func: ValueRef,
- data: ValueRef,
- local_ptr: ValueRef,
- dest: ValueRef) {
+fn codegen_gnu_try(
+ bx: &Builder<'a, 'll, 'tcx>,
+ cx: &CodegenCx,
+ func: ValueRef,
+ data: ValueRef,
+ local_ptr: ValueRef,
+ dest: ValueRef,
+) {
let llfn = get_rust_try_fn(cx, &mut |bx| {
let cx = bx.cx;
// 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.
-fn gen_fn<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>,
- name: &str,
- inputs: Vec<Ty<'tcx>>,
- output: Ty<'tcx>,
- codegen: &mut dyn for<'b> FnMut(Builder<'b, 'tcx>))
- -> ValueRef {
+fn gen_fn<'ll, 'tcx>(
+ cx: &CodegenCx<'ll, 'tcx>,
+ name: &str,
+ inputs: Vec<Ty<'tcx>>,
+ output: Ty<'tcx>,
+ 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(
inputs.into_iter(),
output,
// catch exceptions.
//
// This function is only generated once and is then cached.
-fn get_rust_try_fn<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>,
- codegen: &mut dyn for<'b> FnMut(Builder<'b, 'tcx>))
- -> ValueRef {
+fn get_rust_try_fn<'ll, 'tcx>(
+ cx: &CodegenCx<'ll, 'tcx>,
+ codegen: &mut dyn FnMut(Builder<'_, 'll, 'tcx>),
+) -> ValueRef {
if let Some(llfn) = cx.rust_try_fn.get() {
return llfn;
}
span_err!(a, b, E0511, "{}", c);
}
-fn generic_simd_intrinsic<'a, 'tcx>(
- bx: &Builder<'a, 'tcx>,
+fn generic_simd_intrinsic(
+ bx: &Builder<'a, 'll, 'tcx>,
name: &str,
callee_ty: Ty<'tcx>,
args: &[OperandRef<'tcx>],
ret_ty: Ty<'tcx>,
- llret_ty: Type,
+ llret_ty: &'ll Type,
span: Span
) -> Result<ValueRef, ()> {
// macros for error handling:
}
// truncate the mask to a vector of i1s
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);
return Ok(bx.select(m_i1s, args[1].immediate(), args[2].immediate()));
}
- fn simd_simple_float_intrinsic<'a, 'tcx>(name: &str,
- in_elem: &::rustc::ty::TyS,
- in_ty: &::rustc::ty::TyS,
- in_len: usize,
- bx: &Builder<'a, 'tcx>,
- span: Span,
- args: &[OperandRef<'tcx>])
- -> Result<ValueRef, ()> {
+ fn simd_simple_float_intrinsic(
+ name: &str,
+ in_elem: &::rustc::ty::TyS,
+ in_ty: &::rustc::ty::TyS,
+ in_len: usize,
+ bx: &Builder<'a, 'll, 'tcx>,
+ span: Span,
+ args: &[OperandRef<'tcx>],
+ ) -> Result<ValueRef, ()> {
macro_rules! emit_error {
($msg: tt) => {
emit_error!($msg, )
}
}
- fn llvm_vector_ty(cx: &CodegenCx, elem_ty: ty::Ty, vec_len: usize,
- mut no_pointers: usize) -> Type {
+ fn llvm_vector_ty(cx: &CodegenCx<'ll, '_>, elem_ty: ty::Ty, vec_len: usize,
+ mut no_pointers: usize) -> &'ll Type {
// FIXME: use cx.layout_of(ty).llvm_type() ?
let mut elem_ty = match elem_ty.sty {
ty::TyInt(v) => Type::int_from_ty(cx, v),
elem_ty = elem_ty.ptr_to();
no_pointers -= 1;
}
- Type::vector(&elem_ty, vec_len as u64)
+ Type::vector(elem_ty, vec_len as u64)
}
// Truncate the mask vector to a vector of i1s:
let (mask, mask_ty) = {
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)
};
llvm_elem_vec_str, llvm_pointer_vec_str);
let f = declare::declare_cfn(bx.cx, &llvm_intrinsic,
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);
let v = bx.call(f, &[args[1].immediate(), alignment, mask, args[0].immediate()],
None);
// Truncate the mask vector to a vector of i1s:
let (mask, mask_ty) = {
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)
};
Type::func(&[llvm_elem_vec_ty,
llvm_pointer_vec_ty,
alignment_ty,
- mask_ty], &ret_t));
+ mask_ty], ret_t));
llvm::SetUnnamedAddr(f, false);
let v = bx.call(f, &[args[0].immediate(), args[1].immediate(), alignment, mask],
None);
// boolean reductions operate on vectors of i1s:
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)
};
return match in_elem.sty {
// Opaque pointer types
extern { pub type Module; }
extern { pub type Context; }
-extern { pub type Type_opaque; }
-pub type TypeRef = *mut Type_opaque;
+extern { pub type Type; }
extern { pub type Value_opaque; }
pub type ValueRef = *mut Value_opaque;
extern { pub type Metadata_opaque; }
pub fn LLVMRustAppendModuleInlineAsm(M: &Module, Asm: *const c_char);
/// See llvm::LLVMTypeKind::getTypeID.
- pub fn LLVMRustGetTypeKind(Ty: TypeRef) -> TypeKind;
+ pub fn LLVMRustGetTypeKind(Ty: &Type) -> TypeKind;
// Operations on integer types
- pub fn LLVMInt1TypeInContext(C: &Context) -> TypeRef;
- pub fn LLVMInt8TypeInContext(C: &Context) -> TypeRef;
- pub fn LLVMInt16TypeInContext(C: &Context) -> TypeRef;
- pub fn LLVMInt32TypeInContext(C: &Context) -> TypeRef;
- pub fn LLVMInt64TypeInContext(C: &Context) -> TypeRef;
- pub fn LLVMIntTypeInContext(C: &Context, NumBits: c_uint) -> TypeRef;
+ pub fn LLVMInt1TypeInContext(C: &Context) -> &Type;
+ pub fn LLVMInt8TypeInContext(C: &Context) -> &Type;
+ pub fn LLVMInt16TypeInContext(C: &Context) -> &Type;
+ pub fn LLVMInt32TypeInContext(C: &Context) -> &Type;
+ pub fn LLVMInt64TypeInContext(C: &Context) -> &Type;
+ 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
- pub fn LLVMFloatTypeInContext(C: &Context) -> TypeRef;
- pub fn LLVMDoubleTypeInContext(C: &Context) -> TypeRef;
+ pub fn LLVMFloatTypeInContext(C: &Context) -> &Type;
+ pub fn LLVMDoubleTypeInContext(C: &Context) -> &Type;
// Operations on function types
- pub fn LLVMFunctionType(ReturnType: TypeRef,
- ParamTypes: *const TypeRef,
+ pub fn LLVMFunctionType(ReturnType: &'a Type,
+ ParamTypes: *const &'a Type,
ParamCount: c_uint,
IsVarArg: Bool)
- -> TypeRef;
- pub fn LLVMGetReturnType(FunctionTy: TypeRef) -> TypeRef;
- pub fn LLVMCountParamTypes(FunctionTy: TypeRef) -> c_uint;
- pub fn LLVMGetParamTypes(FunctionTy: TypeRef, Dest: *mut TypeRef);
+ -> &'a Type;
+ pub fn LLVMGetReturnType(FunctionTy: &Type) -> &Type;
+ pub fn LLVMCountParamTypes(FunctionTy: &Type) -> c_uint;
+ pub fn LLVMGetParamTypes(FunctionTy: &'a Type, Dest: *mut &'a Type);
// Operations on struct types
- pub fn LLVMStructTypeInContext(C: &Context,
- ElementTypes: *const TypeRef,
+ pub fn LLVMStructTypeInContext(C: &'a Context,
+ ElementTypes: *const &'a Type,
ElementCount: c_uint,
Packed: Bool)
- -> TypeRef;
- pub fn LLVMIsPackedStruct(StructTy: TypeRef) -> Bool;
+ -> &'a Type;
+ pub fn LLVMIsPackedStruct(StructTy: &Type) -> Bool;
// Operations on array, pointer, and vector types (sequence types)
- pub fn LLVMRustArrayType(ElementType: TypeRef, ElementCount: u64) -> TypeRef;
- pub fn LLVMPointerType(ElementType: TypeRef, AddressSpace: c_uint) -> TypeRef;
- pub fn LLVMVectorType(ElementType: TypeRef, ElementCount: c_uint) -> TypeRef;
+ pub fn LLVMRustArrayType(ElementType: &Type, ElementCount: u64) -> &Type;
+ pub fn LLVMPointerType(ElementType: &Type, AddressSpace: c_uint) -> &Type;
+ pub fn LLVMVectorType(ElementType: &Type, ElementCount: c_uint) -> &Type;
- pub fn LLVMGetElementType(Ty: TypeRef) -> TypeRef;
- pub fn LLVMGetVectorSize(VectorTy: TypeRef) -> c_uint;
+ pub fn LLVMGetElementType(Ty: &Type) -> &Type;
+ pub fn LLVMGetVectorSize(VectorTy: &Type) -> c_uint;
// Operations on other types
- pub fn LLVMVoidTypeInContext(C: &Context) -> TypeRef;
- pub fn LLVMX86MMXTypeInContext(C: &Context) -> TypeRef;
- pub fn LLVMRustMetadataTypeInContext(C: &Context) -> TypeRef;
+ pub fn LLVMVoidTypeInContext(C: &Context) -> &Type;
+ pub fn LLVMX86MMXTypeInContext(C: &Context) -> &Type;
+ pub fn LLVMRustMetadataTypeInContext(C: &Context) -> &Type;
// 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 LLVMSetValueName(Val: ValueRef, Name: *const c_char);
pub fn LLVMReplaceAllUsesWith(OldVal: ValueRef, NewVal: ValueRef);
pub fn LLVMGetOperand(Val: ValueRef, Index: c_uint) -> ValueRef;
// 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 LLVMConstFCmp(Pred: RealPredicate, V1: ValueRef, V2: ValueRef) -> ValueRef;
- pub fn LLVMGetUndef(Ty: TypeRef) -> ValueRef;
+ pub fn LLVMGetUndef(Ty: &Type) -> ValueRef;
// Operations on metadata
pub fn LLVMMDStringInContext(C: &Context, Str: *const c_char, SLen: c_uint) -> ValueRef;
pub fn LLVMAddNamedMetadataOperand(M: &Module, Name: *const c_char, Val: ValueRef);
// Operations on scalar constants
- pub fn LLVMConstInt(IntTy: TypeRef, N: c_ulonglong, SignExtend: Bool) -> ValueRef;
- pub fn LLVMConstIntOfArbitraryPrecision(IntTy: TypeRef, Wn: c_uint, Ws: *const u64) -> ValueRef;
+ pub fn LLVMConstInt(IntTy: &Type, N: c_ulonglong, SignExtend: Bool) -> ValueRef;
+ pub fn LLVMConstIntOfArbitraryPrecision(IntTy: &Type, Wn: c_uint, Ws: *const u64) -> ValueRef;
pub fn LLVMConstIntGetZExtValue(ConstantVal: ValueRef) -> c_ulonglong;
pub fn LLVMConstIntGetSExtValue(ConstantVal: ValueRef) -> c_longlong;
pub fn LLVMRustConstInt128Get(ConstantVal: ValueRef, SExt: bool,
Packed: Bool)
-> ValueRef;
- pub fn LLVMConstArray(ElementTy: TypeRef,
+ pub fn LLVMConstArray(ElementTy: &Type,
ConstantVals: *const ValueRef,
Length: c_uint)
-> ValueRef;
pub fn LLVMConstVector(ScalarConstantVals: *const ValueRef, Size: c_uint) -> ValueRef;
// Constant expressions
- pub fn LLVMSizeOf(Ty: TypeRef) -> ValueRef;
+ pub fn LLVMSizeOf(Ty: &Type) -> ValueRef;
pub fn LLVMConstNeg(ConstantVal: ValueRef) -> ValueRef;
pub fn LLVMConstFNeg(ConstantVal: ValueRef) -> ValueRef;
pub fn LLVMConstNot(ConstantVal: ValueRef) -> ValueRef;
ConstantIndices: *const ValueRef,
NumIndices: c_uint,
) -> ValueRef;
- pub fn LLVMConstTrunc(ConstantVal: ValueRef, ToType: TypeRef) -> ValueRef;
- pub fn LLVMConstZExt(ConstantVal: ValueRef, ToType: TypeRef) -> ValueRef;
- pub fn LLVMConstUIToFP(ConstantVal: ValueRef, ToType: TypeRef) -> ValueRef;
- pub fn LLVMConstSIToFP(ConstantVal: ValueRef, ToType: TypeRef) -> ValueRef;
- pub fn LLVMConstFPToUI(ConstantVal: ValueRef, ToType: TypeRef) -> ValueRef;
- pub fn LLVMConstFPToSI(ConstantVal: ValueRef, ToType: TypeRef) -> ValueRef;
- pub fn LLVMConstPtrToInt(ConstantVal: ValueRef, ToType: TypeRef) -> ValueRef;
- pub fn LLVMConstIntToPtr(ConstantVal: ValueRef, ToType: TypeRef) -> ValueRef;
- pub fn LLVMConstBitCast(ConstantVal: ValueRef, ToType: TypeRef) -> ValueRef;
- pub fn LLVMConstPointerCast(ConstantVal: ValueRef, ToType: TypeRef) -> ValueRef;
- pub fn LLVMConstIntCast(ConstantVal: ValueRef, ToType: TypeRef, isSigned: Bool) -> ValueRef;
- pub fn LLVMConstFPCast(ConstantVal: ValueRef, ToType: TypeRef) -> ValueRef;
+ pub fn LLVMConstTrunc(ConstantVal: ValueRef, ToType: &Type) -> ValueRef;
+ pub fn LLVMConstZExt(ConstantVal: ValueRef, ToType: &Type) -> ValueRef;
+ pub fn LLVMConstUIToFP(ConstantVal: ValueRef, ToType: &Type) -> ValueRef;
+ pub fn LLVMConstSIToFP(ConstantVal: ValueRef, ToType: &Type) -> ValueRef;
+ pub fn LLVMConstFPToUI(ConstantVal: ValueRef, ToType: &Type) -> ValueRef;
+ pub fn LLVMConstFPToSI(ConstantVal: ValueRef, ToType: &Type) -> ValueRef;
+ pub fn LLVMConstPtrToInt(ConstantVal: ValueRef, ToType: &Type) -> ValueRef;
+ pub fn LLVMConstIntToPtr(ConstantVal: ValueRef, ToType: &Type) -> ValueRef;
+ pub fn LLVMConstBitCast(ConstantVal: ValueRef, ToType: &Type) -> ValueRef;
+ pub fn LLVMConstPointerCast(ConstantVal: ValueRef, ToType: &Type) -> ValueRef;
+ pub fn LLVMConstIntCast(ConstantVal: ValueRef, ToType: &Type, isSigned: Bool) -> ValueRef;
+ pub fn LLVMConstFPCast(ConstantVal: ValueRef, ToType: &Type) -> ValueRef;
pub fn LLVMConstExtractValue(AggConstant: ValueRef,
IdxList: *const c_uint,
NumIdx: c_uint)
-> ValueRef;
- pub fn LLVMConstInlineAsm(Ty: TypeRef,
+ pub fn LLVMConstInlineAsm(Ty: &Type,
AsmString: *const c_char,
Constraints: *const c_char,
HasSideEffects: Bool,
// Operations on global variables
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 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 LLVMGetNextGlobal(GlobalVar: ValueRef) -> ValueRef;
pub fn LLVMDeleteGlobal(GlobalVar: ValueRef);
pub fn LLVMSetTailCall(CallInst: ValueRef, IsTailCall: Bool);
// 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 LLVMGetFirstFunction(M: &Module) -> ValueRef;
pub fn LLVMGetNextFunction(Fn: ValueRef) -> ValueRef;
pub fn LLVMRustGetOrInsertFunction(M: &Module,
Name: *const c_char,
- FunctionTy: TypeRef)
+ FunctionTy: &Type)
-> ValueRef;
pub fn LLVMSetFunctionCallConv(Fn: ValueRef, CC: c_uint);
pub fn LLVMRustAddAlignmentAttr(Fn: ValueRef, index: c_uint, bytes: u32);
Name: *const c_char)
-> ValueRef;
pub fn LLVMBuildLandingPad(B: BuilderRef,
- Ty: TypeRef,
+ Ty: &Type,
PersFn: ValueRef,
NumClauses: c_uint,
Name: *const c_char)
pub fn LLVMRustSetHasUnsafeAlgebra(Instr: ValueRef);
// 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 LLVMBuildLoad(B: BuilderRef, PointerVal: ValueRef, Name: *const c_char) -> ValueRef;
// Casts
pub fn LLVMBuildTrunc(B: BuilderRef,
Val: ValueRef,
- DestTy: TypeRef,
+ DestTy: &Type,
Name: *const c_char)
-> ValueRef;
pub fn LLVMBuildZExt(B: BuilderRef,
Val: ValueRef,
- DestTy: TypeRef,
+ DestTy: &Type,
Name: *const c_char)
-> ValueRef;
pub fn LLVMBuildSExt(B: BuilderRef,
Val: ValueRef,
- DestTy: TypeRef,
+ DestTy: &Type,
Name: *const c_char)
-> ValueRef;
pub fn LLVMBuildFPToUI(B: BuilderRef,
Val: ValueRef,
- DestTy: TypeRef,
+ DestTy: &Type,
Name: *const c_char)
-> ValueRef;
pub fn LLVMBuildFPToSI(B: BuilderRef,
Val: ValueRef,
- DestTy: TypeRef,
+ DestTy: &Type,
Name: *const c_char)
-> ValueRef;
pub fn LLVMBuildUIToFP(B: BuilderRef,
Val: ValueRef,
- DestTy: TypeRef,
+ DestTy: &Type,
Name: *const c_char)
-> ValueRef;
pub fn LLVMBuildSIToFP(B: BuilderRef,
Val: ValueRef,
- DestTy: TypeRef,
+ DestTy: &Type,
Name: *const c_char)
-> ValueRef;
pub fn LLVMBuildFPTrunc(B: BuilderRef,
Val: ValueRef,
- DestTy: TypeRef,
+ DestTy: &Type,
Name: *const c_char)
-> ValueRef;
pub fn LLVMBuildFPExt(B: BuilderRef,
Val: ValueRef,
- DestTy: TypeRef,
+ DestTy: &Type,
Name: *const c_char)
-> ValueRef;
pub fn LLVMBuildPtrToInt(B: BuilderRef,
Val: ValueRef,
- DestTy: TypeRef,
+ DestTy: &Type,
Name: *const c_char)
-> ValueRef;
pub fn LLVMBuildIntToPtr(B: BuilderRef,
Val: ValueRef,
- DestTy: TypeRef,
+ DestTy: &Type,
Name: *const c_char)
-> ValueRef;
pub fn LLVMBuildBitCast(B: BuilderRef,
Val: ValueRef,
- DestTy: TypeRef,
+ DestTy: &Type,
Name: *const c_char)
-> ValueRef;
pub fn LLVMBuildZExtOrBitCast(B: BuilderRef,
Val: ValueRef,
- DestTy: TypeRef,
+ DestTy: &Type,
Name: *const c_char)
-> ValueRef;
pub fn LLVMBuildSExtOrBitCast(B: BuilderRef,
Val: ValueRef,
- DestTy: TypeRef,
+ DestTy: &Type,
Name: *const c_char)
-> ValueRef;
pub fn LLVMBuildTruncOrBitCast(B: BuilderRef,
Val: ValueRef,
- DestTy: TypeRef,
+ DestTy: &Type,
Name: *const c_char)
-> ValueRef;
pub fn LLVMBuildCast(B: BuilderRef,
Op: Opcode,
Val: ValueRef,
- DestTy: TypeRef,
+ DestTy: &Type,
Name: *const c_char)
-> ValueRef;
pub fn LLVMBuildPointerCast(B: BuilderRef,
Val: ValueRef,
- DestTy: TypeRef,
+ DestTy: &Type,
Name: *const c_char)
-> ValueRef;
pub fn LLVMRustBuildIntCast(B: BuilderRef,
Val: ValueRef,
- DestTy: TypeRef,
+ DestTy: &Type,
IsSized: bool)
-> ValueRef;
pub fn LLVMBuildFPCast(B: BuilderRef,
Val: ValueRef,
- DestTy: TypeRef,
+ DestTy: &Type,
Name: *const c_char)
-> ValueRef;
-> ValueRef;
// 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,
Fn: ValueRef,
Args: *const ValueRef,
-> ValueRef;
pub fn LLVMBuildVAArg(B: BuilderRef,
list: ValueRef,
- Ty: TypeRef,
+ Ty: &Type,
Name: *const c_char)
-> ValueRef;
pub fn LLVMBuildExtractElement(B: BuilderRef,
/// Print the pass timings since static dtors aren't picking them up.
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,
- ElementTypes: *const TypeRef,
+ pub fn LLVMStructSetBody(StructTy: &'a Type,
+ ElementTypes: *const &'a Type,
ElementCount: c_uint,
Packed: Bool);
/// Prepares inline assembly.
- pub fn LLVMRustInlineAsm(Ty: TypeRef,
+ pub fn LLVMRustInlineAsm(Ty: &Type,
AsmString: *const c_char,
Constraints: *const c_char,
SideEffects: Bool,
pub fn LLVMRustDIBuilderCreateOpDeref() -> 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 LLVMIsAConstantInt(value_ref: ValueRef) -> ValueRef;
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,
fn_ty: &FnType<'tcx, Ty<'tcx>>) -> ValueRef {
// Load the data pointer from the object.
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.
debug!("get_int({:?}, {:?})", Value(llvtable), self);
use type_of::LayoutLlvmExt;
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 mut analyzer = LocalAnalyzer::new(fx);
analyzer.non_ssa_locals
}
-struct LocalAnalyzer<'mir, 'a: 'mir, 'tcx: 'a> {
- fx: &'mir FunctionCx<'a, 'tcx>,
+struct LocalAnalyzer<'mir, 'a: 'mir, 'll: 'a, 'tcx: 'll> {
+ fx: &'mir FunctionCx<'a, 'll, 'tcx>,
dominators: Dominators<mir::BasicBlock>,
non_ssa_locals: BitVector<mir::Local>,
// The location of the first visited direct assignment to each
first_assignment: IndexVec<mir::Local, Location>
}
-impl<'mir, 'a, 'tcx> LocalAnalyzer<'mir, 'a, 'tcx> {
- fn new(fx: &'mir FunctionCx<'a, 'tcx>) -> LocalAnalyzer<'mir, 'a, 'tcx> {
+impl LocalAnalyzer<'mir, 'a, 'll, 'tcx> {
+ fn new(fx: &'mir FunctionCx<'a, 'll, 'tcx>) -> Self {
let invalid_location =
mir::BasicBlock::new(fx.mir.basic_blocks().len()).start_location();
let mut analyzer = LocalAnalyzer {
}
}
-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,
block: mir::BasicBlock,
place: &mir::Place<'tcx>,
use super::operand::OperandRef;
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) {
let mut bx = self.build_block(bb);
let data = &self.mir[bb];
}
fn codegen_terminator(&mut self,
- mut bx: Builder<'a, 'tcx>,
+ mut bx: Builder<'a, 'll, 'tcx>,
bb: mir::BasicBlock,
terminator: &mir::Terminator<'tcx>)
{
let do_call = |
this: &mut Self,
- bx: Builder<'a, 'tcx>,
+ bx: Builder<'a, 'll, 'tcx>,
fn_ty: FnType<'tcx, Ty<'tcx>>,
fn_ptr: ValueRef,
llargs: &[ValueRef],
}
fn codegen_argument(&mut self,
- bx: &Builder<'a, 'tcx>,
+ bx: &Builder<'a, 'll, 'tcx>,
op: OperandRef<'tcx>,
llargs: &mut Vec<ValueRef>,
arg: &ArgType<'tcx, Ty<'tcx>>) {
}
fn codegen_arguments_untupled(&mut self,
- bx: &Builder<'a, 'tcx>,
+ bx: &Builder<'a, 'll, 'tcx>,
operand: &mir::Operand<'tcx>,
llargs: &mut Vec<ValueRef>,
args: &[ArgType<'tcx, Ty<'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;
if let Some(slot) = self.personality_slot {
slot
bx.llbb()
}
- fn landing_pad_type(&self) -> Type {
+ fn landing_pad_type(&self) -> &'ll Type {
let cx = self.cx;
Type::struct_(cx, &[Type::i8p(cx), Type::i32(cx)], false)
}
})
}
- 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)
}
- 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);
bx.position_at_end(self.blocks[bb]);
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>>,
llargs: &mut Vec<ValueRef>, is_intrinsic: bool)
-> ReturnDest<'tcx> {
}
}
- fn codegen_transmute(&mut self, bx: &Builder<'a, 'tcx>,
+ fn codegen_transmute(&mut self, bx: &Builder<'a, 'll, 'tcx>,
src: &mir::Operand<'tcx>,
dst: &mir::Place<'tcx>) {
if let mir::Place::Local(index) = *dst {
}
}
- 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>,
dst: PlaceRef<'tcx>) {
let src = self.codegen_operand(bx, src);
// Stores the return value of a function call into it's final location.
fn store_return(&mut self,
- bx: &Builder<'a, 'tcx>,
+ bx: &Builder<'a, 'll, 'tcx>,
dest: ReturnDest<'tcx>,
ret_ty: &ArgType<'tcx, Ty<'tcx>>,
llval: ValueRef) {
pub fn scalar_to_llvm(cx: &CodegenCx,
cv: Scalar,
layout: &layout::Scalar,
- llty: Type) -> ValueRef {
+ llty: &Type) -> ValueRef {
let bitsize = if layout.is_bool() { 1 } else { layout.value.size(cx).bits() };
match cv {
Scalar::Bits { defined, .. } if (defined as u64) < bitsize || defined == 0 => {
Scalar::Bits { bits, .. } => {
let llval = C_uint_big(Type::ix(cx, bitsize), bits);
if layout.value == layout::Pointer {
- unsafe { llvm::LLVMConstIntToPtr(llval, llty.to_ref()) }
+ unsafe { llvm::LLVMConstIntToPtr(llval, llty) }
} else {
consts::bitcast(llval, llty)
}
1,
) };
if layout.value != layout::Pointer {
- unsafe { llvm::LLVMConstPtrToInt(llval, llty.to_ref()) }
+ unsafe { llvm::LLVMConstPtrToInt(llval, llty) }
} else {
consts::bitcast(llval, llty)
}
Ok((const_alloc_to_llvm(cx, alloc), alloc))
}
-impl<'a, 'tcx> FunctionCx<'a, 'tcx> {
+impl FunctionCx<'a, 'll, 'tcx> {
fn fully_evaluate(
&mut self,
- bx: &Builder<'a, 'tcx>,
+ bx: &Builder<'a, 'll, 'tcx>,
constant: &'tcx ty::Const<'tcx>,
) -> Result<&'tcx ty::Const<'tcx>, Lrc<ConstEvalErr<'tcx>>> {
match constant.val {
pub fn eval_mir_constant(
&mut self,
- bx: &Builder<'a, 'tcx>,
+ bx: &Builder<'a, 'll, 'tcx>,
constant: &mir::Constant<'tcx>,
) -> Result<&'tcx ty::Const<'tcx>, Lrc<ConstEvalErr<'tcx>>> {
let c = self.monomorphize(&constant.literal);
/// process constant containing SIMD shuffle indices
pub fn simd_shuffle_indices(
&mut self,
- bx: &Builder<'a, 'tcx>,
+ bx: &Builder<'a, 'll, 'tcx>,
span: Span,
ty: Ty<'tcx>,
constant: Result<&'tcx ty::Const<'tcx>, Lrc<ConstEvalErr<'tcx>>>,
use self::operand::{OperandRef, OperandValue};
/// Master context for codegenning from MIR.
-pub struct FunctionCx<'a, 'tcx:'a> {
+pub struct FunctionCx<'a, 'll: 'a, 'tcx: 'll> {
instance: Instance<'tcx>,
mir: &'a mir::Mir<'tcx>,
llfn: ValueRef,
- cx: &'a CodegenCx<'a, 'tcx>,
+ cx: &'a CodegenCx<'ll, 'tcx>,
fn_ty: FnType<'tcx, Ty<'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
where T: TypeFoldable<'tcx>
{
///////////////////////////////////////////////////////////////////////////
-pub fn codegen_mir<'a, 'tcx: 'a>(
- cx: &'a CodegenCx<'a, 'tcx>,
+pub fn codegen_mir(
+ cx: &'a CodegenCx<'ll, 'tcx>,
llfn: ValueRef,
mir: &'a Mir<'tcx>,
instance: Instance<'tcx>,
}
}
-fn create_funclets<'a, 'tcx>(
+fn create_funclets(
mir: &'a Mir<'tcx>,
- bx: &Builder<'a, 'tcx>,
+ bx: &Builder<'a, 'll, 'tcx>,
cleanup_kinds: &IndexVec<mir::BasicBlock, CleanupKind>,
block_bxs: &IndexVec<mir::BasicBlock, BasicBlockRef>)
-> (IndexVec<mir::BasicBlock, Option<BasicBlockRef>>,
/// Produce, for each argument, a `ValueRef` pointing at the
/// argument's value. As arguments are places, these are always
/// indirect.
-fn arg_local_refs<'a, 'tcx>(bx: &Builder<'a, 'tcx>,
- fx: &FunctionCx<'a, 'tcx>,
- scopes: &IndexVec<mir::SourceScope, debuginfo::MirDebugScope>,
- memory_locals: &BitVector<mir::Local>)
- -> Vec<LocalRef<'tcx>> {
+fn arg_local_refs(
+ bx: &Builder<'a, 'll, 'tcx>,
+ fx: &FunctionCx<'a, 'll, 'tcx>,
+ scopes: &IndexVec<mir::SourceScope, debuginfo::MirDebugScope>,
+ memory_locals: &BitVector<mir::Local>,
+) -> Vec<LocalRef<'tcx>> {
let mir = fx.mir;
let tcx = bx.tcx();
let mut idx = 0;
}
}
- pub fn from_const(bx: &Builder<'a, 'tcx>,
+ pub fn from_const(bx: &Builder<'a, 'll, 'tcx>,
val: &'tcx ty::Const<'tcx>)
-> Result<OperandRef<'tcx>, Lrc<ConstEvalErr<'tcx>>> {
let layout = bx.cx.layout_of(val.ty);
/// If this operand is a `Pair`, we return an aggregate with the two values.
/// 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 {
let llty = self.layout.llvm_type(bx.cx);
debug!("Operand::immediate_or_packed_pair: packing {:?} into {:?}",
}
/// 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,
layout: TyLayout<'tcx>)
-> OperandRef<'tcx> {
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 offset = self.layout.fields.offset(i);
}
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());
}
- 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);
}
- 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);
}
- 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);
}
- 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);
// 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.
}
}
-impl<'a, 'tcx> FunctionCx<'a, 'tcx> {
+impl FunctionCx<'a, 'll, 'tcx> {
fn maybe_codegen_consume_direct(&mut self,
- bx: &Builder<'a, 'tcx>,
+ bx: &Builder<'a, 'll, 'tcx>,
place: &mir::Place<'tcx>)
-> Option<OperandRef<'tcx>>
{
}
pub fn codegen_consume(&mut self,
- bx: &Builder<'a, 'tcx>,
+ bx: &Builder<'a, 'll, 'tcx>,
place: &mir::Place<'tcx>)
-> OperandRef<'tcx>
{
}
pub fn codegen_operand(&mut self,
- bx: &Builder<'a, 'tcx>,
+ bx: &Builder<'a, 'll, 'tcx>,
operand: &mir::Operand<'tcx>)
-> OperandRef<'tcx>
{
}
pub fn from_const_alloc(
- bx: &Builder<'a, 'tcx>,
+ bx: &Builder<'a, 'll, 'tcx>,
layout: TyLayout<'tcx>,
alloc: &mir::interpret::Allocation,
offset: Size,
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> {
debug!("alloca({:?}: {:?})", name, layout);
let tmp = bx.alloca(layout.llvm_type(bx.cx), name, layout.align);
!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);
assert!(!self.has_extra());
}
/// 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 field = self.layout.field(cx, ix);
let offset = self.layout.fields.offset(ix);
}
/// 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);
if self.layout.abi == layout::Abi::Uninhabited {
return C_undef(cast_to);
/// Set the discriminant for a new value of the given case of the given
/// 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 {
return;
}
}
}
- 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 {
llval: bx.inbounds_gep(self.llval, &[C_usize(bx.cx, 0), llindex]),
}
}
- 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> {
let mut downcast = *self;
downcast.layout = self.layout.for_variant(bx.cx, variant_index);
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);
}
- 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);
}
}
-impl<'a, 'tcx> FunctionCx<'a, 'tcx> {
+impl FunctionCx<'a, 'll, 'tcx> {
pub fn codegen_place(&mut self,
- bx: &Builder<'a, 'tcx>,
+ bx: &Builder<'a, 'll, 'tcx>,
place: &mir::Place<'tcx>)
-> PlaceRef<'tcx> {
debug!("codegen_place(place={:?})", place);
use super::operand::{OperandRef, OperandValue};
use super::place::PlaceRef;
-impl<'a, 'tcx> FunctionCx<'a, 'tcx> {
+impl FunctionCx<'a, 'll, 'tcx> {
pub fn codegen_rvalue(&mut self,
- bx: Builder<'a, 'tcx>,
+ bx: Builder<'a, 'll, 'tcx>,
dest: PlaceRef<'tcx>,
rvalue: &mir::Rvalue<'tcx>)
- -> Builder<'a, 'tcx>
+ -> Builder<'a, 'll, 'tcx>
{
debug!("codegen_rvalue(dest.llval={:?}, rvalue={:?})",
Value(dest.llval), rvalue);
}
pub fn codegen_rvalue_operand(&mut self,
- bx: Builder<'a, 'tcx>,
+ bx: Builder<'a, 'll, '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);
}
fn evaluate_array_len(&mut self,
- bx: &Builder<'a, 'tcx>,
+ bx: &Builder<'a, 'll, 'tcx>,
place: &mir::Place<'tcx>) -> ValueRef
{
// ZST are passed as operands and require special handling
}
pub fn codegen_scalar_binop(&mut self,
- bx: &Builder<'a, 'tcx>,
+ bx: &Builder<'a, 'll, 'tcx>,
op: mir::BinOp,
lhs: ValueRef,
rhs: ValueRef,
}
pub fn codegen_fat_ptr_binop(&mut self,
- bx: &Builder<'a, 'tcx>,
+ bx: &Builder<'a, 'll, 'tcx>,
op: mir::BinOp,
lhs_addr: ValueRef,
lhs_extra: ValueRef,
}
pub fn codegen_scalar_checked_binop(&mut self,
- bx: &Builder<'a, 'tcx>,
+ bx: &Builder<'a, 'll, 'tcx>,
op: mir::BinOp,
lhs: ValueRef,
rhs: ValueRef,
bx.cx.get_intrinsic(&name)
}
-fn cast_int_to_float(bx: &Builder,
+fn cast_int_to_float(bx: &Builder<'_, 'll, '_>,
signed: bool,
x: ValueRef,
- int_ty: Type,
- float_ty: Type) -> ValueRef {
+ int_ty: &'ll Type,
+ float_ty: &'ll Type) -> ValueRef {
// 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).
// LLVM's uitofp produces undef in those cases, so we manually check for that case.
}
}
-fn cast_float_to_int(bx: &Builder,
+fn cast_float_to_int(bx: &Builder<'_, 'll, '_>,
signed: bool,
x: ValueRef,
- float_ty: Type,
- int_ty: Type) -> ValueRef {
+ float_ty: &'ll Type,
+ int_ty: &'ll Type) -> ValueRef {
let fptosui_result = if signed {
bx.fptosi(x, int_ty)
} else {
// 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).
// 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);
assert_eq!(rounded_min.status, Status::OK);
let rounded_max = F::from_u128_r(int_max(signed, int_ty), Round::TowardZero);
assert!(rounded_max.value.is_finite());
(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();
if signed {
i128::MAX as u128 >> 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 {
i128::MIN >> (128 - int_ty.int_width())
} else {
use super::FunctionCx;
use super::LocalRef;
-impl<'a, 'tcx> FunctionCx<'a, 'tcx> {
+impl FunctionCx<'a, 'll, 'tcx> {
pub fn codegen_statement(&mut self,
- bx: Builder<'a, 'tcx>,
+ bx: Builder<'a, 'll, 'tcx>,
statement: &mir::Statement<'tcx>)
- -> Builder<'a, 'tcx> {
+ -> Builder<'a, 'll, 'tcx> {
debug!("codegen_statement(statement={:?})", statement);
self.set_debug_loc(&bx, statement.source_info);
#![allow(non_upper_case_globals)]
+pub use llvm::Type;
+
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 context::CodegenCx;
use std::ffi::CString;
use std::fmt;
-use std::mem;
use libc::c_uint;
-#[derive(Clone, Copy, PartialEq)]
-#[repr(C)]
-pub struct Type {
- rf: TypeRef
+impl PartialEq for Type {
+ fn eq(&self, other: &Self) -> bool {
+ self as *const _ == other as *const _
+ }
}
impl fmt::Debug for Type {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
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"))
}
}
-macro_rules! ty {
- ($e:expr) => ( Type::from_ref(unsafe { $e }))
-}
-
-/// Wrapper for LLVM TypeRef
impl Type {
- #[inline(always)]
- pub fn from_ref(r: TypeRef) -> Type {
- Type {
- rf: r
+ pub fn void(cx: &CodegenCx<'ll, '_>) -> &'ll Type {
+ unsafe {
+ llvm::LLVMVoidTypeInContext(cx.llcx)
}
}
- #[inline(always)] // So it doesn't kill --opt-level=0 builds of the compiler
- pub fn to_ref(&self) -> TypeRef {
- self.rf
- }
-
- pub fn to_ref_slice(slice: &[Type]) -> &[TypeRef] {
- unsafe { mem::transmute(slice) }
- }
-
- pub fn void(cx: &CodegenCx) -> Type {
- ty!(llvm::LLVMVoidTypeInContext(cx.llcx))
- }
-
- pub fn metadata(cx: &CodegenCx) -> Type {
- ty!(llvm::LLVMRustMetadataTypeInContext(cx.llcx))
+ pub fn metadata(cx: &CodegenCx<'ll, '_>) -> &'ll Type {
+ unsafe {
+ llvm::LLVMRustMetadataTypeInContext(cx.llcx)
+ }
}
- pub fn i1(cx: &CodegenCx) -> Type {
- ty!(llvm::LLVMInt1TypeInContext(cx.llcx))
+ pub fn i1(cx: &CodegenCx<'ll, '_>) -> &'ll Type {
+ unsafe {
+ llvm::LLVMInt1TypeInContext(cx.llcx)
+ }
}
- pub fn i8(cx: &CodegenCx) -> Type {
- ty!(llvm::LLVMInt8TypeInContext(cx.llcx))
+ pub fn i8(cx: &CodegenCx<'ll, '_>) -> &'ll Type {
+ unsafe {
+ llvm::LLVMInt8TypeInContext(cx.llcx)
+ }
}
- pub fn i8_llcx(llcx: &llvm::Context) -> Type {
- ty!(llvm::LLVMInt8TypeInContext(llcx))
+ pub fn i8_llcx(llcx: &llvm::Context) -> &Type {
+ unsafe {
+ llvm::LLVMInt8TypeInContext(llcx)
+ }
}
- pub fn i16(cx: &CodegenCx) -> Type {
- ty!(llvm::LLVMInt16TypeInContext(cx.llcx))
+ pub fn i16(cx: &CodegenCx<'ll, '_>) -> &'ll Type {
+ unsafe {
+ llvm::LLVMInt16TypeInContext(cx.llcx)
+ }
}
- pub fn i32(cx: &CodegenCx) -> Type {
- ty!(llvm::LLVMInt32TypeInContext(cx.llcx))
+ pub fn i32(cx: &CodegenCx<'ll, '_>) -> &'ll Type {
+ unsafe {
+ llvm::LLVMInt32TypeInContext(cx.llcx)
+ }
}
- pub fn i64(cx: &CodegenCx) -> Type {
- ty!(llvm::LLVMInt64TypeInContext(cx.llcx))
+ pub fn i64(cx: &CodegenCx<'ll, '_>) -> &'ll Type {
+ unsafe {
+ llvm::LLVMInt64TypeInContext(cx.llcx)
+ }
}
- pub fn i128(cx: &CodegenCx) -> Type {
- ty!(llvm::LLVMIntTypeInContext(cx.llcx, 128))
+ pub fn i128(cx: &CodegenCx<'ll, '_>) -> &'ll Type {
+ unsafe {
+ llvm::LLVMIntTypeInContext(cx.llcx, 128)
+ }
}
// Creates an integer type with the given number of bits, e.g. i24
- pub fn ix(cx: &CodegenCx, num_bits: u64) -> Type {
- ty!(llvm::LLVMIntTypeInContext(cx.llcx, num_bits as c_uint))
+ pub fn ix(cx: &CodegenCx<'ll, '_>, num_bits: u64) -> &'ll Type {
+ unsafe {
+ llvm::LLVMIntTypeInContext(cx.llcx, num_bits as c_uint)
+ }
}
// Creates an integer type with the given number of bits, e.g. i24
- pub fn ix_llcx(llcx: &llvm::Context, num_bits: u64) -> Type {
- ty!(llvm::LLVMIntTypeInContext(llcx, num_bits as c_uint))
+ pub fn ix_llcx(llcx: &llvm::Context, num_bits: u64) -> &Type {
+ unsafe {
+ llvm::LLVMIntTypeInContext(llcx, num_bits as c_uint)
+ }
}
- pub fn f32(cx: &CodegenCx) -> Type {
- ty!(llvm::LLVMFloatTypeInContext(cx.llcx))
+ pub fn f32(cx: &CodegenCx<'ll, '_>) -> &'ll Type {
+ unsafe {
+ llvm::LLVMFloatTypeInContext(cx.llcx)
+ }
}
- pub fn f64(cx: &CodegenCx) -> Type {
- ty!(llvm::LLVMDoubleTypeInContext(cx.llcx))
+ pub fn f64(cx: &CodegenCx<'ll, '_>) -> &'ll Type {
+ unsafe {
+ llvm::LLVMDoubleTypeInContext(cx.llcx)
+ }
}
- pub fn bool(cx: &CodegenCx) -> Type {
+ pub fn bool(cx: &CodegenCx<'ll, '_>) -> &'ll Type {
Type::i8(cx)
}
- pub fn char(cx: &CodegenCx) -> Type {
+ pub fn char(cx: &CodegenCx<'ll, '_>) -> &'ll Type {
Type::i32(cx)
}
- pub fn i8p(cx: &CodegenCx) -> Type {
+ pub fn i8p(cx: &CodegenCx<'ll, '_>) -> &'ll Type {
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()
}
- pub fn isize(cx: &CodegenCx) -> Type {
+ pub fn isize(cx: &CodegenCx<'ll, '_>) -> &'ll Type {
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[..] {
"16" => Type::i16(cx),
"32" => Type::i32(cx),
}
}
- 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 {
ast::IntTy::Isize => cx.isize_ty,
ast::IntTy::I8 => Type::i8(cx),
}
}
- 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 {
ast::UintTy::Usize => cx.isize_ty,
ast::UintTy::U8 => Type::i8(cx),
}
}
- 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 {
ast::FloatTy::F32 => Type::f32(cx),
ast::FloatTy::F64 => Type::f64(cx),
}
}
- pub fn func(args: &[Type], ret: &Type) -> Type {
- let slice: &[TypeRef] = Type::to_ref_slice(args);
- ty!(llvm::LLVMFunctionType(ret.to_ref(), slice.as_ptr(),
- args.len() as c_uint, False))
+ pub fn func(args: &[&'ll Type], ret: &'ll Type) -> &'ll Type {
+ unsafe {
+ llvm::LLVMFunctionType(ret, args.as_ptr(),
+ args.len() as c_uint, False)
+ }
}
- pub fn variadic_func(args: &[Type], ret: &Type) -> Type {
- let slice: &[TypeRef] = Type::to_ref_slice(args);
- ty!(llvm::LLVMFunctionType(ret.to_ref(), slice.as_ptr(),
- args.len() as c_uint, True))
+ pub fn variadic_func(args: &[&'ll Type], ret: &'ll Type) -> &'ll Type {
+ unsafe {
+ llvm::LLVMFunctionType(ret, args.as_ptr(),
+ args.len() as c_uint, True)
+ }
}
- pub fn struct_(cx: &CodegenCx, els: &[Type], packed: bool) -> Type {
- let els: &[TypeRef] = Type::to_ref_slice(els);
- ty!(llvm::LLVMStructTypeInContext(cx.llcx, els.as_ptr(),
+ pub fn struct_(cx: &CodegenCx<'ll, '_>, els: &[&'ll Type], packed: bool) -> &'ll Type {
+ unsafe {
+ llvm::LLVMStructTypeInContext(cx.llcx, els.as_ptr(),
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();
- ty!(llvm::LLVMStructCreateNamed(cx.llcx, name.as_ptr()))
+ unsafe {
+ llvm::LLVMStructCreateNamed(cx.llcx, name.as_ptr())
+ }
}
- pub fn array(ty: &Type, len: u64) -> Type {
- ty!(llvm::LLVMRustArrayType(ty.to_ref(), len))
+ pub fn array(ty: &Type, len: u64) -> &Type {
+ unsafe {
+ llvm::LLVMRustArrayType(ty, len)
+ }
}
- pub fn vector(ty: &Type, len: u64) -> Type {
- ty!(llvm::LLVMVectorType(ty.to_ref(), len as c_uint))
+ pub fn vector(ty: &Type, len: u64) -> &Type {
+ unsafe {
+ llvm::LLVMVectorType(ty, len as c_uint)
+ }
}
pub fn kind(&self) -> TypeKind {
unsafe {
- llvm::LLVMRustGetTypeKind(self.to_ref())
+ llvm::LLVMRustGetTypeKind(self)
}
}
- pub fn set_struct_body(&mut self, els: &[Type], packed: bool) {
- let slice: &[TypeRef] = Type::to_ref_slice(els);
+ pub fn set_struct_body(&'ll self, els: &[&'ll Type], packed: bool) {
unsafe {
- llvm::LLVMStructSetBody(self.to_ref(), slice.as_ptr(),
+ llvm::LLVMStructSetBody(self, els.as_ptr(),
els.len() as c_uint, packed as Bool)
}
}
- pub fn ptr_to(&self) -> Type {
- ty!(llvm::LLVMPointerType(self.to_ref(), 0))
+ pub fn ptr_to(&self) -> &Type {
+ unsafe {
+ llvm::LLVMPointerType(self, 0)
+ }
}
- pub fn element_type(&self) -> Type {
+ pub fn element_type(&self) -> &Type {
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.
pub fn vector_length(&self) -> usize {
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 {
- let n_args = llvm::LLVMCountParamTypes(self.to_ref()) as usize;
- let mut args = vec![Type { rf: 0 as *mut _ }; n_args];
- llvm::LLVMGetParamTypes(self.to_ref(),
- args.as_mut_ptr() as *mut TypeRef);
+ let n_args = llvm::LLVMCountParamTypes(self) as usize;
+ let mut args = Vec::with_capacity(n_args);
+ llvm::LLVMGetParamTypes(self, args.as_mut_ptr());
+ args.set_len(n_args);
args
}
}
/// Retrieve the bit width of the integer type `self`.
pub fn int_width(&self) -> u64 {
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::*;
match i {
I8 => Type::i8(cx),
/// Return a LLVM type that has at most the required alignment,
/// 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.
let ity = layout::Integer::approximate_abi_align(cx, align);
Type::from_integer(cx, ity)
/// Return a LLVM type that has at most the required alignment,
/// 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 size = size.bytes();
let unit_size = unit.size().bytes();
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 {
- ty!(llvm::LLVMX86MMXTypeInContext(cx.llcx))
+ pub fn x86_mmx(cx: &CodegenCx<'ll, '_>) -> &'ll Type {
+ unsafe {
+ llvm::LLVMX86MMXTypeInContext(cx.llcx)
+ }
}
}
fn uncached_llvm_type<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>,
layout: TyLayout<'tcx>,
- defer: &mut Option<(Type, TyLayout<'tcx>)>)
- -> Type {
+ defer: &mut Option<(&'a Type, TyLayout<'tcx>)>)
+ -> &'a Type {
match layout.abi {
layout::Abi::Scalar(_) => bug!("handled elsewhere"),
layout::Abi::Vector { ref element, count } => {
return Type::x86_mmx(cx)
} else {
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::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 { .. } => {
match name {
fn struct_llfields<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>,
layout: TyLayout<'tcx>)
- -> (Vec<Type>, bool) {
+ -> (Vec<&'a Type>, bool) {
debug!("struct_llfields: {:#?}", layout);
let field_count = layout.fields.count();
let mut packed = false;
let mut offset = Size::ZERO;
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() {
let field = layout.field(cx, i);
packed |= layout.align.abi() < field.align.abi();
pub trait LayoutLlvmExt<'tcx> {
fn is_llvm_immediate(&self) -> bool;
fn is_llvm_scalar_pair<'a>(&self) -> bool;
- fn llvm_type<'a>(&self, cx: &CodegenCx<'a, 'tcx>) -> Type;
- fn immediate_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>) -> &'a Type;
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>,
- index: usize, immediate: bool) -> Type;
+ index: usize, immediate: bool) -> &'a Type;
fn llvm_field_index(&self, index: usize) -> u64;
fn pointee_info_at<'a>(&self, cx: &CodegenCx<'a, 'tcx>, offset: Size)
-> Option<PointeeInfo>;
/// with the inner-most trailing unsized field using the "minimal unit"
/// of that field's type - this is useful for taking the address of
/// 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 {
// Use a different cache for scalars because pointers to DSTs
// can be either fat or thin (data pointers of fat pointers).
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);
llty.set_struct_body(&llfields, packed)
}
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 scalar.is_bool() {
return Type::i1(cx);
}
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 {
layout::Int(i, _) => Type::from_integer(cx, i),
layout::Float(FloatTy::F32) => Type::f32(cx),
}
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
// pointee types, to avoid bitcasting every `OperandRef::deref`.
match self.ty.sty {