trans: Get functions and do calls only through Callee.
This commit is contained in:
parent
062a05dde8
commit
16201d45f1
@ -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");
|
||||
|
@ -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,
|
||||
|
@ -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>,
|
||||
|
@ -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();
|
||||
|
@ -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)
|
||||
|
@ -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
|
||||
}
|
||||
|
@ -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,
|
||||
|
@ -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)
|
||||
}
|
||||
|
@ -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)
|
||||
}
|
||||
|
||||
|
@ -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"),
|
||||
};
|
||||
|
||||
|
@ -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()
|
||||
}
|
||||
|
@ -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 {
|
||||
|
@ -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);
|
||||
|
Loading…
Reference in New Issue
Block a user