Remove fn_ty from FunctionContext
This commit is contained in:
parent
15b9b27bb0
commit
bd009dc444
@ -598,10 +598,9 @@ pub fn trans_instance<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, instance: Instance
|
||||
|
||||
let fn_ty = FnType::new(ccx, abi, &sig, &[]);
|
||||
|
||||
let fcx = FunctionContext::new(ccx, lldecl, fn_ty);
|
||||
|
||||
let fcx = FunctionContext::new(ccx, lldecl);
|
||||
let mir = ccx.tcx().item_mir(instance.def);
|
||||
mir::trans_mir(&fcx, &mir, instance, &sig, abi);
|
||||
mir::trans_mir(&fcx, fn_ty, &mir, instance, &sig, abi);
|
||||
}
|
||||
|
||||
pub fn trans_ctor_shim<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
|
||||
@ -618,28 +617,28 @@ pub fn trans_ctor_shim<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
|
||||
let sig = ccx.tcx().erase_late_bound_regions_and_normalize(&ctor_ty.fn_sig());
|
||||
let fn_ty = FnType::new(ccx, Abi::Rust, &sig, &[]);
|
||||
|
||||
let fcx = FunctionContext::new(ccx, llfndecl, fn_ty);
|
||||
let fcx = FunctionContext::new(ccx, llfndecl);
|
||||
let bcx = fcx.get_entry_block();
|
||||
if !fcx.fn_ty.ret.is_ignore() {
|
||||
if !fn_ty.ret.is_ignore() {
|
||||
// But if there are no nested returns, we skip the indirection
|
||||
// and have a single retslot
|
||||
let dest = if fcx.fn_ty.ret.is_indirect() {
|
||||
let dest = if fn_ty.ret.is_indirect() {
|
||||
get_param(fcx.llfn, 0)
|
||||
} else {
|
||||
// We create an alloca to hold a pointer of type `ret.original_ty`
|
||||
// which will hold the pointer to the right alloca which has the
|
||||
// final ret value
|
||||
fcx.alloca(fcx.fn_ty.ret.memory_ty(ccx), "sret_slot")
|
||||
fcx.alloca(fn_ty.ret.memory_ty(ccx), "sret_slot")
|
||||
};
|
||||
let dest_val = adt::MaybeSizedValue::sized(dest); // Can return unsized value
|
||||
let mut llarg_idx = fcx.fn_ty.ret.is_indirect() as usize;
|
||||
let mut llarg_idx = fn_ty.ret.is_indirect() as usize;
|
||||
let mut arg_idx = 0;
|
||||
for (i, arg_ty) in sig.inputs().iter().enumerate() {
|
||||
let lldestptr = adt::trans_field_ptr(&bcx, sig.output(), dest_val, Disr::from(disr), i);
|
||||
let arg = &fcx.fn_ty.args[arg_idx];
|
||||
let arg = &fn_ty.args[arg_idx];
|
||||
arg_idx += 1;
|
||||
if common::type_is_fat_ptr(bcx.ccx, arg_ty) {
|
||||
let meta = &fcx.fn_ty.args[arg_idx];
|
||||
let meta = &fn_ty.args[arg_idx];
|
||||
arg_idx += 1;
|
||||
arg.store_fn_arg(&bcx, &mut llarg_idx, get_dataptr(&bcx, lldestptr));
|
||||
meta.store_fn_arg(&bcx, &mut llarg_idx, get_meta(&bcx, lldestptr));
|
||||
@ -649,14 +648,14 @@ pub fn trans_ctor_shim<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
|
||||
}
|
||||
adt::trans_set_discr(&bcx, sig.output(), dest, disr);
|
||||
|
||||
if fcx.fn_ty.ret.is_indirect() {
|
||||
if fn_ty.ret.is_indirect() {
|
||||
bcx.ret_void();
|
||||
return;
|
||||
}
|
||||
|
||||
if let Some(cast_ty) = fcx.fn_ty.ret.cast {
|
||||
if let Some(cast_ty) = fn_ty.ret.cast {
|
||||
let load = bcx.load(bcx.pointercast(dest, cast_ty.ptr_to()));
|
||||
let llalign = llalign_of_min(ccx, fcx.fn_ty.ret.ty);
|
||||
let llalign = llalign_of_min(ccx, fn_ty.ret.ty);
|
||||
unsafe {
|
||||
llvm::LLVMSetAlignment(load, llalign);
|
||||
}
|
||||
|
@ -328,7 +328,8 @@ fn trans_fn_once_adapter_shim<'a, 'tcx>(
|
||||
let lloncefn = declare::define_internal_fn(ccx, &function_name, llonce_fn_ty);
|
||||
attributes::set_frame_pointer_elimination(ccx, lloncefn);
|
||||
|
||||
let fcx = FunctionContext::new(ccx, lloncefn, fn_ty);
|
||||
let orig_fn_ty = fn_ty;
|
||||
let fcx = FunctionContext::new(ccx, lloncefn);
|
||||
let mut bcx = fcx.get_entry_block();
|
||||
|
||||
let callee = Callee {
|
||||
@ -342,7 +343,7 @@ fn trans_fn_once_adapter_shim<'a, 'tcx>(
|
||||
let fn_ret = callee.ty.fn_ret();
|
||||
let fn_ty = callee.direct_fn_type(bcx.ccx, &[]);
|
||||
let idx = fn_ty.ret.is_indirect() as usize;
|
||||
let env_arg = &fcx.fn_ty.args[0];
|
||||
let env_arg = &orig_fn_ty.args[0];
|
||||
let llenv = if env_arg.is_indirect() {
|
||||
llargs[idx]
|
||||
} else {
|
||||
@ -494,12 +495,12 @@ fn trans_fn_pointer_shim<'a, 'tcx>(
|
||||
let llfn = declare::define_internal_fn(ccx, &function_name, tuple_fn_ty);
|
||||
attributes::set_frame_pointer_elimination(ccx, llfn);
|
||||
//
|
||||
let fcx = FunctionContext::new(ccx, llfn, fn_ty);
|
||||
let fcx = FunctionContext::new(ccx, llfn);
|
||||
let bcx = fcx.get_entry_block();
|
||||
|
||||
let mut llargs = get_params(fcx.llfn);
|
||||
|
||||
let self_arg = llargs.remove(fcx.fn_ty.ret.is_indirect() as usize);
|
||||
let self_arg = llargs.remove(fn_ty.ret.is_indirect() as usize);
|
||||
let llfnpointer = llfnpointer.unwrap_or_else(|| {
|
||||
// the first argument (`self`) will be ptr to the fn pointer
|
||||
if is_by_ref {
|
||||
|
@ -21,7 +21,7 @@ use rustc::hir::def_id::DefId;
|
||||
use rustc::hir::map::DefPathData;
|
||||
use rustc::util::common::MemoizationMap;
|
||||
use middle::lang_items::LangItem;
|
||||
use abi::{Abi, FnType};
|
||||
use abi::Abi;
|
||||
use base;
|
||||
use builder::Builder;
|
||||
use callee::Callee;
|
||||
@ -236,9 +236,6 @@ pub struct FunctionContext<'a, 'tcx: 'a> {
|
||||
// allocas, so that LLVM will coalesce them into a single alloca call.
|
||||
alloca_insert_pt: Option<ValueRef>,
|
||||
|
||||
// Describes the return/argument LLVM types and their ABI handling.
|
||||
pub fn_ty: FnType,
|
||||
|
||||
// This function's enclosing crate context.
|
||||
pub ccx: &'a CrateContext<'a, 'tcx>,
|
||||
|
||||
@ -248,15 +245,10 @@ pub struct FunctionContext<'a, 'tcx: 'a> {
|
||||
impl<'a, 'tcx> FunctionContext<'a, 'tcx> {
|
||||
/// Create a function context for the given function.
|
||||
/// Call FunctionContext::get_entry_block for the first entry block.
|
||||
pub fn new(
|
||||
ccx: &'a CrateContext<'a, 'tcx>,
|
||||
llfndecl: ValueRef,
|
||||
fn_ty: FnType,
|
||||
) -> FunctionContext<'a, 'tcx> {
|
||||
pub fn new(ccx: &'a CrateContext<'a, 'tcx>, llfndecl: ValueRef) -> FunctionContext<'a, 'tcx> {
|
||||
let mut fcx = FunctionContext {
|
||||
llfn: llfndecl,
|
||||
alloca_insert_pt: None,
|
||||
fn_ty: fn_ty,
|
||||
ccx: ccx,
|
||||
alloca_builder: Builder::with_ccx(ccx),
|
||||
};
|
||||
|
@ -186,9 +186,9 @@ fn get_drop_glue_core<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, g: DropGlueKind<'t
|
||||
|
||||
pub fn implement_drop_glue<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, g: DropGlueKind<'tcx>) {
|
||||
assert_eq!(g.ty(), get_drop_glue_type(ccx.shared(), g.ty()));
|
||||
let (llfn, fn_ty) = ccx.drop_glues().borrow().get(&g).unwrap().clone();
|
||||
let (llfn, _) = ccx.drop_glues().borrow().get(&g).unwrap().clone();
|
||||
|
||||
let fcx = FunctionContext::new(ccx, llfn, fn_ty);
|
||||
let fcx = FunctionContext::new(ccx, llfn);
|
||||
let bcx = fcx.get_entry_block();
|
||||
|
||||
ccx.stats().n_glues_created.set(ccx.stats().n_glues_created.get() + 1);
|
||||
|
@ -878,7 +878,6 @@ fn gen_fn<'a, 'tcx>(fcx: &FunctionContext<'a, 'tcx>,
|
||||
-> ValueRef {
|
||||
let ccx = fcx.ccx;
|
||||
let sig = ccx.tcx().mk_fn_sig(inputs.into_iter(), output, false);
|
||||
let fn_ty = FnType::new(ccx, Abi::Rust, &sig, &[]);
|
||||
|
||||
let rust_fn_ty = ccx.tcx().mk_fn_ptr(ccx.tcx().mk_bare_fn(ty::BareFnTy {
|
||||
unsafety: hir::Unsafety::Unsafe,
|
||||
@ -886,7 +885,7 @@ fn gen_fn<'a, 'tcx>(fcx: &FunctionContext<'a, 'tcx>,
|
||||
sig: ty::Binder(sig)
|
||||
}));
|
||||
let llfn = declare::define_internal_fn(ccx, name, rust_fn_ty);
|
||||
let fcx = FunctionContext::new(ccx, llfn, fn_ty);
|
||||
let fcx = FunctionContext::new(ccx, llfn);
|
||||
trans(fcx.get_entry_block());
|
||||
llfn
|
||||
}
|
||||
|
@ -11,7 +11,6 @@
|
||||
use attributes;
|
||||
use llvm::{ValueRef, get_params};
|
||||
use rustc::traits;
|
||||
use abi::FnType;
|
||||
use callee::{Callee, CalleeData};
|
||||
use common::*;
|
||||
use consts;
|
||||
@ -63,25 +62,20 @@ pub fn get_virtual_method<'a, 'tcx>(bcx: &BlockAndBuilder<'a, 'tcx>,
|
||||
pub fn trans_object_shim<'a, 'tcx>(ccx: &'a CrateContext<'a, 'tcx>,
|
||||
callee: Callee<'tcx>)
|
||||
-> ValueRef {
|
||||
let tcx = ccx.tcx();
|
||||
|
||||
debug!("trans_object_shim({:?})", callee);
|
||||
|
||||
let (sig, abi, function_name) = match callee.ty.sty {
|
||||
ty::TyFnDef(def_id, substs, f) => {
|
||||
let function_name = match callee.ty.sty {
|
||||
ty::TyFnDef(def_id, substs, _) => {
|
||||
let instance = Instance::new(def_id, substs);
|
||||
(&f.sig, f.abi, instance.symbol_name(ccx.shared()))
|
||||
instance.symbol_name(ccx.shared())
|
||||
}
|
||||
_ => bug!()
|
||||
};
|
||||
|
||||
let sig = tcx.erase_late_bound_regions_and_normalize(sig);
|
||||
let fn_ty = FnType::new(ccx, abi, &sig, &[]);
|
||||
|
||||
let llfn = declare::define_internal_fn(ccx, &function_name, callee.ty);
|
||||
attributes::set_frame_pointer_elimination(ccx, llfn);
|
||||
|
||||
let fcx = FunctionContext::new(ccx, llfn, fn_ty);
|
||||
let fcx = FunctionContext::new(ccx, llfn);
|
||||
let bcx = fcx.get_entry_block();
|
||||
|
||||
let mut llargs = get_params(fcx.llfn);
|
||||
@ -103,7 +97,7 @@ pub fn trans_object_shim<'a, 'tcx>(ccx: &'a CrateContext<'a, 'tcx>,
|
||||
if fn_ret.0.is_never() {
|
||||
bcx.unreachable();
|
||||
} else {
|
||||
if fn_ty.ret.is_indirect() || fcx.fn_ty.ret.is_ignore() {
|
||||
if fn_ty.ret.is_indirect() || fn_ty.ret.is_ignore() {
|
||||
bcx.ret_void();
|
||||
} else {
|
||||
bcx.ret(llret);
|
||||
|
@ -192,7 +192,7 @@ impl<'a, 'tcx> MirContext<'a, 'tcx> {
|
||||
}
|
||||
|
||||
mir::TerminatorKind::Return => {
|
||||
let ret = bcx.fcx().fn_ty.ret;
|
||||
let ret = self.fn_ty.ret;
|
||||
if ret.is_ignore() || ret.is_indirect() {
|
||||
bcx.ret_void();
|
||||
return;
|
||||
|
@ -22,6 +22,7 @@ use base;
|
||||
use common::{self, BlockAndBuilder, CrateContext, FunctionContext, C_null, Funclet};
|
||||
use debuginfo::{self, declare_local, VariableAccess, VariableKind, FunctionDebugContext};
|
||||
use monomorphize::{self, Instance};
|
||||
use abi::FnType;
|
||||
use machine;
|
||||
use type_of;
|
||||
|
||||
@ -52,6 +53,8 @@ pub struct MirContext<'a, 'tcx:'a> {
|
||||
|
||||
ccx: &'a CrateContext<'a, 'tcx>,
|
||||
|
||||
fn_ty: FnType,
|
||||
|
||||
/// When unwinding is initiated, we have to store this personality
|
||||
/// value somewhere so that we can load it and re-use it in the
|
||||
/// resume instruction. The personality is (afaik) some kind of
|
||||
@ -197,6 +200,7 @@ impl<'tcx> LocalRef<'tcx> {
|
||||
|
||||
pub fn trans_mir<'a, 'tcx: 'a>(
|
||||
fcx: &'a FunctionContext<'a, 'tcx>,
|
||||
fn_ty: FnType,
|
||||
mir: &'a Mir<'tcx>,
|
||||
instance: Instance<'tcx>,
|
||||
sig: &ty::FnSig<'tcx>,
|
||||
@ -224,6 +228,7 @@ pub fn trans_mir<'a, 'tcx: 'a>(
|
||||
let mut mircx = MirContext {
|
||||
mir: mir,
|
||||
fcx: fcx,
|
||||
fn_ty: fn_ty,
|
||||
ccx: fcx.ccx,
|
||||
llpersonalityslot: None,
|
||||
blocks: block_bcxs,
|
||||
@ -271,7 +276,7 @@ pub fn trans_mir<'a, 'tcx: 'a>(
|
||||
LocalRef::Lvalue(lvalue)
|
||||
} else {
|
||||
// Temporary or return pointer
|
||||
if local == mir::RETURN_POINTER && fcx.fn_ty.ret.is_indirect() {
|
||||
if local == mir::RETURN_POINTER && mircx.fn_ty.ret.is_indirect() {
|
||||
debug!("alloc: {:?} (return pointer) -> lvalue", local);
|
||||
let llretptr = llvm::get_param(fcx.llfn, 0);
|
||||
LocalRef::Lvalue(LvalueRef::new_sized(llretptr, LvalueTy::from_ty(ty)))
|
||||
@ -351,7 +356,7 @@ fn arg_local_refs<'a, 'tcx>(bcx: &BlockAndBuilder<'a, 'tcx>,
|
||||
let fcx = bcx.fcx();
|
||||
let tcx = bcx.tcx();
|
||||
let mut idx = 0;
|
||||
let mut llarg_idx = fcx.fn_ty.ret.is_indirect() as usize;
|
||||
let mut llarg_idx = mircx.fn_ty.ret.is_indirect() as usize;
|
||||
|
||||
// Get the argument scope, if it exists and if we need it.
|
||||
let arg_scope = scopes[mir::ARGUMENT_VISIBILITY_SCOPE];
|
||||
@ -379,12 +384,12 @@ fn arg_local_refs<'a, 'tcx>(bcx: &BlockAndBuilder<'a, 'tcx>,
|
||||
let lltemp = base::alloc_ty(&bcx, arg_ty, &format!("arg{}", arg_index));
|
||||
for (i, &tupled_arg_ty) in tupled_arg_tys.iter().enumerate() {
|
||||
let dst = bcx.struct_gep(lltemp, i);
|
||||
let arg = &fcx.fn_ty.args[idx];
|
||||
let arg = &mircx.fn_ty.args[idx];
|
||||
idx += 1;
|
||||
if common::type_is_fat_ptr(bcx.ccx, tupled_arg_ty) {
|
||||
// We pass fat pointers as two words, but inside the tuple
|
||||
// they are the two sub-fields of a single aggregate field.
|
||||
let meta = &fcx.fn_ty.args[idx];
|
||||
let meta = &mircx.fn_ty.args[idx];
|
||||
idx += 1;
|
||||
arg.store_fn_arg(bcx, &mut llarg_idx, base::get_dataptr(bcx, dst));
|
||||
meta.store_fn_arg(bcx, &mut llarg_idx, base::get_meta(bcx, dst));
|
||||
@ -413,7 +418,7 @@ fn arg_local_refs<'a, 'tcx>(bcx: &BlockAndBuilder<'a, 'tcx>,
|
||||
return LocalRef::Lvalue(LvalueRef::new_sized(lltemp, LvalueTy::from_ty(arg_ty)));
|
||||
}
|
||||
|
||||
let arg = &fcx.fn_ty.args[idx];
|
||||
let arg = &mircx.fn_ty.args[idx];
|
||||
idx += 1;
|
||||
let llval = if arg.is_indirect() && bcx.sess().opts.debuginfo != FullDebugInfo {
|
||||
// Don't copy an indirect argument to an alloca, the caller
|
||||
@ -442,7 +447,7 @@ fn arg_local_refs<'a, 'tcx>(bcx: &BlockAndBuilder<'a, 'tcx>,
|
||||
let llarg = llvm::get_param(fcx.llfn, llarg_idx as c_uint);
|
||||
llarg_idx += 1;
|
||||
let val = if common::type_is_fat_ptr(bcx.ccx, arg_ty) {
|
||||
let meta = &fcx.fn_ty.args[idx];
|
||||
let meta = &mircx.fn_ty.args[idx];
|
||||
idx += 1;
|
||||
assert_eq!((meta.cast, meta.pad), (None, None));
|
||||
let llmeta = llvm::get_param(fcx.llfn, llarg_idx as c_uint);
|
||||
@ -462,7 +467,7 @@ fn arg_local_refs<'a, 'tcx>(bcx: &BlockAndBuilder<'a, 'tcx>,
|
||||
// we pass fat pointers as two words, but we want to
|
||||
// represent them internally as a pointer to two words,
|
||||
// so make an alloca to store them in.
|
||||
let meta = &fcx.fn_ty.args[idx];
|
||||
let meta = &mircx.fn_ty.args[idx];
|
||||
idx += 1;
|
||||
arg.store_fn_arg(bcx, &mut llarg_idx, base::get_dataptr(bcx, lltemp));
|
||||
meta.store_fn_arg(bcx, &mut llarg_idx, base::get_meta(bcx, lltemp));
|
||||
|
Loading…
Reference in New Issue
Block a user