Move codegen_llvm::common::ty_fn_sig into rustc::ty::Instance.
This commit is contained in:
parent
06b6b1c790
commit
e568e98063
@ -8,13 +8,15 @@
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
use hir::Unsafety;
|
||||
use hir::def_id::DefId;
|
||||
use ty::{self, Ty, TypeFoldable, Substs, TyCtxt};
|
||||
use ty::{self, Ty, PolyFnSig, TypeFoldable, Substs, TyCtxt};
|
||||
use traits;
|
||||
use rustc_target::spec::abi::Abi;
|
||||
use util::ppaux;
|
||||
|
||||
use std::fmt;
|
||||
use std::iter;
|
||||
|
||||
#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug, RustcEncodable, RustcDecodable)]
|
||||
pub struct Instance<'tcx> {
|
||||
@ -59,6 +61,65 @@ pub fn ty(&self,
|
||||
&ty,
|
||||
)
|
||||
}
|
||||
|
||||
fn fn_sig_noadjust(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>) -> PolyFnSig<'tcx> {
|
||||
let ty = self.ty(tcx);
|
||||
match ty.sty {
|
||||
ty::FnDef(..) |
|
||||
// Shims currently have type FnPtr. Not sure this should remain.
|
||||
ty::FnPtr(_) => ty.fn_sig(tcx),
|
||||
ty::Closure(def_id, substs) => {
|
||||
let sig = substs.closure_sig(def_id, tcx);
|
||||
|
||||
let env_ty = tcx.closure_env_ty(def_id, substs).unwrap();
|
||||
sig.map_bound(|sig| tcx.mk_fn_sig(
|
||||
iter::once(*env_ty.skip_binder()).chain(sig.inputs().iter().cloned()),
|
||||
sig.output(),
|
||||
sig.variadic,
|
||||
sig.unsafety,
|
||||
sig.abi
|
||||
))
|
||||
}
|
||||
ty::Generator(def_id, substs, _) => {
|
||||
let sig = substs.poly_sig(def_id, tcx);
|
||||
|
||||
let env_region = ty::ReLateBound(ty::INNERMOST, ty::BrEnv);
|
||||
let env_ty = tcx.mk_mut_ref(tcx.mk_region(env_region), ty);
|
||||
|
||||
sig.map_bound(|sig| {
|
||||
let state_did = tcx.lang_items().gen_state().unwrap();
|
||||
let state_adt_ref = tcx.adt_def(state_did);
|
||||
let state_substs = tcx.intern_substs(&[
|
||||
sig.yield_ty.into(),
|
||||
sig.return_ty.into(),
|
||||
]);
|
||||
let ret_ty = tcx.mk_adt(state_adt_ref, state_substs);
|
||||
|
||||
tcx.mk_fn_sig(iter::once(env_ty),
|
||||
ret_ty,
|
||||
false,
|
||||
Unsafety::Normal,
|
||||
Abi::Rust
|
||||
)
|
||||
})
|
||||
}
|
||||
_ => bug!("unexpected type {:?} in Instance::fn_sig_noadjust", ty)
|
||||
}
|
||||
}
|
||||
|
||||
pub fn fn_sig(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>) -> ty::PolyFnSig<'tcx> {
|
||||
let mut fn_sig = self.fn_sig_noadjust(tcx);
|
||||
if let InstanceDef::VtableShim(..) = self.def {
|
||||
// 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] = tcx.mk_mut_ptr(inputs_and_output[0]);
|
||||
fn_sig.inputs_and_output = tcx.intern_type_list(&inputs_and_output);
|
||||
fn_sig
|
||||
});
|
||||
}
|
||||
fn_sig
|
||||
}
|
||||
}
|
||||
|
||||
impl<'tcx> InstanceDef<'tcx> {
|
||||
|
@ -11,7 +11,7 @@
|
||||
use llvm::{self, AttributePlace};
|
||||
use base;
|
||||
use builder::{Builder, MemFlags};
|
||||
use common::{ty_fn_sig, C_usize};
|
||||
use common::C_usize;
|
||||
use context::CodegenCx;
|
||||
use mir::place::PlaceRef;
|
||||
use mir::operand::OperandValue;
|
||||
@ -283,8 +283,7 @@ fn adjust_for_abi(&mut self,
|
||||
|
||||
impl<'tcx> FnTypeExt<'tcx> for FnType<'tcx, Ty<'tcx>> {
|
||||
fn of_instance(cx: &CodegenCx<'ll, 'tcx>, instance: &ty::Instance<'tcx>) -> Self {
|
||||
let fn_ty = instance.ty(cx.tcx);
|
||||
let sig = ty_fn_sig(cx, fn_ty);
|
||||
let sig = instance.fn_sig(cx.tcx);
|
||||
let sig = cx.tcx.normalize_erasing_late_bound_regions(ty::ParamEnv::reveal_all(), &sig);
|
||||
FnType::new(cx, sig, &[])
|
||||
}
|
||||
|
@ -56,7 +56,7 @@
|
||||
use common::{C_bool, C_bytes_in_context, C_i32, C_usize};
|
||||
use rustc_mir::monomorphize::collector::{self, MonoItemCollectionMode};
|
||||
use rustc_mir::monomorphize::item::DefPathBasedNames;
|
||||
use common::{self, C_struct_in_context, C_array, val_ty};
|
||||
use common::{C_struct_in_context, C_array, val_ty};
|
||||
use consts;
|
||||
use context::CodegenCx;
|
||||
use debuginfo;
|
||||
@ -491,8 +491,7 @@ pub fn codegen_instance<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>, instance: Instance<'
|
||||
// release builds.
|
||||
info!("codegen_instance({})", instance);
|
||||
|
||||
let fn_ty = instance.ty(cx.tcx);
|
||||
let sig = common::ty_fn_sig_vtable(cx, fn_ty, instance.is_vtable_shim());
|
||||
let sig = instance.fn_sig(cx.tcx);
|
||||
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(||
|
||||
|
@ -47,16 +47,16 @@ pub fn get_fn(
|
||||
assert!(!instance.substs.has_escaping_regions());
|
||||
assert!(!instance.substs.has_param_types());
|
||||
|
||||
let fn_ty = instance.ty(cx.tcx);
|
||||
let sig = instance.fn_sig(cx.tcx);
|
||||
if let Some(&llfn) = cx.instances.borrow().get(&instance) {
|
||||
return llfn;
|
||||
}
|
||||
|
||||
let sym = tcx.symbol_name(instance).as_str();
|
||||
debug!("get_fn({:?}: {:?}) => {}", instance, fn_ty, sym);
|
||||
debug!("get_fn({:?}: {:?}) => {}", instance, sig, sym);
|
||||
|
||||
// Create a fn pointer with the substituted signature.
|
||||
let fn_ptr_ty = tcx.mk_fn_ptr(common::ty_fn_sig_vtable(cx, fn_ty, instance.is_vtable_shim()));
|
||||
let fn_ptr_ty = tcx.mk_fn_ptr(sig);
|
||||
let llptrty = cx.layout_of(fn_ptr_ty).llvm_type(cx);
|
||||
|
||||
let llfn = if let Some(llfn) = declare::get_declared_value(cx, &sym) {
|
||||
@ -91,7 +91,7 @@ pub fn get_fn(
|
||||
llfn
|
||||
}
|
||||
} else {
|
||||
let llfn = declare::declare_fn(cx, &sym, common::ty_fn_sig_vtable(cx, fn_ty, instance.is_vtable_shim()));
|
||||
let llfn = declare::declare_fn(cx, &sym, sig);
|
||||
assert_eq!(common::val_ty(llfn), llptrty);
|
||||
debug!("get_fn: not casting pointer!");
|
||||
|
||||
|
@ -30,9 +30,7 @@
|
||||
use rustc::hir;
|
||||
|
||||
use libc::{c_uint, c_char};
|
||||
use std::iter;
|
||||
|
||||
use rustc_target::spec::abi::Abi;
|
||||
use syntax::symbol::LocalInternedString;
|
||||
use syntax_pos::{Span, DUMMY_SP};
|
||||
|
||||
@ -404,71 +402,3 @@ pub fn shift_mask_val(
|
||||
_ => bug!("shift_mask_val: expected Integer or Vector, found {:?}", kind),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn ty_fn_sig<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>,
|
||||
ty: Ty<'tcx>)
|
||||
-> ty::PolyFnSig<'tcx>
|
||||
{
|
||||
match ty.sty {
|
||||
ty::FnDef(..) |
|
||||
// Shims currently have type FnPtr. Not sure this should remain.
|
||||
ty::FnPtr(_) => ty.fn_sig(cx.tcx),
|
||||
ty::Closure(def_id, substs) => {
|
||||
let tcx = cx.tcx;
|
||||
let sig = substs.closure_sig(def_id, tcx);
|
||||
|
||||
let env_ty = tcx.closure_env_ty(def_id, substs).unwrap();
|
||||
sig.map_bound(|sig| tcx.mk_fn_sig(
|
||||
iter::once(*env_ty.skip_binder()).chain(sig.inputs().iter().cloned()),
|
||||
sig.output(),
|
||||
sig.variadic,
|
||||
sig.unsafety,
|
||||
sig.abi
|
||||
))
|
||||
}
|
||||
ty::Generator(def_id, substs, _) => {
|
||||
let tcx = cx.tcx;
|
||||
let sig = substs.poly_sig(def_id, cx.tcx);
|
||||
|
||||
let env_region = ty::ReLateBound(ty::INNERMOST, ty::BrEnv);
|
||||
let env_ty = tcx.mk_mut_ref(tcx.mk_region(env_region), ty);
|
||||
|
||||
sig.map_bound(|sig| {
|
||||
let state_did = tcx.lang_items().gen_state().unwrap();
|
||||
let state_adt_ref = tcx.adt_def(state_did);
|
||||
let state_substs = tcx.intern_substs(&[
|
||||
sig.yield_ty.into(),
|
||||
sig.return_ty.into(),
|
||||
]);
|
||||
let ret_ty = tcx.mk_adt(state_adt_ref, state_substs);
|
||||
|
||||
tcx.mk_fn_sig(iter::once(env_ty),
|
||||
ret_ty,
|
||||
false,
|
||||
hir::Unsafety::Normal,
|
||||
Abi::Rust
|
||||
)
|
||||
})
|
||||
}
|
||||
_ => 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
|
||||
}
|
||||
|
@ -298,8 +298,7 @@ fn codegen_terminator(&mut self,
|
||||
};
|
||||
let (drop_fn, fn_ty) = match ty.sty {
|
||||
ty::Dynamic(..) => {
|
||||
let fn_ty = drop_fn.ty(bx.cx.tcx);
|
||||
let sig = common::ty_fn_sig(bx.cx, fn_ty);
|
||||
let sig = drop_fn.fn_sig(bx.cx.tcx);
|
||||
let sig = bx.tcx().normalize_erasing_late_bound_regions(
|
||||
ty::ParamEnv::reveal_all(),
|
||||
&sig,
|
||||
|
@ -17,7 +17,6 @@
|
||||
use asm;
|
||||
use attributes;
|
||||
use base;
|
||||
use common;
|
||||
use consts;
|
||||
use context::CodegenCx;
|
||||
use declare;
|
||||
@ -154,8 +153,7 @@ fn predefine_fn<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>,
|
||||
assert!(!instance.substs.needs_infer() &&
|
||||
!instance.substs.has_param_types());
|
||||
|
||||
let mono_ty = instance.ty(cx.tcx);
|
||||
let mono_sig = common::ty_fn_sig_vtable(cx, mono_ty, instance.is_vtable_shim());
|
||||
let mono_sig = instance.fn_sig(cx.tcx);
|
||||
let attrs = cx.tcx.codegen_fn_attrs(instance.def_id());
|
||||
let lldecl = declare::declare_fn(cx, symbol_name, mono_sig);
|
||||
unsafe { llvm::LLVMRustSetLinkage(lldecl, base::linkage_to_llvm(linkage)) };
|
||||
@ -180,7 +178,7 @@ fn predefine_fn<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>,
|
||||
}
|
||||
}
|
||||
|
||||
debug!("predefine_fn: mono_ty = {:?} instance = {:?}", mono_ty, instance);
|
||||
debug!("predefine_fn: mono_sig = {:?} instance = {:?}", mono_sig, instance);
|
||||
if instance.def.is_inline(cx.tcx) {
|
||||
attributes::inline(cx, lldecl, attributes::InlineAttr::Hint);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user