trans: Get functions and do calls only through Callee.

This commit is contained in:
Eduard Burtescu 2016-02-23 21:21:50 +02:00
parent 062a05dde8
commit 16201d45f1
13 changed files with 198 additions and 227 deletions

View File

@ -200,12 +200,13 @@ use middle::lang_items::StrEqFnLangItem;
use middle::mem_categorization as mc;
use middle::mem_categorization::Categorization;
use middle::pat_util::*;
use middle::subst::Substs;
use trans::adt;
use trans::base::*;
use trans::build::{AddCase, And, Br, CondBr, GEPi, InBoundsGEP, Load, PointerCast};
use trans::build::{Not, Store, Sub, add_comment};
use trans::build;
use trans::callee;
use trans::callee::{Callee, ArgVals};
use trans::cleanup::{self, CleanupMethods, DropHintMethods};
use trans::common::*;
use trans::consts;
@ -881,7 +882,7 @@ fn compare_values<'blk, 'tcx>(cx: Block<'blk, 'tcx>,
rhs_t: Ty<'tcx>,
debug_loc: DebugLoc)
-> Result<'blk, 'tcx> {
fn compare_str<'blk, 'tcx>(cx: Block<'blk, 'tcx>,
fn compare_str<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
lhs_data: ValueRef,
lhs_len: ValueRef,
rhs_data: ValueRef,
@ -889,11 +890,13 @@ fn compare_values<'blk, 'tcx>(cx: Block<'blk, 'tcx>,
rhs_t: Ty<'tcx>,
debug_loc: DebugLoc)
-> Result<'blk, 'tcx> {
let did = langcall(cx,
let did = langcall(bcx,
None,
&format!("comparison of `{}`", rhs_t),
StrEqFnLangItem);
callee::trans_lang_call(cx, did, &[lhs_data, lhs_len, rhs_data, rhs_len], None, debug_loc)
let args = [lhs_data, lhs_len, rhs_data, rhs_len];
Callee::def(bcx.ccx(), did, bcx.tcx().mk_substs(Substs::empty()))
.call(bcx, debug_loc, ArgVals(&args), None)
}
let _icx = push_ctxt("compare_values");

View File

@ -57,7 +57,7 @@ use trans::assert_dep_graph;
use trans::attributes;
use trans::build::*;
use trans::builder::{Builder, noname};
use trans::callee;
use trans::callee::{Callee, CallArgs, ArgExprs, ArgVals};
use trans::cleanup::{self, CleanupMethods, DropHint};
use trans::closure;
use trans::common::{Block, C_bool, C_bytes_in_context, C_i32, C_int, C_uint, C_integral};
@ -280,11 +280,9 @@ pub fn malloc_raw_dyn<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
let _icx = push_ctxt("malloc_raw_exchange");
// Allocate space:
let r = callee::trans_lang_call(bcx,
require_alloc_fn(bcx, info_ty, ExchangeMallocFnLangItem),
&[size, align],
None,
debug_loc);
let def_id = require_alloc_fn(bcx, info_ty, ExchangeMallocFnLangItem);
let r = Callee::def(bcx.ccx(), def_id, bcx.tcx().mk_substs(Substs::empty()))
.call(bcx, debug_loc, ArgVals(&[size, align]), None);
Result::new(r.bcx, PointerCast(r.bcx, r.val, llty_ptr))
}
@ -1219,9 +1217,8 @@ pub fn trans_unwind_resume(bcx: Block, lpval: ValueRef) {
Resume(bcx, lpval);
} else {
let exc_ptr = ExtractValue(bcx, lpval, 0);
let llunwresume = bcx.fcx.eh_unwind_resume();
Call(bcx, llunwresume, &[exc_ptr], None, DebugLoc::None);
Unreachable(bcx);
bcx.fcx.eh_unwind_resume()
.call(bcx, DebugLoc::None, ArgVals(&[exc_ptr]), None);
}
}
@ -2147,20 +2144,10 @@ pub fn trans_fn<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
closure::ClosureEnv::NotClosure);
}
pub fn trans_enum_variant<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
ctor_id: ast::NodeId,
disr: Disr,
param_substs: &'tcx Substs<'tcx>,
llfndecl: ValueRef) {
let _icx = push_ctxt("trans_enum_variant");
trans_enum_variant_or_tuple_like_struct(ccx, ctor_id, disr, param_substs, llfndecl);
}
pub fn trans_named_tuple_constructor<'blk, 'tcx>(mut bcx: Block<'blk, 'tcx>,
ctor_ty: Ty<'tcx>,
disr: Disr,
args: callee::CallArgs,
args: CallArgs,
dest: expr::Dest,
debug_loc: DebugLoc)
-> Result<'blk, 'tcx> {
@ -2188,7 +2175,7 @@ pub fn trans_named_tuple_constructor<'blk, 'tcx>(mut bcx: Block<'blk, 'tcx>,
if !type_is_zero_size(ccx, result_ty) {
match args {
callee::ArgExprs(exprs) => {
ArgExprs(exprs) => {
let fields = exprs.iter().map(|x| &**x).enumerate().collect::<Vec<_>>();
bcx = expr::trans_adt(bcx,
result_ty,
@ -2204,7 +2191,7 @@ pub fn trans_named_tuple_constructor<'blk, 'tcx>(mut bcx: Block<'blk, 'tcx>,
// Just eval all the expressions (if any). Since expressions in Rust can have arbitrary
// contents, there could be side-effects we need from them.
match args {
callee::ArgExprs(exprs) => {
ArgExprs(exprs) => {
for expr in exprs {
bcx = expr::trans_into(bcx, expr, expr::Ignore);
}
@ -2500,8 +2487,9 @@ pub fn trans_item(ccx: &CrateContext, item: &hir::Item) {
// compilation unit that references the item, so it will still get
// translated everywhere it's needed.
for (ref ccx, is_origin) in ccx.maybe_iter(!from_external && trans_everywhere) {
let llfn = get_item_val(ccx, item.id);
let empty_substs = ccx.tcx().mk_substs(Substs::trans_empty());
let empty_substs = tcx.mk_substs(Substs::trans_empty());
let def_id = tcx.map.local_def_id(item.id);
let llfn = Callee::def(ccx, def_id, empty_substs).reify(ccx).val;
if abi != Abi::Rust {
foreign::trans_rust_fn_with_foreign_abi(ccx,
&decl,
@ -2536,9 +2524,8 @@ pub fn trans_item(ccx: &CrateContext, item: &hir::Item) {
// error in trans. This is used to write compile-fail tests
// that actually test that compilation succeeds without
// reporting an error.
let item_def_id = ccx.tcx().map.local_def_id(item.id);
if ccx.tcx().has_attr(item_def_id, "rustc_error") {
ccx.tcx().sess.span_fatal(item.span, "compilation successful");
if tcx.has_attr(def_id, "rustc_error") {
tcx.sess.span_fatal(item.span, "compilation successful");
}
}
}
@ -2671,17 +2658,10 @@ pub fn create_entry_wrapper(ccx: &CrateContext, sp: Span, main_llfn: ValueRef) {
let (start_fn, args) = if use_start_lang_item {
let start_def_id = match ccx.tcx().lang_items.require(StartFnLangItem) {
Ok(id) => id,
Err(s) => {
ccx.sess().fatal(&s[..]);
}
};
let start_fn = if let Some(start_node_id) = ccx.tcx()
.map
.as_local_node_id(start_def_id) {
get_item_val(ccx, start_node_id)
} else {
get_extern_fn(ccx, start_def_id).val
Err(s) => ccx.sess().fatal(&s)
};
let empty_substs = ccx.tcx().mk_substs(Substs::trans_empty());
let start_fn = Callee::def(ccx, start_def_id, empty_substs).reify(ccx).val;
let args = {
let opaque_rust_main =
llvm::LLVMBuildPointerCast(bld,

View File

@ -97,26 +97,19 @@ impl<'tcx> Callee<'tcx> {
pub fn method<'blk>(bcx: Block<'blk, 'tcx>,
method: ty::MethodCallee<'tcx>) -> Callee<'tcx> {
let substs = bcx.tcx().mk_substs(bcx.fcx.monomorphize(&method.substs));
let ty = bcx.fcx.monomorphize(&method.ty);
Callee::def(bcx.ccx(), method.def_id, substs, ty)
Callee::def(bcx.ccx(), method.def_id, substs)
}
/// Function or method definition.
pub fn def<'a>(ccx: &CrateContext<'a, 'tcx>,
def_id: DefId,
substs: &'tcx subst::Substs<'tcx>,
ty: Ty<'tcx>)
substs: &'tcx subst::Substs<'tcx>)
-> Callee<'tcx> {
let tcx = ccx.tcx();
if substs.self_ty().is_some() {
// Only trait methods can have a Self parameter.
let method_item = tcx.impl_or_trait_item(def_id);
let trait_id = method_item.container().id();
let trait_ref = ty::Binder(substs.to_trait_ref(tcx, trait_id));
let vtbl = common::fulfill_obligation(ccx, DUMMY_SP, trait_ref);
return meth::callee_for_trait_impl(ccx, def_id, substs,
trait_id, ty, vtbl);
return Callee::trait_method(ccx, def_id, substs);
}
let maybe_node_id = inline::get_local_instance(ccx, def_id)
@ -124,34 +117,95 @@ impl<'tcx> Callee<'tcx> {
let maybe_ast_node = maybe_node_id.and_then(|node_id| {
tcx.map.find(node_id)
});
match maybe_ast_node {
let data = match maybe_ast_node {
Some(hir_map::NodeStructCtor(_)) => {
return Callee {
data: NamedTupleConstructor(Disr(0)),
ty: ty
};
NamedTupleConstructor(Disr(0))
}
Some(hir_map::NodeVariant(_)) => {
let vinfo = common::inlined_variant_def(ccx, maybe_node_id.unwrap());
assert_eq!(vinfo.kind(), ty::VariantKind::Tuple);
return Callee {
data: NamedTupleConstructor(Disr::from(vinfo.disr_val)),
ty: ty
};
NamedTupleConstructor(Disr::from(vinfo.disr_val))
}
Some(hir_map::NodeForeignItem(fi)) => {
Some(hir_map::NodeForeignItem(fi)) if {
let abi = tcx.map.get_foreign_abi(fi.id);
if abi == Abi::RustIntrinsic || abi == Abi::PlatformIntrinsic {
return Callee {
data: Intrinsic(fi.id, substs),
ty: ty
};
abi == Abi::RustIntrinsic || abi == Abi::PlatformIntrinsic
} => Intrinsic,
_ => return Callee::ptr(get_fn(ccx, def_id, substs))
};
Callee {
data: data,
ty: def_ty(tcx, def_id, substs)
}
}
/// Trait method, which has to be resolved to an impl method.
pub fn trait_method<'a>(ccx: &CrateContext<'a, 'tcx>,
def_id: DefId,
substs: &'tcx subst::Substs<'tcx>)
-> Callee<'tcx> {
let tcx = ccx.tcx();
let method_item = tcx.impl_or_trait_item(def_id);
let trait_id = method_item.container().id();
let trait_ref = ty::Binder(substs.to_trait_ref(tcx, trait_id));
match common::fulfill_obligation(ccx, DUMMY_SP, trait_ref) {
traits::VtableImpl(vtable_impl) => {
let impl_did = vtable_impl.impl_def_id;
let mname = tcx.item_name(def_id);
// create a concatenated set of substitutions which includes
// those from the impl and those from the method:
let impl_substs = vtable_impl.substs.with_method_from(&substs);
let substs = tcx.mk_substs(impl_substs);
let mth = tcx.get_impl_method(impl_did, substs, mname);
// Translate the function, bypassing Callee::def.
// That is because default methods have the same ID as the
// trait method used to look up the impl method that ended
// up here, so calling Callee::def would infinitely recurse.
Callee::ptr(get_fn(ccx, mth.method.def_id, mth.substs))
}
traits::VtableClosure(vtable_closure) => {
// The substitutions should have no type parameters remaining
// after passing through fulfill_obligation
let trait_closure_kind = tcx.lang_items.fn_trait_kind(trait_id).unwrap();
let llfn = closure::trans_closure_method(ccx,
vtable_closure.closure_def_id,
vtable_closure.substs,
trait_closure_kind);
let method_ty = def_ty(tcx, def_id, substs);
let fn_ptr_ty = match method_ty.sty {
ty::TyFnDef(_, _, fty) => tcx.mk_ty(ty::TyFnPtr(fty)),
_ => unreachable!("expected fn item type, found {}",
method_ty)
};
Callee::ptr(immediate_rvalue(llfn, fn_ptr_ty))
}
traits::VtableFnPointer(fn_ty) => {
let trait_closure_kind = tcx.lang_items.fn_trait_kind(trait_id).unwrap();
let llfn = trans_fn_pointer_shim(ccx, trait_closure_kind, fn_ty);
let method_ty = def_ty(tcx, def_id, substs);
let fn_ptr_ty = match method_ty.sty {
ty::TyFnDef(_, _, fty) => tcx.mk_ty(ty::TyFnPtr(fty)),
_ => unreachable!("expected fn item type, found {}",
method_ty)
};
Callee::ptr(immediate_rvalue(llfn, fn_ptr_ty))
}
traits::VtableObject(ref data) => {
Callee {
data: Virtual(traits::get_vtable_index_of_object_method(
tcx, data, def_id)),
ty: def_ty(tcx, def_id, substs)
}
}
_ => {}
vtable => {
unreachable!("resolved vtable bad vtable {:?} in trans", vtable);
}
}
Callee::ptr(trans_fn_ref_with_substs(ccx, def_id, Some(ty), substs))
}
/// This behemoth of a function translates function calls. Unfortunately, in
@ -187,7 +241,7 @@ impl<'tcx> Callee<'tcx> {
Virtual(idx) => meth::trans_object_shim(ccx, self.ty, idx),
NamedTupleConstructor(_) => match self.ty.sty {
ty::TyFnDef(def_id, substs, _) => {
return trans_fn_ref_with_substs(ccx, def_id, Some(self.ty), substs);
return get_fn(ccx, def_id, substs);
}
_ => unreachable!("expected fn item type, found {}", self.ty)
},
@ -196,31 +250,13 @@ impl<'tcx> Callee<'tcx> {
}
}
/// Translates a reference (with id `ref_id`) to the fn/method with id `def_id` into a function
/// pointer. This may require monomorphization or inlining.
pub fn trans_fn_ref<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
def_id: DefId,
node: ExprOrMethodCall,
param_substs: &'tcx subst::Substs<'tcx>)
-> Datum<'tcx, Rvalue> {
let _icx = push_ctxt("trans_fn_ref");
let substs = common::node_id_substs(ccx, node, param_substs);
debug!("trans_fn_ref(def_id={:?}, node={:?}, substs={:?})",
def_id,
node,
substs);
let ref_ty = match node {
ExprId(0) => return trans_fn_ref_with_substs(ccx, def_id, None, substs),
ExprId(id) => ccx.tcx().node_id_to_type(id),
MethodCallKey(method_call) => {
ccx.tcx().tables.borrow().method_map[&method_call].ty
}
};
let ref_ty = monomorphize::apply_param_substs(ccx.tcx(),
param_substs,
&ref_ty);
trans_fn_ref_with_substs(ccx, def_id, Some(ref_ty), substs)
/// Given a DefId and some Substs, produces the monomorphic item type.
fn def_ty<'tcx>(tcx: &TyCtxt<'tcx>,
def_id: DefId,
substs: &'tcx subst::Substs<'tcx>)
-> Ty<'tcx> {
let ty = tcx.lookup_item_type(def_id).ty;
monomorphize::apply_param_substs(tcx, substs, &ty)
}
/// Translates an adapter that implements the `Fn` trait for a fn
@ -323,7 +359,7 @@ pub fn trans_fn_pointer_shim<'a, 'tcx>(
let llfnpointer = match bare_fn_ty.sty {
ty::TyFnDef(def_id, substs, _) => {
// Function definitions have to be turned into a pointer.
Callee::def(ccx, def_id, substs, bare_fn_ty).reify(ccx).val
Callee::def(ccx, def_id, substs).reify(ccx).val
}
// the first argument (`self`) will be ptr to the fn pointer
@ -360,25 +396,14 @@ pub fn trans_fn_pointer_shim<'a, 'tcx>(
///
/// - `ccx`: the crate context
/// - `def_id`: def id of the fn or method item being referenced
/// - `node`: node id of the reference to the fn/method, if applicable.
/// This parameter may be zero; but, if so, the resulting value may not
/// have the right type, so it must be cast before being used.
/// - `ref_ty`: monotype of the reference to the fn/method, if applicable.
/// This parameter may be None; but, if so, the resulting value may not
/// have the right type, so it must be cast before being used.
/// - `substs`: values for each of the fn/method's parameters
pub fn trans_fn_ref_with_substs<'a, 'tcx>(
ccx: &CrateContext<'a, 'tcx>,
def_id: DefId,
ref_ty: Option<Ty<'tcx>>,
substs: &'tcx subst::Substs<'tcx>)
-> Datum<'tcx, Rvalue>
{
let _icx = push_ctxt("trans_fn_ref_with_substs");
fn get_fn<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
def_id: DefId,
substs: &'tcx subst::Substs<'tcx>)
-> Datum<'tcx, Rvalue> {
let tcx = ccx.tcx();
debug!("trans_fn_ref_with_substs(def_id={:?}, ref_ty={:?}, substs={:?})",
def_id, ref_ty, substs);
debug!("get_fn(def_id={:?}, substs={:?})", def_id, substs);
assert!(!substs.types.needs_infer());
assert!(!substs.types.has_escaping_regions());
@ -408,7 +433,7 @@ pub fn trans_fn_ref_with_substs<'a, 'tcx>(
let must_monomorphise =
!substs.types.is_empty() || is_named_tuple_constructor(tcx, def_id);
debug!("trans_fn_ref_with_substs({:?}) must_monomorphise: {}",
debug!("get_fn({:?}) must_monomorphise: {}",
def_id, must_monomorphise);
// Create a monomorphic version of generic functions
@ -494,16 +519,6 @@ pub fn trans_fn_ref_with_substs<'a, 'tcx>(
// ______________________________________________________________________
// Translating calls
pub fn trans_lang_call<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
did: DefId,
args: &[ValueRef],
dest: Option<expr::Dest>,
debug_loc: DebugLoc)
-> Result<'blk, 'tcx> {
let datum = trans_fn_ref(bcx.ccx(), did, ExprId(0), bcx.fcx.param_substs);
Callee::ptr(datum).call(bcx, debug_loc, ArgVals(args), dest)
}
fn trans_call_inner<'a, 'blk, 'tcx>(mut bcx: Block<'blk, 'tcx>,
debug_loc: DebugLoc,
callee: Callee<'tcx>,

View File

@ -512,11 +512,12 @@ impl<'a, 'tcx> FunctionContext<'a, 'tcx> {
// `rust_eh_personality` function, but rather we wired it up to the
// CRT's custom personality function, which forces LLVM to consider
// landing pads as "landing pads for SEH".
let target = &self.ccx.sess().target.target;
match self.ccx.tcx().lang_items.eh_personality() {
Some(def_id) if !base::wants_msvc_seh(self.ccx.sess()) => {
callee::trans_fn_ref(self.ccx, def_id, ExprId(0),
self.param_substs).val
let ccx = self.ccx;
let tcx = ccx.tcx();
let target = &ccx.sess().target.target;
match tcx.lang_items.eh_personality() {
Some(def_id) if !base::wants_msvc_seh(ccx.sess()) => {
Callee::def(ccx, def_id, tcx.mk_substs(Substs::empty())).reify(ccx).val
}
_ => {
let mut personality = self.ccx.eh_personality().borrow_mut();

View File

@ -352,9 +352,7 @@ pub fn const_expr<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
Some(AdjustReifyFnPointer) => {
match ety.sty {
ty::TyFnDef(def_id, substs, _) => {
let datum = Callee::def(cx, def_id, substs, ety).reify(cx);
llconst = datum.val;
ety_adjusted = datum.ty;
llconst = Callee::def(cx, def_id, substs).reify(cx).val;
}
_ => {
unreachable!("{} cannot be reified to a fn ptr", ety)

View File

@ -11,10 +11,11 @@
use llvm::ValueRef;
use middle::def::Def;
use middle::lang_items::{PanicFnLangItem, PanicBoundsCheckFnLangItem};
use middle::subst::Substs;
use trans::base::*;
use trans::basic_block::BasicBlock;
use trans::build::*;
use trans::callee;
use trans::callee::{Callee, ArgVals};
use trans::cleanup::CleanupMethods;
use trans::cleanup;
use trans::common::*;
@ -405,13 +406,8 @@ pub fn trans_fail<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
let expr_file_line = consts::addr_of(ccx, expr_file_line_const, align, "panic_loc");
let args = vec!(expr_file_line);
let did = langcall(bcx, Some(call_info.span), "", PanicFnLangItem);
let bcx = callee::trans_lang_call(bcx,
did,
&args[..],
Some(expr::Ignore),
call_info.debug_loc()).bcx;
Unreachable(bcx);
return bcx;
Callee::def(ccx, did, ccx.tcx().mk_substs(Substs::empty()))
.call(bcx, call_info.debug_loc(), ArgVals(&args), None).bcx
}
pub fn trans_fail_bounds_check<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
@ -438,11 +434,6 @@ pub fn trans_fail_bounds_check<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
let file_line = consts::addr_of(ccx, file_line_const, align, "panic_bounds_check_loc");
let args = vec!(file_line, index, len);
let did = langcall(bcx, Some(call_info.span), "", PanicBoundsCheckFnLangItem);
let bcx = callee::trans_lang_call(bcx,
did,
&args[..],
Some(expr::Ignore),
call_info.debug_loc()).bcx;
Unreachable(bcx);
return bcx;
Callee::def(ccx, did, ccx.tcx().mk_substs(Substs::empty()))
.call(bcx, call_info.debug_loc(), ArgVals(&args), None).bcx
}

View File

@ -385,7 +385,7 @@ fn apply_adjustments<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
AdjustReifyFnPointer => {
match datum.ty.sty {
ty::TyFnDef(def_id, substs, _) => {
datum = Callee::def(bcx.ccx(), def_id, substs, datum.ty)
datum = Callee::def(bcx.ccx(), def_id, substs)
.reify(bcx.ccx()).to_expr_datum();
}
_ => {
@ -1143,7 +1143,7 @@ fn trans_rvalue_dps_unadjusted<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
let f = unpack_datum!(bcx, trans(bcx, f));
(match f.ty.sty {
ty::TyFnDef(def_id, substs, _) => {
Callee::def(bcx.ccx(), def_id, substs, f.ty)
Callee::def(bcx.ccx(), def_id, substs)
}
ty::TyFnPtr(_) => {
let f = unpack_datum!(bcx,

View File

@ -25,7 +25,7 @@ use trans::adt;
use trans::adt::GetDtorType; // for tcx.dtor_type()
use trans::base::*;
use trans::build::*;
use trans::callee;
use trans::callee::{Callee, ArgVals};
use trans::cleanup;
use trans::cleanup::CleanupMethods;
use trans::collector::{self, TransItem};
@ -44,19 +44,18 @@ use libc::c_uint;
use syntax::ast;
use syntax::codemap::DUMMY_SP;
pub fn trans_exchange_free_dyn<'blk, 'tcx>(cx: Block<'blk, 'tcx>,
pub fn trans_exchange_free_dyn<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
v: ValueRef,
size: ValueRef,
align: ValueRef,
debug_loc: DebugLoc)
-> Block<'blk, 'tcx> {
let _icx = push_ctxt("trans_exchange_free");
let ccx = cx.ccx();
callee::trans_lang_call(cx,
langcall(cx, None, "", ExchangeFreeFnLangItem),
&[PointerCast(cx, v, Type::i8p(ccx)), size, align],
Some(expr::Ignore),
debug_loc).bcx
let def_id = langcall(bcx, None, "", ExchangeFreeFnLangItem);
let args = [PointerCast(bcx, v, Type::i8p(bcx.ccx())), size, align];
Callee::def(bcx.ccx(), def_id, bcx.tcx().mk_substs(Substs::empty()))
.call(bcx, debug_loc, ArgVals(&args), None).bcx
}
pub fn trans_exchange_free<'blk, 'tcx>(cx: Block<'blk, 'tcx>,
@ -366,9 +365,8 @@ fn trans_struct_drop<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
_ => tcx.sess.bug(&format!("dtor for {:?} is not an impl???", t))
};
let dtor_did = def.destructor().unwrap();
bcx = callee::Callee::ptr(callee::trans_fn_ref_with_substs(
bcx.ccx(), dtor_did, None, vtbl.substs))
.call(bcx, DebugLoc::None, callee::ArgVals(args), Some(expr::Ignore)).bcx;
bcx = Callee::def(bcx.ccx(), dtor_did, vtbl.substs)
.call(bcx, DebugLoc::None, ArgVals(args), None).bcx;
bcx.fcx.pop_and_trans_custom_cleanup_scope(bcx, contents_scope)
}

View File

@ -12,7 +12,8 @@ use llvm::{AvailableExternallyLinkage, InternalLinkage, SetLinkage};
use middle::cstore::{CrateStore, FoundAst, InlinedItem};
use middle::def_id::DefId;
use middle::subst::Substs;
use trans::base::{push_ctxt, trans_item, get_item_val, trans_fn};
use trans::base::{push_ctxt, trans_item, trans_fn};
use trans::callee::Callee;
use trans::common::*;
use rustc::dep_graph::DepNode;
@ -21,14 +22,15 @@ use rustc_front::hir;
fn instantiate_inline(ccx: &CrateContext, fn_id: DefId) -> Option<DefId> {
debug!("instantiate_inline({:?})", fn_id);
let _icx = push_ctxt("instantiate_inline");
let _task = ccx.tcx().dep_graph.in_task(DepNode::TransInlinedItem(fn_id));
let tcx = ccx.tcx();
let _task = tcx.dep_graph.in_task(DepNode::TransInlinedItem(fn_id));
match ccx.external().borrow().get(&fn_id) {
Some(&Some(node_id)) => {
// Already inline
debug!("instantiate_inline({}): already inline as node id {}",
ccx.tcx().item_path_str(fn_id), node_id);
let node_def_id = ccx.tcx().map.local_def_id(node_id);
tcx.item_path_str(fn_id), node_id);
let node_def_id = tcx.map.local_def_id(node_id);
return Some(node_def_id);
}
Some(&None) => {
@ -39,7 +41,7 @@ fn instantiate_inline(ccx: &CrateContext, fn_id: DefId) -> Option<DefId> {
}
}
let inlined = ccx.tcx().sess.cstore.maybe_get_item_ast(ccx.tcx(), fn_id);
let inlined = tcx.sess.cstore.maybe_get_item_ast(tcx, fn_id);
let inline_id = match inlined {
FoundAst::NotFound => {
ccx.external().borrow_mut().insert(fn_id, None);
@ -52,38 +54,27 @@ fn instantiate_inline(ccx: &CrateContext, fn_id: DefId) -> Option<DefId> {
ccx.stats().n_inlines.set(ccx.stats().n_inlines.get() + 1);
trans_item(ccx, item);
let linkage = match item.node {
hir::ItemFn(_, _, _, _, ref generics, _) => {
if generics.is_type_parameterized() {
// Generics have no symbol, so they can't be given any
// linkage.
None
if let hir::ItemFn(_, _, _, _, ref generics, _) = item.node {
// Generics have no symbol, so they can't be given any linkage.
if !generics.is_type_parameterized() {
let linkage = if ccx.sess().opts.cg.codegen_units == 1 {
// We could use AvailableExternallyLinkage here,
// but InternalLinkage allows LLVM to optimize more
// aggressively (at the cost of sometimes
// duplicating code).
InternalLinkage
} else {
if ccx.sess().opts.cg.codegen_units == 1 {
// We could use AvailableExternallyLinkage here,
// but InternalLinkage allows LLVM to optimize more
// aggressively (at the cost of sometimes
// duplicating code).
Some(InternalLinkage)
} else {
// With multiple compilation units, duplicated code
// is more of a problem. Also, `codegen_units > 1`
// means the user is okay with losing some
// performance.
Some(AvailableExternallyLinkage)
}
}
// With multiple compilation units, duplicated code
// is more of a problem. Also, `codegen_units > 1`
// means the user is okay with losing some
// performance.
AvailableExternallyLinkage
};
let empty_substs = tcx.mk_substs(Substs::trans_empty());
let def_id = tcx.map.local_def_id(item.id);
let llfn = Callee::def(ccx, def_id, empty_substs).reify(ccx).val;
SetLinkage(llfn, linkage);
}
hir::ItemConst(..) => None,
_ => unreachable!(),
};
match linkage {
Some(linkage) => {
let g = get_item_val(ccx, item.id);
SetLinkage(g, linkage);
}
None => {}
}
item.id
@ -120,7 +111,6 @@ fn instantiate_inline(ccx: &CrateContext, fn_id: DefId) -> Option<DefId> {
_ => ccx.sess().bug("instantiate_inline: item has a \
non-enum, non-struct parent")
}
trans_item(ccx, &item);
my_id
}
FoundAst::Found(&InlinedItem::TraitItem(_, ref trait_item)) => {
@ -133,10 +123,10 @@ fn instantiate_inline(ccx: &CrateContext, fn_id: DefId) -> Option<DefId> {
// the logic to do that already exists in `middle`. In order to
// reuse that code, it needs to be able to look up the traits for
// inlined items.
let ty_trait_item = ccx.tcx().impl_or_trait_item(fn_id).clone();
let trait_item_def_id = ccx.tcx().map.local_def_id(trait_item.id);
ccx.tcx().impl_or_trait_items.borrow_mut()
.insert(trait_item_def_id, ty_trait_item);
let ty_trait_item = tcx.impl_or_trait_item(fn_id).clone();
let trait_item_def_id = tcx.map.local_def_id(trait_item.id);
tcx.impl_or_trait_items.borrow_mut()
.insert(trait_item_def_id, ty_trait_item);
// If this is a default method, we can't look up the
// impl type. But we aren't going to translate anyways, so
@ -151,11 +141,12 @@ fn instantiate_inline(ccx: &CrateContext, fn_id: DefId) -> Option<DefId> {
// Translate monomorphic impl methods immediately.
if let hir::ImplItemKind::Method(ref sig, ref body) = impl_item.node {
let impl_tpt = ccx.tcx().lookup_item_type(impl_did);
let impl_tpt = tcx.lookup_item_type(impl_did);
if impl_tpt.generics.types.is_empty() &&
sig.generics.ty_params.is_empty() {
let empty_substs = ccx.tcx().mk_substs(Substs::trans_empty());
let llfn = get_item_val(ccx, impl_item.id);
let empty_substs = tcx.mk_substs(Substs::trans_empty());
let def_id = tcx.map.local_def_id(impl_item.id);
let llfn = Callee::def(ccx, def_id, empty_substs).reify(ccx).val;
trans_fn(ccx,
&sig.decl,
body,
@ -176,7 +167,7 @@ fn instantiate_inline(ccx: &CrateContext, fn_id: DefId) -> Option<DefId> {
}
};
let inline_def_id = ccx.tcx().map.local_def_id(inline_id);
let inline_def_id = tcx.map.local_def_id(inline_id);
Some(inline_def_id)
}

View File

@ -213,7 +213,7 @@ pub fn trans_intrinsic_call<'a, 'blk, 'tcx>(mut bcx: Block<'blk, 'tcx>,
if out_type_size != 0 {
// FIXME #19925 Remove this hack after a release cycle.
let _ = unpack_datum!(bcx, expr::trans(bcx, &arg_exprs[0]));
let llfn = Callee::def(ccx, def_id, substs, in_type).reify(ccx).val;
let llfn = Callee::def(ccx, def_id, substs).reify(ccx).val;
let llfnty = val_ty(llfn);
let llresult = match dest {
expr::SaveIn(d) => d,
@ -1208,6 +1208,7 @@ fn trans_gnu_try<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
dloc: DebugLoc) -> Block<'blk, 'tcx> {
let llfn = get_rust_try_fn(bcx.fcx, &mut |bcx| {
let ccx = bcx.ccx();
let tcx = ccx.tcx();
let dloc = DebugLoc::None;
// Translates the shims described above:
@ -1228,10 +1229,11 @@ fn trans_gnu_try<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
// managed by the standard library.
attributes::emit_uwtable(bcx.fcx.llfn, true);
let catch_pers = match bcx.tcx().lang_items.eh_personality_catch() {
Some(did) => callee::trans_fn_ref(ccx, did, ExprId(0),
bcx.fcx.param_substs).val,
None => bcx.tcx().sess.bug("eh_personality_catch not defined"),
let catch_pers = match tcx.lang_items.eh_personality_catch() {
Some(did) => {
Callee::def(ccx, did, tcx.mk_substs(Substs::empty())).reify(ccx).val
}
None => ccx.sess().bug("eh_personality_catch not defined"),
};
let then = bcx.fcx.new_temp_block("then");
@ -1341,9 +1343,10 @@ fn generate_filter_fn<'a, 'tcx>(fcx: &FunctionContext<'a, 'tcx>,
let tcx = ccx.tcx();
let dloc = DebugLoc::None;
let rust_try_filter = match ccx.tcx().lang_items.msvc_try_filter() {
Some(did) => callee::trans_fn_ref(ccx, did, ExprId(0),
fcx.param_substs).val,
let rust_try_filter = match tcx.lang_items.msvc_try_filter() {
Some(did) => {
Callee::def(ccx, did, tcx.mk_substs(Substs::empty())).reify(ccx).val
}
None => ccx.sess().bug("msvc_try_filter not defined"),
};

View File

@ -310,17 +310,9 @@ pub fn get_vtable<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
let nullptr = C_null(Type::nil(ccx).ptr_to());
get_vtable_methods(ccx, id, substs)
.into_iter()
.map(|opt_mth| {
match opt_mth {
Some(mth) => {
trans_fn_ref_with_substs(ccx,
mth.method.def_id,
None,
&mth.substs).val
}
None => nullptr
}
})
.map(|opt_mth| opt_mth.map_or(nullptr, |mth| {
Callee::def(ccx, mth.method.def_id, &mth.substs).reify(ccx).val
}))
.collect::<Vec<_>>()
.into_iter()
}

View File

@ -163,7 +163,7 @@ impl<'bcx, 'tcx> MirContext<'bcx, 'tcx> {
let (callee, fty) = match callee.ty.sty {
ty::TyFnDef(def_id, substs, f) => {
(Callee::def(bcx.ccx(), def_id, substs, callee.ty), f)
(Callee::def(bcx.ccx(), def_id, substs), f)
}
ty::TyFnPtr(f) => {
(Callee {

View File

@ -201,7 +201,7 @@ impl<'bcx, 'tcx> MirContext<'bcx, 'tcx> {
match operand.ty.sty {
ty::TyFnDef(def_id, substs, _) => {
OperandValue::Immediate(
Callee::def(bcx.ccx(), def_id, substs, operand.ty)
Callee::def(bcx.ccx(), def_id, substs)
.reify(bcx.ccx()).val)
}
_ => {
@ -511,8 +511,7 @@ impl<'bcx, 'tcx> MirContext<'bcx, 'tcx> {
if use_fmod {
let f64t = Type::f64(bcx.ccx());
let fty = Type::func(&[f64t, f64t], &f64t);
let llfn = declare::declare_cfn(bcx.ccx(), "fmod", fty,
tcx.types.f64);
let llfn = declare::declare_cfn(bcx.ccx(), "fmod", fty);
if input_ty == tcx.types.f32 {
let lllhs = bcx.fpext(lhs, f64t);
let llrhs = bcx.fpext(rhs, f64t);