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 {
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 => {
@ -118,14 +118,14 @@ impl LlvmType for Reg {
}
}
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)
@ -142,7 +142,7 @@ impl LlvmType for CastTarget {
// 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);
}
}
@ -165,15 +165,15 @@ impl LlvmType for CastTarget {
}
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)
}
@ -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.
/// 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;
}
@ -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 val = llvm::get_param(bx.llfn(), *idx as c_uint);
*idx += 1;
@ -270,10 +270,10 @@ pub trait FnTypeExt<'a, 'tcx> {
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>> {
@ -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|
if arg.pad.is_some() { 1 } else { 0 } +
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 {
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)
}
}
@ -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 apply = |attrs: &ArgAttributes| {
attrs.apply_callsite(llvm::AttributePlace::Argument(i), callsite);

View File

@ -24,8 +24,8 @@ use syntax::ast::AsmDialect;
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>

View File

@ -831,7 +831,7 @@ unsafe fn embed_bitcode(cgcx: &CodegenContext,
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);
@ -851,7 +851,7 @@ unsafe fn embed_bitcode(cgcx: &CodegenContext,
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);
@ -2380,7 +2380,7 @@ fn create_msvc_imps(cgcx: &CodegenContext, llcx: &llvm::Context, llmod: &llvm::M
.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);

View File

@ -19,9 +19,9 @@
//!
//! * 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;
@ -91,14 +91,14 @@ use mir::operand::OperandValue;
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,
@ -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) {
if self.cx.sess().codegen_stats() {
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>(
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 {
@ -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.
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>
@ -271,9 +271,11 @@ pub fn unsize_thin_ptr<'a, '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 = || {
@ -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))
}
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() {
@ -378,7 +380,7 @@ pub fn wants_msvc_seh(sess: &Session) -> bool {
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);
}
@ -430,8 +432,8 @@ pub fn call_memcpy(bx: &Builder,
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>,
@ -446,12 +448,14 @@ pub fn memcpy_ty<'a, '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);
@ -553,7 +557,7 @@ fn maybe_create_entry_wrapper(cx: &CodegenCx) {
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,
@ -656,7 +660,7 @@ fn write_metadata<'a, 'gcx>(tcx: TyCtxt<'a, 'gcx, 'gcx>,
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);
@ -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
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);
}
@ -1221,7 +1225,7 @@ fn compile_codegen_unit<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
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);

View File

@ -31,12 +31,12 @@ use syntax_pos::Span;
// 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);
@ -59,8 +59,8 @@ bitflags! {
}
}
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();
@ -74,7 +74,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
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)
@ -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)
}
@ -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);
bx.position_at_start(unsafe {
llvm::LLVMGetFirstBasicBlock(self.llfn())
@ -512,14 +512,14 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
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);
@ -678,136 +678,136 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
}
/* 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())
}
}
@ -828,14 +828,14 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
}
/* 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");
@ -865,7 +865,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
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)
};
@ -874,7 +874,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
}
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");
@ -890,10 +890,10 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
}).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)
}
}
@ -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");
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 {
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))
}
}
@ -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 {
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())
}
}

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 {
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())
}
}
@ -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 {
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
// 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 {
@ -356,8 +357,8 @@ pub fn build_unchecked_lshift<'a, 'tcx>(
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
@ -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);
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();

View File

@ -31,15 +31,15 @@ use rustc::hir::{self, CodegenFnAttrs, CodegenFnAttrFlags};
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)
}
}
@ -294,7 +294,7 @@ pub fn codegen_static<'a, 'tcx>(
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
};
@ -316,7 +316,7 @@ pub fn codegen_static<'a, 'tcx>(
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);
@ -411,7 +411,7 @@ pub fn codegen_static<'a, 'tcx>(
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);
}
}

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
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>>,
@ -373,7 +373,7 @@ impl<'b, 'tcx> CodegenCx<'b, '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)
}
};
@ -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 {
&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>;
@ -475,7 +475,7 @@ fn declare_intrinsic(cx: &CodegenCx, key: &str) -> Option<ValueRef> {
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);
@ -483,7 +483,7 @@ fn declare_intrinsic(cx: &CodegenCx, key: &str) -> Option<ValueRef> {
);
($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);
@ -491,7 +491,7 @@ fn declare_intrinsic(cx: &CodegenCx, key: &str) -> Option<ValueRef> {
);
($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);
@ -513,14 +513,14 @@ fn declare_intrinsic(cx: &CodegenCx, key: &str) -> Option<ValueRef> {
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);

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";
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,

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

View File

@ -49,8 +49,7 @@ pub fn span_start(cx: &CodegenCx, span: Span) -> syntax_pos::Loc {
}
#[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()
}

View File

@ -40,13 +40,13 @@ use std::ffi::CString;
///
/// If theres 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)
}
}
@ -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
/// 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);
@ -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
/// 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)
}
@ -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
/// 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).
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 {

View File

@ -23,7 +23,7 @@ use rustc::ty::layout::LayoutOf;
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));

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,
/// 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;
@ -545,7 +547,7 @@ pub fn codegen_intrinsic_call<'a, 'tcx>(bx: &Builder<'a, '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)],
@ -567,7 +569,7 @@ pub fn codegen_intrinsic_call<'a, 'tcx>(bx: &Builder<'a, 'tcx>,
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()
@ -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
// 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) => {
@ -616,7 +619,7 @@ pub fn codegen_intrinsic_call<'a, 'tcx>(bx: &Builder<'a, 'tcx>,
}
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
@ -644,7 +647,7 @@ pub fn codegen_intrinsic_call<'a, 'tcx>(bx: &Builder<'a, 'tcx>,
intrinsics::IntrinsicDef::Named(name) => {
let f = declare::declare_cfn(cx,
name,
Type::func(&inputs, &outputs));
Type::func(&inputs, outputs));
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>,
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());
@ -712,8 +716,8 @@ fn copy_intrinsic<'a, 'tcx>(bx: &Builder<'a, 'tcx>,
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,
@ -728,8 +732,8 @@ fn memset_intrinsic<'a, 'tcx>(
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,
@ -754,12 +758,14 @@ fn try_intrinsic<'a, 'tcx>(
// 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;
@ -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
// 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;
@ -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.
// 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,
@ -945,9 +954,10 @@ fn gen_fn<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>,
// 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;
}
@ -972,13 +982,13 @@ fn span_invalid_monomorphization_error(a: &Session, b: Span, c: &str) {
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:
@ -1145,19 +1155,20 @@ fn generic_simd_intrinsic<'a, 'tcx>(
}
// 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, )
@ -1283,8 +1294,8 @@ fn generic_simd_intrinsic<'a, 'tcx>(
}
}
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),
@ -1296,7 +1307,7 @@ fn generic_simd_intrinsic<'a, 'tcx>(
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)
}
@ -1379,7 +1390,7 @@ fn generic_simd_intrinsic<'a, 'tcx>(
// 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)
};
@ -1395,7 +1406,7 @@ fn generic_simd_intrinsic<'a, 'tcx>(
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);
@ -1476,7 +1487,7 @@ fn generic_simd_intrinsic<'a, 'tcx>(
// 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)
};
@ -1496,7 +1507,7 @@ fn generic_simd_intrinsic<'a, 'tcx>(
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);
@ -1629,7 +1640,7 @@ unsupported {} from `{}` with element `{}` of size `{}` to `{}`"#,
// 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 {

View File

@ -377,8 +377,7 @@ pub enum ThreadLocalMode {
// 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; }
@ -517,55 +516,55 @@ extern "C" {
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);
@ -580,10 +579,10 @@ extern "C" {
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;
@ -591,8 +590,8 @@ extern "C" {
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,
@ -612,14 +611,14 @@ extern "C" {
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;
@ -651,23 +650,23 @@ extern "C" {
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,
@ -690,9 +689,9 @@ extern "C" {
// 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);
@ -706,13 +705,13 @@ extern "C" {
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);
@ -801,7 +800,7 @@ extern "C" {
Name: *const c_char)
-> ValueRef;
pub fn LLVMBuildLandingPad(B: BuilderRef,
Ty: TypeRef,
Ty: &Type,
PersFn: ValueRef,
NumClauses: c_uint,
Name: *const c_char)
@ -989,7 +988,7 @@ extern "C" {
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;
@ -1024,98 +1023,98 @@ extern "C" {
// 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;
@ -1134,7 +1133,7 @@ extern "C" {
-> 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,
@ -1150,7 +1149,7 @@ extern "C" {
-> ValueRef;
pub fn LLVMBuildVAArg(B: BuilderRef,
list: ValueRef,
Ty: TypeRef,
Ty: &Type,
Name: *const c_char)
-> ValueRef;
pub fn LLVMBuildExtractElement(B: BuilderRef,
@ -1347,15 +1346,15 @@ extern "C" {
/// 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,
@ -1587,7 +1586,7 @@ extern "C" {
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;

View File

@ -33,7 +33,7 @@ impl<'a, 'tcx> VirtualIndex {
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.
@ -48,7 +48,7 @@ impl<'a, 'tcx> VirtualIndex {
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);

View File

@ -22,7 +22,7 @@ use rustc::ty::layout::LayoutOf;
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);
@ -51,8 +51,8 @@ pub fn non_ssa_locals<'a, 'tcx>(fx: &FunctionCx<'a, 'tcx>) -> BitVector<mir::Loc
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
@ -60,8 +60,8 @@ struct LocalAnalyzer<'mir, 'a: 'mir, 'tcx: 'a> {
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 {
@ -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,
block: mir::BasicBlock,
place: &mir::Place<'tcx>,

View File

@ -33,7 +33,7 @@ use super::place::PlaceRef;
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];
@ -48,7 +48,7 @@ impl<'a, 'tcx> FunctionCx<'a, 'tcx> {
}
fn codegen_terminator(&mut self,
mut bx: Builder<'a, 'tcx>,
mut bx: Builder<'a, 'll, 'tcx>,
bb: mir::BasicBlock,
terminator: &mir::Terminator<'tcx>)
{
@ -110,7 +110,7 @@ impl<'a, 'tcx> FunctionCx<'a, '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],
@ -627,7 +627,7 @@ impl<'a, 'tcx> FunctionCx<'a, 'tcx> {
}
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>>) {
@ -706,7 +706,7 @@ impl<'a, 'tcx> FunctionCx<'a, '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>>]) {
@ -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;
if let Some(slot) = self.personality_slot {
slot
@ -777,7 +777,7 @@ impl<'a, 'tcx> FunctionCx<'a, 'tcx> {
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)
}
@ -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)
}
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> {
@ -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>,
dst: &mir::Place<'tcx>) {
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>,
dst: PlaceRef<'tcx>) {
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.
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) {

View File

@ -33,7 +33,7 @@ use super::FunctionCx;
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 => {
@ -42,7 +42,7 @@ pub fn scalar_to_llvm(cx: &CodegenCx,
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)
}
@ -73,7 +73,7 @@ pub fn scalar_to_llvm(cx: &CodegenCx,
1,
) };
if layout.value != layout::Pointer {
unsafe { llvm::LLVMConstPtrToInt(llval, llty.to_ref()) }
unsafe { llvm::LLVMConstPtrToInt(llval, llty) }
} else {
consts::bitcast(llval, llty)
}
@ -135,10 +135,10 @@ pub fn codegen_static_initializer<'a, 'tcx>(
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 {
@ -158,7 +158,7 @@ impl<'a, 'tcx> FunctionCx<'a, 'tcx> {
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);
@ -168,7 +168,7 @@ impl<'a, 'tcx> FunctionCx<'a, 'tcx> {
/// 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>>>,

View File

@ -43,7 +43,7 @@ use rustc::mir::traversal;
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>,
@ -52,7 +52,7 @@ pub struct FunctionCx<'a, 'tcx:'a> {
llfn: ValueRef,
cx: &'a CodegenCx<'a, 'tcx>,
cx: &'a CodegenCx<'ll, 'tcx>,
fn_ty: FnType<'tcx, Ty<'tcx>>,
@ -106,7 +106,7 @@ pub struct FunctionCx<'a, 'tcx:'a> {
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>
{
@ -198,8 +198,8 @@ impl<'a, 'tcx> LocalRef<'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>,
@ -344,9 +344,9 @@ pub fn codegen_mir<'a, 'tcx: 'a>(
}
}
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>>,
@ -413,11 +413,12 @@ fn create_funclets<'a, 'tcx>(
/// 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;

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>)
-> Result<OperandRef<'tcx>, Lrc<ConstEvalErr<'tcx>>> {
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.
/// 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 {:?}",
@ -190,7 +190,7 @@ impl<'a, 'tcx> OperandRef<'tcx> {
}
/// 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> {
@ -208,7 +208,7 @@ impl<'a, '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);
@ -267,23 +267,23 @@ impl<'a, 'tcx> OperandRef<'tcx> {
}
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.
@ -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,
bx: &Builder<'a, 'tcx>,
bx: &Builder<'a, 'll, 'tcx>,
place: &mir::Place<'tcx>)
-> Option<OperandRef<'tcx>>
{
@ -360,7 +360,7 @@ impl<'a, 'tcx> FunctionCx<'a, 'tcx> {
}
pub fn codegen_consume(&mut self,
bx: &Builder<'a, 'tcx>,
bx: &Builder<'a, 'll, 'tcx>,
place: &mir::Place<'tcx>)
-> OperandRef<'tcx>
{
@ -384,7 +384,7 @@ impl<'a, 'tcx> FunctionCx<'a, 'tcx> {
}
pub fn codegen_operand(&mut self,
bx: &Builder<'a, 'tcx>,
bx: &Builder<'a, 'll, 'tcx>,
operand: &mir::Operand<'tcx>)
-> OperandRef<'tcx>
{

View File

@ -56,7 +56,7 @@ impl<'a, 'tcx> PlaceRef<'tcx> {
}
pub fn from_const_alloc(
bx: &Builder<'a, 'tcx>,
bx: &Builder<'a, 'll, 'tcx>,
layout: TyLayout<'tcx>,
alloc: &mir::interpret::Allocation,
offset: Size,
@ -73,7 +73,7 @@ impl<'a, 'tcx> PlaceRef<'tcx> {
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);
@ -98,7 +98,7 @@ impl<'a, 'tcx> PlaceRef<'tcx> {
!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());
@ -162,7 +162,7 @@ impl<'a, 'tcx> PlaceRef<'tcx> {
}
/// 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);
@ -266,7 +266,7 @@ impl<'a, 'tcx> PlaceRef<'tcx> {
}
/// 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);
@ -330,7 +330,7 @@ impl<'a, 'tcx> PlaceRef<'tcx> {
/// 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;
}
@ -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 {
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> {
let mut downcast = *self;
downcast.layout = self.layout.for_variant(bx.cx, variant_index);
@ -406,18 +406,18 @@ impl<'a, 'tcx> PlaceRef<'tcx> {
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);

View File

@ -32,12 +32,12 @@ use super::{FunctionCx, LocalRef};
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);
@ -176,9 +176,9 @@ impl<'a, 'tcx> FunctionCx<'a, 'tcx> {
}
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);
@ -512,7 +512,7 @@ impl<'a, 'tcx> FunctionCx<'a, 'tcx> {
}
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
@ -531,7 +531,7 @@ impl<'a, 'tcx> FunctionCx<'a, 'tcx> {
}
pub fn codegen_scalar_binop(&mut self,
bx: &Builder<'a, 'tcx>,
bx: &Builder<'a, 'll, 'tcx>,
op: mir::BinOp,
lhs: ValueRef,
rhs: ValueRef,
@ -597,7 +597,7 @@ impl<'a, 'tcx> FunctionCx<'a, 'tcx> {
}
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,
@ -644,7 +644,7 @@ impl<'a, 'tcx> FunctionCx<'a, 'tcx> {
}
pub fn codegen_scalar_checked_binop(&mut self,
bx: &Builder<'a, 'tcx>,
bx: &Builder<'a, 'll, 'tcx>,
op: mir::BinOp,
lhs: ValueRef,
rhs: ValueRef,
@ -796,11 +796,11 @@ fn get_overflow_intrinsic(oop: OverflowOp, bx: &Builder, ty: Ty) -> 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.
@ -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,
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 {
@ -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
// 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
@ -874,7 +874,7 @@ fn cast_float_to_int(bx: &Builder,
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 {

View File

@ -16,11 +16,11 @@ use builder::Builder;
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);

View File

@ -10,8 +10,10 @@
#![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;
@ -21,121 +23,125 @@ use rustc::ty::layout::{self, Align, Size};
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 metadata(cx: &CodegenCx<'ll, '_>) -> &'ll Type {
unsafe {
llvm::LLVMRustMetadataTypeInContext(cx.llcx)
}
}
pub fn to_ref_slice(slice: &[Type]) -> &[TypeRef] {
unsafe { mem::transmute(slice) }
pub fn i1(cx: &CodegenCx<'ll, '_>) -> &'ll Type {
unsafe {
llvm::LLVMInt1TypeInContext(cx.llcx)
}
}
pub fn void(cx: &CodegenCx) -> Type {
ty!(llvm::LLVMVoidTypeInContext(cx.llcx))
pub fn i8(cx: &CodegenCx<'ll, '_>) -> &'ll Type {
unsafe {
llvm::LLVMInt8TypeInContext(cx.llcx)
}
}
pub fn metadata(cx: &CodegenCx) -> Type {
ty!(llvm::LLVMRustMetadataTypeInContext(cx.llcx))
pub fn i8_llcx(llcx: &llvm::Context) -> &Type {
unsafe {
llvm::LLVMInt8TypeInContext(llcx)
}
}
pub fn i1(cx: &CodegenCx) -> Type {
ty!(llvm::LLVMInt1TypeInContext(cx.llcx))
pub fn i16(cx: &CodegenCx<'ll, '_>) -> &'ll Type {
unsafe {
llvm::LLVMInt16TypeInContext(cx.llcx)
}
}
pub fn i8(cx: &CodegenCx) -> Type {
ty!(llvm::LLVMInt8TypeInContext(cx.llcx))
pub fn i32(cx: &CodegenCx<'ll, '_>) -> &'ll Type {
unsafe {
llvm::LLVMInt32TypeInContext(cx.llcx)
}
}
pub fn i8_llcx(llcx: &llvm::Context) -> Type {
ty!(llvm::LLVMInt8TypeInContext(llcx))
pub fn i64(cx: &CodegenCx<'ll, '_>) -> &'ll Type {
unsafe {
llvm::LLVMInt64TypeInContext(cx.llcx)
}
}
pub fn i16(cx: &CodegenCx) -> Type {
ty!(llvm::LLVMInt16TypeInContext(cx.llcx))
}
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))
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),
@ -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 {
ast::IntTy::Isize => cx.isize_ty,
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 {
ast::UintTy::Usize => cx.isize_ty,
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 {
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
}
}
@ -260,11 +276,11 @@ impl Type {
/// 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),
@ -277,7 +293,7 @@ impl Type {
/// 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)
@ -285,15 +301,17 @@ impl Type {
/// 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)
}
}
}

View File

@ -23,8 +23,8 @@ use std::fmt::Write;
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 } => {
@ -42,7 +42,7 @@ fn uncached_llvm_type<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>,
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(..) => {
@ -96,7 +96,7 @@ fn uncached_llvm_type<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>,
}
}
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 {
@ -116,14 +116,14 @@ fn uncached_llvm_type<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>,
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();
@ -201,12 +201,12 @@ pub struct PointeeInfo {
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>;
@ -244,7 +244,7 @@ impl<'tcx> LayoutLlvmExt<'tcx> for TyLayout<'tcx> {
/// 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).
@ -304,7 +304,7 @@ impl<'tcx> LayoutLlvmExt<'tcx> for TyLayout<'tcx> {
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)
}
@ -312,7 +312,7 @@ impl<'tcx> LayoutLlvmExt<'tcx> for TyLayout<'tcx> {
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);
@ -322,7 +322,7 @@ impl<'tcx> LayoutLlvmExt<'tcx> for TyLayout<'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 {
layout::Int(i, _) => Type::from_integer(cx, i),
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>,
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 {