--- /dev/null
+cmd: ./x.py -i check
use type_of::{LayoutLlvmExt, PointerKind};
use value::Value;
+use traits::BuilderMethods;
+
use rustc_target::abi::{HasDataLayout, LayoutOf, Size, TyLayout, Abi as LayoutAbi};
use rustc::ty::{self, Ty};
use rustc::ty::layout;
}
}
RegKind::Vector => {
- Type::vector(Type::i8(cx), self.size.bytes())
+ Type::vector::<Value>(Type::i8(cx), self.size.bytes())
}
}
}
// 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::<Value>(rest_ll_unit, rest_count);
}
}
pub trait ArgTypeExt<'ll, 'tcx> {
fn memory_ty(&self, cx: &CodegenCx<'ll, 'tcx>) -> &'ll Type;
- fn store(&self, bx: &Builder<'_, 'll, 'tcx>, val: &'ll Value, dst: PlaceRef<'tcx, &'ll Value>);
+ fn store(
+ &self,
+ bx: &Builder<'_, 'll, 'tcx>,
+ val: &'ll Value,
+ dst: PlaceRef<'tcx, &'ll Value>,
+ );
fn store_fn_arg(
&self,
bx: &Builder<'_, 'll, '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<'_, 'll, 'tcx>, val: &'ll Value, dst: PlaceRef<'tcx, &'ll Value>) {
+ fn store(
+ &self,
+ bx: &Builder<'_, 'll, 'tcx>,
+ val: &'ll Value,
+ dst: PlaceRef<'tcx, &'ll Value>,
+ ) {
if self.is_ignore() {
return;
}
}
if self.variadic {
- Type::variadic_func(&llargument_tys, llreturn_ty)
+ Type::variadic_func::<Value>(&llargument_tys, llreturn_ty)
} else {
- Type::func(&llargument_tys, llreturn_ty)
+ Type::func::<Value>(&llargument_tys, llreturn_ty)
}
}
use value::Value;
use rustc::hir;
+use traits::BuilderMethods;
use mir::place::PlaceRef;
use mir::operand::OperandValue;
.filter(|l| !l.is_empty())
}
-pub fn apply_target_cpu_attr(cx: &CodegenCx<'ll, '_>, llfn: &'ll Value) {
+pub fn apply_target_cpu_attr(cx: &CodegenCx<'ll, '_, &'ll Value>, llfn: &'ll Value) {
let cpu = llvm_util::target_cpu(cx.tcx.sess);
let target_cpu = CString::new(cpu).unwrap();
llvm::AddFunctionAttrStringValue(
use common::{C_bytes_in_context, val_ty};
use jobserver::{Client, Acquired};
use rustc_demangle;
+use value::Value;
use std::any::Any;
use std::ffi::{CString, CStr};
"\x01__imp_"
};
unsafe {
- let i8p_ty = Type::i8p_llcx(llcx);
+ let i8p_ty = Type::i8p_llcx::<Value>(llcx);
let globals = base::iter_globals(llmod)
.filter(|&val| {
llvm::LLVMRustGetLinkage(val) == llvm::Linkage::ExternalLinkage &&
use rustc_data_structures::sync::Lrc;
use rustc_data_structures::indexed_vec::Idx;
+use traits::BuilderMethods;
+
use std::any::Any;
use std::cmp;
use std::ffi::CString;
use syntax::attr;
use rustc::hir::{self, CodegenFnAttrs};
-use value::Value;
+use value::{Value, ValueTrait};
use mir::operand::OperandValue;
bx.call(assume_intrinsic, &[val], None);
}
-pub fn from_immediate(bx: &Builder<'_, 'll, '_>, val: &'ll Value) -> &'ll Value {
- if val_ty(val) == Type::i1(bx.cx) {
- bx.zext(val, Type::i8(bx.cx))
+pub fn from_immediate<'a, 'll: 'a, 'tcx: 'll,
+ Value : ?Sized,
+ Builder: BuilderMethods<'a, 'll, 'tcx, Value>>(
+ bx: &Builder,
+ val: &'ll Value
+) -> &'ll Value where Value : ValueTrait {
+ if val_ty(val) == Type::i1(bx.cx()) {
+ bx.zext(val, Type::i8(bx.cx()))
} else {
val
}
val
}
-pub fn call_memcpy(
- bx: &Builder<'_, 'll, '_>,
+pub fn call_memcpy<'a, 'll: 'a, 'tcx: 'll,
+ Value : ?Sized,
+ Builder: BuilderMethods<'a, 'll, 'tcx, Value>>(
+ bx: &Builder,
dst: &'ll Value,
dst_align: Align,
src: &'ll Value,
src_align: Align,
n_bytes: &'ll Value,
flags: MemFlags,
-) {
+) where Value : ValueTrait {
if flags.contains(MemFlags::NONTEMPORAL) {
// HACK(nox): This is inefficient but there is no nontemporal memcpy.
let val = bx.load(src, src_align);
bx.store_with_flags(val, ptr, dst_align, flags);
return;
}
- let cx = bx.cx;
+ let cx = bx.cx();
let src_ptr = bx.pointercast(src, Type::i8p(cx));
let dst_ptr = bx.pointercast(dst, Type::i8p(cx));
let size = bx.intcast(n_bytes, cx.isize_ty, false);
bx.memcpy(dst_ptr, dst_align.abi(), src_ptr, src_align.abi(), size, volatile);
}
-pub fn memcpy_ty(
- bx: &Builder<'_, 'll, 'tcx>,
+pub fn memcpy_ty<'a, 'll: 'a, 'tcx: 'll,
+ Value : ?Sized,
+ Builder: BuilderMethods<'a, 'll, 'tcx, Value>>(
+ bx: &Builder,
dst: &'ll Value,
dst_align: Align,
src: &'ll Value,
src_align: Align,
layout: TyLayout<'tcx>,
flags: MemFlags,
-) {
+) where Value : ValueTrait {
let size = layout.size.bytes();
if size == 0 {
return;
}
- call_memcpy(bx, dst, dst_align, src, src_align, C_usize(bx.cx, size), flags);
+ call_memcpy(bx, dst, dst_align, src, src_align, C_usize(bx.cx(), size), flags);
}
pub fn call_memset(
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::<Value>(&[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,
use rustc::ty::layout::{Align, Size};
use rustc::session::{config, Session};
use rustc_data_structures::small_c_str::SmallCStr;
+use traits::BuilderMethods;
use std::borrow::Cow;
use std::ops::Range;
}
}
-impl Builder<'a, 'll, 'tcx> {
- pub fn new_block<'b>(cx: &'a CodegenCx<'ll, 'tcx>, llfn: &'ll Value, name: &'b str) -> Self {
+impl BuilderMethods<'a, 'll, 'tcx, Value> for Builder<'a, 'll, 'tcx> {
+ fn new_block<'b>(
+ cx: &'a CodegenCx<'ll, 'tcx>,
+ llfn: &'ll Value,
+ name: &'b str
+ ) -> Self {
let bx = Builder::with_cx(cx);
let llbb = unsafe {
let name = SmallCStr::new(name);
bx
}
- pub fn with_cx(cx: &'a CodegenCx<'ll, 'tcx>) -> Self {
+ fn with_cx(cx: &'a CodegenCx<'ll, 'tcx>) -> Self {
// Create a fresh builder from the crate context.
let llbuilder = unsafe {
llvm::LLVMCreateBuilderInContext(cx.llcx)
}
}
- pub fn build_sibling_block<'b>(&self, name: &'b str) -> Builder<'a, 'll, 'tcx> {
+ fn build_sibling_block<'b>(&self, name: &'b str) -> Self {
Builder::new_block(self.cx, self.llfn(), name)
}
- pub fn sess(&self) -> &Session {
+ fn sess(&self) -> &Session {
self.cx.sess()
}
- pub fn tcx(&self) -> TyCtxt<'a, 'tcx, 'tcx> {
+ fn tcx(&self) -> TyCtxt<'a, 'tcx, 'tcx> {
self.cx.tcx
}
- pub fn llfn(&self) -> &'ll Value {
+ fn llfn(&self) -> &'ll Value {
unsafe {
llvm::LLVMGetBasicBlockParent(self.llbb())
}
}
- pub fn llbb(&self) -> &'ll BasicBlock {
+ fn llbb(&self) -> &'ll BasicBlock {
unsafe {
llvm::LLVMGetInsertBlock(self.llbuilder)
}
}
fn count_insn(&self, category: &str) {
- if self.cx.sess().codegen_stats() {
- self.cx.stats.borrow_mut().n_llvm_insns += 1;
+ if self.cx().sess().codegen_stats() {
+ self.cx().stats.borrow_mut().n_llvm_insns += 1;
}
- if self.cx.sess().count_llvm_insns() {
- *self.cx.stats
- .borrow_mut()
- .llvm_insns
- .entry(category.to_string())
- .or_insert(0) += 1;
+ if self.cx().sess().count_llvm_insns() {
+ *self.cx().stats
+ .borrow_mut()
+ .llvm_insns
+ .entry(category.to_string())
+ .or_insert(0) += 1;
}
}
- pub fn set_value_name(&self, value: &'ll Value, name: &str) {
+ fn set_value_name(&self, value: &'ll Value, name: &str) {
let cname = SmallCStr::new(name);
unsafe {
llvm::LLVMSetValueName(value, cname.as_ptr());
}
}
- pub fn position_at_end(&self, llbb: &'ll BasicBlock) {
+ fn position_at_end(&self, llbb: &'ll BasicBlock) {
unsafe {
llvm::LLVMPositionBuilderAtEnd(self.llbuilder, llbb);
}
}
- pub fn position_at_start(&self, llbb: &'ll BasicBlock) {
+ fn position_at_start(&self, llbb: &'ll BasicBlock) {
unsafe {
llvm::LLVMRustPositionBuilderAtStart(self.llbuilder, llbb);
}
}
- pub fn ret_void(&self) {
+ fn ret_void(&self) {
self.count_insn("retvoid");
unsafe {
llvm::LLVMBuildRetVoid(self.llbuilder);
}
}
- pub fn ret(&self, v: &'ll Value) {
+ fn ret(&self, v: &'ll Value) {
self.count_insn("ret");
unsafe {
llvm::LLVMBuildRet(self.llbuilder, v);
}
}
- pub fn br(&self, dest: &'ll BasicBlock) {
+ fn br(&self, dest: &'ll BasicBlock) {
self.count_insn("br");
unsafe {
llvm::LLVMBuildBr(self.llbuilder, dest);
}
}
- pub fn cond_br(
+ fn cond_br(
&self,
cond: &'ll Value,
then_llbb: &'ll BasicBlock,
}
}
- pub fn switch(
+ fn switch(
&self,
v: &'ll Value,
else_llbb: &'ll BasicBlock,
}
}
- pub fn invoke(&self,
+ fn invoke(&self,
llfn: &'ll Value,
args: &[&'ll Value],
then: &'ll BasicBlock,
}
}
- pub fn unreachable(&self) {
+ fn unreachable(&self) {
self.count_insn("unreachable");
unsafe {
llvm::LLVMBuildUnreachable(self.llbuilder);
}
/* Arithmetic */
- pub fn add(&self, lhs: &'ll Value, rhs: &'ll Value) -> &'ll Value {
+ fn add(&self, lhs: &'ll Value, rhs: &'ll Value) -> &'ll Value {
self.count_insn("add");
unsafe {
llvm::LLVMBuildAdd(self.llbuilder, lhs, rhs, noname())
}
}
- pub fn fadd(&self, lhs: &'ll Value, rhs: &'ll Value) -> &'ll Value {
+ fn fadd(&self, lhs: &'ll Value, rhs: &'ll Value) -> &'ll Value {
self.count_insn("fadd");
unsafe {
llvm::LLVMBuildFAdd(self.llbuilder, lhs, rhs, noname())
}
}
- pub fn fadd_fast(&self, lhs: &'ll Value, rhs: &'ll Value) -> &'ll Value {
+ fn fadd_fast(&self, lhs: &'ll Value, rhs: &'ll Value) -> &'ll Value {
self.count_insn("fadd");
unsafe {
let instr = llvm::LLVMBuildFAdd(self.llbuilder, lhs, rhs, noname());
}
}
- pub fn sub(&self, lhs: &'ll Value, rhs: &'ll Value) -> &'ll Value {
+ fn sub(&self, lhs: &'ll Value, rhs: &'ll Value) -> &'ll Value {
self.count_insn("sub");
unsafe {
llvm::LLVMBuildSub(self.llbuilder, lhs, rhs, noname())
}
}
- pub fn fsub(&self, lhs: &'ll Value, rhs: &'ll Value) -> &'ll Value {
+ fn fsub(&self, lhs: &'ll Value, rhs: &'ll Value) -> &'ll Value {
self.count_insn("fsub");
unsafe {
llvm::LLVMBuildFSub(self.llbuilder, lhs, rhs, noname())
}
}
- pub fn fsub_fast(&self, lhs: &'ll Value, rhs: &'ll Value) -> &'ll Value {
+ fn fsub_fast(&self, lhs: &'ll Value, rhs: &'ll Value) -> &'ll Value {
self.count_insn("fsub");
unsafe {
let instr = llvm::LLVMBuildFSub(self.llbuilder, lhs, rhs, noname());
}
}
- pub fn mul(&self, lhs: &'ll Value, rhs: &'ll Value) -> &'ll Value {
+ fn mul(&self, lhs: &'ll Value, rhs: &'ll Value) -> &'ll Value {
self.count_insn("mul");
unsafe {
llvm::LLVMBuildMul(self.llbuilder, lhs, rhs, noname())
}
}
- pub fn fmul(&self, lhs: &'ll Value, rhs: &'ll Value) -> &'ll Value {
+ fn fmul(&self, lhs: &'ll Value, rhs: &'ll Value) -> &'ll Value {
self.count_insn("fmul");
unsafe {
llvm::LLVMBuildFMul(self.llbuilder, lhs, rhs, noname())
}
}
- pub fn fmul_fast(&self, lhs: &'ll Value, rhs: &'ll Value) -> &'ll Value {
+ fn fmul_fast(&self, lhs: &'ll Value, rhs: &'ll Value) -> &'ll Value {
self.count_insn("fmul");
unsafe {
let instr = llvm::LLVMBuildFMul(self.llbuilder, lhs, rhs, noname());
}
- pub fn udiv(&self, lhs: &'ll Value, rhs: &'ll Value) -> &'ll Value {
+ fn udiv(&self, lhs: &'ll Value, rhs: &'ll Value) -> &'ll Value {
self.count_insn("udiv");
unsafe {
llvm::LLVMBuildUDiv(self.llbuilder, lhs, rhs, noname())
}
}
- pub fn exactudiv(&self, lhs: &'ll Value, rhs: &'ll Value) -> &'ll Value {
+ fn exactudiv(&self, lhs: &'ll Value, rhs: &'ll Value) -> &'ll Value {
self.count_insn("exactudiv");
unsafe {
llvm::LLVMBuildExactUDiv(self.llbuilder, lhs, rhs, noname())
}
}
- pub fn sdiv(&self, lhs: &'ll Value, rhs: &'ll Value) -> &'ll Value {
+ fn sdiv(&self, lhs: &'ll Value, rhs: &'ll Value) -> &'ll Value {
self.count_insn("sdiv");
unsafe {
llvm::LLVMBuildSDiv(self.llbuilder, lhs, rhs, noname())
}
}
- pub fn exactsdiv(&self, lhs: &'ll Value, rhs: &'ll Value) -> &'ll Value {
+ fn exactsdiv(&self, lhs: &'ll Value, rhs: &'ll Value) -> &'ll Value {
self.count_insn("exactsdiv");
unsafe {
llvm::LLVMBuildExactSDiv(self.llbuilder, lhs, rhs, noname())
}
}
- pub fn fdiv(&self, lhs: &'ll Value, rhs: &'ll Value) -> &'ll Value {
+ fn fdiv(&self, lhs: &'ll Value, rhs: &'ll Value) -> &'ll Value {
self.count_insn("fdiv");
unsafe {
llvm::LLVMBuildFDiv(self.llbuilder, lhs, rhs, noname())
}
}
- pub fn fdiv_fast(&self, lhs: &'ll Value, rhs: &'ll Value) -> &'ll Value {
+ fn fdiv_fast(&self, lhs: &'ll Value, rhs: &'ll Value) -> &'ll Value {
self.count_insn("fdiv");
unsafe {
let instr = llvm::LLVMBuildFDiv(self.llbuilder, lhs, rhs, noname());
}
}
- pub fn urem(&self, lhs: &'ll Value, rhs: &'ll Value) -> &'ll Value {
+ fn urem(&self, lhs: &'ll Value, rhs: &'ll Value) -> &'ll Value {
self.count_insn("urem");
unsafe {
llvm::LLVMBuildURem(self.llbuilder, lhs, rhs, noname())
}
}
- pub fn srem(&self, lhs: &'ll Value, rhs: &'ll Value) -> &'ll Value {
+ fn srem(&self, lhs: &'ll Value, rhs: &'ll Value) -> &'ll Value {
self.count_insn("srem");
unsafe {
llvm::LLVMBuildSRem(self.llbuilder, lhs, rhs, noname())
}
}
- pub fn frem(&self, lhs: &'ll Value, rhs: &'ll Value) -> &'ll Value {
+ fn frem(&self, lhs: &'ll Value, rhs: &'ll Value) -> &'ll Value {
self.count_insn("frem");
unsafe {
llvm::LLVMBuildFRem(self.llbuilder, lhs, rhs, noname())
}
}
- pub fn frem_fast(&self, lhs: &'ll Value, rhs: &'ll Value) -> &'ll Value {
+ fn frem_fast(&self, lhs: &'ll Value, rhs: &'ll Value) -> &'ll Value {
self.count_insn("frem");
unsafe {
let instr = llvm::LLVMBuildFRem(self.llbuilder, lhs, rhs, noname());
}
}
- pub fn shl(&self, lhs: &'ll Value, rhs: &'ll Value) -> &'ll Value {
+ fn shl(&self, lhs: &'ll Value, rhs: &'ll Value) -> &'ll Value {
self.count_insn("shl");
unsafe {
llvm::LLVMBuildShl(self.llbuilder, lhs, rhs, noname())
}
}
- pub fn lshr(&self, lhs: &'ll Value, rhs: &'ll Value) -> &'ll Value {
+ fn lshr(&self, lhs: &'ll Value, rhs: &'ll Value) -> &'ll Value {
self.count_insn("lshr");
unsafe {
llvm::LLVMBuildLShr(self.llbuilder, lhs, rhs, noname())
}
}
- pub fn ashr(&self, lhs: &'ll Value, rhs: &'ll Value) -> &'ll Value {
+ fn ashr(&self, lhs: &'ll Value, rhs: &'ll Value) -> &'ll Value {
self.count_insn("ashr");
unsafe {
llvm::LLVMBuildAShr(self.llbuilder, lhs, rhs, noname())
}
}
- pub fn and(&self, lhs: &'ll Value, rhs: &'ll Value) -> &'ll Value {
+ fn and(&self, lhs: &'ll Value, rhs: &'ll Value) -> &'ll Value {
self.count_insn("and");
unsafe {
llvm::LLVMBuildAnd(self.llbuilder, lhs, rhs, noname())
}
}
- pub fn or(&self, lhs: &'ll Value, rhs: &'ll Value) -> &'ll Value {
+ fn or(&self, lhs: &'ll Value, rhs: &'ll Value) -> &'ll Value {
self.count_insn("or");
unsafe {
llvm::LLVMBuildOr(self.llbuilder, lhs, rhs, noname())
}
}
- pub fn xor(&self, lhs: &'ll Value, rhs: &'ll Value) -> &'ll Value {
+ fn xor(&self, lhs: &'ll Value, rhs: &'ll Value) -> &'ll Value {
self.count_insn("xor");
unsafe {
llvm::LLVMBuildXor(self.llbuilder, lhs, rhs, noname())
}
}
- pub fn neg(&self, v: &'ll Value) -> &'ll Value {
+ fn neg(&self, v: &'ll Value) -> &'ll Value {
self.count_insn("neg");
unsafe {
llvm::LLVMBuildNeg(self.llbuilder, v, noname())
}
}
- pub fn fneg(&self, v: &'ll Value) -> &'ll Value {
+ fn fneg(&self, v: &'ll Value) -> &'ll Value {
self.count_insn("fneg");
unsafe {
llvm::LLVMBuildFNeg(self.llbuilder, v, noname())
}
}
- pub fn not(&self, v: &'ll Value) -> &'ll Value {
+ fn not(&self, v: &'ll Value) -> &'ll Value {
self.count_insn("not");
unsafe {
llvm::LLVMBuildNot(self.llbuilder, v, noname())
}
}
- pub fn alloca(&self, ty: &'ll Type, name: &str, align: Align) -> &'ll Value {
+ fn alloca(&self, ty: &'ll Type, name: &str, align: Align) -> &'ll Value {
let bx = Builder::with_cx(self.cx);
bx.position_at_start(unsafe {
llvm::LLVMGetFirstBasicBlock(self.llfn())
bx.dynamic_alloca(ty, name, align)
}
- pub fn dynamic_alloca(&self, ty: &'ll Type, name: &str, align: Align) -> &'ll Value {
+ fn dynamic_alloca(&self, ty: &'ll Type, name: &str, align: Align) -> &'ll Value {
self.count_insn("alloca");
unsafe {
let alloca = if name.is_empty() {
}
}
- pub fn array_alloca(&self,
+ fn array_alloca(&self,
ty: &'ll Type,
len: &'ll Value,
name: &str,
}
}
- pub fn load(&self, ptr: &'ll Value, align: Align) -> &'ll Value {
+ fn load(&self, ptr: &'ll Value, align: Align) -> &'ll Value {
self.count_insn("load");
unsafe {
let load = llvm::LLVMBuildLoad(self.llbuilder, ptr, noname());
}
}
- pub fn volatile_load(&self, ptr: &'ll Value) -> &'ll Value {
+ fn volatile_load(&self, ptr: &'ll Value) -> &'ll Value {
self.count_insn("load.volatile");
unsafe {
let insn = llvm::LLVMBuildLoad(self.llbuilder, ptr, noname());
}
}
- pub fn atomic_load(&self, ptr: &'ll Value, order: AtomicOrdering, size: Size) -> &'ll Value {
+ fn atomic_load(&self, ptr: &'ll Value, order: AtomicOrdering, size: Size) -> &'ll Value {
self.count_insn("load.atomic");
unsafe {
let load = llvm::LLVMRustBuildAtomicLoad(self.llbuilder, ptr, noname(), order);
}
- pub fn range_metadata(&self, load: &'ll Value, range: Range<u128>) {
+ fn range_metadata(&self, load: &'ll Value, range: Range<u128>) {
if self.sess().target.target.arch == "amdgpu" {
// amdgpu/LLVM does something weird and thinks a i64 value is
// split into a v2i32, halving the bitwidth LLVM expects,
}
}
- pub fn nonnull_metadata(&self, load: &'ll Value) {
+ fn nonnull_metadata(&self, load: &'ll Value) {
unsafe {
llvm::LLVMSetMetadata(load, llvm::MD_nonnull as c_uint,
llvm::LLVMMDNodeInContext(self.cx.llcx, ptr::null(), 0));
}
}
- pub fn store(&self, val: &'ll Value, ptr: &'ll Value, align: Align) -> &'ll Value {
+ fn store(&self, val: &'ll Value, ptr: &'ll Value, align: Align) -> &'ll Value {
self.store_with_flags(val, ptr, align, MemFlags::empty())
}
- pub fn store_with_flags(
+ fn store_with_flags(
&self,
val: &'ll Value,
ptr: &'ll Value,
}
}
- pub fn atomic_store(&self, val: &'ll Value, ptr: &'ll Value,
- order: AtomicOrdering, size: Size) {
+ fn atomic_store(&self, val: &'ll Value, ptr: &'ll Value,
+ order: AtomicOrdering, size: Size) {
debug!("Store {:?} -> {:?}", val, ptr);
self.count_insn("store.atomic");
let ptr = self.check_store(val, ptr);
}
}
- pub fn gep(&self, ptr: &'ll Value, indices: &[&'ll Value]) -> &'ll Value {
+ fn gep(&self, ptr: &'ll Value, indices: &[&'ll Value]) -> &'ll Value {
self.count_insn("gep");
unsafe {
llvm::LLVMBuildGEP(self.llbuilder, ptr, indices.as_ptr(),
}
}
- pub fn inbounds_gep(&self, ptr: &'ll Value, indices: &[&'ll Value]) -> &'ll Value {
+ fn inbounds_gep(&self, ptr: &'ll Value, indices: &[&'ll Value]) -> &'ll Value {
self.count_insn("inboundsgep");
unsafe {
llvm::LLVMBuildInBoundsGEP(
}
}
- pub fn struct_gep(&self, ptr: &'ll Value, idx: u64) -> &'ll Value {
- self.count_insn("structgep");
- assert_eq!(idx as c_uint as u64, idx);
- unsafe {
- llvm::LLVMBuildStructGEP(self.llbuilder, ptr, idx as c_uint, noname())
- }
- }
-
/* Casts */
- pub fn trunc(&self, val: &'ll Value, dest_ty: &'ll Type) -> &'ll Value {
+ fn trunc(&self, val: &'ll Value, dest_ty: &'ll Type) -> &'ll Value {
self.count_insn("trunc");
unsafe {
llvm::LLVMBuildTrunc(self.llbuilder, val, dest_ty, noname())
}
}
- pub fn zext(&self, val: &'ll Value, dest_ty: &'ll Type) -> &'ll Value {
- self.count_insn("zext");
- unsafe {
- llvm::LLVMBuildZExt(self.llbuilder, val, dest_ty, noname())
- }
- }
-
- pub fn sext(&self, val: &'ll Value, dest_ty: &'ll Type) -> &'ll Value {
+ fn sext(&self, val: &'ll Value, dest_ty: &'ll Type) -> &'ll Value {
self.count_insn("sext");
unsafe {
llvm::LLVMBuildSExt(self.llbuilder, val, dest_ty, noname())
}
}
- pub fn fptoui(&self, val: &'ll Value, dest_ty: &'ll Type) -> &'ll Value {
+ fn fptoui(&self, val: &'ll Value, dest_ty: &'ll Type) -> &'ll Value {
self.count_insn("fptoui");
unsafe {
llvm::LLVMBuildFPToUI(self.llbuilder, val, dest_ty, noname())
}
}
- pub fn fptosi(&self, val: &'ll Value, dest_ty: &'ll Type) -> &'ll Value {
+ fn fptosi(&self, val: &'ll Value, dest_ty: &'ll Type) -> &'ll Value {
self.count_insn("fptosi");
unsafe {
llvm::LLVMBuildFPToSI(self.llbuilder, val, dest_ty,noname())
}
}
- pub fn uitofp(&self, val: &'ll Value, dest_ty: &'ll Type) -> &'ll Value {
+ fn uitofp(&self, val: &'ll Value, dest_ty: &'ll Type) -> &'ll Value {
self.count_insn("uitofp");
unsafe {
llvm::LLVMBuildUIToFP(self.llbuilder, val, dest_ty, noname())
}
}
- pub fn sitofp(&self, val: &'ll Value, dest_ty: &'ll Type) -> &'ll Value {
+ fn sitofp(&self, val: &'ll Value, dest_ty: &'ll Type) -> &'ll Value {
self.count_insn("sitofp");
unsafe {
llvm::LLVMBuildSIToFP(self.llbuilder, val, dest_ty, noname())
}
}
- pub fn fptrunc(&self, val: &'ll Value, dest_ty: &'ll Type) -> &'ll Value {
+ fn fptrunc(&self, val: &'ll Value, dest_ty: &'ll Type) -> &'ll Value {
self.count_insn("fptrunc");
unsafe {
llvm::LLVMBuildFPTrunc(self.llbuilder, val, dest_ty, noname())
}
}
- pub fn fpext(&self, val: &'ll Value, dest_ty: &'ll Type) -> &'ll Value {
+ fn fpext(&self, val: &'ll Value, dest_ty: &'ll Type) -> &'ll Value {
self.count_insn("fpext");
unsafe {
llvm::LLVMBuildFPExt(self.llbuilder, val, dest_ty, noname())
}
}
- pub fn ptrtoint(&self, val: &'ll Value, dest_ty: &'ll Type) -> &'ll Value {
+ fn ptrtoint(&self, val: &'ll Value, dest_ty: &'ll Type) -> &'ll Value {
self.count_insn("ptrtoint");
unsafe {
llvm::LLVMBuildPtrToInt(self.llbuilder, val, dest_ty, noname())
}
}
- pub fn inttoptr(&self, val: &'ll Value, dest_ty: &'ll Type) -> &'ll Value {
+ fn inttoptr(&self, val: &'ll Value, dest_ty: &'ll Type) -> &'ll Value {
self.count_insn("inttoptr");
unsafe {
llvm::LLVMBuildIntToPtr(self.llbuilder, val, dest_ty, noname())
}
}
- pub fn bitcast(&self, val: &'ll Value, dest_ty: &'ll Type) -> &'ll Value {
+ fn bitcast(&self, val: &'ll Value, dest_ty: &'ll Type) -> &'ll Value {
self.count_insn("bitcast");
unsafe {
llvm::LLVMBuildBitCast(self.llbuilder, val, dest_ty, noname())
}
}
- pub fn pointercast(&self, val: &'ll Value, dest_ty: &'ll Type) -> &'ll Value {
- self.count_insn("pointercast");
+
+ fn intcast(&self, val: &'ll Value, dest_ty: &'ll Type, is_signed: bool) -> &'ll Value {
+ self.count_insn("intcast");
unsafe {
- llvm::LLVMBuildPointerCast(self.llbuilder, val, dest_ty, noname())
+ llvm::LLVMRustBuildIntCast(self.llbuilder, val, dest_ty, is_signed)
}
}
- pub fn intcast(&self, val: &'ll Value, dest_ty: &'ll Type, is_signed: bool) -> &'ll Value {
- self.count_insn("intcast");
+ fn pointercast(&self, val: &'ll Value, dest_ty: &'ll Type) -> &'ll Value {
+ self.count_insn("pointercast");
unsafe {
- llvm::LLVMRustBuildIntCast(self.llbuilder, val, dest_ty, is_signed)
+ llvm::LLVMBuildPointerCast(self.llbuilder, val, dest_ty, noname())
}
}
/* Comparisons */
- pub fn icmp(&self, op: IntPredicate, lhs: &'ll Value, rhs: &'ll Value) -> &'ll Value {
+ fn icmp(&self, op: IntPredicate, lhs: &'ll Value, rhs: &'ll Value) -> &'ll Value {
self.count_insn("icmp");
unsafe {
llvm::LLVMBuildICmp(self.llbuilder, op as c_uint, lhs, rhs, noname())
}
}
- pub fn fcmp(&self, op: RealPredicate, lhs: &'ll Value, rhs: &'ll Value) -> &'ll Value {
+ fn fcmp(&self, op: RealPredicate, lhs: &'ll Value, rhs: &'ll Value) -> &'ll Value {
self.count_insn("fcmp");
unsafe {
llvm::LLVMBuildFCmp(self.llbuilder, op as c_uint, lhs, rhs, noname())
}
/* Miscellaneous instructions */
- pub fn empty_phi(&self, ty: &'ll Type) -> &'ll Value {
+ fn empty_phi(&self, ty: &'ll Type) -> &'ll Value {
self.count_insn("emptyphi");
unsafe {
llvm::LLVMBuildPhi(self.llbuilder, ty, noname())
}
}
- pub fn phi(&self, ty: &'ll Type, vals: &[&'ll Value], bbs: &[&'ll BasicBlock]) -> &'ll Value {
+ fn phi(&self, ty: &'ll Type, vals: &[&'ll Value], bbs: &[&'ll BasicBlock]) -> &'ll Value {
assert_eq!(vals.len(), bbs.len());
let phi = self.empty_phi(ty);
self.count_insn("addincoming");
}
}
- pub fn inline_asm_call(&self, asm: *const c_char, cons: *const c_char,
- inputs: &[&'ll Value], output: &'ll Type,
- volatile: bool, alignstack: bool,
- dia: AsmDialect) -> Option<&'ll Value> {
+ fn inline_asm_call(&self, asm: *const c_char, cons: *const c_char,
+ inputs: &[&'ll Value], output: &'ll Type,
+ volatile: bool, alignstack: bool,
+ dia: AsmDialect) -> Option<&'ll Value> {
self.count_insn("inlineasm");
let volatile = if volatile { llvm::True }
}).collect::<Vec<_>>();
debug!("Asm Output Type: {:?}", output);
- let fty = Type::func(&argtys[..], output);
+ let fty = Type::func::<Value>(&argtys[..], output);
unsafe {
// Ask LLVM to verify that the constraints are well-formed.
let constraints_ok = llvm::LLVMRustInlineAsmVerify(fty, cons);
}
}
- pub fn call(&self, llfn: &'ll Value, args: &[&'ll Value],
- bundle: Option<&OperandBundleDef<'ll>>) -> &'ll Value {
- self.count_insn("call");
-
- debug!("Call {:?} with args ({:?})",
- llfn,
- args);
-
- let args = self.check_call("call", llfn, args);
- let bundle = bundle.map(|b| &*b.raw);
-
- unsafe {
- llvm::LLVMRustBuildCall(self.llbuilder, llfn, args.as_ptr(),
- args.len() as c_uint, bundle, noname())
- }
- }
-
- pub fn memcpy(&self, dst: &'ll Value, dst_align: u64,
+ fn memcpy(&self, dst: &'ll Value, dst_align: u64,
src: &'ll Value, src_align: u64,
size: &'ll Value, is_volatile: bool) -> &'ll Value {
unsafe {
}
}
- pub fn memmove(&self, dst: &'ll Value, dst_align: u64,
+ fn memmove(&self, dst: &'ll Value, dst_align: u64,
src: &'ll Value, src_align: u64,
size: &'ll Value, is_volatile: bool) -> &'ll Value {
unsafe {
}
}
- pub fn minnum(&self, lhs: &'ll Value, rhs: &'ll Value) -> &'ll Value {
+ fn minnum(&self, lhs: &'ll Value, rhs: &'ll Value) -> &'ll Value {
self.count_insn("minnum");
unsafe {
let instr = llvm::LLVMRustBuildMinNum(self.llbuilder, lhs, rhs);
instr.expect("LLVMRustBuildMinNum is not available in LLVM version < 6.0")
}
}
- pub fn maxnum(&self, lhs: &'ll Value, rhs: &'ll Value) -> &'ll Value {
+ fn maxnum(&self, lhs: &'ll Value, rhs: &'ll Value) -> &'ll Value {
self.count_insn("maxnum");
unsafe {
let instr = llvm::LLVMRustBuildMaxNum(self.llbuilder, lhs, rhs);
}
}
- pub fn select(
+ fn select(
&self, cond: &'ll Value,
then_val: &'ll Value,
else_val: &'ll Value,
}
#[allow(dead_code)]
- pub fn va_arg(&self, list: &'ll Value, ty: &'ll Type) -> &'ll Value {
+ fn va_arg(&self, list: &'ll Value, ty: &'ll Type) -> &'ll Value {
self.count_insn("vaarg");
unsafe {
llvm::LLVMBuildVAArg(self.llbuilder, list, ty, noname())
}
}
- pub fn extract_element(&self, vec: &'ll Value, idx: &'ll Value) -> &'ll Value {
+ fn extract_element(&self, vec: &'ll Value, idx: &'ll Value) -> &'ll Value {
self.count_insn("extractelement");
unsafe {
llvm::LLVMBuildExtractElement(self.llbuilder, vec, idx, noname())
}
}
- pub fn insert_element(
+ fn insert_element(
&self, vec: &'ll Value,
elt: &'ll Value,
idx: &'ll Value,
}
}
- pub fn shuffle_vector(&self, v1: &'ll Value, v2: &'ll Value, mask: &'ll Value) -> &'ll Value {
+ fn shuffle_vector(&self, v1: &'ll Value, v2: &'ll Value, mask: &'ll Value) -> &'ll Value {
self.count_insn("shufflevector");
unsafe {
llvm::LLVMBuildShuffleVector(self.llbuilder, v1, v2, mask, noname())
}
}
- pub fn vector_splat(&self, num_elts: usize, elt: &'ll Value) -> &'ll Value {
+ fn vector_splat(&self, num_elts: usize, elt: &'ll Value) -> &'ll Value {
unsafe {
let elt_ty = val_ty(elt);
- let undef = llvm::LLVMGetUndef(Type::vector(elt_ty, num_elts as u64));
+ let undef = llvm::LLVMGetUndef(Type::vector::<Value>(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::<Value>(Type::i32(self.cx), num_elts as u64);
self.shuffle_vector(vec, undef, C_null(vec_i32_ty))
}
}
- pub fn vector_reduce_fadd_fast(&self, acc: &'ll Value, src: &'ll Value) -> &'ll Value {
+ fn vector_reduce_fadd_fast(&self, acc: &'ll Value, src: &'ll Value) -> &'ll Value {
self.count_insn("vector.reduce.fadd_fast");
unsafe {
// FIXME: add a non-fast math version once
instr
}
}
- pub fn vector_reduce_fmul_fast(&self, acc: &'ll Value, src: &'ll Value) -> &'ll Value {
+ fn vector_reduce_fmul_fast(&self, acc: &'ll Value, src: &'ll Value) -> &'ll Value {
self.count_insn("vector.reduce.fmul_fast");
unsafe {
// FIXME: add a non-fast math version once
instr
}
}
- pub fn vector_reduce_add(&self, src: &'ll Value) -> &'ll Value {
+ fn vector_reduce_add(&self, src: &'ll Value) -> &'ll Value {
self.count_insn("vector.reduce.add");
unsafe { llvm::LLVMRustBuildVectorReduceAdd(self.llbuilder, src) }
}
- pub fn vector_reduce_mul(&self, src: &'ll Value) -> &'ll Value {
+ fn vector_reduce_mul(&self, src: &'ll Value) -> &'ll Value {
self.count_insn("vector.reduce.mul");
unsafe { llvm::LLVMRustBuildVectorReduceMul(self.llbuilder, src) }
}
- pub fn vector_reduce_and(&self, src: &'ll Value) -> &'ll Value {
+ fn vector_reduce_and(&self, src: &'ll Value) -> &'ll Value {
self.count_insn("vector.reduce.and");
unsafe { llvm::LLVMRustBuildVectorReduceAnd(self.llbuilder, src) }
}
- pub fn vector_reduce_or(&self, src: &'ll Value) -> &'ll Value {
+ fn vector_reduce_or(&self, src: &'ll Value) -> &'ll Value {
self.count_insn("vector.reduce.or");
unsafe { llvm::LLVMRustBuildVectorReduceOr(self.llbuilder, src) }
}
- pub fn vector_reduce_xor(&self, src: &'ll Value) -> &'ll Value {
+ fn vector_reduce_xor(&self, src: &'ll Value) -> &'ll Value {
self.count_insn("vector.reduce.xor");
unsafe { llvm::LLVMRustBuildVectorReduceXor(self.llbuilder, src) }
}
- pub fn vector_reduce_fmin(&self, src: &'ll Value) -> &'ll Value {
+ fn vector_reduce_fmin(&self, src: &'ll Value) -> &'ll Value {
self.count_insn("vector.reduce.fmin");
unsafe { llvm::LLVMRustBuildVectorReduceFMin(self.llbuilder, src, /*NoNaNs:*/ false) }
}
- pub fn vector_reduce_fmax(&self, src: &'ll Value) -> &'ll Value {
+ fn vector_reduce_fmax(&self, src: &'ll Value) -> &'ll Value {
self.count_insn("vector.reduce.fmax");
unsafe { llvm::LLVMRustBuildVectorReduceFMax(self.llbuilder, src, /*NoNaNs:*/ false) }
}
- pub fn vector_reduce_fmin_fast(&self, src: &'ll Value) -> &'ll Value {
+ fn vector_reduce_fmin_fast(&self, src: &'ll Value) -> &'ll Value {
self.count_insn("vector.reduce.fmin_fast");
unsafe {
let instr = llvm::LLVMRustBuildVectorReduceFMin(self.llbuilder, src, /*NoNaNs:*/ true);
instr
}
}
- pub fn vector_reduce_fmax_fast(&self, src: &'ll Value) -> &'ll Value {
+ fn vector_reduce_fmax_fast(&self, src: &'ll Value) -> &'ll Value {
self.count_insn("vector.reduce.fmax_fast");
unsafe {
let instr = llvm::LLVMRustBuildVectorReduceFMax(self.llbuilder, src, /*NoNaNs:*/ true);
instr
}
}
- pub fn vector_reduce_min(&self, src: &'ll Value, is_signed: bool) -> &'ll Value {
+ fn vector_reduce_min(&self, src: &'ll Value, is_signed: bool) -> &'ll Value {
self.count_insn("vector.reduce.min");
unsafe { llvm::LLVMRustBuildVectorReduceMin(self.llbuilder, src, is_signed) }
}
- pub fn vector_reduce_max(&self, src: &'ll Value, is_signed: bool) -> &'ll Value {
+ fn vector_reduce_max(&self, src: &'ll Value, is_signed: bool) -> &'ll Value {
self.count_insn("vector.reduce.max");
unsafe { llvm::LLVMRustBuildVectorReduceMax(self.llbuilder, src, is_signed) }
}
- pub fn extract_value(&self, agg_val: &'ll Value, idx: u64) -> &'ll Value {
+ fn extract_value(&self, agg_val: &'ll Value, idx: u64) -> &'ll Value {
self.count_insn("extractvalue");
assert_eq!(idx as c_uint as u64, idx);
unsafe {
}
}
- pub fn insert_value(&self, agg_val: &'ll Value, elt: &'ll Value,
+ fn insert_value(&self, agg_val: &'ll Value, elt: &'ll Value,
idx: u64) -> &'ll Value {
self.count_insn("insertvalue");
assert_eq!(idx as c_uint as u64, idx);
}
}
- pub fn landing_pad(&self, ty: &'ll Type, pers_fn: &'ll Value,
+ fn landing_pad(&self, ty: &'ll Type, pers_fn: &'ll Value,
num_clauses: usize) -> &'ll Value {
self.count_insn("landingpad");
unsafe {
}
}
- pub fn add_clause(&self, landing_pad: &'ll Value, clause: &'ll Value) {
+ fn add_clause(&self, landing_pad: &'ll Value, clause: &'ll Value) {
unsafe {
llvm::LLVMAddClause(landing_pad, clause);
}
}
- pub fn set_cleanup(&self, landing_pad: &'ll Value) {
+ fn set_cleanup(&self, landing_pad: &'ll Value) {
self.count_insn("setcleanup");
unsafe {
llvm::LLVMSetCleanup(landing_pad, llvm::True);
}
}
- pub fn resume(&self, exn: &'ll Value) -> &'ll Value {
+ fn resume(&self, exn: &'ll Value) -> &'ll Value {
self.count_insn("resume");
unsafe {
llvm::LLVMBuildResume(self.llbuilder, exn)
}
}
- pub fn cleanup_pad(&self,
+ fn cleanup_pad(&self,
parent: Option<&'ll Value>,
args: &[&'ll Value]) -> &'ll Value {
self.count_insn("cleanuppad");
ret.expect("LLVM does not have support for cleanuppad")
}
- pub fn cleanup_ret(
+ fn cleanup_ret(
&self, cleanup: &'ll Value,
unwind: Option<&'ll BasicBlock>,
) -> &'ll Value {
ret.expect("LLVM does not have support for cleanupret")
}
- pub fn catch_pad(&self,
+ fn catch_pad(&self,
parent: &'ll Value,
args: &[&'ll Value]) -> &'ll Value {
self.count_insn("catchpad");
ret.expect("LLVM does not have support for catchpad")
}
- pub fn catch_ret(&self, pad: &'ll Value, unwind: &'ll BasicBlock) -> &'ll Value {
+ fn catch_ret(&self, pad: &'ll Value, unwind: &'ll BasicBlock) -> &'ll Value {
self.count_insn("catchret");
let ret = unsafe {
llvm::LLVMRustBuildCatchRet(self.llbuilder, pad, unwind)
ret.expect("LLVM does not have support for catchret")
}
- pub fn catch_switch(
+ fn catch_switch(
&self,
parent: Option<&'ll Value>,
unwind: Option<&'ll BasicBlock>,
ret.expect("LLVM does not have support for catchswitch")
}
- pub fn add_handler(&self, catch_switch: &'ll Value, handler: &'ll BasicBlock) {
+ fn add_handler(&self, catch_switch: &'ll Value, handler: &'ll BasicBlock) {
unsafe {
llvm::LLVMRustAddHandler(catch_switch, handler);
}
}
- pub fn set_personality_fn(&self, personality: &'ll Value) {
+ fn set_personality_fn(&self, personality: &'ll Value) {
unsafe {
llvm::LLVMSetPersonalityFn(self.llfn(), personality);
}
}
// Atomic Operations
- pub fn atomic_cmpxchg(
+ fn atomic_cmpxchg(
&self,
dst: &'ll Value,
cmp: &'ll Value,
order, failure_order, weak)
}
}
- pub fn atomic_rmw(
+ fn atomic_rmw(
&self,
op: AtomicRmwBinOp,
dst: &'ll Value,
}
}
- pub fn atomic_fence(&self, order: AtomicOrdering, scope: SynchronizationScope) {
+ fn atomic_fence(&self, order: AtomicOrdering, scope: SynchronizationScope) {
unsafe {
llvm::LLVMRustBuildAtomicFence(self.llbuilder, order, scope);
}
}
- pub fn add_case(&self, s: &'ll Value, on_val: &'ll Value, dest: &'ll BasicBlock) {
+ fn add_case(&self, s: &'ll Value, on_val: &'ll Value, dest: &'ll BasicBlock) {
unsafe {
llvm::LLVMAddCase(s, on_val, dest)
}
}
- pub fn add_incoming_to_phi(&self, phi: &'ll Value, val: &'ll Value, bb: &'ll BasicBlock) {
+ fn add_incoming_to_phi(&self, phi: &'ll Value, val: &'ll Value, bb: &'ll BasicBlock) {
self.count_insn("addincoming");
unsafe {
llvm::LLVMAddIncoming(phi, &val, &bb, 1 as c_uint);
}
}
- pub fn set_invariant_load(&self, load: &'ll Value) {
+ fn set_invariant_load(&self, load: &'ll Value) {
unsafe {
llvm::LLVMSetMetadata(load, llvm::MD_invariant_load as c_uint,
llvm::LLVMMDNodeInContext(self.cx.llcx, ptr::null(), 0));
Cow::Owned(casted_args)
}
- pub fn lifetime_start(&self, ptr: &'ll Value, size: Size) {
+ fn lifetime_start(&self, ptr: &'ll Value, size: Size) {
self.call_lifetime_intrinsic("llvm.lifetime.start", ptr, size);
}
- pub fn lifetime_end(&self, ptr: &'ll Value, size: Size) {
+ fn lifetime_end(&self, ptr: &'ll Value, size: Size) {
self.call_lifetime_intrinsic("llvm.lifetime.end", ptr, size);
}
let ptr = self.pointercast(ptr, Type::i8p(self.cx));
self.call(lifetime_intrinsic, &[C_u64(self.cx, size), ptr], None);
}
+
+ fn call(&self, llfn: &'ll Value, args: &[&'ll Value],
+ bundle: Option<&OperandBundleDef<'ll>>) -> &'ll Value {
+ self.count_insn("call");
+
+ debug!("Call {:?} with args ({:?})",
+ llfn,
+ args);
+
+ let args = self.check_call("call", llfn, args);
+ let bundle = bundle.map(|b| &*b.raw);
+
+ unsafe {
+ llvm::LLVMRustBuildCall(
+ self.llbuilder,
+ llfn,
+ args.as_ptr() as *const &llvm::Value,
+ args.len() as c_uint,
+ bundle, noname()
+ )
+ }
+ }
+
+ fn zext(&self, val: &'ll Value, dest_ty: &'ll Type) -> &'ll Value {
+ self.count_insn("zext");
+ unsafe {
+ llvm::LLVMBuildZExt(self.llbuilder, val, dest_ty, noname())
+ }
+ }
+
+ fn struct_gep(&self, ptr: &'ll Value, idx: u64) -> &'ll Value {
+ self.count_insn("structgep");
+ assert_eq!(idx as c_uint as u64, idx);
+ unsafe {
+ llvm::LLVMBuildStructGEP(self.llbuilder, ptr, idx as c_uint, noname())
+ }
+ }
+
+ fn cx(&self) -> &'a CodegenCx<'ll, 'tcx, &'ll Value> {
+ &self.cx
+ }
}
use declare;
use type_::Type;
use type_of::LayoutLlvmExt;
-use value::Value;
+use value::{Value, ValueTrait};
use rustc::ty::{self, Ty, TyCtxt};
use rustc::ty::layout::{HasDataLayout, LayoutOf};
use rustc::hir;
+use traits::BuilderMethods;
use libc::{c_uint, c_char};
}
}
-pub fn val_ty(v: &'ll Value) -> &'ll Type {
+pub fn val_ty<Value : ?Sized>(v: &'ll Value) -> &'ll Type where Value : ValueTrait {
unsafe {
- llvm::LLVMTypeOf(v)
+ llvm::LLVMTypeOf(v.to_llvm())
}
}
}
}
-pub fn C_undef(t: &'ll Type) -> &'ll Value {
+pub fn C_undef<Value : ?Sized>(t: &'ll Type) -> &'ll Value where Value : ValueTrait {
unsafe {
- llvm::LLVMGetUndef(t)
+ Value::of_llvm(llvm::LLVMGetUndef(t))
}
}
-pub fn C_int(t: &'ll Type, i: i64) -> &'ll Value {
+pub fn C_int<Value : ?Sized>(t: &'ll Type, i: i64) -> &'ll Value where Value : ValueTrait {
unsafe {
- llvm::LLVMConstInt(t, i as u64, True)
+ Value::of_llvm(llvm::LLVMConstInt(t, i as u64, True))
}
}
-pub fn C_uint(t: &'ll Type, i: u64) -> &'ll Value {
+pub fn C_uint<Value : ?Sized>(t: &'ll Type, i: u64) -> &'ll Value where Value : ValueTrait {
unsafe {
- llvm::LLVMConstInt(t, i, False)
+ Value::of_llvm(llvm::LLVMConstInt(t, i, False))
}
}
}
}
-pub fn C_bool(cx: &CodegenCx<'ll, '_>, val: bool) -> &'ll Value {
+pub fn C_bool<Value : ?Sized>(
+ cx: &CodegenCx<'ll, '_, &'ll Value>,
+ val: bool
+) -> &'ll Value where Value : ValueTrait {
C_uint(Type::i1(cx), val as u64)
}
-pub fn C_i32(cx: &CodegenCx<'ll, '_>, i: i32) -> &'ll Value {
+pub fn C_i32<Value : ?Sized>(
+ cx: &CodegenCx<'ll, '_, &'ll Value>,
+ i: i32
+) -> &'ll Value where Value : ValueTrait {
C_int(Type::i32(cx), i as i64)
}
C_uint(Type::i64(cx), i)
}
-pub fn C_usize(cx: &CodegenCx<'ll, '_>, i: u64) -> &'ll Value {
+pub fn C_usize<Value : ?Sized>(
+ cx: &CodegenCx<'ll, '_, &'ll Value>,
+ i: u64
+) -> &'ll Value where Value : ValueTrait {
let bit_size = cx.data_layout().pointer_size.bits();
if bit_size < 64 {
// make sure it doesn't overflow
use base;
use declare;
use monomorphize::Instance;
-use value::Value;
+use value::{Value, ValueTrait};
use monomorphize::partitioning::CodegenUnit;
use type_::Type;
None
};
- let isize_ty = Type::ix_llcx(llcx, tcx.data_layout.pointer_size.bits());
+ let isize_ty = Type::ix_llcx::<Value>(llcx, tcx.data_layout.pointer_size.bits());
CodegenCx {
tcx,
}
}
-impl<'b, 'tcx> CodegenCx<'b, 'tcx> {
+impl<'b, 'tcx, Value : ?Sized> CodegenCx<'b, 'tcx, &'b Value> where Value : ValueTrait {
pub fn sess<'a>(&'a self) -> &'a Session {
&self.tcx.sess
}
declare_intrinsic(self, key).unwrap_or_else(|| bug!("unknown intrinsic '{}'", key))
}
+}
+impl<'b, 'tcx> CodegenCx<'b, 'tcx, &'b Value> {
/// Generate a new symbol name with the given prefix. This symbol name must
/// only be used for definitions with `internal` or `private` linkage.
pub fn generate_local_symbol_name(&self, prefix: &str) -> String {
} else {
"rust_eh_personality"
};
- let fty = Type::variadic_func(&[], Type::i32(self));
+ let fty = Type::variadic_func::<Value>(&[], Type::i32(self));
declare::declare_cfn(self, name, fty)
}
};
}
/// Declare any llvm intrinsics that you might need
-fn declare_intrinsic(cx: &CodegenCx<'ll, '_>, key: &str) -> Option<&'ll Value> {
+fn declare_intrinsic<Value : ?Sized>(
+ cx: &CodegenCx<'ll, '_, &'ll Value>,
+ key: &str
+) -> Option<&'ll Value> where Value : ValueTrait {
macro_rules! ifn {
($name:expr, fn() -> $ret:expr) => (
if key == $name {
- let f = declare::declare_cfn(cx, $name, Type::func(&[], $ret));
- llvm::SetUnnamedAddr(f, false);
+ let f = declare::declare_cfn(cx, $name, Type::func::<Value>(&[], $ret));
+ llvm::SetUnnamedAddr(f.to_llvm(), false);
cx.intrinsics.borrow_mut().insert($name, f.clone());
return Some(f);
}
);
($name:expr, fn(...) -> $ret:expr) => (
if key == $name {
- let f = declare::declare_cfn(cx, $name, Type::variadic_func(&[], $ret));
- llvm::SetUnnamedAddr(f, false);
+ let f = declare::declare_cfn(cx, $name, Type::variadic_func::<Value>(&[], $ret));
+ llvm::SetUnnamedAddr(f.to_llvm(), false);
cx.intrinsics.borrow_mut().insert($name, f.clone());
return Some(f);
}
);
($name:expr, fn($($arg:expr),*) -> $ret:expr) => (
if key == $name {
- let f = declare::declare_cfn(cx, $name, Type::func(&[$($arg),*], $ret));
- llvm::SetUnnamedAddr(f, false);
+ let f = declare::declare_cfn(cx, $name, Type::func::<Value>(&[$($arg),*], $ret));
+ llvm::SetUnnamedAddr(f.to_llvm(), false);
cx.intrinsics.borrow_mut().insert($name, f.clone());
return Some(f);
}
let t_f32 = Type::f32(cx);
let t_f64 = Type::f64(cx);
- let t_v2f32 = Type::vector(t_f32, 2);
- let t_v4f32 = Type::vector(t_f32, 4);
- let t_v8f32 = Type::vector(t_f32, 8);
- let t_v16f32 = Type::vector(t_f32, 16);
+ let t_v2f32 = Type::vector::<Value>(t_f32, 2);
+ let t_v4f32 = Type::vector::<Value>(t_f32, 4);
+ let t_v8f32 = Type::vector::<Value>(t_f32, 8);
+ let t_v16f32 = Type::vector::<Value>(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::<Value>(t_f64, 2);
+ let t_v4f64 = Type::vector::<Value>(t_f64, 4);
+ let t_v8f64 = Type::vector::<Value>(t_f64, 8);
ifn!("llvm.memset.p0i8.i16", fn(i8p, t_i8, t_i16, t_i32, i1) -> void);
ifn!("llvm.memset.p0i8.i32", fn(i8p, t_i8, t_i32, t_i32, i1) -> void);
use rustc::session::config::DebugInfo;
use type_::Type;
use value::Value;
+use traits::BuilderMethods;
use syntax::attr;
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::<Value>(Type::i8(cx),
section_contents.len() as u64);
let section_var = declare::define_global(cx, section_var_name,
use syntax::ast;
use syntax::symbol::{Symbol, InternedString};
use rustc::ty::layout::{self, LayoutOf};
+use traits::BuilderMethods;
pub mod gdb;
mod utils;
use llvm;
use llvm::debuginfo::DIScope;
use builder::Builder;
+use traits::BuilderMethods;
use libc::c_uint;
use syntax_pos::{Span, Pos};
}
}
-pub fn set_debug_location(bx: &Builder<'_, 'll, '_>, debug_location: InternalDebugLocation<'ll>) {
+pub fn set_debug_location(
+ bx: &Builder<'_, 'll, '_>,
+ debug_location: InternalDebugLocation<'ll>
+) {
let metadata_node = match debug_location {
KnownLocation { scope, line, col } => {
// For MSVC, set the column number to zero.
use attributes;
use context::CodegenCx;
use type_::Type;
-use value::Value;
+use value::{Value, ValueTrait};
/// Declare a global value.
///
/// If there’s a value with the same name already declared, the function will
/// update the declaration and return existing Value instead.
-fn declare_raw_fn(
- cx: &CodegenCx<'ll, '_>,
+fn declare_raw_fn<Value : ?Sized>(
+ cx: &CodegenCx<'ll, '_, &'ll Value>,
name: &str,
callconv: llvm::CallConv,
ty: &'ll Type,
-) -> &'ll Value {
+) -> &'ll Value where Value : ValueTrait {
debug!("declare_raw_fn(name={:?}, ty={:?})", name, ty);
let namebuf = SmallCStr::new(name);
let llfn = unsafe {
attributes::non_lazy_bind(cx.sess(), llfn);
- llfn
+ Value::of_llvm(llfn)
}
///
/// If there’s a value with the same name already declared, the function will
/// update the declaration and return existing Value instead.
-pub fn declare_cfn(cx: &CodegenCx<'ll, '_>, name: &str, fn_type: &'ll Type) -> &'ll Value {
+pub fn declare_cfn<Value : ?Sized>(
+ cx: &CodegenCx<'ll, '_, &'ll Value>,
+ name: &str,
+ fn_type: &'ll Type
+) -> &'ll Value where Value : ValueTrait {
declare_raw_fn(cx, name, llvm::CCallConv, fn_type)
}
/// Declare a private global
///
/// Use this function when you intend to define a global without a name.
-pub fn define_private_global(cx: &CodegenCx<'ll, '_>, ty: &'ll Type) -> &'ll Value {
+pub fn define_private_global(cx: &CodegenCx<'ll, '_, &'ll Value>, ty: &'ll Type) -> &'ll Value {
unsafe {
llvm::LLVMRustInsertPrivateGlobal(cx.llmod, ty)
}
use rustc::ty::layout::LayoutOf;
use rustc::ty::{self, Ty};
use value::Value;
+use traits::BuilderMethods;
-pub fn size_and_align_of_dst(bx: &Builder<'_, 'll, 'tcx>, t: Ty<'tcx>, info: Option<&'ll Value>)
- -> (&'ll Value, &'ll Value) {
+pub fn size_and_align_of_dst(
+ bx: &Builder<'_, 'll, 'tcx>,
+ t: Ty<'tcx>,
+ info: Option<&'ll Value>
+) -> (&'ll Value, &'ll Value) {
debug!("calculate size of DST: {}; with lost info: {:?}",
t, info);
if bx.cx.type_is_sized(t) {
use builder::Builder;
use value::Value;
+use traits::BuilderMethods;
+
use rustc::session::Session;
use syntax_pos::Span;
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::<Value>(elem, length as u64)]
}
Aggregate(false, ref contents) => {
let elems = contents.iter()
}
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::<Value>(llvm_elem, length as u64))
+ ]
}
intrinsics::Type::Integer(_, width, llvm_width) if width != llvm_width => {
// the LLVM intrinsic uses a smaller integer
intrinsics::IntrinsicDef::Named(name) => {
let f = declare::declare_cfn(cx,
name,
- Type::func(&inputs, outputs));
+ Type::func::<Value>(&inputs, outputs));
bx.call(f, &llargs, None)
}
};
}
// 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::<Value>(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()));
}
elem_ty = elem_ty.ptr_to();
no_pointers -= 1;
}
- Type::vector(elem_ty, vec_len as u64)
+ Type::vector::<Value>(elem_ty, vec_len as u64)
}
// Truncate the mask vector to a vector of i1s:
let (mask, mask_ty) = {
let i1 = Type::i1(bx.cx);
- let i1xn = Type::vector(i1, in_len as u64);
+ let i1xn = Type::vector::<Value>(i1, in_len as u64);
(bx.trunc(args[2].immediate(), i1xn), i1xn)
};
let llvm_intrinsic = format!("llvm.masked.gather.{}.{}",
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));
+ Type::func::<Value>(&[
+ llvm_pointer_vec_ty,
+ alignment_ty,
+ mask_ty,
+ llvm_elem_vec_ty], llvm_elem_vec_ty));
llvm::SetUnnamedAddr(f, false);
let v = bx.call(f, &[args[1].immediate(), alignment, mask, args[0].immediate()],
None);
// Truncate the mask vector to a vector of i1s:
let (mask, mask_ty) = {
let i1 = Type::i1(bx.cx);
- let i1xn = Type::vector(i1, in_len as u64);
+ let i1xn = Type::vector::<Value>(i1, in_len as u64);
(bx.trunc(args[2].immediate(), i1xn), i1xn)
};
let llvm_intrinsic = format!("llvm.masked.scatter.{}.{}",
llvm_elem_vec_str, llvm_pointer_vec_str);
let f = declare::declare_cfn(bx.cx, &llvm_intrinsic,
- Type::func(&[llvm_elem_vec_ty,
+ Type::func::<Value>(&[llvm_elem_vec_ty,
llvm_pointer_vec_ty,
alignment_ty,
mask_ty], ret_t));
// 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::<Value>(i1, in_len as u64);
bx.trunc(args[0].immediate(), i1xn)
};
return match in_elem.sty {
pub mod wasm;
}
+mod traits;
+
mod abi;
mod allocator;
mod asm;
use type_::Type;
use value::Value;
+use traits::BuilderMethods;
+
use rustc::ty::{self, Ty};
use rustc::ty::layout::HasDataLayout;
use debuginfo;
ptr
}
- pub fn get_usize(self, bx: &Builder<'a, 'll, 'tcx>, llvtable: &'ll Value) -> &'ll Value {
+ pub fn get_usize(
+ self,
+ bx: &Builder<'a, 'll, 'tcx, &'ll Value>,
+ llvtable: &'ll Value
+ ) -> &'ll Value {
// Load the data pointer from the object.
debug!("get_int({:?}, {:?})", llvtable, self);
use type_::Type;
use value::Value;
+use traits::BuilderMethods;
+
use syntax::symbol::Symbol;
use syntax_pos::Pos;
}
};
- let funclet_br = |this: &mut Self, bx: Builder<'_, 'll, '_>, target: mir::BasicBlock| {
- let (lltarget, is_cleanupret) = lltarget(this, target);
- if is_cleanupret {
- // micro-optimization: generate a `ret` rather than a jump
- // to a trampoline.
- bx.cleanup_ret(cleanup_pad.unwrap(), Some(lltarget));
- } else {
- bx.br(lltarget);
- }
- };
+ let funclet_br =
+ |this: &mut Self, bx: Builder<'_, 'll, '_, &'ll Value>, target: mir::BasicBlock| {
+ let (lltarget, is_cleanupret) = lltarget(this, target);
+ if is_cleanupret {
+ // micro-optimization: generate a `ret` rather than a jump
+ // to a trampoline.
+ bx.cleanup_ret(cleanup_pad.unwrap(), Some(lltarget));
+ } else {
+ bx.br(lltarget);
+ }
+ };
let do_call = |
this: &mut Self,
}
}
- fn get_personality_slot(&mut self, bx: &Builder<'a, 'll, 'tcx>) -> PlaceRef<'tcx, &'ll Value> {
+ fn get_personality_slot(
+ &mut self,
+ bx: &Builder<'a, 'll, 'tcx, &'ll Value>
+ ) -> PlaceRef<'tcx, &'ll Value> {
let cx = bx.cx;
if let Some(slot) = self.personality_slot {
slot
use syntax::ast::Mutability;
use syntax::source_map::Span;
use value::Value;
+use traits::BuilderMethods;
use super::super::callee;
use super::FunctionCx;
use abi::{ArgTypeExt, FnType, FnTypeExt, PassMode};
use type_::Type;
use value::Value;
+use traits::BuilderMethods;
use syntax_pos::{DUMMY_SP, NO_EXPANSION, BytePos, Span};
use syntax::symbol::keywords;
)
}
- pub fn set_debug_loc(&mut self, bx: &Builder<'_, 'll, '_>, source_info: mir::SourceInfo) {
+ pub fn set_debug_loc(
+ &mut self,
+ bx: &Builder<'_, 'll, '_, &'ll Value>,
+ source_info: mir::SourceInfo
+ ) {
let (scope, span) = self.debug_loc(source_info);
debuginfo::set_source_location(&self.debug_context, bx, scope, span);
}
use type_::Type;
use glue;
+use traits::BuilderMethods;
+
use std::fmt;
use super::{FunctionCx, LocalRef};
self.store_with_flags(bx, dest, MemFlags::empty());
}
- pub fn volatile_store(self, bx: &Builder<'a, 'll, 'tcx>, dest: PlaceRef<'tcx, &'ll Value>) {
+ pub fn volatile_store(
+ self,
+ bx: &Builder<'a, 'll, 'tcx, &'ll Value>,
+ dest: PlaceRef<'tcx, &'ll Value>
+ ) {
self.store_with_flags(bx, dest, MemFlags::VOLATILE);
}
) {
self.store_with_flags(bx, dest, MemFlags::VOLATILE | MemFlags::UNALIGNED);
}
+}
- pub fn nontemporal_store(self, bx: &Builder<'a, 'll, 'tcx>, dest: PlaceRef<'tcx, &'ll Value>) {
+impl<'a, 'll: 'a, 'tcx: 'll, Value : ?Sized> OperandValue<&'ll Value> where
+ Value : ValueTrait,
+ Builder<'a, 'll, 'tcx, &'ll Value>: BuilderMethods<'a, 'll, 'tcx, Value>
+{
+ pub fn nontemporal_store(
+ self,
+ bx: &Builder<'a, 'll, 'tcx, &'ll Value>,
+ dest: PlaceRef<'tcx, &'ll Value>
+ ) {
self.store_with_flags(bx, dest, MemFlags::NONTEMPORAL);
}
- fn store_with_flags(
+ fn store_with_flags<Builder: BuilderMethods<'a, 'll, 'tcx, Value>>(
self,
- bx: &Builder<'a, 'll, 'tcx>,
+ bx: &Builder,
dest: PlaceRef<'tcx, &'ll Value>,
flags: MemFlags,
) {
}
}
}
+}
+impl OperandValue<&'ll Value> {
pub fn store_unsized(
self,
- bx: &Builder<'a, 'll, 'tcx>,
- indirect_dest: PlaceRef<'tcx, &'ll Value>,
+ bx: &Builder<'a, 'll, 'tcx, &'ll Value>,
+ indirect_dest: PlaceRef<'tcx, &'ll Value>
) {
debug!("OperandRef::store_unsized: operand={:?}, indirect_dest={:?}", self, indirect_dest);
let flags = MemFlags::empty();
let min_align = Align::from_bits(8, 8).unwrap();
// Allocate an appropriate region on the stack, and copy the value into it
- let (llsize, _) = glue::size_and_align_of_dst(&bx, unsized_ty, Some(llextra));
+ let (llsize, _) = glue::size_and_align_of_dst(bx, unsized_ty, Some(llextra));
let lldst = bx.array_alloca(Type::i8(bx.cx), llsize, "unsized_tmp", max_align);
- base::call_memcpy(&bx, lldst, max_align, llptr, min_align, llsize, flags);
+ base::call_memcpy(bx, lldst, max_align, llptr, min_align, llsize, flags);
// Store the allocated region and the extra to the indirect place.
let indirect_operand = OperandValue::Pair(lldst, llextra);
- indirect_operand.store(&bx, indirect_dest);
+ indirect_operand.store(bx, indirect_dest);
}
}
use glue;
use mir::constant::const_alloc_to_llvm;
+use traits::BuilderMethods;
+
use super::{FunctionCx, LocalRef};
use super::operand::{OperandRef, OperandValue};
}
/// Obtain the actual discriminant of a value.
- pub fn codegen_get_discr(self, bx: &Builder<'a, 'll, 'tcx>, cast_to: Ty<'tcx>) -> &'ll Value {
+ pub fn codegen_get_discr(
+ self,
+ bx: &Builder<'a, 'll, 'tcx, &'ll Value>,
+ cast_to: Ty<'tcx>
+ ) -> &'ll Value {
let cast_to = bx.cx.layout_of(cast_to).immediate_llvm_type(bx.cx);
if self.layout.abi.is_uninhabited() {
return C_undef(cast_to);
use type_of::LayoutLlvmExt;
use value::Value;
+use traits::BuilderMethods;
+
use super::{FunctionCx, LocalRef};
use super::operand::{OperandRef, OperandValue};
use super::place::PlaceRef;
}
}
- pub fn codegen_rvalue_unsized(
- &mut self,
- bx: Builder<'a, 'll, 'tcx>,
- indirect_dest: PlaceRef<'tcx, &'ll Value>,
- rvalue: &mir::Rvalue<'tcx>,
- ) -> Builder<'a, 'll, 'tcx> {
+ pub fn codegen_rvalue_unsized(&mut self,
+ bx: Builder<'a, 'll, 'tcx, &'ll Value>,
+ indirect_dest: PlaceRef<'tcx, &'ll Value>,
+ rvalue: &mir::Rvalue<'tcx>)
+ -> Builder<'a, 'll, 'tcx, &'ll Value>
+ {
debug!("codegen_rvalue_unsized(indirect_dest.llval={:?}, rvalue={:?})",
indirect_dest.llval, rvalue);
}
}
- pub fn codegen_rvalue_operand(&mut self,
- bx: Builder<'a, 'll, 'tcx>,
- rvalue: &mir::Rvalue<'tcx>)
- -> (Builder<'a, 'll, 'tcx>, OperandRef<'tcx, &'ll Value>)
- {
+ pub fn codegen_rvalue_operand(
+ &mut self,
+ bx: Builder<'a, 'll, 'tcx, &'ll Value>,
+ rvalue: &mir::Rvalue<'tcx>
+ ) -> (Builder<'a, 'll, 'tcx, &'ll Value>, OperandRef<'tcx, &'ll Value>) {
assert!(self.rvalue_creates_operand(rvalue), "cannot codegen {:?} to operand", rvalue);
match *rvalue {
Add, Sub, Mul
}
-fn get_overflow_intrinsic(oop: OverflowOp, bx: &Builder<'_, 'll, '_>, ty: Ty) -> &'ll Value {
+fn get_overflow_intrinsic(
+ oop: OverflowOp,
+ bx: &Builder<'_, 'll, '_, &'ll Value>,
+ ty: Ty
+) -> &'ll Value {
use syntax::ast::IntTy::*;
use syntax::ast::UintTy::*;
use rustc::ty::{Int, Uint};
use asm;
use builder::Builder;
+use traits::BuilderMethods;
use super::FunctionCx;
use super::LocalRef;
--- /dev/null
+// Copyright 2018 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+use llvm::{AtomicRmwBinOp, AtomicOrdering, SynchronizationScope, AsmDialect};
+use llvm::{IntPredicate, RealPredicate, OperandBundleDef};
+use llvm::{self, BasicBlock};
+use common::*;
+use type_::Type;
+use libc::c_char;
+use rustc::ty::TyCtxt;
+use rustc::ty::layout::{Align, Size};
+use rustc::session::Session;
+use builder::MemFlags;
+
+use std::borrow::Cow;
+use std::ops::Range;
+
+
+pub trait BuilderMethods<'a, 'll :'a, 'tcx: 'll, Value : ?Sized> {
+ fn new_block<'b>(
+ cx: &'a CodegenCx<'ll, 'tcx, &'ll Value>,
+ llfn: &'ll Value,
+ name: &'b str
+ ) -> Self;
+ fn with_cx(cx: &'a CodegenCx<'ll, 'tcx, &'ll Value>) -> Self;
+ fn build_sibling_block<'b>(&self, name: &'b str) -> Self;
+ fn sess(&self) -> &Session;
+ fn cx(&self) -> &'a CodegenCx<'ll, 'tcx, &'ll Value>;
+ fn tcx(&self) -> TyCtxt<'a, 'tcx, 'tcx>;
+ fn llfn(&self) -> &'ll Value;
+ fn llbb(&self) -> &'ll BasicBlock;
+ fn count_insn(&self, category: &str);
+
+ fn set_value_name(&self, value: &'ll Value, name: &str);
+ fn position_at_end(&self, llbb: &'ll BasicBlock);
+ fn position_at_start(&self, llbb: &'ll BasicBlock);
+ fn ret_void(&self);
+ fn ret(&self, v: &'ll Value);
+ fn br(&self, dest: &'ll BasicBlock);
+ fn cond_br(
+ &self,
+ cond: &'ll Value,
+ then_llbb: &'ll BasicBlock,
+ else_llbb: &'ll BasicBlock,
+ );
+ fn switch(
+ &self,
+ v: &'ll Value,
+ else_llbb: &'ll BasicBlock,
+ num_cases: usize,
+ ) -> &'ll Value;
+ fn invoke(
+ &self,
+ llfn: &'ll Value,
+ args: &[&'ll Value],
+ then: &'ll BasicBlock,
+ catch: &'ll BasicBlock,
+ bundle: Option<&OperandBundleDef<'ll>>
+ ) -> &'ll Value;
+ fn unreachable(&self);
+ fn add(&self, lhs: &'ll Value, rhs: &'ll Value) -> &'ll Value;
+ fn fadd(&self, lhs: &'ll Value, rhs: &'ll Value) -> &'ll Value;
+ fn fadd_fast(&self, lhs: &'ll Value, rhs: &'ll Value) -> &'ll Value;
+ fn sub(&self, lhs: &'ll Value, rhs: &'ll Value) -> &'ll Value;
+ fn fsub(&self, lhs: &'ll Value, rhs: &'ll Value) -> &'ll Value;
+ fn fsub_fast(&self, lhs: &'ll Value, rhs: &'ll Value) -> &'ll Value;
+ fn mul(&self, lhs: &'ll Value, rhs: &'ll Value) -> &'ll Value;
+ fn fmul(&self, lhs: &'ll Value, rhs: &'ll Value) -> &'ll Value;
+ fn fmul_fast(&self, lhs: &'ll Value, rhs: &'ll Value) -> &'ll Value;
+ fn udiv(&self, lhs: &'ll Value, rhs: &'ll Value) -> &'ll Value;
+ fn exactudiv(&self, lhs: &'ll Value, rhs: &'ll Value) -> &'ll Value;
+ fn sdiv(&self, lhs: &'ll Value, rhs: &'ll Value) -> &'ll Value;
+ fn exactsdiv(&self, lhs: &'ll Value, rhs: &'ll Value) -> &'ll Value;
+ fn fdiv(&self, lhs: &'ll Value, rhs: &'ll Value) -> &'ll Value;
+ fn fdiv_fast(&self, lhs: &'ll Value, rhs: &'ll Value) -> &'ll Value;
+ fn urem(&self, lhs: &'ll Value, rhs: &'ll Value) -> &'ll Value;
+ fn srem(&self, lhs: &'ll Value, rhs: &'ll Value) -> &'ll Value;
+ fn frem(&self, lhs: &'ll Value, rhs: &'ll Value) -> &'ll Value;
+ fn frem_fast(&self, lhs: &'ll Value, rhs: &'ll Value) -> &'ll Value;
+ fn shl(&self, lhs: &'ll Value, rhs: &'ll Value) -> &'ll Value;
+ fn lshr(&self, lhs: &'ll Value, rhs: &'ll Value) -> &'ll Value;
+ fn ashr(&self, lhs: &'ll Value, rhs: &'ll Value) -> &'ll Value;
+ fn and(&self, lhs: &'ll Value, rhs: &'ll Value) -> &'ll Value;
+ fn or(&self, lhs: &'ll Value, rhs: &'ll Value) -> &'ll Value;
+ fn xor(&self, lhs: &'ll Value, rhs: &'ll Value) -> &'ll Value;
+ fn neg(&self, v: &'ll Value) -> &'ll Value;
+ fn fneg(&self, v: &'ll Value) -> &'ll Value;
+ fn not(&self, v: &'ll Value) -> &'ll Value;
+
+ fn alloca(&self, ty: &'ll Type, name: &str, align: Align) -> &'ll Value;
+ fn dynamic_alloca(&self, ty: &'ll Type, name: &str, align: Align) -> &'ll Value;
+ fn array_alloca(
+ &self,
+ ty: &'ll Type,
+ len: &'ll Value,
+ name: &str,
+ align: Align
+ ) -> &'ll Value;
+
+ fn load(&self, ptr: &'ll Value, align: Align) -> &'ll Value;
+ fn volatile_load(&self, ptr: &'ll Value) -> &'ll Value;
+ fn atomic_load(&self, ptr: &'ll Value, order: AtomicOrdering, size: Size) -> &'ll Value;
+
+ fn range_metadata(&self, load: &'ll Value, range: Range<u128>);
+ fn nonnull_metadata(&self, load: &'ll Value);
+
+ fn store(&self, val: &'ll Value, ptr: &'ll Value, align: Align) -> &'ll Value;
+ fn store_with_flags(
+ &self,
+ val: &'ll Value,
+ ptr: &'ll Value,
+ align: Align,
+ flags: MemFlags,
+ ) -> &'ll Value;
+ fn atomic_store(
+ &self,
+ val: &'ll Value,
+ ptr: &'ll Value,
+ order: AtomicOrdering,
+ size: Size
+ );
+
+ fn gep(&self, ptr: &'ll Value, indices: &[&'ll Value]) -> &'ll Value;
+ fn inbounds_gep(&self, ptr: &'ll Value, indices: &[&'ll Value]) -> &'ll Value;
+ fn struct_gep(&self, ptr: &'ll Value, idx: u64) -> &'ll Value;
+
+ fn trunc(&self, val: &'ll Value, dest_ty: &'ll Type) -> &'ll Value;
+ fn sext(&self, val: &'ll Value, dest_ty: &'ll Type) -> &'ll Value;
+ fn fptoui(&self, val: &'ll Value, dest_ty: &'ll Type) -> &'ll Value;
+ fn fptosi(&self, val: &'ll Value, dest_ty: &'ll Type) -> &'ll Value;
+ fn uitofp(&self, val: &'ll Value, dest_ty: &'ll Type) -> &'ll Value;
+ fn sitofp(&self, val: &'ll Value, dest_ty: &'ll Type) -> &'ll Value;
+ fn fptrunc(&self, val: &'ll Value, dest_ty: &'ll Type) -> &'ll Value;
+ fn fpext(&self, val: &'ll Value, dest_ty: &'ll Type) -> &'ll Value;
+ fn ptrtoint(&self, val: &'ll Value, dest_ty: &'ll Type) -> &'ll Value;
+ fn inttoptr(&self, val: &'ll Value, dest_ty: &'ll Type) -> &'ll Value;
+ fn bitcast(&self, val: &'ll Value, dest_ty: &'ll Type) -> &'ll Value;
+ fn intcast(&self, val: &'ll Value, dest_ty: &'ll Type, is_signed: bool) -> &'ll Value;
+ fn pointercast(&self, val: &'ll Value, dest_ty: &'ll Type) -> &'ll Value;
+
+ fn icmp(&self, op: IntPredicate, lhs: &'ll Value, rhs: &'ll Value) -> &'ll Value;
+ fn fcmp(&self, op: RealPredicate, lhs: &'ll Value, rhs: &'ll Value) -> &'ll Value;
+
+ fn empty_phi(&self, ty: &'ll Type) -> &'ll Value;
+ fn phi(&self, ty: &'ll Type, vals: &[&'ll Value], bbs: &[&'ll BasicBlock]) -> &'ll Value;
+ fn inline_asm_call(
+ &self,
+ asm: *const c_char,
+ cons: *const c_char,
+ inputs: &[&'ll Value],
+ output: &'ll Type,
+ volatile: bool,
+ alignstack: bool,
+ dia: AsmDialect
+ ) -> Option<&'ll Value>;
+
+
+ fn memcpy(&self, dst: &'ll Value, dst_align: u64,
+ src: &'ll Value, src_align: u64,
+ size: &'ll Value, is_volatile: bool) -> &'ll Value;
+ fn memmove(&self, dst: &'ll Value, dst_align: u64,
+ src: &'ll Value, src_align: u64,
+ size: &'ll Value, is_volatile: bool) -> &'ll Value;
+
+ fn minnum(&self, lhs: &'ll Value, rhs: &'ll Value) -> &'ll Value;
+ fn maxnum(&self, lhs: &'ll Value, rhs: &'ll Value) -> &'ll Value;
+ fn select(
+ &self, cond: &'ll Value,
+ then_val: &'ll Value,
+ else_val: &'ll Value,
+ ) -> &'ll Value;
+
+ fn va_arg(&self, list: &'ll Value, ty: &'ll Type) -> &'ll Value;
+ fn extract_element(&self, vec: &'ll Value, idx: &'ll Value) -> &'ll Value;
+ fn insert_element(
+ &self, vec: &'ll Value,
+ elt: &'ll Value,
+ idx: &'ll Value,
+ ) -> &'ll Value;
+ fn shuffle_vector(&self, v1: &'ll Value, v2: &'ll Value, mask: &'ll Value) -> &'ll Value;
+ fn vector_splat(&self, num_elts: usize, elt: &'ll Value) -> &'ll Value;
+ fn vector_reduce_fadd_fast(&self, acc: &'ll Value, src: &'ll Value) -> &'ll Value;
+ fn vector_reduce_fmul_fast(&self, acc: &'ll Value, src: &'ll Value) -> &'ll Value;
+ fn vector_reduce_add(&self, src: &'ll Value) -> &'ll Value;
+ fn vector_reduce_mul(&self, src: &'ll Value) -> &'ll Value;
+ fn vector_reduce_and(&self, src: &'ll Value) -> &'ll Value;
+ fn vector_reduce_or(&self, src: &'ll Value) -> &'ll Value;
+ fn vector_reduce_xor(&self, src: &'ll Value) -> &'ll Value;
+ fn vector_reduce_fmin(&self, src: &'ll Value) -> &'ll Value;
+ fn vector_reduce_fmax(&self, src: &'ll Value) -> &'ll Value;
+ fn vector_reduce_fmin_fast(&self, src: &'ll Value) -> &'ll Value;
+ fn vector_reduce_fmax_fast(&self, src: &'ll Value) -> &'ll Value;
+ fn vector_reduce_min(&self, src: &'ll Value, is_signed: bool) -> &'ll Value;
+ fn vector_reduce_max(&self, src: &'ll Value, is_signed: bool) -> &'ll Value;
+ fn extract_value(&self, agg_val: &'ll Value, idx: u64) -> &'ll Value;
+ fn insert_value(
+ &self,
+ agg_val: &'ll Value,
+ elt: &'ll Value,
+ idx: u64
+ ) -> &'ll Value;
+
+ fn landing_pad(
+ &self,
+ ty: &'ll Type,
+ pers_fn: &'ll Value,
+ num_clauses: usize
+ ) -> &'ll Value;
+ fn add_clause(&self, landing_pad: &'ll Value, clause: &'ll Value);
+ fn set_cleanup(&self, landing_pad: &'ll Value);
+ fn resume(&self, exn: &'ll Value) -> &'ll Value;
+ fn cleanup_pad(
+ &self,
+ parent: Option<&'ll Value>,
+ args: &[&'ll Value]
+ ) -> &'ll Value;
+ fn cleanup_ret(
+ &self, cleanup: &'ll Value,
+ unwind: Option<&'ll BasicBlock>,
+ ) -> &'ll Value;
+ fn catch_pad(
+ &self,
+ parent: &'ll Value,
+ args: &[&'ll Value]
+ ) -> &'ll Value;
+ fn catch_ret(&self, pad: &'ll Value, unwind: &'ll BasicBlock) -> &'ll Value;
+ fn catch_switch(
+ &self,
+ parent: Option<&'ll Value>,
+ unwind: Option<&'ll BasicBlock>,
+ num_handlers: usize,
+ ) -> &'ll Value;
+ fn add_handler(&self, catch_switch: &'ll Value, handler: &'ll BasicBlock);
+ fn set_personality_fn(&self, personality: &'ll Value);
+
+ fn atomic_cmpxchg(
+ &self,
+ dst: &'ll Value,
+ cmp: &'ll Value,
+ src: &'ll Value,
+ order: AtomicOrdering,
+ failure_order: AtomicOrdering,
+ weak: llvm::Bool,
+ ) -> &'ll Value;
+ fn atomic_rmw(
+ &self,
+ op: AtomicRmwBinOp,
+ dst: &'ll Value,
+ src: &'ll Value,
+ order: AtomicOrdering,
+ ) -> &'ll Value;
+ fn atomic_fence(&self, order: AtomicOrdering, scope: SynchronizationScope);
+ fn add_case(&self, s: &'ll Value, on_val: &'ll Value, dest: &'ll BasicBlock);
+ fn add_incoming_to_phi(&self, phi: &'ll Value, val: &'ll Value, bb: &'ll BasicBlock);
+ fn set_invariant_load(&self, load: &'ll Value);
+
+ fn check_store(
+ &self,
+ val: &'ll Value,
+ ptr: &'ll Value
+ ) -> &'ll Value;
+ fn check_call<'b>(
+ &self,
+ typ: &str,
+ llfn: &'ll Value,
+ args: &'b [&'ll Value]
+ ) -> Cow<'b, [&'ll Value]>;
+ fn lifetime_start(&self, ptr: &'ll Value, size: Size);
+ fn lifetime_end(&self, ptr: &'ll Value, size: Size);
+
+ fn call_lifetime_intrinsic(&self, intrinsic: &str, ptr: &'ll Value, size: Size);
+
+ fn call(&self, llfn: &'ll Value, args: &[&'ll Value],
+ bundle: Option<&OperandBundleDef<'ll>>) -> &'ll Value;
+ fn zext(&self, val: &'ll Value, dest_ty: &'ll Type) -> &'ll Value;
+}
use llvm::{Bool, False, True, TypeKind};
use context::CodegenCx;
+use value::{Value, ValueTrait};
use syntax::ast;
use rustc::ty::layout::{self, Align, Size};
}
impl Type {
- pub fn void(cx: &CodegenCx<'ll, '_>) -> &'ll Type {
+ pub fn void<Value : ?Sized>(
+ cx: &CodegenCx<'ll, '_, &'ll Value>
+ ) -> &'ll Type where Value : ValueTrait {
unsafe {
llvm::LLVMVoidTypeInContext(cx.llcx)
}
}
- pub fn metadata(cx: &CodegenCx<'ll, '_>) -> &'ll Type {
+ pub fn metadata<Value : ?Sized>(
+ cx: &CodegenCx<'ll, '_, &'ll Value>
+ ) -> &'ll Type where Value : ValueTrait {
unsafe {
llvm::LLVMRustMetadataTypeInContext(cx.llcx)
}
}
- pub fn i1(cx: &CodegenCx<'ll, '_>) -> &'ll Type {
+ pub fn i1<Value : ?Sized>(
+ cx: &CodegenCx<'ll, '_, &'ll Value>
+ ) -> &'ll Type where Value : ValueTrait {
unsafe {
llvm::LLVMInt1TypeInContext(cx.llcx)
}
}
- pub fn i8(cx: &CodegenCx<'ll, '_>) -> &'ll Type {
+ pub fn i8<Value : ?Sized>(
+ cx: &CodegenCx<'ll, '_, &'ll Value>
+ ) -> &'ll Type where Value : ValueTrait {
unsafe {
llvm::LLVMInt8TypeInContext(cx.llcx)
}
}
- pub fn i8_llcx(llcx: &llvm::Context) -> &Type {
+ pub fn i8_llcx<Value : ?Sized>(llcx: &llvm::Context) -> &Type where Value : ValueTrait {
unsafe {
llvm::LLVMInt8TypeInContext(llcx)
}
}
- pub fn i16(cx: &CodegenCx<'ll, '_>) -> &'ll Type {
+ pub fn i16<Value : ?Sized>(
+ cx: &CodegenCx<'ll, '_, &'ll Value>) -> &'ll Type where Value : ValueTrait {
unsafe {
+
llvm::LLVMInt16TypeInContext(cx.llcx)
}
}
- pub fn i32(cx: &CodegenCx<'ll, '_>) -> &'ll Type {
+ pub fn i32<Value : ?Sized>(
+ cx: &CodegenCx<'ll, '_, &'ll Value>
+ ) -> &'ll Type where Value : ValueTrait {
unsafe {
llvm::LLVMInt32TypeInContext(cx.llcx)
}
}
- pub fn i64(cx: &CodegenCx<'ll, '_>) -> &'ll Type {
+ pub fn i64<Value : ?Sized>(
+ cx: &CodegenCx<'ll, '_, &'ll Value>
+ ) -> &'ll Type where Value : ValueTrait {
unsafe {
llvm::LLVMInt64TypeInContext(cx.llcx)
}
}
- pub fn i128(cx: &CodegenCx<'ll, '_>) -> &'ll Type {
+ pub fn i128<Value : ?Sized>(
+ cx: &CodegenCx<'ll, '_, &'ll Value>
+ ) -> &'ll Type where Value : ValueTrait {
unsafe {
llvm::LLVMIntTypeInContext(cx.llcx, 128)
}
}
// Creates an integer type with the given number of bits, e.g. i24
- pub fn ix(cx: &CodegenCx<'ll, '_>, num_bits: u64) -> &'ll Type {
+ pub fn ix<Value : ?Sized>(
+ cx: &CodegenCx<'ll, '_, &'ll Value>,
+ num_bits: u64
+ ) -> &'ll Type where Value : ValueTrait {
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 {
+ pub fn ix_llcx<Value : ?Sized>(
+ llcx: &llvm::Context,
+ num_bits: u64
+ ) -> &Type where Value : ValueTrait {
unsafe {
llvm::LLVMIntTypeInContext(llcx, num_bits as c_uint)
}
}
- pub fn f32(cx: &CodegenCx<'ll, '_>) -> &'ll Type {
+ pub fn f32<Value : ?Sized>(
+ cx: &CodegenCx<'ll, '_, &'ll Value>
+ ) -> &'ll Type where Value : ValueTrait {
unsafe {
llvm::LLVMFloatTypeInContext(cx.llcx)
}
}
- pub fn f64(cx: &CodegenCx<'ll, '_>) -> &'ll Type {
+ pub fn f64<Value : ?Sized>(
+ cx: &CodegenCx<'ll, '_, &'ll Value>
+ ) -> &'ll Type where Value : ValueTrait {
unsafe {
llvm::LLVMDoubleTypeInContext(cx.llcx)
}
}
- pub fn bool(cx: &CodegenCx<'ll, '_>) -> &'ll Type {
+ pub fn bool<Value : ?Sized>(
+ cx: &CodegenCx<'ll, '_, &'ll Value>
+ ) -> &'ll Type where Value : ValueTrait {
Type::i8(cx)
}
- pub fn char(cx: &CodegenCx<'ll, '_>) -> &'ll Type {
+ pub fn char<Value : ?Sized>(
+ cx: &CodegenCx<'ll, '_, &'ll Value>
+ ) -> &'ll Type where Value : ValueTrait {
Type::i32(cx)
}
- pub fn i8p(cx: &CodegenCx<'ll, '_>) -> &'ll Type {
+ pub fn i8p<Value : ?Sized>(
+ cx: &CodegenCx<'ll, '_, &'ll Value>
+ ) -> &'ll Type where Value : ValueTrait {
Type::i8(cx).ptr_to()
}
- pub fn i8p_llcx(llcx: &llvm::Context) -> &Type {
- Type::i8_llcx(llcx).ptr_to()
+ pub fn i8p_llcx<Value : ?Sized>(llcx: &llvm::Context) -> &Type where Value : ValueTrait {
+ Type::i8_llcx::<Value>(llcx).ptr_to()
}
- pub fn isize(cx: &CodegenCx<'ll, '_>) -> &'ll Type {
+ pub fn isize<Value : ?Sized>(
+ cx: &CodegenCx<'ll, '_, &'ll Value>
+ ) -> &'ll Type where Value : ValueTrait {
cx.isize_ty
}
- pub fn c_int(cx: &CodegenCx<'ll, '_>) -> &'ll Type {
+ pub fn c_int<Value : ?Sized>(
+ cx: &CodegenCx<'ll, '_, &'ll Value>
+ ) -> &'ll Type where Value : ValueTrait {
match &cx.tcx.sess.target.target.target_c_int_width[..] {
"16" => Type::i16(cx),
"32" => Type::i32(cx),
}
}
- pub fn int_from_ty(cx: &CodegenCx<'ll, '_>, t: ast::IntTy) -> &'ll Type {
+ pub fn int_from_ty<Value : ?Sized>(
+ cx: &CodegenCx<'ll, '_, &'ll Value>,
+ t: ast::IntTy
+ ) -> &'ll Type where Value : ValueTrait {
match t {
ast::IntTy::Isize => cx.isize_ty,
ast::IntTy::I8 => Type::i8(cx),
}
}
- pub fn uint_from_ty(cx: &CodegenCx<'ll, '_>, t: ast::UintTy) -> &'ll Type {
+ pub fn uint_from_ty<Value : ?Sized>(
+ cx: &CodegenCx<'ll, '_, &'ll Value>,
+ t: ast::UintTy
+ ) -> &'ll Type where Value : ValueTrait {
match t {
ast::UintTy::Usize => cx.isize_ty,
ast::UintTy::U8 => Type::i8(cx),
}
}
- pub fn float_from_ty(cx: &CodegenCx<'ll, '_>, t: ast::FloatTy) -> &'ll Type {
+ pub fn float_from_ty<Value : ?Sized>(
+ cx: &CodegenCx<'ll, '_, &'ll Value>,
+ t: ast::FloatTy
+ ) -> &'ll Type where Value : ValueTrait {
match t {
ast::FloatTy::F32 => Type::f32(cx),
ast::FloatTy::F64 => Type::f64(cx),
}
}
- pub fn func(args: &[&'ll Type], ret: &'ll Type) -> &'ll Type {
+ pub fn func<Value : ?Sized>(
+ args: &[&'ll Type],
+ ret: &'ll Type
+ ) -> &'ll Type where Value : ValueTrait {
unsafe {
llvm::LLVMFunctionType(ret, args.as_ptr(),
args.len() as c_uint, False)
}
}
- pub fn variadic_func(args: &[&'ll Type], ret: &'ll Type) -> &'ll Type {
+ pub fn variadic_func<Value : ?Sized>(
+ args: &[&'ll Type],
+ ret: &'ll Type
+ ) -> &'ll Type where Value : ValueTrait {
unsafe {
llvm::LLVMFunctionType(ret, args.as_ptr(),
args.len() as c_uint, True)
}
}
- pub fn struct_(cx: &CodegenCx<'ll, '_>, els: &[&'ll Type], packed: bool) -> &'ll Type {
+ pub fn struct_<Value : ?Sized>(
+ cx: &CodegenCx<'ll, '_, &'ll Value>,
+ els: &[&'ll Type],
+ packed: bool
+ ) -> &'ll Type where Value : ValueTrait {
unsafe {
llvm::LLVMStructTypeInContext(cx.llcx, els.as_ptr(),
els.len() as c_uint,
}
- pub fn array(ty: &Type, len: u64) -> &Type {
+ pub fn array<Value : ?Sized>(ty: &Type, len: u64) -> &Type where Value : ValueTrait {
unsafe {
llvm::LLVMRustArrayType(ty, len)
}
}
- pub fn vector(ty: &Type, len: u64) -> &Type {
+ pub fn vector<Value : ?Sized>(ty: &Type, len: u64) -> &Type where Value : ValueTrait {
unsafe {
llvm::LLVMVectorType(ty, len as c_uint)
}
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::<Value>(Type::from_integer(cx, unit), size / unit_size)
}
pub fn x86_mmx(cx: &CodegenCx<'ll, '_>) -> &'ll Type {
use rustc_target::abi::FloatTy;
use rustc_mir::monomorphize::item::DefPathBasedNames;
use type_::Type;
+use value::Value;
use std::fmt::Write;
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::<Value>(element, count);
}
}
layout::Abi::ScalarPair(..) => {
}
}
layout::FieldPlacement::Array { count, .. } => {
- Type::array(layout.field(cx, 0).llvm_type(cx), count)
+ Type::array::<Value>(layout.field(cx, 0).llvm_type(cx), count)
}
layout::FieldPlacement::Arbitrary { .. } => {
match name {
use std::fmt;
use std::hash::{Hash, Hasher};
-pub trait ValueTrait: fmt::Debug {}
+pub trait ValueTrait: fmt::Debug {
+ fn to_llvm(&self) -> &llvm::Value;
+ fn of_llvm(&llvm::Value) -> &Self;
+}
impl PartialEq for Value {
fn eq(&self, other: &Self) -> bool {
}
}
-impl ValueTrait for Value {}
+impl ValueTrait for Value {
+ fn to_llvm(&self) -> &llvm::Value {
+ &self
+ }
+ fn of_llvm(v: &llvm::Value) -> &Self {
+ &v
+ }
+}
impl Eq for Value {}