about summary refs log tree commit diff
diff options
context:
space:
mode:
authorMasaki Hara <ackie.h.gmai@gmail.com>2018-09-11 23:26:38 +0900
committerMasaki Hara <ackie.h.gmai@gmail.com>2018-10-24 21:59:06 +0900
commitfe3f606cda083aec9564add4f7ff6ed4c4a0fff7 (patch)
tree8d17d0fb27e1809aac66d557110044db5ca16502
parent824315a7220895b0e21783726eb2b7856bc27406 (diff)
downloadrust-fe3f606cda083aec9564add4f7ff6ed4c4a0fff7.tar.gz
rust-fe3f606cda083aec9564add4f7ff6ed4c4a0fff7.zip
Add ty_fn_sig_vtable for getting adjusted signature for vtable shims.
-rw-r--r--src/librustc_codegen_llvm/base.rs2
-rw-r--r--src/librustc_codegen_llvm/callee.rs2
-rw-r--r--src/librustc_codegen_llvm/common.rs19
3 files changed, 21 insertions, 2 deletions
diff --git a/src/librustc_codegen_llvm/base.rs b/src/librustc_codegen_llvm/base.rs
index 614a562846e..501a0b8af76 100644
--- a/src/librustc_codegen_llvm/base.rs
+++ b/src/librustc_codegen_llvm/base.rs
@@ -492,7 +492,7 @@ pub fn codegen_instance<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>, instance: Instance<'
     info!("codegen_instance({})", instance);
 
     let fn_ty = instance.ty(cx.tcx);
-    let sig = common::ty_fn_sig(cx, fn_ty);
+    let sig = common::ty_fn_sig_vtable(cx, fn_ty, instance.is_vtable_shim());
     let sig = cx.tcx.normalize_erasing_late_bound_regions(ty::ParamEnv::reveal_all(), &sig);
 
     let lldecl = cx.instances.borrow().get(&instance).cloned().unwrap_or_else(||
diff --git a/src/librustc_codegen_llvm/callee.rs b/src/librustc_codegen_llvm/callee.rs
index 4b4ccb3b600..972cccd5d68 100644
--- a/src/librustc_codegen_llvm/callee.rs
+++ b/src/librustc_codegen_llvm/callee.rs
@@ -56,7 +56,7 @@ pub fn get_fn(
     debug!("get_fn({:?}: {:?}) => {}", instance, fn_ty, sym);
 
     // Create a fn pointer with the substituted signature.
-    let fn_ptr_ty = tcx.mk_fn_ptr(common::ty_fn_sig(cx, fn_ty));
+    let fn_ptr_ty = tcx.mk_fn_ptr(common::ty_fn_sig_vtable(cx, fn_ty, instance.is_vtable_shim()));
     let llptrty = cx.layout_of(fn_ptr_ty).llvm_type(cx);
 
     let llfn = if let Some(llfn) = declare::get_declared_value(cx, &sym) {
diff --git a/src/librustc_codegen_llvm/common.rs b/src/librustc_codegen_llvm/common.rs
index c08937fa9b9..df91f758374 100644
--- a/src/librustc_codegen_llvm/common.rs
+++ b/src/librustc_codegen_llvm/common.rs
@@ -453,3 +453,22 @@ pub fn ty_fn_sig<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>,
         _ => bug!("unexpected type {:?} to ty_fn_sig", ty)
     }
 }
+
+pub fn ty_fn_sig_vtable<'a, 'tcx>(
+    cx: &CodegenCx<'a, 'tcx>,
+    ty: Ty<'tcx>,
+    is_vtable_shim: bool
+    ) -> ty::PolyFnSig<'tcx>
+{
+    let mut fn_sig = ty_fn_sig(cx, ty);
+    if is_vtable_shim {
+        // Modify fn(self, ...) to fn(self: *mut Self, ...)
+        fn_sig = fn_sig.map_bound(|mut fn_sig| {
+            let mut inputs_and_output = fn_sig.inputs_and_output.to_vec();
+            inputs_and_output[0] = cx.tcx.mk_mut_ptr(inputs_and_output[0]);
+            fn_sig.inputs_and_output = cx.tcx.intern_type_list(&inputs_and_output);
+            fn_sig
+        });
+    }
+    fn_sig
+}