]> git.lizzy.rs Git - rust.git/blobdiff - src/librustc_trans/abi.rs
refactor trans::mir::block to trans all calls through the same code
[rust.git] / src / librustc_trans / abi.rs
index c4fdc46d030c9e163d2b0a9d8d2f4637f8f5ef58..120f201a9c8b73ef6bd4a93f079f96cc1cf5094a 100644 (file)
@@ -11,7 +11,7 @@
 use llvm::{self, ValueRef, AttributePlace};
 use base;
 use builder::Builder;
-use common::{type_is_fat_ptr, C_uint};
+use common::{instance_ty, ty_fn_sig, type_is_fat_ptr, C_uint};
 use context::CrateContext;
 use cabi_x86;
 use cabi_x86_64;
@@ -29,6 +29,7 @@
 use cabi_sparc64;
 use cabi_nvptx;
 use cabi_nvptx64;
+use cabi_hexagon;
 use machine::llalign_of_min;
 use type_::Type;
 use type_of;
@@ -553,7 +554,7 @@ pub fn store(&self, bcx: &Builder<'a, 'tcx>, mut val: ValueRef, dst: ValueRef) {
                 //   bitcasting to the struct type yields invalid cast errors.
 
                 // We instead thus allocate some scratch space...
-                let llscratch = bcx.alloca(ty, "abi_cast");
+                let llscratch = bcx.alloca(ty, "abi_cast", None);
                 base::Lifetime::Start.call(bcx, llscratch);
 
                 // ...where we first store the value...
@@ -609,6 +610,14 @@ pub struct FnType<'tcx> {
 }
 
 impl<'a, 'tcx> FnType<'tcx> {
+    pub fn of_instance(ccx: &CrateContext<'a, 'tcx>, instance: &ty::Instance<'tcx>)
+                       -> Self {
+        let fn_ty = instance_ty(ccx.shared(), &instance);
+        let sig = ty_fn_sig(ccx, fn_ty);
+        let sig = ccx.tcx().erase_late_bound_regions_and_normalize(&sig);
+        Self::new(ccx, sig, &[])
+    }
+
     pub fn new(ccx: &CrateContext<'a, 'tcx>,
                sig: ty::FnSig<'tcx>,
                extra_args: &[Ty<'tcx>]) -> FnType<'tcx> {
@@ -630,6 +639,8 @@ pub fn new_vtable(ccx: &CrateContext<'a, 'tcx>,
     pub fn unadjusted(ccx: &CrateContext<'a, 'tcx>,
                       sig: ty::FnSig<'tcx>,
                       extra_args: &[Ty<'tcx>]) -> FnType<'tcx> {
+        debug!("FnType::unadjusted({:?}, {:?})", sig, extra_args);
+
         use self::Abi::*;
         let cconv = match ccx.sess().target.target.adjust_abi(sig.abi) {
             RustIntrinsic | PlatformIntrinsic |
@@ -641,6 +652,7 @@ pub fn unadjusted(ccx: &CrateContext<'a, 'tcx>,
             Stdcall => llvm::X86StdcallCallConv,
             Fastcall => llvm::X86FastcallCallConv,
             Vectorcall => llvm::X86_VectorCall,
+            Thiscall => llvm::X86_ThisCall,
             C => llvm::CCallConv,
             Unadjusted => llvm::CCallConv,
             Win64 => llvm::X86_64_Win64,
@@ -746,13 +758,13 @@ pub fn unadjusted(ccx: &CrateContext<'a, 'tcx>,
                 // `&T` where `T` contains no `UnsafeCell<U>` is immutable, and can be marked as
                 // both `readonly` and `noalias`, as LLVM's definition of `noalias` is based solely
                 // on memory dependencies rather than pointer equality
-                let interior_unsafe = mt.ty.type_contents(ccx.tcx()).interior_unsafe();
+                let is_freeze = ccx.shared().type_is_freeze(mt.ty);
 
-                if mt.mutbl != hir::MutMutable && !interior_unsafe {
+                if mt.mutbl != hir::MutMutable && is_freeze {
                     arg.attrs.set(ArgAttribute::NoAlias);
                 }
 
-                if mt.mutbl == hir::MutImmutable && !interior_unsafe {
+                if mt.mutbl == hir::MutImmutable && is_freeze {
                     arg.attrs.set(ArgAttribute::ReadOnly);
                 }
 
@@ -896,6 +908,7 @@ fn adjust_for_abi(&mut self,
             "sparc64" => cabi_sparc64::compute_abi_info(ccx, self),
             "nvptx" => cabi_nvptx::compute_abi_info(ccx, self),
             "nvptx64" => cabi_nvptx64::compute_abi_info(ccx, self),
+            "hexagon" => cabi_hexagon::compute_abi_info(ccx, self),
             a => ccx.sess().fatal(&format!("unrecognized arch \"{}\" in target specification", a))
         }