Remove AST from metadata except for consts and const fns.
This commit is contained in:
parent
119508cdb4
commit
25cf8001b1
19 changed files with 127 additions and 572 deletions
|
@ -315,8 +315,7 @@ impl<'ast> Map<'ast> {
|
||||||
RootInlinedParent(parent) => match *parent {
|
RootInlinedParent(parent) => match *parent {
|
||||||
InlinedItem::Item(def_id, _) |
|
InlinedItem::Item(def_id, _) |
|
||||||
InlinedItem::TraitItem(def_id, _) |
|
InlinedItem::TraitItem(def_id, _) |
|
||||||
InlinedItem::ImplItem(def_id, _) |
|
InlinedItem::ImplItem(def_id, _) =>
|
||||||
InlinedItem::Foreign(def_id, _) =>
|
|
||||||
return DepNode::MetaData(def_id)
|
return DepNode::MetaData(def_id)
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -940,8 +939,6 @@ pub fn map_decoded_item<'ast, F: FoldOps>(map: &Map<'ast>,
|
||||||
II::ImplItem(fld.fold_ops.new_def_id(d),
|
II::ImplItem(fld.fold_ops.new_def_id(d),
|
||||||
ii.map(|ii| fld.fold_impl_item(ii)))
|
ii.map(|ii| fld.fold_impl_item(ii)))
|
||||||
}
|
}
|
||||||
II::Foreign(d, i) => II::Foreign(fld.fold_ops.new_def_id(d),
|
|
||||||
i.map(|i| fld.fold_foreign_item(i)))
|
|
||||||
};
|
};
|
||||||
|
|
||||||
let ii = map.forest.inlined_items.alloc(ii);
|
let ii = map.forest.inlined_items.alloc(ii);
|
||||||
|
|
|
@ -96,8 +96,7 @@ pub enum DefLike {
|
||||||
pub enum InlinedItem {
|
pub enum InlinedItem {
|
||||||
Item(DefId /* def-id in source crate */, P<hir::Item>),
|
Item(DefId /* def-id in source crate */, P<hir::Item>),
|
||||||
TraitItem(DefId /* impl id */, P<hir::TraitItem>),
|
TraitItem(DefId /* impl id */, P<hir::TraitItem>),
|
||||||
ImplItem(DefId /* impl id */, P<hir::ImplItem>),
|
ImplItem(DefId /* impl id */, P<hir::ImplItem>)
|
||||||
Foreign(DefId /* extern item */, P<hir::ForeignItem>),
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// A borrowed version of `hir::InlinedItem`.
|
/// A borrowed version of `hir::InlinedItem`.
|
||||||
|
@ -105,8 +104,7 @@ pub enum InlinedItem {
|
||||||
pub enum InlinedItemRef<'a> {
|
pub enum InlinedItemRef<'a> {
|
||||||
Item(DefId, &'a hir::Item),
|
Item(DefId, &'a hir::Item),
|
||||||
TraitItem(DefId, &'a hir::TraitItem),
|
TraitItem(DefId, &'a hir::TraitItem),
|
||||||
ImplItem(DefId, &'a hir::ImplItem),
|
ImplItem(DefId, &'a hir::ImplItem)
|
||||||
Foreign(DefId, &'a hir::ForeignItem)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Item definitions in the currently-compiled crate would have the CrateNum
|
/// Item definitions in the currently-compiled crate would have the CrateNum
|
||||||
|
@ -286,7 +284,6 @@ impl InlinedItem {
|
||||||
{
|
{
|
||||||
match *self {
|
match *self {
|
||||||
InlinedItem::Item(_, ref i) => visitor.visit_item(&i),
|
InlinedItem::Item(_, ref i) => visitor.visit_item(&i),
|
||||||
InlinedItem::Foreign(_, ref i) => visitor.visit_foreign_item(&i),
|
|
||||||
InlinedItem::TraitItem(_, ref ti) => visitor.visit_trait_item(ti),
|
InlinedItem::TraitItem(_, ref ti) => visitor.visit_trait_item(ti),
|
||||||
InlinedItem::ImplItem(_, ref ii) => visitor.visit_impl_item(ii),
|
InlinedItem::ImplItem(_, ref ii) => visitor.visit_impl_item(ii),
|
||||||
}
|
}
|
||||||
|
|
|
@ -79,7 +79,6 @@ pub fn encode_inlined_item(ecx: &e::EncodeContext,
|
||||||
ii: InlinedItemRef) {
|
ii: InlinedItemRef) {
|
||||||
let id = match ii {
|
let id = match ii {
|
||||||
InlinedItemRef::Item(_, i) => i.id,
|
InlinedItemRef::Item(_, i) => i.id,
|
||||||
InlinedItemRef::Foreign(_, i) => i.id,
|
|
||||||
InlinedItemRef::TraitItem(_, ti) => ti.id,
|
InlinedItemRef::TraitItem(_, ti) => ti.id,
|
||||||
InlinedItemRef::ImplItem(_, ii) => ii.id,
|
InlinedItemRef::ImplItem(_, ii) => ii.id,
|
||||||
};
|
};
|
||||||
|
@ -147,7 +146,6 @@ pub fn decode_inlined_item<'a, 'tcx>(cdata: &cstore::CrateMetadata,
|
||||||
dcx);
|
dcx);
|
||||||
let name = match *ii {
|
let name = match *ii {
|
||||||
InlinedItem::Item(_, ref i) => i.name,
|
InlinedItem::Item(_, ref i) => i.name,
|
||||||
InlinedItem::Foreign(_, ref i) => i.name,
|
|
||||||
InlinedItem::TraitItem(_, ref ti) => ti.name,
|
InlinedItem::TraitItem(_, ref ti) => ti.name,
|
||||||
InlinedItem::ImplItem(_, ref ii) => ii.name
|
InlinedItem::ImplItem(_, ref ii) => ii.name
|
||||||
};
|
};
|
||||||
|
@ -357,9 +355,6 @@ fn simplify_ast(ii: InlinedItemRef) -> (InlinedItem, IdRange) {
|
||||||
InlinedItemRef::ImplItem(d, ii) => {
|
InlinedItemRef::ImplItem(d, ii) => {
|
||||||
InlinedItem::ImplItem(d, P(fold::noop_fold_impl_item(ii.clone(), &mut fld)))
|
InlinedItem::ImplItem(d, P(fold::noop_fold_impl_item(ii.clone(), &mut fld)))
|
||||||
}
|
}
|
||||||
InlinedItemRef::Foreign(d, i) => {
|
|
||||||
InlinedItem::Foreign(d, P(fold::noop_fold_foreign_item(i.clone(), &mut fld)))
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
(ii, fld.id_range)
|
(ii, fld.id_range)
|
||||||
|
@ -1208,8 +1203,7 @@ fn copy_item_types(dcx: &DecodeContext, ii: &InlinedItem, orig_did: DefId) {
|
||||||
let item_node_id = match ii {
|
let item_node_id = match ii {
|
||||||
&InlinedItem::Item(_, ref i) => i.id,
|
&InlinedItem::Item(_, ref i) => i.id,
|
||||||
&InlinedItem::TraitItem(_, ref ti) => ti.id,
|
&InlinedItem::TraitItem(_, ref ti) => ti.id,
|
||||||
&InlinedItem::ImplItem(_, ref ii) => ii.id,
|
&InlinedItem::ImplItem(_, ref ii) => ii.id
|
||||||
&InlinedItem::Foreign(_, ref fi) => fi.id
|
|
||||||
};
|
};
|
||||||
copy_item_type(dcx, item_node_id, orig_did);
|
copy_item_type(dcx, item_node_id, orig_did);
|
||||||
|
|
||||||
|
|
|
@ -562,11 +562,6 @@ impl<'tcx> CrateStore<'tcx> for cstore::CStore {
|
||||||
let inlined_root_node_id = find_inlined_item_root(item.id);
|
let inlined_root_node_id = find_inlined_item_root(item.id);
|
||||||
cache_inlined_item(def_id, item.id, inlined_root_node_id);
|
cache_inlined_item(def_id, item.id, inlined_root_node_id);
|
||||||
}
|
}
|
||||||
decoder::FoundAst::Found(&InlinedItem::Foreign(d, ref item)) => {
|
|
||||||
assert_eq!(d, def_id);
|
|
||||||
let inlined_root_node_id = find_inlined_item_root(item.id);
|
|
||||||
cache_inlined_item(def_id, item.id, inlined_root_node_id);
|
|
||||||
}
|
|
||||||
decoder::FoundAst::FoundParent(parent_did, item) => {
|
decoder::FoundAst::FoundParent(parent_did, item) => {
|
||||||
let inlined_root_node_id = find_inlined_item_root(item.id);
|
let inlined_root_node_id = find_inlined_item_root(item.id);
|
||||||
cache_inlined_item(parent_did, item.id, inlined_root_node_id);
|
cache_inlined_item(parent_did, item.id, inlined_root_node_id);
|
||||||
|
|
|
@ -40,7 +40,6 @@ use std::io::prelude::*;
|
||||||
use std::io::{Cursor, SeekFrom};
|
use std::io::{Cursor, SeekFrom};
|
||||||
use std::rc::Rc;
|
use std::rc::Rc;
|
||||||
use std::u32;
|
use std::u32;
|
||||||
use syntax::abi::Abi;
|
|
||||||
use syntax::ast::{self, NodeId, Name, CRATE_NODE_ID, CrateNum};
|
use syntax::ast::{self, NodeId, Name, CRATE_NODE_ID, CrateNum};
|
||||||
use syntax::attr::{self,AttrMetaMethods,AttributeMethods};
|
use syntax::attr::{self,AttrMetaMethods,AttributeMethods};
|
||||||
use errors::Handler;
|
use errors::Handler;
|
||||||
|
@ -626,11 +625,6 @@ impl<'a, 'tcx, 'encoder> ItemContentBuilder<'a, 'tcx, 'encoder> {
|
||||||
|
|
||||||
if body.is_some() {
|
if body.is_some() {
|
||||||
encode_item_sort(self.rbml_w, 'p');
|
encode_item_sort(self.rbml_w, 'p');
|
||||||
encode_inlined_item(ecx,
|
|
||||||
self.rbml_w,
|
|
||||||
InlinedItemRef::TraitItem(
|
|
||||||
trait_def_id,
|
|
||||||
trait_item));
|
|
||||||
self.encode_mir(trait_item.id);
|
self.encode_mir(trait_item.id);
|
||||||
} else {
|
} else {
|
||||||
encode_item_sort(self.rbml_w, 'r');
|
encode_item_sort(self.rbml_w, 'r');
|
||||||
|
@ -728,12 +722,14 @@ impl<'a, 'tcx, 'encoder> ItemContentBuilder<'a, 'tcx, 'encoder> {
|
||||||
let types = generics.parent_types as usize + generics.types.len();
|
let types = generics.parent_types as usize + generics.types.len();
|
||||||
let needs_inline = types > 0 || is_default_impl ||
|
let needs_inline = types > 0 || is_default_impl ||
|
||||||
attr::requests_inline(&impl_item.attrs);
|
attr::requests_inline(&impl_item.attrs);
|
||||||
if needs_inline || sig.constness == hir::Constness::Const {
|
if sig.constness == hir::Constness::Const {
|
||||||
encode_inlined_item(
|
encode_inlined_item(
|
||||||
ecx,
|
ecx,
|
||||||
self.rbml_w,
|
self.rbml_w,
|
||||||
InlinedItemRef::ImplItem(ecx.tcx.map.local_def_id(parent_id),
|
InlinedItemRef::ImplItem(ecx.tcx.map.local_def_id(parent_id),
|
||||||
impl_item));
|
impl_item));
|
||||||
|
}
|
||||||
|
if needs_inline || sig.constness == hir::Constness::Const {
|
||||||
self.encode_mir(impl_item.id);
|
self.encode_mir(impl_item.id);
|
||||||
}
|
}
|
||||||
encode_constness(self.rbml_w, sig.constness);
|
encode_constness(self.rbml_w, sig.constness);
|
||||||
|
@ -934,8 +930,10 @@ impl<'a, 'tcx, 'encoder> ItemContentBuilder<'a, 'tcx, 'encoder> {
|
||||||
encode_name(self.rbml_w, item.name);
|
encode_name(self.rbml_w, item.name);
|
||||||
encode_attributes(self.rbml_w, &item.attrs);
|
encode_attributes(self.rbml_w, &item.attrs);
|
||||||
let needs_inline = tps_len > 0 || attr::requests_inline(&item.attrs);
|
let needs_inline = tps_len > 0 || attr::requests_inline(&item.attrs);
|
||||||
if needs_inline || constness == hir::Constness::Const {
|
if constness == hir::Constness::Const {
|
||||||
encode_inlined_item(ecx, self.rbml_w, InlinedItemRef::Item(def_id, item));
|
encode_inlined_item(ecx, self.rbml_w, InlinedItemRef::Item(def_id, item));
|
||||||
|
}
|
||||||
|
if needs_inline || constness == hir::Constness::Const {
|
||||||
self.encode_mir(item.id);
|
self.encode_mir(item.id);
|
||||||
}
|
}
|
||||||
encode_constness(self.rbml_w, constness);
|
encode_constness(self.rbml_w, constness);
|
||||||
|
@ -982,8 +980,6 @@ impl<'a, 'tcx, 'encoder> ItemContentBuilder<'a, 'tcx, 'encoder> {
|
||||||
for v in &enum_definition.variants {
|
for v in &enum_definition.variants {
|
||||||
encode_variant_id(self.rbml_w, ecx.tcx.map.local_def_id(v.node.data.id()));
|
encode_variant_id(self.rbml_w, ecx.tcx.map.local_def_id(v.node.data.id()));
|
||||||
}
|
}
|
||||||
encode_inlined_item(ecx, self.rbml_w, InlinedItemRef::Item(def_id, item));
|
|
||||||
self.encode_mir(item.id);
|
|
||||||
|
|
||||||
// Encode inherent implementations for self enumeration.
|
// Encode inherent implementations for self enumeration.
|
||||||
encode_inherent_implementations(ecx, self.rbml_w, def_id);
|
encode_inherent_implementations(ecx, self.rbml_w, def_id);
|
||||||
|
@ -1019,9 +1015,6 @@ impl<'a, 'tcx, 'encoder> ItemContentBuilder<'a, 'tcx, 'encoder> {
|
||||||
needs to know*/
|
needs to know*/
|
||||||
self.encode_struct_fields(variant);
|
self.encode_struct_fields(variant);
|
||||||
|
|
||||||
encode_inlined_item(ecx, self.rbml_w, InlinedItemRef::Item(def_id, item));
|
|
||||||
self.encode_mir(item.id);
|
|
||||||
|
|
||||||
// Encode inherent implementations for self structure.
|
// Encode inherent implementations for self structure.
|
||||||
encode_inherent_implementations(ecx, self.rbml_w, def_id);
|
encode_inherent_implementations(ecx, self.rbml_w, def_id);
|
||||||
|
|
||||||
|
@ -1265,7 +1258,6 @@ impl<'a, 'tcx, 'encoder> ItemContentBuilder<'a, 'tcx, 'encoder> {
|
||||||
let ecx = self.ecx();
|
let ecx = self.ecx();
|
||||||
|
|
||||||
debug!("writing foreign item {}", ecx.tcx.node_path_str(nitem.id));
|
debug!("writing foreign item {}", ecx.tcx.node_path_str(nitem.id));
|
||||||
let abi = ecx.tcx.map.get_foreign_abi(nitem.id);
|
|
||||||
|
|
||||||
encode_def_id_and_key(ecx, self.rbml_w, def_id);
|
encode_def_id_and_key(ecx, self.rbml_w, def_id);
|
||||||
let parent_id = ecx.tcx.map.get_parent(nitem.id);
|
let parent_id = ecx.tcx.map.get_parent(nitem.id);
|
||||||
|
@ -1276,12 +1268,6 @@ impl<'a, 'tcx, 'encoder> ItemContentBuilder<'a, 'tcx, 'encoder> {
|
||||||
encode_family(self.rbml_w, FN_FAMILY);
|
encode_family(self.rbml_w, FN_FAMILY);
|
||||||
self.encode_bounds_and_type_for_item(nitem.id);
|
self.encode_bounds_and_type_for_item(nitem.id);
|
||||||
encode_name(self.rbml_w, nitem.name);
|
encode_name(self.rbml_w, nitem.name);
|
||||||
if abi == Abi::RustIntrinsic || abi == Abi::PlatformIntrinsic {
|
|
||||||
encode_inlined_item(ecx,
|
|
||||||
self.rbml_w,
|
|
||||||
InlinedItemRef::Foreign(def_id, nitem));
|
|
||||||
self.encode_mir(nitem.id);
|
|
||||||
}
|
|
||||||
encode_attributes(self.rbml_w, &nitem.attrs);
|
encode_attributes(self.rbml_w, &nitem.attrs);
|
||||||
let stab = ecx.tcx.lookup_stability(ecx.tcx.map.local_def_id(nitem.id));
|
let stab = ecx.tcx.lookup_stability(ecx.tcx.map.local_def_id(nitem.id));
|
||||||
let depr = ecx.tcx.lookup_deprecation(ecx.tcx.map.local_def_id(nitem.id));
|
let depr = ecx.tcx.lookup_deprecation(ecx.tcx.map.local_def_id(nitem.id));
|
||||||
|
|
|
@ -66,7 +66,6 @@ use consts;
|
||||||
use context::{SharedCrateContext, CrateContextList};
|
use context::{SharedCrateContext, CrateContextList};
|
||||||
use debuginfo::{self, DebugLoc};
|
use debuginfo::{self, DebugLoc};
|
||||||
use declare;
|
use declare;
|
||||||
use inline;
|
|
||||||
use machine;
|
use machine;
|
||||||
use machine::{llalign_of_min, llsize_of};
|
use machine::{llalign_of_min, llsize_of};
|
||||||
use meth;
|
use meth;
|
||||||
|
@ -949,14 +948,17 @@ impl<'blk, 'tcx> FunctionContext<'blk, 'tcx> {
|
||||||
false
|
false
|
||||||
};
|
};
|
||||||
|
|
||||||
let debug_context = if let (false, Some((instance, sig, abi))) = (no_debug, definition) {
|
let mir = def_id.and_then(|id| ccx.get_mir(id));
|
||||||
debuginfo::create_function_debug_context(ccx, instance, sig, abi, llfndecl)
|
|
||||||
|
let debug_context = if let (false, Some((instance, sig, abi)), &Some(ref mir)) =
|
||||||
|
(no_debug, definition, &mir) {
|
||||||
|
debuginfo::create_function_debug_context(ccx, instance, sig, abi, llfndecl, mir)
|
||||||
} else {
|
} else {
|
||||||
debuginfo::empty_function_debug_context(ccx)
|
debuginfo::empty_function_debug_context(ccx)
|
||||||
};
|
};
|
||||||
|
|
||||||
FunctionContext {
|
FunctionContext {
|
||||||
mir: def_id.and_then(|id| ccx.get_mir(id)),
|
mir: mir,
|
||||||
llfn: llfndecl,
|
llfn: llfndecl,
|
||||||
llretslotptr: Cell::new(None),
|
llretslotptr: Cell::new(None),
|
||||||
param_env: ccx.tcx().empty_parameter_environment(),
|
param_env: ccx.tcx().empty_parameter_environment(),
|
||||||
|
@ -1134,8 +1136,7 @@ pub fn trans_instance<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, instance: Instance
|
||||||
let sig = ccx.tcx().normalize_associated_type(&sig);
|
let sig = ccx.tcx().normalize_associated_type(&sig);
|
||||||
let abi = fn_ty.fn_abi();
|
let abi = fn_ty.fn_abi();
|
||||||
|
|
||||||
let local_instance = inline::maybe_inline_instance(ccx, instance);
|
let lldecl = match ccx.instances().borrow().get(&instance) {
|
||||||
let lldecl = match ccx.instances().borrow().get(&local_instance) {
|
|
||||||
Some(&val) => val,
|
Some(&val) => val,
|
||||||
None => bug!("Instance `{:?}` not already declared", instance)
|
None => bug!("Instance `{:?}` not already declared", instance)
|
||||||
};
|
};
|
||||||
|
@ -1144,12 +1145,15 @@ pub fn trans_instance<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, instance: Instance
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn trans_ctor_shim<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
|
pub fn trans_ctor_shim<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
|
||||||
ctor_id: ast::NodeId,
|
def_id: DefId,
|
||||||
|
substs: &'tcx Substs<'tcx>,
|
||||||
disr: Disr,
|
disr: Disr,
|
||||||
param_substs: &'tcx Substs<'tcx>,
|
|
||||||
llfndecl: ValueRef) {
|
llfndecl: ValueRef) {
|
||||||
let ctor_ty = ccx.tcx().node_id_to_type(ctor_id);
|
attributes::inline(llfndecl, attributes::InlineAttr::Hint);
|
||||||
let ctor_ty = monomorphize::apply_param_substs(ccx.tcx(), param_substs, &ctor_ty);
|
attributes::set_frame_pointer_elimination(ccx, llfndecl);
|
||||||
|
|
||||||
|
let ctor_ty = ccx.tcx().lookup_item_type(def_id).ty;
|
||||||
|
let ctor_ty = monomorphize::apply_param_substs(ccx.tcx(), substs, &ctor_ty);
|
||||||
|
|
||||||
let sig = ccx.tcx().erase_late_bound_regions(&ctor_ty.fn_sig());
|
let sig = ccx.tcx().erase_late_bound_regions(&ctor_ty.fn_sig());
|
||||||
let sig = ccx.tcx().normalize_associated_type(&sig);
|
let sig = ccx.tcx().normalize_associated_type(&sig);
|
||||||
|
@ -1742,10 +1746,7 @@ pub fn trans_crate<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||||
println!("n_null_glues: {}", stats.n_null_glues.get());
|
println!("n_null_glues: {}", stats.n_null_glues.get());
|
||||||
println!("n_real_glues: {}", stats.n_real_glues.get());
|
println!("n_real_glues: {}", stats.n_real_glues.get());
|
||||||
|
|
||||||
println!("n_fallback_instantiations: {}", stats.n_fallback_instantiations.get());
|
|
||||||
|
|
||||||
println!("n_fns: {}", stats.n_fns.get());
|
println!("n_fns: {}", stats.n_fns.get());
|
||||||
println!("n_monos: {}", stats.n_monos.get());
|
|
||||||
println!("n_inlines: {}", stats.n_inlines.get());
|
println!("n_inlines: {}", stats.n_inlines.get());
|
||||||
println!("n_closures: {}", stats.n_closures.get());
|
println!("n_closures: {}", stats.n_closures.get());
|
||||||
println!("fn stats:");
|
println!("fn stats:");
|
||||||
|
|
|
@ -18,12 +18,10 @@ pub use self::CalleeData::*;
|
||||||
|
|
||||||
use arena::TypedArena;
|
use arena::TypedArena;
|
||||||
use back::symbol_names;
|
use back::symbol_names;
|
||||||
use llvm::{ValueRef, get_params};
|
use llvm::{self, ValueRef, get_params};
|
||||||
use middle::cstore::LOCAL_CRATE;
|
|
||||||
use rustc::hir::def_id::DefId;
|
use rustc::hir::def_id::DefId;
|
||||||
use rustc::ty::subst::Substs;
|
use rustc::ty::subst::Substs;
|
||||||
use rustc::traits;
|
use rustc::traits;
|
||||||
use rustc::hir::map as hir_map;
|
|
||||||
use abi::{Abi, FnType};
|
use abi::{Abi, FnType};
|
||||||
use attributes;
|
use attributes;
|
||||||
use base;
|
use base;
|
||||||
|
@ -34,18 +32,15 @@ use common::{self, Block, Result, CrateContext, FunctionContext};
|
||||||
use consts;
|
use consts;
|
||||||
use debuginfo::DebugLoc;
|
use debuginfo::DebugLoc;
|
||||||
use declare;
|
use declare;
|
||||||
use inline;
|
|
||||||
use meth;
|
use meth;
|
||||||
use monomorphize::{self, Instance};
|
use monomorphize::{self, Instance};
|
||||||
use trans_item::TransItem;
|
use trans_item::TransItem;
|
||||||
use type_of;
|
use type_of;
|
||||||
use value::Value;
|
|
||||||
use Disr;
|
use Disr;
|
||||||
use rustc::ty::{self, Ty, TyCtxt, TypeFoldable};
|
use rustc::ty::{self, Ty, TyCtxt, TypeFoldable};
|
||||||
use rustc::hir;
|
use rustc::hir;
|
||||||
|
|
||||||
use syntax_pos::DUMMY_SP;
|
use syntax_pos::DUMMY_SP;
|
||||||
use errors;
|
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub enum CalleeData {
|
pub enum CalleeData {
|
||||||
|
@ -102,35 +97,28 @@ impl<'tcx> Callee<'tcx> {
|
||||||
return Callee::trait_method(ccx, trait_id, def_id, substs);
|
return Callee::trait_method(ccx, trait_id, def_id, substs);
|
||||||
}
|
}
|
||||||
|
|
||||||
let maybe_node_id = inline::get_local_instance(ccx, def_id)
|
let fn_ty = def_ty(tcx, def_id, substs);
|
||||||
.and_then(|def_id| tcx.map.as_local_node_id(def_id));
|
if let ty::TyFnDef(_, _, f) = fn_ty.sty {
|
||||||
let maybe_ast_node = maybe_node_id.and_then(|node_id| {
|
if f.abi == Abi::RustIntrinsic || f.abi == Abi::PlatformIntrinsic {
|
||||||
tcx.map.find(node_id)
|
return Callee {
|
||||||
});
|
data: Intrinsic,
|
||||||
|
ty: fn_ty
|
||||||
let data = match maybe_ast_node {
|
};
|
||||||
Some(hir_map::NodeStructCtor(_)) => {
|
|
||||||
NamedTupleConstructor(Disr(0))
|
|
||||||
}
|
}
|
||||||
Some(hir_map::NodeVariant(_)) => {
|
|
||||||
let vinfo = common::inlined_variant_def(ccx, maybe_node_id.unwrap());
|
|
||||||
NamedTupleConstructor(Disr::from(vinfo.disr_val))
|
|
||||||
}
|
|
||||||
Some(hir_map::NodeForeignItem(fi)) if {
|
|
||||||
let abi = tcx.map.get_foreign_abi(fi.id);
|
|
||||||
abi == Abi::RustIntrinsic || abi == Abi::PlatformIntrinsic
|
|
||||||
} => Intrinsic,
|
|
||||||
|
|
||||||
_ => {
|
|
||||||
let (llfn, ty) = get_fn(ccx, def_id, substs);
|
|
||||||
return Callee::ptr(llfn, ty);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
Callee {
|
|
||||||
data: data,
|
|
||||||
ty: def_ty(tcx, def_id, substs)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// FIXME(eddyb) Detect ADT constructors more efficiently.
|
||||||
|
if let Some(adt_def) = fn_ty.fn_ret().skip_binder().ty_adt_def() {
|
||||||
|
if let Some(v) = adt_def.variants.iter().find(|v| def_id == v.did) {
|
||||||
|
return Callee {
|
||||||
|
data: NamedTupleConstructor(Disr::from(v.disr_val)),
|
||||||
|
ty: fn_ty
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let (llfn, ty) = get_fn(ccx, def_id, substs);
|
||||||
|
Callee::ptr(llfn, ty)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Trait method, which has to be resolved to an impl method.
|
/// Trait method, which has to be resolved to an impl method.
|
||||||
|
@ -168,24 +156,14 @@ impl<'tcx> Callee<'tcx> {
|
||||||
trait_closure_kind);
|
trait_closure_kind);
|
||||||
|
|
||||||
let method_ty = def_ty(tcx, def_id, substs);
|
let method_ty = def_ty(tcx, def_id, substs);
|
||||||
let fn_ptr_ty = match method_ty.sty {
|
Callee::ptr(llfn, method_ty)
|
||||||
ty::TyFnDef(_, _, fty) => tcx.mk_fn_ptr(fty),
|
|
||||||
_ => bug!("expected fn item type, found {}",
|
|
||||||
method_ty)
|
|
||||||
};
|
|
||||||
Callee::ptr(llfn, fn_ptr_ty)
|
|
||||||
}
|
}
|
||||||
traits::VtableFnPointer(vtable_fn_pointer) => {
|
traits::VtableFnPointer(vtable_fn_pointer) => {
|
||||||
let trait_closure_kind = tcx.lang_items.fn_trait_kind(trait_id).unwrap();
|
let trait_closure_kind = tcx.lang_items.fn_trait_kind(trait_id).unwrap();
|
||||||
let llfn = trans_fn_pointer_shim(ccx, trait_closure_kind, vtable_fn_pointer.fn_ty);
|
let llfn = trans_fn_pointer_shim(ccx, trait_closure_kind, vtable_fn_pointer.fn_ty);
|
||||||
|
|
||||||
let method_ty = def_ty(tcx, def_id, substs);
|
let method_ty = def_ty(tcx, def_id, substs);
|
||||||
let fn_ptr_ty = match method_ty.sty {
|
Callee::ptr(llfn, method_ty)
|
||||||
ty::TyFnDef(_, _, fty) => tcx.mk_fn_ptr(fty),
|
|
||||||
_ => bug!("expected fn item type, found {}",
|
|
||||||
method_ty)
|
|
||||||
};
|
|
||||||
Callee::ptr(llfn, fn_ptr_ty)
|
|
||||||
}
|
}
|
||||||
traits::VtableObject(ref data) => {
|
traits::VtableObject(ref data) => {
|
||||||
Callee {
|
Callee {
|
||||||
|
@ -242,9 +220,21 @@ impl<'tcx> Callee<'tcx> {
|
||||||
Virtual(idx) => {
|
Virtual(idx) => {
|
||||||
meth::trans_object_shim(ccx, self.ty, idx)
|
meth::trans_object_shim(ccx, self.ty, idx)
|
||||||
}
|
}
|
||||||
NamedTupleConstructor(_) => match self.ty.sty {
|
NamedTupleConstructor(disr) => match self.ty.sty {
|
||||||
ty::TyFnDef(def_id, substs, _) => {
|
ty::TyFnDef(def_id, substs, _) => {
|
||||||
return get_fn(ccx, def_id, substs).0;
|
let instance = Instance::new(def_id, substs);
|
||||||
|
if let Some(&llfn) = ccx.instances().borrow().get(&instance) {
|
||||||
|
return llfn;
|
||||||
|
}
|
||||||
|
|
||||||
|
let sym = ccx.symbol_map().get_or_compute(ccx.shared(),
|
||||||
|
TransItem::Fn(instance));
|
||||||
|
assert!(!ccx.codegen_unit().contains_item(&TransItem::Fn(instance)));
|
||||||
|
let lldecl = declare::define_internal_fn(ccx, &sym, self.ty);
|
||||||
|
base::trans_ctor_shim(ccx, def_id, substs, disr, lldecl);
|
||||||
|
ccx.instances().borrow_mut().insert(instance, lldecl);
|
||||||
|
|
||||||
|
lldecl
|
||||||
}
|
}
|
||||||
_ => bug!("expected fn item type, found {}", self.ty)
|
_ => bug!("expected fn item type, found {}", self.ty)
|
||||||
},
|
},
|
||||||
|
@ -412,83 +402,20 @@ fn get_fn<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
|
||||||
|
|
||||||
assert!(!substs.types.needs_infer());
|
assert!(!substs.types.needs_infer());
|
||||||
assert!(!substs.types.has_escaping_regions());
|
assert!(!substs.types.has_escaping_regions());
|
||||||
|
assert!(!substs.types.has_param_types());
|
||||||
|
|
||||||
// Check whether this fn has an inlined copy and, if so, redirect
|
let substs = tcx.normalize_associated_type(&substs);
|
||||||
// def_id to the local id of the inlined copy.
|
let instance = Instance::new(def_id, substs);
|
||||||
let def_id = inline::maybe_instantiate_inline(ccx, def_id);
|
let item_ty = ccx.tcx().lookup_item_type(def_id).ty;
|
||||||
|
let fn_ty = monomorphize::apply_param_substs(ccx.tcx(), substs, &item_ty);
|
||||||
|
|
||||||
fn is_named_tuple_constructor(tcx: TyCtxt, def_id: DefId) -> bool {
|
|
||||||
let node_id = match tcx.map.as_local_node_id(def_id) {
|
|
||||||
Some(n) => n,
|
|
||||||
None => { return false; }
|
|
||||||
};
|
|
||||||
let map_node = errors::expect(
|
|
||||||
&tcx.sess.diagnostic(),
|
|
||||||
tcx.map.find(node_id),
|
|
||||||
|| "local item should be in ast map".to_string());
|
|
||||||
|
|
||||||
match map_node {
|
|
||||||
hir_map::NodeVariant(v) => {
|
|
||||||
v.node.data.is_tuple()
|
|
||||||
}
|
|
||||||
hir_map::NodeStructCtor(_) => true,
|
|
||||||
_ => false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
let must_monomorphise =
|
|
||||||
!substs.types.is_empty() || is_named_tuple_constructor(tcx, def_id);
|
|
||||||
|
|
||||||
debug!("get_fn({:?}) must_monomorphise: {}",
|
|
||||||
def_id, must_monomorphise);
|
|
||||||
|
|
||||||
// Create a monomorphic version of generic functions
|
|
||||||
if must_monomorphise {
|
|
||||||
// Should be either intra-crate or inlined.
|
|
||||||
assert_eq!(def_id.krate, LOCAL_CRATE);
|
|
||||||
|
|
||||||
let substs = tcx.normalize_associated_type(&substs);
|
|
||||||
let (val, fn_ty) = monomorphize::monomorphic_fn(ccx, def_id, substs);
|
|
||||||
let fn_ptr_ty = match fn_ty.sty {
|
|
||||||
ty::TyFnDef(_, _, fty) => {
|
|
||||||
// Create a fn pointer with the substituted signature.
|
|
||||||
tcx.mk_fn_ptr(fty)
|
|
||||||
}
|
|
||||||
_ => bug!("expected fn item type, found {}", fn_ty)
|
|
||||||
};
|
|
||||||
assert_eq!(type_of::type_of(ccx, fn_ptr_ty), common::val_ty(val));
|
|
||||||
return (val, fn_ptr_ty);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Find the actual function pointer.
|
|
||||||
let ty = ccx.tcx().lookup_item_type(def_id).ty;
|
|
||||||
let fn_ptr_ty = match ty.sty {
|
|
||||||
ty::TyFnDef(_, _, ref fty) => {
|
|
||||||
// Create a fn pointer with the normalized signature.
|
|
||||||
tcx.mk_fn_ptr(tcx.normalize_associated_type(fty))
|
|
||||||
}
|
|
||||||
_ => bug!("expected fn item type, found {}", ty)
|
|
||||||
};
|
|
||||||
|
|
||||||
let instance = Instance::mono(ccx.shared(), def_id);
|
|
||||||
if let Some(&llfn) = ccx.instances().borrow().get(&instance) {
|
if let Some(&llfn) = ccx.instances().borrow().get(&instance) {
|
||||||
return (llfn, fn_ptr_ty);
|
return (llfn, fn_ty);
|
||||||
}
|
}
|
||||||
|
|
||||||
let local_id = ccx.tcx().map.as_local_node_id(def_id);
|
let sym = ccx.symbol_map().get_or_compute(ccx.shared(),
|
||||||
let local_item = match local_id.and_then(|id| tcx.map.find(id)) {
|
TransItem::Fn(instance));
|
||||||
Some(hir_map::NodeItem(&hir::Item {
|
debug!("get_fn({:?}: {:?}) => {}", instance, fn_ty, sym);
|
||||||
span, node: hir::ItemFn(..), ..
|
|
||||||
})) |
|
|
||||||
Some(hir_map::NodeTraitItem(&hir::TraitItem {
|
|
||||||
span, node: hir::MethodTraitItem(_, Some(_)), ..
|
|
||||||
})) |
|
|
||||||
Some(hir_map::NodeImplItem(&hir::ImplItem {
|
|
||||||
span, node: hir::ImplItemKind::Method(..), ..
|
|
||||||
})) => {
|
|
||||||
Some(span)
|
|
||||||
}
|
|
||||||
_ => None
|
|
||||||
};
|
|
||||||
|
|
||||||
// This is subtle and surprising, but sometimes we have to bitcast
|
// This is subtle and surprising, but sometimes we have to bitcast
|
||||||
// the resulting fn pointer. The reason has to do with external
|
// the resulting fn pointer. The reason has to do with external
|
||||||
|
@ -514,23 +441,17 @@ fn get_fn<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
|
||||||
// reference. It also occurs when testing libcore and in some
|
// reference. It also occurs when testing libcore and in some
|
||||||
// other weird situations. Annoying.
|
// other weird situations. Annoying.
|
||||||
|
|
||||||
let sym = ccx.symbol_map().get_or_compute(ccx.shared(),
|
let fn_ptr_ty = match fn_ty.sty {
|
||||||
TransItem::Fn(instance));
|
ty::TyFnDef(_, _, fty) => {
|
||||||
|
// Create a fn pointer with the substituted signature.
|
||||||
let llptrty = type_of::type_of(ccx, fn_ptr_ty);
|
tcx.mk_fn_ptr(fty)
|
||||||
let llfn = if let Some(llfn) = declare::get_declared_value(ccx, &sym) {
|
|
||||||
if let Some(span) = local_item {
|
|
||||||
if declare::get_defined_value(ccx, &sym).is_some() {
|
|
||||||
ccx.sess().span_fatal(span,
|
|
||||||
&format!("symbol `{}` is already defined", &sym));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
_ => bug!("expected fn item type, found {}", fn_ty)
|
||||||
|
};
|
||||||
|
let llptrty = type_of::type_of(ccx, fn_ptr_ty);
|
||||||
|
|
||||||
|
let llfn = if let Some(llfn) = declare::get_declared_value(ccx, &sym) {
|
||||||
if common::val_ty(llfn) != llptrty {
|
if common::val_ty(llfn) != llptrty {
|
||||||
if local_item.is_some() {
|
|
||||||
bug!("symbol `{}` previously declared as {:?}, now wanted as {:?}",
|
|
||||||
sym, Value(llfn), llptrty);
|
|
||||||
}
|
|
||||||
debug!("get_fn: casting {:?} to {:?}", llfn, llptrty);
|
debug!("get_fn: casting {:?} to {:?}", llfn, llptrty);
|
||||||
consts::ptrcast(llfn, llptrty)
|
consts::ptrcast(llfn, llptrty)
|
||||||
} else {
|
} else {
|
||||||
|
@ -538,15 +459,21 @@ fn get_fn<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
|
||||||
llfn
|
llfn
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
let llfn = declare::declare_fn(ccx, &sym, ty);
|
let llfn = declare::declare_fn(ccx, &sym, fn_ty);
|
||||||
assert_eq!(common::val_ty(llfn), llptrty);
|
assert_eq!(common::val_ty(llfn), llptrty);
|
||||||
debug!("get_fn: not casting pointer!");
|
debug!("get_fn: not casting pointer!");
|
||||||
|
|
||||||
let attrs = ccx.tcx().get_attrs(def_id);
|
let attrs = ccx.tcx().get_attrs(def_id);
|
||||||
attributes::from_fn_attrs(ccx, &attrs, llfn);
|
attributes::from_fn_attrs(ccx, &attrs, llfn);
|
||||||
if local_item.is_some() {
|
|
||||||
|
let is_local_def = ccx.shared().translation_items().borrow()
|
||||||
|
.contains(&TransItem::Fn(instance));
|
||||||
|
if is_local_def {
|
||||||
// FIXME(eddyb) Doubt all extern fn should allow unwinding.
|
// FIXME(eddyb) Doubt all extern fn should allow unwinding.
|
||||||
attributes::unwind(llfn, true);
|
attributes::unwind(llfn, true);
|
||||||
|
unsafe {
|
||||||
|
llvm::LLVMSetLinkage(llfn, llvm::ExternalLinkage);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
llfn
|
llfn
|
||||||
|
@ -554,7 +481,7 @@ fn get_fn<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
|
||||||
|
|
||||||
ccx.instances().borrow_mut().insert(instance, llfn);
|
ccx.instances().borrow_mut().insert(instance, llfn);
|
||||||
|
|
||||||
(llfn, fn_ptr_ty)
|
(llfn, fn_ty)
|
||||||
}
|
}
|
||||||
|
|
||||||
// ______________________________________________________________________
|
// ______________________________________________________________________
|
||||||
|
|
|
@ -199,12 +199,6 @@ pub fn gensym_name(name: &str) -> ast::Name {
|
||||||
|
|
||||||
use Disr;
|
use Disr;
|
||||||
|
|
||||||
#[derive(Copy, Clone)]
|
|
||||||
pub struct NodeIdAndSpan {
|
|
||||||
pub id: ast::NodeId,
|
|
||||||
pub span: Span,
|
|
||||||
}
|
|
||||||
|
|
||||||
/// The concrete version of ty::FieldDef. The name is the field index if
|
/// The concrete version of ty::FieldDef. The name is the field index if
|
||||||
/// the field is numeric.
|
/// the field is numeric.
|
||||||
pub struct Field<'tcx>(pub ast::Name, pub Ty<'tcx>);
|
pub struct Field<'tcx>(pub ast::Name, pub Ty<'tcx>);
|
||||||
|
@ -1066,34 +1060,6 @@ pub fn langcall(tcx: TyCtxt,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Return the VariantDef corresponding to an inlined variant node
|
|
||||||
pub fn inlined_variant_def<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
|
|
||||||
inlined_vid: ast::NodeId)
|
|
||||||
-> ty::VariantDef<'tcx>
|
|
||||||
{
|
|
||||||
let ctor_ty = ccx.tcx().node_id_to_type(inlined_vid);
|
|
||||||
debug!("inlined_variant_def: ctor_ty={:?} inlined_vid={:?}", ctor_ty,
|
|
||||||
inlined_vid);
|
|
||||||
let adt_def = match ctor_ty.sty {
|
|
||||||
ty::TyFnDef(_, _, &ty::BareFnTy { sig: ty::Binder(ty::FnSig {
|
|
||||||
output, ..
|
|
||||||
}), ..}) => output,
|
|
||||||
_ => ctor_ty
|
|
||||||
}.ty_adt_def().unwrap();
|
|
||||||
let variant_def_id = if ccx.tcx().map.is_inlined_node_id(inlined_vid) {
|
|
||||||
ccx.defid_for_inlined_node(inlined_vid).unwrap()
|
|
||||||
} else {
|
|
||||||
ccx.tcx().map.local_def_id(inlined_vid)
|
|
||||||
};
|
|
||||||
|
|
||||||
adt_def.variants
|
|
||||||
.iter()
|
|
||||||
.find(|v| variant_def_id == v.did)
|
|
||||||
.unwrap_or_else(|| {
|
|
||||||
bug!("no variant for {:?}::{}", adt_def, inlined_vid)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
// To avoid UB from LLVM, these two functions mask RHS with an
|
// To avoid UB from LLVM, these two functions mask RHS with an
|
||||||
// appropriate mask unconditionally (i.e. the fallback behavior for
|
// appropriate mask unconditionally (i.e. the fallback behavior for
|
||||||
// all shifts). For 32- and 64-bit types, this matches the semantics
|
// all shifts). For 32- and 64-bit types, this matches the semantics
|
||||||
|
|
|
@ -105,14 +105,10 @@ pub fn get_static(ccx: &CrateContext, def_id: DefId) -> ValueRef {
|
||||||
let defined_in_current_codegen_unit = ccx.codegen_unit()
|
let defined_in_current_codegen_unit = ccx.codegen_unit()
|
||||||
.items()
|
.items()
|
||||||
.contains_key(&TransItem::Static(id));
|
.contains_key(&TransItem::Static(id));
|
||||||
if defined_in_current_codegen_unit {
|
assert!(!defined_in_current_codegen_unit);
|
||||||
if declare::get_declared_value(ccx, sym).is_none() {
|
|
||||||
span_bug!(span, "trans: Static not properly pre-defined?");
|
if declare::get_declared_value(ccx, sym).is_some() {
|
||||||
}
|
span_bug!(span, "trans: Conflicting symbol names for static?");
|
||||||
} else {
|
|
||||||
if declare::get_declared_value(ccx, sym).is_some() {
|
|
||||||
span_bug!(span, "trans: Conflicting symbol names for static?");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
let g = declare::define_global(ccx, sym, llty).unwrap();
|
let g = declare::define_global(ccx, sym, llty).unwrap();
|
||||||
|
|
|
@ -53,9 +53,7 @@ pub struct Stats {
|
||||||
pub n_glues_created: Cell<usize>,
|
pub n_glues_created: Cell<usize>,
|
||||||
pub n_null_glues: Cell<usize>,
|
pub n_null_glues: Cell<usize>,
|
||||||
pub n_real_glues: Cell<usize>,
|
pub n_real_glues: Cell<usize>,
|
||||||
pub n_fallback_instantiations: Cell<usize>,
|
|
||||||
pub n_fns: Cell<usize>,
|
pub n_fns: Cell<usize>,
|
||||||
pub n_monos: Cell<usize>,
|
|
||||||
pub n_inlines: Cell<usize>,
|
pub n_inlines: Cell<usize>,
|
||||||
pub n_closures: Cell<usize>,
|
pub n_closures: Cell<usize>,
|
||||||
pub n_llvm_insns: Cell<usize>,
|
pub n_llvm_insns: Cell<usize>,
|
||||||
|
@ -103,7 +101,6 @@ pub struct LocalCrateContext<'tcx> {
|
||||||
drop_glues: RefCell<FnvHashMap<DropGlueKind<'tcx>, (ValueRef, FnType)>>,
|
drop_glues: RefCell<FnvHashMap<DropGlueKind<'tcx>, (ValueRef, FnType)>>,
|
||||||
/// Cache instances of monomorphic and polymorphic items
|
/// Cache instances of monomorphic and polymorphic items
|
||||||
instances: RefCell<FnvHashMap<Instance<'tcx>, ValueRef>>,
|
instances: RefCell<FnvHashMap<Instance<'tcx>, ValueRef>>,
|
||||||
monomorphizing: RefCell<DefIdMap<usize>>,
|
|
||||||
/// Cache generated vtables
|
/// Cache generated vtables
|
||||||
vtables: RefCell<FnvHashMap<ty::PolyTraitRef<'tcx>, ValueRef>>,
|
vtables: RefCell<FnvHashMap<ty::PolyTraitRef<'tcx>, ValueRef>>,
|
||||||
/// Cache of constant strings,
|
/// Cache of constant strings,
|
||||||
|
@ -488,9 +485,7 @@ impl<'b, 'tcx> SharedCrateContext<'b, 'tcx> {
|
||||||
n_glues_created: Cell::new(0),
|
n_glues_created: Cell::new(0),
|
||||||
n_null_glues: Cell::new(0),
|
n_null_glues: Cell::new(0),
|
||||||
n_real_glues: Cell::new(0),
|
n_real_glues: Cell::new(0),
|
||||||
n_fallback_instantiations: Cell::new(0),
|
|
||||||
n_fns: Cell::new(0),
|
n_fns: Cell::new(0),
|
||||||
n_monos: Cell::new(0),
|
|
||||||
n_inlines: Cell::new(0),
|
n_inlines: Cell::new(0),
|
||||||
n_closures: Cell::new(0),
|
n_closures: Cell::new(0),
|
||||||
n_llvm_insns: Cell::new(0),
|
n_llvm_insns: Cell::new(0),
|
||||||
|
@ -626,7 +621,6 @@ impl<'tcx> LocalCrateContext<'tcx> {
|
||||||
fn_pointer_shims: RefCell::new(FnvHashMap()),
|
fn_pointer_shims: RefCell::new(FnvHashMap()),
|
||||||
drop_glues: RefCell::new(FnvHashMap()),
|
drop_glues: RefCell::new(FnvHashMap()),
|
||||||
instances: RefCell::new(FnvHashMap()),
|
instances: RefCell::new(FnvHashMap()),
|
||||||
monomorphizing: RefCell::new(DefIdMap()),
|
|
||||||
vtables: RefCell::new(FnvHashMap()),
|
vtables: RefCell::new(FnvHashMap()),
|
||||||
const_cstr_cache: RefCell::new(FnvHashMap()),
|
const_cstr_cache: RefCell::new(FnvHashMap()),
|
||||||
const_unsized: RefCell::new(FnvHashMap()),
|
const_unsized: RefCell::new(FnvHashMap()),
|
||||||
|
@ -830,10 +824,6 @@ impl<'b, 'tcx> CrateContext<'b, 'tcx> {
|
||||||
&self.local().instances
|
&self.local().instances
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn monomorphizing<'a>(&'a self) -> &'a RefCell<DefIdMap<usize>> {
|
|
||||||
&self.local().monomorphizing
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn vtables<'a>(&'a self) -> &'a RefCell<FnvHashMap<ty::PolyTraitRef<'tcx>, ValueRef>> {
|
pub fn vtables<'a>(&'a self) -> &'a RefCell<FnvHashMap<ty::PolyTraitRef<'tcx>, ValueRef>> {
|
||||||
&self.local().vtables
|
&self.local().vtables
|
||||||
}
|
}
|
||||||
|
|
|
@ -28,7 +28,7 @@ use rustc::hir::def_id::DefId;
|
||||||
use rustc::ty::subst::Substs;
|
use rustc::ty::subst::Substs;
|
||||||
use rustc::hir;
|
use rustc::hir;
|
||||||
use {type_of, adt, machine, monomorphize};
|
use {type_of, adt, machine, monomorphize};
|
||||||
use common::{CrateContext, FunctionContext};
|
use common::CrateContext;
|
||||||
use type_::Type;
|
use type_::Type;
|
||||||
use rustc::ty::{self, Ty};
|
use rustc::ty::{self, Ty};
|
||||||
use session::config;
|
use session::config;
|
||||||
|
@ -882,26 +882,6 @@ fn file_metadata_(cx: &CrateContext, key: &str, file_name: &str, work_dir: &str)
|
||||||
file_metadata
|
file_metadata
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Finds the scope metadata node for the given AST node.
|
|
||||||
pub fn scope_metadata(fcx: &FunctionContext,
|
|
||||||
node_id: ast::NodeId,
|
|
||||||
error_reporting_span: Span)
|
|
||||||
-> DIScope {
|
|
||||||
let scope_map = &fcx.debug_context
|
|
||||||
.get_ref(error_reporting_span)
|
|
||||||
.scope_map;
|
|
||||||
match scope_map.borrow().get(&node_id).cloned() {
|
|
||||||
Some(scope_metadata) => scope_metadata,
|
|
||||||
None => {
|
|
||||||
let node = fcx.ccx.tcx().map.get(node_id);
|
|
||||||
|
|
||||||
span_bug!(error_reporting_span,
|
|
||||||
"debuginfo: Could not find scope info for node {:?}",
|
|
||||||
node);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn basic_type_metadata<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
|
fn basic_type_metadata<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
|
||||||
t: Ty<'tcx>) -> DIType {
|
t: Ty<'tcx>) -> DIType {
|
||||||
|
|
||||||
|
|
|
@ -27,15 +27,14 @@ use llvm::debuginfo::{DIFile, DIType, DIScope, DIBuilderRef, DISubprogram, DIArr
|
||||||
use rustc::hir::def_id::DefId;
|
use rustc::hir::def_id::DefId;
|
||||||
use rustc::hir::map::DefPathData;
|
use rustc::hir::map::DefPathData;
|
||||||
use rustc::ty::subst::Substs;
|
use rustc::ty::subst::Substs;
|
||||||
use rustc::hir;
|
|
||||||
|
|
||||||
use abi::Abi;
|
use abi::Abi;
|
||||||
use common::{NodeIdAndSpan, CrateContext, FunctionContext, Block, BlockAndBuilder};
|
use common::{CrateContext, FunctionContext, Block, BlockAndBuilder};
|
||||||
use inline;
|
|
||||||
use monomorphize::{self, Instance};
|
use monomorphize::{self, Instance};
|
||||||
use rustc::ty::{self, Ty};
|
use rustc::ty::{self, Ty};
|
||||||
|
use rustc::mir::repr as mir;
|
||||||
use session::config::{self, FullDebugInfo, LimitedDebugInfo, NoDebugInfo};
|
use session::config::{self, FullDebugInfo, LimitedDebugInfo, NoDebugInfo};
|
||||||
use util::nodemap::{DefIdMap, NodeMap, FnvHashMap, FnvHashSet};
|
use util::nodemap::{DefIdMap, FnvHashMap, FnvHashSet};
|
||||||
|
|
||||||
use libc::c_uint;
|
use libc::c_uint;
|
||||||
use std::cell::{Cell, RefCell};
|
use std::cell::{Cell, RefCell};
|
||||||
|
@ -134,7 +133,6 @@ impl FunctionDebugContext {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct FunctionDebugContextData {
|
pub struct FunctionDebugContextData {
|
||||||
scope_map: RefCell<NodeMap<DIScope>>,
|
|
||||||
fn_metadata: DISubprogram,
|
fn_metadata: DISubprogram,
|
||||||
source_locations_enabled: Cell<bool>,
|
source_locations_enabled: Cell<bool>,
|
||||||
source_location_override: Cell<bool>,
|
source_location_override: Cell<bool>,
|
||||||
|
@ -222,7 +220,8 @@ pub fn create_function_debug_context<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
|
||||||
instance: Instance<'tcx>,
|
instance: Instance<'tcx>,
|
||||||
sig: &ty::FnSig<'tcx>,
|
sig: &ty::FnSig<'tcx>,
|
||||||
abi: Abi,
|
abi: Abi,
|
||||||
llfn: ValueRef) -> FunctionDebugContext {
|
llfn: ValueRef,
|
||||||
|
mir: &mir::Mir) -> FunctionDebugContext {
|
||||||
if cx.sess().opts.debuginfo == NoDebugInfo {
|
if cx.sess().opts.debuginfo == NoDebugInfo {
|
||||||
return FunctionDebugContext::DebugInfoDisabled;
|
return FunctionDebugContext::DebugInfoDisabled;
|
||||||
}
|
}
|
||||||
|
@ -231,8 +230,8 @@ pub fn create_function_debug_context<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
|
||||||
// Do this here already, in case we do an early exit from this function.
|
// Do this here already, in case we do an early exit from this function.
|
||||||
source_loc::set_debug_location(cx, None, UnknownLocation);
|
source_loc::set_debug_location(cx, None, UnknownLocation);
|
||||||
|
|
||||||
let instance = inline::maybe_inline_instance(cx, instance);
|
let containing_scope = get_containing_scope(cx, instance);
|
||||||
let (containing_scope, span) = get_containing_scope_and_span(cx, instance);
|
let span = mir.span;
|
||||||
|
|
||||||
// This can be the case for functions inlined from another crate
|
// This can be the case for functions inlined from another crate
|
||||||
if span == syntax_pos::DUMMY_SP {
|
if span == syntax_pos::DUMMY_SP {
|
||||||
|
@ -298,7 +297,6 @@ pub fn create_function_debug_context<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
|
||||||
|
|
||||||
// Initialize fn debug context (including scope map and namespace map)
|
// Initialize fn debug context (including scope map and namespace map)
|
||||||
let fn_debug_context = box FunctionDebugContextData {
|
let fn_debug_context = box FunctionDebugContextData {
|
||||||
scope_map: RefCell::new(NodeMap()),
|
|
||||||
fn_metadata: fn_metadata,
|
fn_metadata: fn_metadata,
|
||||||
source_locations_enabled: Cell::new(false),
|
source_locations_enabled: Cell::new(false),
|
||||||
source_location_override: Cell::new(false),
|
source_location_override: Cell::new(false),
|
||||||
|
@ -406,9 +404,9 @@ pub fn create_function_debug_context<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
|
||||||
names
|
names
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_containing_scope_and_span<'ccx, 'tcx>(cx: &CrateContext<'ccx, 'tcx>,
|
fn get_containing_scope<'ccx, 'tcx>(cx: &CrateContext<'ccx, 'tcx>,
|
||||||
instance: Instance<'tcx>)
|
instance: Instance<'tcx>)
|
||||||
-> (DIScope, Span) {
|
-> DIScope {
|
||||||
// First, let's see if this is a method within an inherent impl. Because
|
// First, let's see if this is a method within an inherent impl. Because
|
||||||
// if yes, we want to make the result subroutine DIE a child of the
|
// if yes, we want to make the result subroutine DIE a child of the
|
||||||
// subroutine's self-type.
|
// subroutine's self-type.
|
||||||
|
@ -428,22 +426,15 @@ pub fn create_function_debug_context<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
let containing_scope = self_type.unwrap_or_else(|| {
|
self_type.unwrap_or_else(|| {
|
||||||
namespace::item_namespace(cx, DefId {
|
namespace::item_namespace(cx, DefId {
|
||||||
krate: instance.def.krate,
|
krate: instance.def.krate,
|
||||||
index: cx.tcx()
|
index: cx.tcx()
|
||||||
.def_key(instance.def)
|
.def_key(instance.def)
|
||||||
.parent
|
.parent
|
||||||
.expect("get_containing_scope_and_span: missing parent?")
|
.expect("get_containing_scope: missing parent?")
|
||||||
})
|
})
|
||||||
});
|
})
|
||||||
|
|
||||||
// Try to get some span information, if we have an inlined item.
|
|
||||||
let definition_span = cx.tcx()
|
|
||||||
.map
|
|
||||||
.def_id_span(instance.def, syntax_pos::DUMMY_SP);
|
|
||||||
|
|
||||||
(containing_scope, definition_span)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -521,7 +512,6 @@ pub fn declare_local<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
|
||||||
|
|
||||||
#[derive(Copy, Clone, PartialEq, Eq, Debug)]
|
#[derive(Copy, Clone, PartialEq, Eq, Debug)]
|
||||||
pub enum DebugLoc {
|
pub enum DebugLoc {
|
||||||
At(ast::NodeId, Span),
|
|
||||||
ScopeAt(DIScope, Span),
|
ScopeAt(DIScope, Span),
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
|
@ -535,28 +525,3 @@ impl DebugLoc {
|
||||||
source_loc::set_source_location(bcx.fcx(), Some(bcx), self);
|
source_loc::set_source_location(bcx.fcx(), Some(bcx), self);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub trait ToDebugLoc {
|
|
||||||
fn debug_loc(&self) -> DebugLoc;
|
|
||||||
}
|
|
||||||
|
|
||||||
impl ToDebugLoc for hir::Expr {
|
|
||||||
fn debug_loc(&self) -> DebugLoc {
|
|
||||||
DebugLoc::At(self.id, self.span)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl ToDebugLoc for NodeIdAndSpan {
|
|
||||||
fn debug_loc(&self) -> DebugLoc {
|
|
||||||
DebugLoc::At(self.id, self.span)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl ToDebugLoc for Option<NodeIdAndSpan> {
|
|
||||||
fn debug_loc(&self) -> DebugLoc {
|
|
||||||
match *self {
|
|
||||||
Some(NodeIdAndSpan { id, span }) => DebugLoc::At(id, span),
|
|
||||||
None => DebugLoc::None
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
|
@ -11,7 +11,7 @@
|
||||||
use self::InternalDebugLocation::*;
|
use self::InternalDebugLocation::*;
|
||||||
|
|
||||||
use super::utils::{debug_context, span_start};
|
use super::utils::{debug_context, span_start};
|
||||||
use super::metadata::{scope_metadata,UNKNOWN_COLUMN_NUMBER};
|
use super::metadata::{UNKNOWN_COLUMN_NUMBER};
|
||||||
use super::{FunctionDebugContext, DebugLoc};
|
use super::{FunctionDebugContext, DebugLoc};
|
||||||
|
|
||||||
use llvm;
|
use llvm;
|
||||||
|
@ -47,9 +47,6 @@ pub fn set_source_location(fcx: &FunctionContext,
|
||||||
|
|
||||||
let dbg_loc = if function_debug_context.source_locations_enabled.get() {
|
let dbg_loc = if function_debug_context.source_locations_enabled.get() {
|
||||||
let (scope, span) = match debug_loc {
|
let (scope, span) = match debug_loc {
|
||||||
DebugLoc::At(node_id, span) => {
|
|
||||||
(scope_metadata(fcx, node_id, span), span)
|
|
||||||
}
|
|
||||||
DebugLoc::ScopeAt(scope, span) => (scope, span),
|
DebugLoc::ScopeAt(scope, span) => (scope, span),
|
||||||
DebugLoc::None => {
|
DebugLoc::None => {
|
||||||
set_debug_location(fcx.ccx, builder, UnknownLocation);
|
set_debug_location(fcx.ccx, builder, UnknownLocation);
|
||||||
|
|
|
@ -221,10 +221,6 @@ fn get_drop_glue_core<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
|
||||||
g,
|
g,
|
||||||
TransItem::DropGlue(g).to_raw_string(),
|
TransItem::DropGlue(g).to_raw_string(),
|
||||||
ccx.codegen_unit().name());
|
ccx.codegen_unit().name());
|
||||||
|
|
||||||
ccx.stats().n_fallback_instantiations.set(ccx.stats()
|
|
||||||
.n_fallback_instantiations
|
|
||||||
.get() + 1);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,52 +0,0 @@
|
||||||
// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
|
|
||||||
// file at the top-level directory of this distribution and at
|
|
||||||
// http://rust-lang.org/COPYRIGHT.
|
|
||||||
//
|
|
||||||
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
|
||||||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
|
||||||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
|
||||||
// option. This file may not be copied, modified, or distributed
|
|
||||||
// except according to those terms.
|
|
||||||
|
|
||||||
use rustc::hir::def_id::DefId;
|
|
||||||
use base::push_ctxt;
|
|
||||||
use common::*;
|
|
||||||
use monomorphize::Instance;
|
|
||||||
|
|
||||||
use rustc::dep_graph::DepNode;
|
|
||||||
|
|
||||||
fn instantiate_inline(ccx: &CrateContext, fn_id: DefId) -> Option<DefId> {
|
|
||||||
debug!("instantiate_inline({:?})", fn_id);
|
|
||||||
let _icx = push_ctxt("instantiate_inline");
|
|
||||||
let tcx = ccx.tcx();
|
|
||||||
let _task = tcx.dep_graph.in_task(DepNode::TransInlinedItem(fn_id));
|
|
||||||
|
|
||||||
tcx.sess
|
|
||||||
.cstore
|
|
||||||
.maybe_get_item_ast(tcx, fn_id)
|
|
||||||
.map(|(_, inline_id)| {
|
|
||||||
tcx.map.local_def_id(inline_id)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn get_local_instance(ccx: &CrateContext, fn_id: DefId)
|
|
||||||
-> Option<DefId> {
|
|
||||||
if let Some(_) = ccx.tcx().map.as_local_node_id(fn_id) {
|
|
||||||
Some(fn_id)
|
|
||||||
} else {
|
|
||||||
instantiate_inline(ccx, fn_id)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn maybe_instantiate_inline(ccx: &CrateContext, fn_id: DefId) -> DefId {
|
|
||||||
get_local_instance(ccx, fn_id).unwrap_or(fn_id)
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn maybe_inline_instance<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
|
|
||||||
instance: Instance<'tcx>) -> Instance<'tcx> {
|
|
||||||
let def_id = maybe_instantiate_inline(ccx, instance.def);
|
|
||||||
Instance {
|
|
||||||
def: def_id,
|
|
||||||
substs: instance.substs
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -111,7 +111,7 @@ pub fn trans_intrinsic_call<'a, 'blk, 'tcx>(mut bcx: Block<'blk, 'tcx>,
|
||||||
let name = tcx.item_name(def_id).as_str();
|
let name = tcx.item_name(def_id).as_str();
|
||||||
|
|
||||||
let span = match call_debug_location {
|
let span = match call_debug_location {
|
||||||
DebugLoc::At(_, span) | DebugLoc::ScopeAt(_, span) => span,
|
DebugLoc::ScopeAt(_, span) => span,
|
||||||
DebugLoc::None => {
|
DebugLoc::None => {
|
||||||
span_bug!(fcx.span.unwrap_or(DUMMY_SP),
|
span_bug!(fcx.span.unwrap_or(DUMMY_SP),
|
||||||
"intrinsic `{}` called with missing span", name);
|
"intrinsic `{}` called with missing span", name);
|
||||||
|
|
|
@ -114,7 +114,6 @@ mod debuginfo;
|
||||||
mod declare;
|
mod declare;
|
||||||
mod disr;
|
mod disr;
|
||||||
mod glue;
|
mod glue;
|
||||||
mod inline;
|
|
||||||
mod intrinsic;
|
mod intrinsic;
|
||||||
mod machine;
|
mod machine;
|
||||||
mod meth;
|
mod meth;
|
||||||
|
|
|
@ -8,162 +8,14 @@
|
||||||
// option. This file may not be copied, modified, or distributed
|
// option. This file may not be copied, modified, or distributed
|
||||||
// except according to those terms.
|
// except according to those terms.
|
||||||
|
|
||||||
use llvm::ValueRef;
|
|
||||||
use llvm;
|
|
||||||
use rustc::hir::def_id::DefId;
|
use rustc::hir::def_id::DefId;
|
||||||
use rustc::infer::TransNormalize;
|
use rustc::infer::TransNormalize;
|
||||||
use rustc::ty::subst::{Subst, Substs};
|
use rustc::ty::subst::{Subst, Substs};
|
||||||
use rustc::ty::{self, Ty, TypeFoldable, TyCtxt};
|
use rustc::ty::{self, Ty, TyCtxt};
|
||||||
use attributes;
|
|
||||||
use base::{push_ctxt};
|
|
||||||
use base;
|
|
||||||
use common::*;
|
use common::*;
|
||||||
use declare;
|
|
||||||
use Disr;
|
|
||||||
use rustc::hir::map as hir_map;
|
|
||||||
use rustc::util::ppaux;
|
use rustc::util::ppaux;
|
||||||
|
|
||||||
use rustc::hir;
|
|
||||||
|
|
||||||
use errors;
|
|
||||||
|
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
use trans_item::TransItem;
|
|
||||||
|
|
||||||
pub fn monomorphic_fn<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
|
|
||||||
fn_id: DefId,
|
|
||||||
psubsts: &'tcx Substs<'tcx>)
|
|
||||||
-> (ValueRef, Ty<'tcx>) {
|
|
||||||
debug!("monomorphic_fn(fn_id={:?}, real_substs={:?})", fn_id, psubsts);
|
|
||||||
assert!(!psubsts.types.needs_infer() && !psubsts.types.has_param_types());
|
|
||||||
|
|
||||||
let _icx = push_ctxt("monomorphic_fn");
|
|
||||||
|
|
||||||
let instance = Instance::new(fn_id, psubsts);
|
|
||||||
|
|
||||||
let item_ty = ccx.tcx().lookup_item_type(fn_id).ty;
|
|
||||||
|
|
||||||
debug!("monomorphic_fn about to subst into {:?}", item_ty);
|
|
||||||
let mono_ty = apply_param_substs(ccx.tcx(), psubsts, &item_ty);
|
|
||||||
debug!("mono_ty = {:?} (post-substitution)", mono_ty);
|
|
||||||
|
|
||||||
if let Some(&val) = ccx.instances().borrow().get(&instance) {
|
|
||||||
debug!("leaving monomorphic fn {:?}", instance);
|
|
||||||
return (val, mono_ty);
|
|
||||||
} else {
|
|
||||||
assert!(!ccx.codegen_unit().contains_item(&TransItem::Fn(instance)));
|
|
||||||
}
|
|
||||||
|
|
||||||
debug!("monomorphic_fn({:?})", instance);
|
|
||||||
|
|
||||||
ccx.stats().n_monos.set(ccx.stats().n_monos.get() + 1);
|
|
||||||
|
|
||||||
let depth;
|
|
||||||
{
|
|
||||||
let mut monomorphizing = ccx.monomorphizing().borrow_mut();
|
|
||||||
depth = match monomorphizing.get(&fn_id) {
|
|
||||||
Some(&d) => d, None => 0
|
|
||||||
};
|
|
||||||
|
|
||||||
debug!("monomorphic_fn: depth for fn_id={:?} is {:?}", fn_id, depth+1);
|
|
||||||
|
|
||||||
// Random cut-off -- code that needs to instantiate the same function
|
|
||||||
// recursively more than thirty times can probably safely be assumed
|
|
||||||
// to be causing an infinite expansion.
|
|
||||||
if depth > ccx.sess().recursion_limit.get() {
|
|
||||||
let error = format!("reached the recursion limit while instantiating `{}`",
|
|
||||||
instance);
|
|
||||||
if let Some(id) = ccx.tcx().map.as_local_node_id(fn_id) {
|
|
||||||
ccx.sess().span_fatal(ccx.tcx().map.span(id), &error);
|
|
||||||
} else {
|
|
||||||
ccx.sess().fatal(&error);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
monomorphizing.insert(fn_id, depth + 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
let symbol = ccx.symbol_map().get_or_compute(ccx.shared(),
|
|
||||||
TransItem::Fn(instance));
|
|
||||||
|
|
||||||
debug!("monomorphize_fn mangled to {}", &symbol);
|
|
||||||
assert!(declare::get_defined_value(ccx, &symbol).is_none());
|
|
||||||
|
|
||||||
// FIXME(nagisa): perhaps needs a more fine grained selection?
|
|
||||||
let lldecl = declare::define_internal_fn(ccx, &symbol, mono_ty);
|
|
||||||
// FIXME(eddyb) Doubt all extern fn should allow unwinding.
|
|
||||||
attributes::unwind(lldecl, true);
|
|
||||||
|
|
||||||
ccx.instances().borrow_mut().insert(instance, lldecl);
|
|
||||||
|
|
||||||
// we can only monomorphize things in this crate (or inlined into it)
|
|
||||||
let fn_node_id = ccx.tcx().map.as_local_node_id(fn_id).unwrap();
|
|
||||||
let map_node = errors::expect(
|
|
||||||
ccx.sess().diagnostic(),
|
|
||||||
ccx.tcx().map.find(fn_node_id),
|
|
||||||
|| {
|
|
||||||
format!("while instantiating `{}`, couldn't find it in \
|
|
||||||
the item map (may have attempted to monomorphize \
|
|
||||||
an item defined in a different crate?)",
|
|
||||||
instance)
|
|
||||||
});
|
|
||||||
match map_node {
|
|
||||||
hir_map::NodeItem(&hir::Item {
|
|
||||||
ref attrs,
|
|
||||||
node: hir::ItemFn(..), ..
|
|
||||||
}) |
|
|
||||||
hir_map::NodeImplItem(&hir::ImplItem {
|
|
||||||
ref attrs, node: hir::ImplItemKind::Method(
|
|
||||||
hir::MethodSig { .. }, _), ..
|
|
||||||
}) |
|
|
||||||
hir_map::NodeTraitItem(&hir::TraitItem {
|
|
||||||
ref attrs, node: hir::MethodTraitItem(
|
|
||||||
hir::MethodSig { .. }, Some(_)), ..
|
|
||||||
}) => {
|
|
||||||
let trans_item = TransItem::Fn(instance);
|
|
||||||
|
|
||||||
if ccx.shared().translation_items().borrow().contains(&trans_item) {
|
|
||||||
attributes::from_fn_attrs(ccx, attrs, lldecl);
|
|
||||||
unsafe {
|
|
||||||
llvm::LLVMSetLinkage(lldecl, llvm::ExternalLinkage);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
// FIXME: #34151
|
|
||||||
// Normally, getting here would indicate a bug in trans::collector,
|
|
||||||
// since it seems to have missed a translation item. When we are
|
|
||||||
// translating with non-MIR based trans, however, the results of
|
|
||||||
// the collector are not entirely reliable since it bases its
|
|
||||||
// analysis on MIR. Thus, we'll instantiate the missing function
|
|
||||||
// privately in this codegen unit, so that things keep working.
|
|
||||||
ccx.stats().n_fallback_instantiations.set(ccx.stats()
|
|
||||||
.n_fallback_instantiations
|
|
||||||
.get() + 1);
|
|
||||||
trans_item.predefine(ccx, llvm::InternalLinkage);
|
|
||||||
trans_item.define(ccx);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
hir_map::NodeVariant(_) | hir_map::NodeStructCtor(_) => {
|
|
||||||
let disr = match map_node {
|
|
||||||
hir_map::NodeVariant(_) => {
|
|
||||||
Disr::from(inlined_variant_def(ccx, fn_node_id).disr_val)
|
|
||||||
}
|
|
||||||
hir_map::NodeStructCtor(_) => Disr(0),
|
|
||||||
_ => bug!()
|
|
||||||
};
|
|
||||||
attributes::inline(lldecl, attributes::InlineAttr::Hint);
|
|
||||||
attributes::set_frame_pointer_elimination(ccx, lldecl);
|
|
||||||
base::trans_ctor_shim(ccx, fn_node_id, disr, psubsts, lldecl);
|
|
||||||
}
|
|
||||||
|
|
||||||
_ => bug!("can't monomorphize a {:?}", map_node)
|
|
||||||
};
|
|
||||||
|
|
||||||
ccx.monomorphizing().borrow_mut().insert(fn_id, depth);
|
|
||||||
|
|
||||||
debug!("leaving monomorphic fn {}", ccx.tcx().item_path_str(fn_id));
|
|
||||||
(lldecl, mono_ty)
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug)]
|
#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug)]
|
||||||
pub struct Instance<'tcx> {
|
pub struct Instance<'tcx> {
|
||||||
|
|
|
@ -22,17 +22,15 @@ use declare;
|
||||||
use glue::DropGlueKind;
|
use glue::DropGlueKind;
|
||||||
use llvm;
|
use llvm;
|
||||||
use monomorphize::{self, Instance};
|
use monomorphize::{self, Instance};
|
||||||
use inline;
|
|
||||||
use rustc::dep_graph::DepNode;
|
use rustc::dep_graph::DepNode;
|
||||||
use rustc::hir;
|
use rustc::hir;
|
||||||
use rustc::hir::map as hir_map;
|
|
||||||
use rustc::hir::def_id::DefId;
|
use rustc::hir::def_id::DefId;
|
||||||
use rustc::ty::{self, Ty, TyCtxt, TypeFoldable};
|
use rustc::ty::{self, Ty, TyCtxt, TypeFoldable};
|
||||||
use rustc::ty::subst::Substs;
|
use rustc::ty::subst::Substs;
|
||||||
use rustc_const_eval::fatal_const_eval_err;
|
use rustc_const_eval::fatal_const_eval_err;
|
||||||
use std::hash::{Hash, Hasher};
|
use std::hash::{Hash, Hasher};
|
||||||
use syntax::ast::{self, NodeId};
|
use syntax::ast::{self, NodeId};
|
||||||
use syntax::{attr,errors};
|
use syntax::attr;
|
||||||
use type_of;
|
use type_of;
|
||||||
use glue;
|
use glue;
|
||||||
use abi::{Abi, FnType};
|
use abi::{Abi, FnType};
|
||||||
|
@ -157,20 +155,16 @@ impl<'a, 'tcx> TransItem<'tcx> {
|
||||||
let ty = ccx.tcx().lookup_item_type(def_id).ty;
|
let ty = ccx.tcx().lookup_item_type(def_id).ty;
|
||||||
let llty = type_of::type_of(ccx, ty);
|
let llty = type_of::type_of(ccx, ty);
|
||||||
|
|
||||||
match ccx.tcx().map.get(node_id) {
|
let g = declare::define_global(ccx, symbol_name, llty).unwrap_or_else(|| {
|
||||||
hir::map::NodeItem(&hir::Item {
|
ccx.sess().span_fatal(ccx.tcx().map.span(node_id),
|
||||||
span, node: hir::ItemStatic(..), ..
|
&format!("symbol `{}` is already defined", symbol_name))
|
||||||
}) => {
|
});
|
||||||
let g = declare::define_global(ccx, symbol_name, llty).unwrap_or_else(|| {
|
|
||||||
ccx.sess().span_fatal(span,
|
|
||||||
&format!("symbol `{}` is already defined", symbol_name))
|
|
||||||
});
|
|
||||||
|
|
||||||
unsafe { llvm::LLVMSetLinkage(g, linkage) };
|
unsafe { llvm::LLVMSetLinkage(g, linkage) };
|
||||||
}
|
|
||||||
|
|
||||||
item => bug!("predefine_static: expected static, found {:?}", item)
|
let instance = Instance::mono(ccx.shared(), def_id);
|
||||||
}
|
ccx.instances().borrow_mut().insert(instance, g);
|
||||||
|
ccx.statics().borrow_mut().insert(g, def_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn predefine_fn(ccx: &CrateContext<'a, 'tcx>,
|
fn predefine_fn(ccx: &CrateContext<'a, 'tcx>,
|
||||||
|
@ -180,47 +174,22 @@ impl<'a, 'tcx> TransItem<'tcx> {
|
||||||
assert!(!instance.substs.types.needs_infer() &&
|
assert!(!instance.substs.types.needs_infer() &&
|
||||||
!instance.substs.types.has_param_types());
|
!instance.substs.types.has_param_types());
|
||||||
|
|
||||||
let instance = inline::maybe_inline_instance(ccx, instance);
|
|
||||||
|
|
||||||
let item_ty = ccx.tcx().lookup_item_type(instance.def).ty;
|
let item_ty = ccx.tcx().lookup_item_type(instance.def).ty;
|
||||||
let item_ty = ccx.tcx().erase_regions(&item_ty);
|
let item_ty = ccx.tcx().erase_regions(&item_ty);
|
||||||
let mono_ty = monomorphize::apply_param_substs(ccx.tcx(), instance.substs, &item_ty);
|
let mono_ty = monomorphize::apply_param_substs(ccx.tcx(), instance.substs, &item_ty);
|
||||||
|
|
||||||
let fn_node_id = ccx.tcx().map.as_local_node_id(instance.def).unwrap();
|
let attrs = ccx.tcx().get_attrs(instance.def);
|
||||||
let map_node = errors::expect(
|
let lldecl = declare::declare_fn(ccx, symbol_name, mono_ty);
|
||||||
ccx.sess().diagnostic(),
|
unsafe { llvm::LLVMSetLinkage(lldecl, linkage) };
|
||||||
ccx.tcx().map.find(fn_node_id),
|
base::set_link_section(ccx, lldecl, &attrs);
|
||||||
|| {
|
if linkage == llvm::LinkOnceODRLinkage ||
|
||||||
format!("while instantiating `{}`, couldn't find it in \
|
linkage == llvm::WeakODRLinkage {
|
||||||
the item map (may have attempted to monomorphize \
|
llvm::SetUniqueComdat(ccx.llmod(), lldecl);
|
||||||
an item defined in a different crate?)",
|
}
|
||||||
instance)
|
|
||||||
});
|
|
||||||
|
|
||||||
match map_node {
|
attributes::from_fn_attrs(ccx, &attrs, lldecl);
|
||||||
hir_map::NodeItem(&hir::Item {
|
|
||||||
ref attrs, node: hir::ItemFn(..), ..
|
|
||||||
}) |
|
|
||||||
hir_map::NodeTraitItem(&hir::TraitItem {
|
|
||||||
ref attrs, node: hir::MethodTraitItem(..), ..
|
|
||||||
}) |
|
|
||||||
hir_map::NodeImplItem(&hir::ImplItem {
|
|
||||||
ref attrs, node: hir::ImplItemKind::Method(..), ..
|
|
||||||
}) => {
|
|
||||||
let lldecl = declare::declare_fn(ccx, symbol_name, mono_ty);
|
|
||||||
unsafe { llvm::LLVMSetLinkage(lldecl, linkage) };
|
|
||||||
base::set_link_section(ccx, lldecl, attrs);
|
|
||||||
if linkage == llvm::LinkOnceODRLinkage ||
|
|
||||||
linkage == llvm::WeakODRLinkage {
|
|
||||||
llvm::SetUniqueComdat(ccx.llmod(), lldecl);
|
|
||||||
}
|
|
||||||
|
|
||||||
attributes::from_fn_attrs(ccx, attrs, lldecl);
|
|
||||||
ccx.instances().borrow_mut().insert(instance, lldecl);
|
|
||||||
}
|
|
||||||
_ => bug!("Invalid item for TransItem::Fn: `{:?}`", map_node)
|
|
||||||
};
|
|
||||||
|
|
||||||
|
ccx.instances().borrow_mut().insert(instance, lldecl);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn predefine_drop_glue(ccx: &CrateContext<'a, 'tcx>,
|
fn predefine_drop_glue(ccx: &CrateContext<'a, 'tcx>,
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue