]> git.lizzy.rs Git - rust.git/commitdiff
Generalized base.rs#call_memcpy and everything that it uses
authorDenis Merigoux <denis.merigoux@gmail.com>
Tue, 7 Aug 2018 15:14:40 +0000 (17:14 +0200)
committerEduard-Mihai Burtescu <edy.burt@gmail.com>
Fri, 16 Nov 2018 12:11:09 +0000 (14:11 +0200)
Generalized operand.rs#nontemporal_store and fixed tidy issues

Generalized operand.rs#nontemporal_store's implem even more
With a BuilderMethod trait implemented by Builder for LLVM

Cleaned builder.rs : no more code duplication, no more ValueTrait

Full traitification of builder.rs

28 files changed:
.atom-build.yml [new file with mode: 0644]
src/librustc_codegen_llvm/abi.rs
src/librustc_codegen_llvm/asm.rs
src/librustc_codegen_llvm/attributes.rs
src/librustc_codegen_llvm/back/write.rs
src/librustc_codegen_llvm/base.rs
src/librustc_codegen_llvm/builder.rs
src/librustc_codegen_llvm/common.rs
src/librustc_codegen_llvm/context.rs
src/librustc_codegen_llvm/debuginfo/gdb.rs
src/librustc_codegen_llvm/debuginfo/mod.rs
src/librustc_codegen_llvm/debuginfo/source_loc.rs
src/librustc_codegen_llvm/declare.rs
src/librustc_codegen_llvm/glue.rs
src/librustc_codegen_llvm/intrinsic.rs
src/librustc_codegen_llvm/lib.rs
src/librustc_codegen_llvm/meth.rs
src/librustc_codegen_llvm/mir/block.rs
src/librustc_codegen_llvm/mir/constant.rs
src/librustc_codegen_llvm/mir/mod.rs
src/librustc_codegen_llvm/mir/operand.rs
src/librustc_codegen_llvm/mir/place.rs
src/librustc_codegen_llvm/mir/rvalue.rs
src/librustc_codegen_llvm/mir/statement.rs
src/librustc_codegen_llvm/traits.rs [new file with mode: 0644]
src/librustc_codegen_llvm/type_.rs
src/librustc_codegen_llvm/type_of.rs
src/librustc_codegen_llvm/value.rs

diff --git a/.atom-build.yml b/.atom-build.yml
new file mode 100644 (file)
index 0000000..a31bc87
--- /dev/null
@@ -0,0 +1 @@
+cmd: ./x.py -i check
index 9e9467e3645440f837b536c817857fe8ed133a92..b4aa6495da899e47ea2b0ab638fde265caee1c74 100644 (file)
@@ -19,6 +19,8 @@
 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;
@@ -119,7 +121,7 @@ fn llvm_type(&self, cx: &CodegenCx<'ll, '_>) -> &'ll Type {
                 }
             }
             RegKind::Vector => {
-                Type::vector(Type::i8(cx), self.size.bytes())
+                Type::vector::<Value>(Type::i8(cx), self.size.bytes())
             }
         }
     }
@@ -143,7 +145,7 @@ fn llvm_type(&self, cx: &CodegenCx<'ll, '_>) -> &'ll Type {
 
             // 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);
             }
         }
 
@@ -167,7 +169,12 @@ fn llvm_type(&self, cx: &CodegenCx<'ll, '_>) -> &'ll Type {
 
 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>,
@@ -187,7 +194,12 @@ fn memory_ty(&self, cx: &CodegenCx<'ll, 'tcx>) -> &'ll Type {
     /// 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;
         }
@@ -663,9 +675,9 @@ fn llvm_type(&self, cx: &CodegenCx<'ll, 'tcx>) -> &'ll Type {
         }
 
         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)
         }
     }
 
index b267114410734cc0e0a1f42652373ec46f22170d..441888583eaee962b659f2d8cc4177a7ebd3d15e 100644 (file)
@@ -16,6 +16,7 @@
 use value::Value;
 
 use rustc::hir;
+use traits::BuilderMethods;
 
 use mir::place::PlaceRef;
 use mir::operand::OperandValue;
index f45b3728bc1b074aae9d7018d9f978656eb13b1d..8004b7ba88ea825c65f3906091d00c901ca8a159 100644 (file)
@@ -127,7 +127,7 @@ pub fn llvm_target_features(sess: &Session) -> impl Iterator<Item = &str> {
         .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(
index 8973852caa86b351d594d5ae1e730198ade33fe6..e8d5812816ea21ca96e45da9bed5fb23fbede8c4 100644 (file)
@@ -49,6 +49,7 @@
 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};
@@ -2574,7 +2575,7 @@ fn create_msvc_imps(cgcx: &CodegenContext, llcx: &llvm::Context, llmod: &llvm::M
         "\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 &&
index 50fb246a7d467ef8f040d6ed45ee806775c5639d..f268d3dd86fc10a7ed4647be031284466b539376 100644 (file)
@@ -75,6 +75,8 @@
 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;
@@ -86,7 +88,7 @@
 use syntax::attr;
 use rustc::hir::{self, CodegenFnAttrs};
 
-use value::Value;
+use value::{Value, ValueTrait};
 
 use mir::operand::OperandValue;
 
@@ -387,9 +389,14 @@ pub fn call_assume(bx: &Builder<'_, 'll, '_>, val: &'ll Value) {
     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
     }
@@ -417,15 +424,17 @@ pub fn to_immediate_scalar(
     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);
@@ -433,7 +442,7 @@ pub fn call_memcpy(
         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);
@@ -441,21 +450,23 @@ pub fn call_memcpy(
     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(
@@ -545,7 +556,8 @@ fn create_entry_fn(
         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,
index 927ad8aecd8440b50ab76e3ba574b0846988da47..f8074db438830dc8d82e736919399119d13adf59 100644 (file)
@@ -19,6 +19,7 @@
 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;
@@ -54,8 +55,12 @@ pub struct MemFlags: u8 {
     }
 }
 
-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);
@@ -69,7 +74,7 @@ pub fn new_block<'b>(cx: &'a CodegenCx<'ll, 'tcx>, llfn: &'ll Value, name: &'b s
         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)
@@ -80,84 +85,84 @@ pub fn with_cx(cx: &'a CodegenCx<'ll, 'tcx>) -> Self {
         }
     }
 
-    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,
@@ -169,7 +174,7 @@ pub fn cond_br(
         }
     }
 
-    pub fn switch(
+    fn switch(
         &self,
         v: &'ll Value,
         else_llbb: &'ll BasicBlock,
@@ -180,7 +185,7 @@ pub fn switch(
         }
     }
 
-    pub fn invoke(&self,
+    fn invoke(&self,
                   llfn: &'ll Value,
                   args: &[&'ll Value],
                   then: &'ll BasicBlock,
@@ -207,7 +212,7 @@ pub fn invoke(&self,
         }
     }
 
-    pub fn unreachable(&self) {
+    fn unreachable(&self) {
         self.count_insn("unreachable");
         unsafe {
             llvm::LLVMBuildUnreachable(self.llbuilder);
@@ -215,21 +220,21 @@ pub fn unreachable(&self) {
     }
 
     /* 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());
@@ -238,21 +243,21 @@ pub fn fadd_fast(&self, lhs: &'ll Value, rhs: &'ll Value) -> &'ll Value {
         }
     }
 
-    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());
@@ -261,21 +266,21 @@ pub fn fsub_fast(&self, lhs: &'ll Value, rhs: &'ll Value) -> &'ll Value {
         }
     }
 
-    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());
@@ -285,42 +290,42 @@ pub fn fmul_fast(&self, lhs: &'ll Value, rhs: &'ll Value) -> &'ll Value {
     }
 
 
-    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());
@@ -329,28 +334,28 @@ pub fn fdiv_fast(&self, lhs: &'ll Value, rhs: &'ll Value) -> &'ll Value {
         }
     }
 
-    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());
@@ -359,70 +364,70 @@ pub fn frem_fast(&self, lhs: &'ll Value, rhs: &'ll Value) -> &'ll Value {
         }
     }
 
-    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())
@@ -430,7 +435,7 @@ pub fn alloca(&self, ty: &'ll Type, name: &str, align: Align) -> &'ll Value {
         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() {
@@ -445,7 +450,7 @@ pub fn dynamic_alloca(&self, ty: &'ll Type, name: &str, align: Align) -> &'ll Va
         }
     }
 
-    pub fn array_alloca(&self,
+    fn array_alloca(&self,
                         ty: &'ll Type,
                         len: &'ll Value,
                         name: &str,
@@ -464,7 +469,7 @@ pub fn array_alloca(&self,
         }
     }
 
-    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());
@@ -473,7 +478,7 @@ pub fn load(&self, ptr: &'ll Value, align: Align) -> &'ll Value {
         }
     }
 
-    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());
@@ -482,7 +487,7 @@ pub fn volatile_load(&self, ptr: &'ll Value) -> &'ll Value {
         }
     }
 
-    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);
@@ -493,7 +498,7 @@ pub fn atomic_load(&self, ptr: &'ll Value, order: AtomicOrdering, size: Size) ->
     }
 
 
-    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,
@@ -516,18 +521,18 @@ pub fn range_metadata(&self, load: &'ll Value, range: Range<u128>) {
         }
     }
 
-    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,
@@ -561,8 +566,8 @@ pub fn store_with_flags(
         }
     }
 
-    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);
@@ -573,7 +578,7 @@ pub fn atomic_store(&self, val: &'ll Value, ptr: &'ll Value,
         }
     }
 
-    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(),
@@ -581,7 +586,7 @@ pub fn gep(&self, ptr: &'ll Value, indices: &[&'ll Value]) -> &'ll Value {
         }
     }
 
-    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(
@@ -589,122 +594,108 @@ pub fn inbounds_gep(&self, ptr: &'ll Value, indices: &[&'ll Value]) -> &'ll Valu
         }
     }
 
-    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())
@@ -712,14 +703,14 @@ pub fn fcmp(&self, op: RealPredicate, lhs: &'ll Value, rhs: &'ll Value) -> &'ll
     }
 
     /* 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");
@@ -731,10 +722,10 @@ pub fn phi(&self, ty: &'ll Type, vals: &[&'ll Value], bbs: &[&'ll BasicBlock]) -
         }
     }
 
-    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 }
@@ -748,7 +739,7 @@ pub fn inline_asm_call(&self, asm: *const c_char, cons: *const c_char,
         }).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);
@@ -764,24 +755,7 @@ pub fn inline_asm_call(&self, asm: *const c_char, cons: *const c_char,
         }
     }
 
-    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 {
@@ -790,7 +764,7 @@ pub fn memcpy(&self, dst: &'ll Value, dst_align: u64,
         }
     }
 
-    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 {
@@ -799,14 +773,14 @@ pub fn memmove(&self, dst: &'ll Value, dst_align: u64,
         }
     }
 
-    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);
@@ -814,7 +788,7 @@ pub fn maxnum(&self, lhs: &'ll Value, rhs: &'ll Value) -> &'ll Value {
         }
     }
 
-    pub fn select(
+    fn select(
         &self, cond: &'ll Value,
         then_val: &'ll Value,
         else_val: &'ll Value,
@@ -826,21 +800,21 @@ pub fn select(
     }
 
     #[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,
@@ -851,24 +825,24 @@ pub fn insert_element(
         }
     }
 
-    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
@@ -879,7 +853,7 @@ pub fn vector_reduce_fadd_fast(&self, acc: &'ll Value, src: &'ll Value) -> &'ll
             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
@@ -890,35 +864,35 @@ pub fn vector_reduce_fmul_fast(&self, acc: &'ll Value, src: &'ll Value) -> &'ll
             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);
@@ -926,7 +900,7 @@ pub fn vector_reduce_fmin_fast(&self, src: &'ll Value) -> &'ll Value {
             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);
@@ -934,16 +908,16 @@ pub fn vector_reduce_fmax_fast(&self, src: &'ll Value) -> &'ll Value {
             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 {
@@ -951,7 +925,7 @@ pub fn extract_value(&self, agg_val: &'ll Value, idx: u64) -> &'ll Value {
         }
     }
 
-    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);
@@ -961,7 +935,7 @@ pub fn insert_value(&self, agg_val: &'ll Value, elt: &'ll Value,
         }
     }
 
-    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 {
@@ -970,27 +944,27 @@ pub fn landing_pad(&self, ty: &'ll Type, pers_fn: &'ll Value,
         }
     }
 
-    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");
@@ -1005,7 +979,7 @@ pub fn cleanup_pad(&self,
         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 {
@@ -1016,7 +990,7 @@ pub fn cleanup_ret(
         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");
@@ -1029,7 +1003,7 @@ pub fn catch_pad(&self,
         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)
@@ -1037,7 +1011,7 @@ pub fn catch_ret(&self, pad: &'ll Value, unwind: &'ll BasicBlock) -> &'ll Value
         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>,
@@ -1053,20 +1027,20 @@ pub fn catch_switch(
         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,
@@ -1080,7 +1054,7 @@ pub fn atomic_cmpxchg(
                                              order, failure_order, weak)
         }
     }
-    pub fn atomic_rmw(
+    fn atomic_rmw(
         &self,
         op: AtomicRmwBinOp,
         dst: &'ll Value,
@@ -1092,26 +1066,26 @@ pub fn atomic_rmw(
         }
     }
 
-    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));
@@ -1181,11 +1155,11 @@ fn check_call<'b>(&self,
         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);
     }
 
@@ -1212,4 +1186,45 @@ fn call_lifetime_intrinsic(&self, intrinsic: &str, ptr: &'ll Value, size: 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
+    }
 }
index c9b464fd8f3dd48482fa3a307a3f55b0c0bc7856..66f14322fc6725b65c7ca275d9d2a418be4d54d1 100644 (file)
 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};
 
@@ -110,9 +111,9 @@ pub fn bundle(&self) -> &OperandBundleDef<'ll> {
     }
 }
 
-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())
     }
 }
 
@@ -123,21 +124,21 @@ pub fn C_null(t: &'ll Type) -> &'ll Value {
     }
 }
 
-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))
     }
 }
 
@@ -148,11 +149,17 @@ pub fn C_uint_big(t: &'ll Type, u: u128) -> &'ll Value {
     }
 }
 
-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)
 }
 
@@ -164,7 +171,10 @@ pub fn C_u64(cx: &CodegenCx<'ll, '_>, i: u64) -> &'ll Value {
     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
index 4c405150532bd221b9b9475ee7dd2b6d48f9327d..ed9a9e3209ba2ea5927ceaef5b88875323f964b1 100644 (file)
@@ -18,7 +18,7 @@
 use base;
 use declare;
 use monomorphize::Instance;
-use value::Value;
+use value::{Value, ValueTrait};
 
 use monomorphize::partitioning::CodegenUnit;
 use type_::Type;
@@ -283,7 +283,7 @@ impl<'a, 'tcx> CodegenCx<'a, 'tcx> {
             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,
@@ -315,7 +315,7 @@ impl<'a, 'tcx> CodegenCx<'a, '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
     }
@@ -327,7 +327,9 @@ pub fn get_intrinsic(&self, key: &str) -> &'b Value {
 
         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 {
@@ -377,7 +379,7 @@ pub fn eh_personality(&self) -> &'b Value {
                 } 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)
             }
         };
@@ -478,28 +480,31 @@ fn layout_of(&self, ty: Ty<'tcx>) -> Self::TyLayout {
 }
 
 /// 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);
             }
@@ -520,14 +525,14 @@ macro_rules! mk_struct {
     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);
index f6faddb894ffdf41c532659fffc92afea806f412..9d02738fcbdd0b69604e6c18a2e37daab20d5574 100644 (file)
@@ -18,6 +18,7 @@
 use rustc::session::config::DebugInfo;
 use type_::Type;
 use value::Value;
+use traits::BuilderMethods;
 
 use syntax::attr;
 
@@ -55,7 +56,7 @@ pub fn get_or_insert_gdb_debug_scripts_section_global(cx: &CodegenCx<'ll, '_>)
         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,
index 042e72e921ecead4e02951a41c7f3747db5e0966..bce722b4b43ecca817f9f828ab613f98f345bd1a 100644 (file)
@@ -45,6 +45,7 @@
 use syntax::ast;
 use syntax::symbol::{Symbol, InternedString};
 use rustc::ty::layout::{self, LayoutOf};
+use traits::BuilderMethods;
 
 pub mod gdb;
 mod utils;
index 60ebcb888166ff96bb0193f05edf153b7551d9c5..bd8c165d508fcba658561898413a7796ae48515f 100644 (file)
@@ -17,6 +17,7 @@
 use llvm;
 use llvm::debuginfo::DIScope;
 use builder::Builder;
+use traits::BuilderMethods;
 
 use libc::c_uint;
 use syntax_pos::{Span, Pos};
@@ -78,7 +79,10 @@ pub fn new(scope: &'ll DIScope, line: usize, col: usize) -> Self {
     }
 }
 
-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.
index f4aede55ce1a628d4e054b09a78a6547ae114889..d06801518935c5c5f0f89c5a923fea2703fc4dc1 100644 (file)
@@ -31,7 +31,7 @@
 use attributes;
 use context::CodegenCx;
 use type_::Type;
-use value::Value;
+use value::{Value, ValueTrait};
 
 
 /// Declare a global value.
@@ -51,12 +51,12 @@ pub fn declare_global(cx: &CodegenCx<'ll, '_>, name: &str, ty: &'ll Type) -> &'l
 ///
 /// 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 {
@@ -105,7 +105,7 @@ fn declare_raw_fn(
 
     attributes::non_lazy_bind(cx.sess(), llfn);
 
-    llfn
+    Value::of_llvm(llfn)
 }
 
 
@@ -116,7 +116,11 @@ fn declare_raw_fn(
 ///
 /// 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)
 }
 
@@ -168,7 +172,7 @@ pub fn define_global(cx: &CodegenCx<'ll, '_>, name: &str, ty: &'ll Type) -> Opti
 /// 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)
     }
index 842bdf3cb493ff1b01772c5d4026c8388ae440e3..9144e3f07a13355aff3337a3016306ace25282a0 100644 (file)
 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) {
index 29831473ba2bb8f0c6d07365d2f0f5a604d71987..48afda73d792a7711e9f8ecf3464df90659197c1 100644 (file)
@@ -31,6 +31,8 @@
 use builder::Builder;
 use value::Value;
 
+use traits::BuilderMethods;
+
 use rustc::session::Session;
 use syntax_pos::Span;
 
@@ -591,7 +593,7 @@ fn ty_to_type(cx: &CodegenCx<'ll, '_>, t: &intrinsics::Type) -> Vec<&'ll Type> {
                     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()
@@ -640,7 +642,10 @@ fn modify_as_needed(
                     }
                     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
@@ -668,7 +673,7 @@ fn modify_as_needed(
                 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)
                 }
             };
@@ -1155,7 +1160,7 @@ macro_rules! require_simd {
         }
         // 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()));
     }
@@ -1296,7 +1301,7 @@ fn llvm_vector_ty(cx: &CodegenCx<'ll, '_>, elem_ty: ty::Ty, vec_len: usize,
             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)
     }
 
 
@@ -1379,7 +1384,7 @@ fn non_ptr(t: ty::Ty) -> ty::Ty {
         // 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)
         };
 
@@ -1394,8 +1399,11 @@ fn non_ptr(t: ty::Ty) -> ty::Ty {
         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);
@@ -1476,7 +1484,7 @@ fn non_ptr(t: ty::Ty) -> ty::Ty {
         // 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)
         };
 
@@ -1493,7 +1501,7 @@ fn non_ptr(t: ty::Ty) -> ty::Ty {
         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));
@@ -1628,7 +1636,7 @@ macro_rules! bitwise_red {
 
                     // 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 {
index d4cd2f786f813534f9640de6437dcfcf90e4ce86..1baab9b0c4d476ed875e541f3301d2955c07eb9f 100644 (file)
@@ -102,6 +102,8 @@ mod back {
     pub mod wasm;
 }
 
+mod traits;
+
 mod abi;
 mod allocator;
 mod asm;
index 0dc5a4ddde82c538bc820518cff99dfb18b3f5cd..70856a99ce79c55b89bedb88d68fd1634fc3a4f5 100644 (file)
@@ -17,6 +17,8 @@
 use type_::Type;
 use value::Value;
 
+use traits::BuilderMethods;
+
 use rustc::ty::{self, Ty};
 use rustc::ty::layout::HasDataLayout;
 use debuginfo;
@@ -48,7 +50,11 @@ pub fn get_fn(self, bx: &Builder<'a, 'll, 'tcx>,
         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);
 
index aade88648641498bf4c8f164d45ca48c13fbf3c3..5f7f138cb6eb2e33a2c724fc6900840b473d867e 100644 (file)
@@ -26,6 +26,8 @@
 use type_::Type;
 use value::Value;
 
+use traits::BuilderMethods;
+
 use syntax::symbol::Symbol;
 use syntax_pos::Pos;
 
@@ -98,16 +100,17 @@ fn codegen_terminator(&mut self,
             }
         };
 
-        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,
@@ -843,7 +846,10 @@ fn codegen_arguments_untupled(&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
index 2c241d938e5436db54cba5b21cb86ee4788c0f65..62fce894cf7a9582cc5a8f3f1f39edf7094b3824 100644 (file)
@@ -26,6 +26,7 @@
 use syntax::ast::Mutability;
 use syntax::source_map::Span;
 use value::Value;
+use traits::BuilderMethods;
 
 use super::super::callee;
 use super::FunctionCx;
index 7eda7ea0b7d7476cc87fc6f63588ac0bd64ec710..526c8f75f4943ea8ac14ff2ec7f9124a761da8fe 100644 (file)
@@ -26,6 +26,7 @@
 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;
@@ -119,7 +120,11 @@ pub fn monomorphize<T>(&self, value: &T) -> T
         )
     }
 
-    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);
     }
index 32609b06952beacf40a5093b0023bcf9be52e97a..e640b72cd44587a5c58e4e9c60d64a9b3eb77ceb 100644 (file)
@@ -21,6 +21,8 @@
 use type_::Type;
 use glue;
 
+use traits::BuilderMethods;
+
 use std::fmt;
 
 use super::{FunctionCx, LocalRef};
@@ -260,7 +262,11 @@ pub fn store(self, bx: &Builder<'a, 'll, 'tcx>, dest: PlaceRef<'tcx, &'ll Value>
         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);
     }
 
@@ -271,14 +277,23 @@ pub fn unaligned_volatile_store(
     ) {
         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,
     ) {
@@ -309,11 +324,13 @@ fn store_with_flags(
             }
         }
     }
+}
 
+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();
@@ -334,13 +351,13 @@ pub fn store_unsized(
         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);
     }
 }
 
index 4dc9eeb5a9ff789c443e5d845525b88eb5c4b5f0..b9bd07499651ea291da4805d84375e83e1ac7ce6 100644 (file)
@@ -23,6 +23,8 @@
 use glue;
 use mir::constant::const_alloc_to_llvm;
 
+use traits::BuilderMethods;
+
 use super::{FunctionCx, LocalRef};
 use super::operand::{OperandRef, OperandValue};
 
@@ -280,7 +282,11 @@ pub fn project_field(
     }
 
     /// 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);
index af166fe501e7f38dafc55135090cbc57227212fa..017b13410cd53c36b279449b4417f90af9752a90 100644 (file)
@@ -28,6 +28,8 @@
 use type_of::LayoutLlvmExt;
 use value::Value;
 
+use traits::BuilderMethods;
+
 use super::{FunctionCx, LocalRef};
 use super::operand::{OperandRef, OperandValue};
 use super::place::PlaceRef;
@@ -178,12 +180,12 @@ pub fn codegen_rvalue(&mut self,
         }
     }
 
-    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);
 
@@ -198,11 +200,11 @@ pub fn codegen_rvalue_unsized(
         }
     }
 
-    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 {
@@ -750,7 +752,11 @@ enum OverflowOp {
     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};
index 8fa5a8cc5510302fc44f95bb7d370b291f5c2bed..a3aea7b9180a1e81b312439054b4577bb7b64752 100644 (file)
@@ -12,6 +12,7 @@
 
 use asm;
 use builder::Builder;
+use traits::BuilderMethods;
 
 use super::FunctionCx;
 use super::LocalRef;
diff --git a/src/librustc_codegen_llvm/traits.rs b/src/librustc_codegen_llvm/traits.rs
new file mode 100644 (file)
index 0000000..2a6dbe9
--- /dev/null
@@ -0,0 +1,283 @@
+// 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;
+}
index 6fb78fe4aa5a4124c590b755153451f3a4fab0c0..44162ef0a50427ef070b976fc49ce17fbbebcbf0 100644 (file)
@@ -16,6 +16,7 @@
 use llvm::{Bool, False, True, TypeKind};
 
 use context::CodegenCx;
+use value::{Value, ValueTrait};
 
 use syntax::ast;
 use rustc::ty::layout::{self, Align, Size};
@@ -40,107 +41,143 @@ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
 }
 
 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),
@@ -149,7 +186,10 @@ pub fn c_int(cx: &CodegenCx<'ll, '_>) -> &'ll Type {
         }
     }
 
-    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),
@@ -160,7 +200,10 @@ pub fn int_from_ty(cx: &CodegenCx<'ll, '_>, t: ast::IntTy) -> &'ll Type {
         }
     }
 
-    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),
@@ -171,28 +214,41 @@ pub fn uint_from_ty(cx: &CodegenCx<'ll, '_>, t: ast::UintTy) -> &'ll Type {
         }
     }
 
-    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,
@@ -208,13 +264,13 @@ pub fn named_struct(cx: &CodegenCx<'ll, '_>, name: &str) -> &'ll Type {
     }
 
 
-    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)
         }
@@ -307,7 +363,7 @@ pub fn padding_filler(cx: &CodegenCx<'ll, '_>, size: Size, align: Align) -> &'ll
         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 {
index fea02edf7be01b70748d68f73f53285515b6e5d2..07a0878c7a7c934f5d2e1c0405b457288afe90bd 100644 (file)
@@ -16,6 +16,7 @@
 use rustc_target::abi::FloatTy;
 use rustc_mir::monomorphize::item::DefPathBasedNames;
 use type_::Type;
+use value::Value;
 
 use std::fmt::Write;
 
@@ -40,7 +41,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::<Value>(element, count);
             }
         }
         layout::Abi::ScalarPair(..) => {
@@ -93,7 +94,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::<Value>(layout.field(cx, 0).llvm_type(cx), count)
         }
         layout::FieldPlacement::Arbitrary { .. } => {
             match name {
index 357cc8fbf80e8439f7b58b9b84761be42c303148..1b789f67b57b9c0c0cfd8d70d03699293d0459d7 100644 (file)
 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 {
@@ -23,7 +26,14 @@ 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 {}