trans: Move trans_foreign_mod and trans_impl to trans_item.

This commit is contained in:
Eduard Burtescu 2016-02-23 21:32:44 +02:00
parent 16201d45f1
commit e0970498c7
4 changed files with 42 additions and 164 deletions

View File

@ -2476,6 +2476,7 @@ fn set_global_section(ccx: &CrateContext, llval: ValueRef, i: &hir::Item) {
pub fn trans_item(ccx: &CrateContext, item: &hir::Item) {
let _icx = push_ctxt("trans_item");
let tcx = ccx.tcx();
let from_external = ccx.external_srcs().borrow().contains_key(&item.id);
match item.node {
@ -2532,20 +2533,39 @@ pub fn trans_item(ccx: &CrateContext, item: &hir::Item) {
}
}
hir::ItemImpl(_, _, ref generics, _, _, ref impl_items) => {
meth::trans_impl(ccx, item.name, impl_items, generics, item.id);
}
hir::ItemMod(_) => {
// modules have no equivalent at runtime, they just affect
// the mangled names of things contained within
// Both here and below with generic methods, be sure to recurse and look for
// items that we need to translate.
if !generics.ty_params.is_empty() {
return;
}
for impl_item in impl_items {
if let hir::ImplItemKind::Method(ref sig, ref body) = impl_item.node {
if sig.generics.ty_params.is_empty() {
let trans_everywhere = attr::requests_inline(&impl_item.attrs);
for (ref ccx, is_origin) in ccx.maybe_iter(trans_everywhere) {
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, llfn, empty_substs,
impl_item.id, &impl_item.attrs);
update_linkage(ccx, llfn, Some(impl_item.id),
if is_origin {
OriginalTranslation
} else {
InlinedCopy
});
}
}
}
}
}
hir::ItemEnum(ref enum_definition, ref gens) => {
if gens.ty_params.is_empty() {
// sizes only make sense for non-generic types
enum_variant_size_lint(ccx, enum_definition, item.span, item.id);
}
}
hir::ItemConst(..) => {}
hir::ItemStatic(_, m, ref expr) => {
let g = match consts::trans_static(ccx, m, expr, item.id, &item.attrs) {
Ok(g) => g,
@ -2554,13 +2574,16 @@ pub fn trans_item(ccx: &CrateContext, item: &hir::Item) {
set_global_section(ccx, g, item);
update_linkage(ccx, g, Some(item.id), OriginalTranslation);
}
hir::ItemForeignMod(ref foreign_mod) => {
foreign::trans_foreign_mod(ccx, foreign_mod);
}
hir::ItemTrait(..) => {}
_ => {
// fall through
hir::ItemForeignMod(ref m) => {
if m.abi == Abi::RustIntrinsic || m.abi == Abi::PlatformIntrinsic {
return;
}
for fi in &m.items {
let lname = foreign::link_name(fi.name, &fi.attrs).to_string();
ccx.item_symbols().borrow_mut().insert(fi.id, lname);
}
}
_ => {}
}
}

View File

@ -158,7 +158,7 @@ impl<'tcx> Callee<'tcx> {
// 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);
let mth = meth::get_impl_method(tcx, impl_did, substs, mname);
// Translate the function, bypassing Callee::def.
// That is because default methods have the same ID as the

View File

@ -463,31 +463,6 @@ pub fn trans_native_call<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
return bcx;
}
pub fn trans_foreign_mod(ccx: &CrateContext, foreign_mod: &hir::ForeignMod) {
let _icx = push_ctxt("foreign::trans_foreign_mod");
for foreign_item in &foreign_mod.items {
let lname = link_name(foreign_item);
if let hir::ForeignItemFn(ref decl, _) = foreign_item.node {
match foreign_mod.abi {
Abi::Rust | Abi::RustIntrinsic | Abi::PlatformIntrinsic => {}
abi => {
let ty = ccx.tcx().node_id_to_type(foreign_item.id);
register_foreign_item_fn(ccx, abi, ty, &lname, &foreign_item.attrs);
// Unlike for other items, we shouldn't call
// `base::update_linkage` here. Foreign items have
// special linkage requirements, which are handled
// inside `foreign::register_*`.
}
}
}
ccx.item_symbols().borrow_mut().insert(foreign_item.id,
lname.to_string());
}
}
///////////////////////////////////////////////////////////////////////////
// Rust functions with foreign ABIs
//
@ -890,12 +865,12 @@ pub fn trans_rust_fn_with_foreign_abi<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
// This code is kind of a confused mess and needs to be reworked given
// the massive simplifications that have occurred.
pub fn link_name(i: &hir::ForeignItem) -> InternedString {
match attr::first_attr_value_str_by_name(&i.attrs, "link_name") {
pub fn link_name(name: ast::Name, attrs: &[ast::Attribute]) -> InternedString {
match attr::first_attr_value_str_by_name(attrs, "link_name") {
Some(ln) => ln.clone(),
None => match weak_lang_items::link_name(&i.attrs) {
None => match weak_lang_items::link_name(attrs) {
Some(name) => name,
None => i.name.as_str(),
None => name.as_str(),
}
}
}

View File

@ -20,8 +20,7 @@ use middle::subst;
use middle::traits::{self, ProjectionMode};
use trans::base::*;
use trans::build::*;
use trans::callee::{Callee, Virtual, ArgVals,
trans_fn_pointer_shim, trans_fn_ref_with_substs};
use trans::callee::{Callee, Virtual, ArgVals, trans_fn_pointer_shim};
use trans::closure;
use trans::common::*;
use trans::consts;
@ -37,130 +36,11 @@ use trans::value::Value;
use middle::ty::{self, Ty, TyCtxt, TypeFoldable};
use syntax::ast::{self, Name};
use syntax::attr;
use syntax::codemap::DUMMY_SP;
use rustc_front::hir;
// drop_glue pointer, size, align.
const VTABLE_OFFSET: usize = 3;
/// The main "translation" pass for methods. Generates code
/// for non-monomorphized methods only. Other methods will
/// be generated once they are invoked with specific type parameters,
/// see `trans::base::lval_static_fn()` or `trans::base::monomorphic_fn()`.
pub fn trans_impl(ccx: &CrateContext,
name: ast::Name,
impl_items: &[hir::ImplItem],
generics: &hir::Generics,
id: ast::NodeId) {
let _icx = push_ctxt("meth::trans_impl");
let tcx = ccx.tcx();
debug!("trans_impl(name={}, id={})", name, id);
// Both here and below with generic methods, be sure to recurse and look for
// items that we need to translate.
if !generics.ty_params.is_empty() {
return;
}
for impl_item in impl_items {
match impl_item.node {
hir::ImplItemKind::Method(ref sig, ref body) => {
if sig.generics.ty_params.is_empty() {
let trans_everywhere = attr::requests_inline(&impl_item.attrs);
for (ref ccx, is_origin) in ccx.maybe_iter(trans_everywhere) {
let llfn = get_item_val(ccx, impl_item.id);
let empty_substs = tcx.mk_substs(Substs::trans_empty());
trans_fn(ccx,
&sig.decl,
body,
llfn,
empty_substs,
impl_item.id,
&impl_item.attrs);
update_linkage(ccx,
llfn,
Some(impl_item.id),
if is_origin { OriginalTranslation } else { InlinedCopy });
}
}
}
_ => {}
}
}
}
/// Compute the appropriate callee, give na method's ID, trait ID,
/// substitutions and a Vtable for that trait.
pub fn callee_for_trait_impl<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
method_id: DefId,
substs: &'tcx subst::Substs<'tcx>,
trait_id: DefId,
method_ty: Ty<'tcx>,
vtable: traits::Vtable<'tcx, ()>)
-> Callee<'tcx> {
let _icx = push_ctxt("meth::callee_for_trait_impl");
match vtable {
traits::VtableImpl(vtable_impl) => {
let impl_did = vtable_impl.impl_def_id;
let mname = ccx.tcx().item_name(method_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 = ccx.tcx().mk_substs(impl_substs);
let mth = get_impl_method(ccx.tcx(), 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(trans_fn_ref_with_substs(ccx, mth.method.def_id,
Some(method_ty), mth.substs))
}
traits::VtableClosure(vtable_closure) => {
// The substitutions should have no type parameters remaining
// after passing through fulfill_obligation
let trait_closure_kind = ccx.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 fn_ptr_ty = match method_ty.sty {
ty::TyFnDef(_, _, fty) => ccx.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 = ccx.tcx().lang_items.fn_trait_kind(trait_id).unwrap();
let llfn = trans_fn_pointer_shim(ccx, trait_closure_kind, fn_ty);
let fn_ptr_ty = match method_ty.sty {
ty::TyFnDef(_, _, fty) => ccx.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(
ccx.tcx(), data, method_id)),
ty: method_ty
}
}
traits::VtableBuiltin(..) |
traits::VtableDefaultImpl(..) |
traits::VtableParam(..) => {
ccx.sess().bug(
&format!("resolved vtable bad vtable {:?} in trans",
vtable));
}
}
}
/// Extracts a method from a trait object's vtable, at the
/// specified index, and casts it to the given type.
pub fn get_virtual_method<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,