trans: move exported_name's logic into symbol_names.
This commit is contained in:
parent
39184741bc
commit
14133d33bc
@ -97,17 +97,18 @@
|
||||
//! virtually impossible. Thus, symbol hash generation exclusively relies on
|
||||
//! DefPaths which are much more robust in the face of changes to the code base.
|
||||
|
||||
use common::{CrateContext, gensym_name};
|
||||
use common::{CrateContext, SharedCrateContext, gensym_name};
|
||||
use monomorphize::Instance;
|
||||
use util::sha2::{Digest, Sha256};
|
||||
|
||||
use rustc::middle::cstore;
|
||||
use rustc::middle::{cstore, weak_lang_items};
|
||||
use rustc::hir::def_id::DefId;
|
||||
use rustc::ty::{self, TyCtxt, TypeFoldable};
|
||||
use rustc::ty::item_path::{ItemPathBuffer, RootMode};
|
||||
use rustc::ty::item_path::{self, ItemPathBuffer, RootMode};
|
||||
use rustc::hir::map::definitions::{DefPath, DefPathData};
|
||||
|
||||
use std::fmt::Write;
|
||||
use syntax::attr;
|
||||
use syntax::parse::token::{self, InternedString};
|
||||
use serialize::hex::ToHex;
|
||||
|
||||
@ -134,7 +135,7 @@ fn def_path_to_string<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_path: &DefPath)
|
||||
s
|
||||
}
|
||||
|
||||
fn get_symbol_hash<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
|
||||
fn get_symbol_hash<'a, 'tcx>(scx: &SharedCrateContext<'a, 'tcx>,
|
||||
|
||||
// path to the item this name is for
|
||||
def_path: &DefPath,
|
||||
@ -152,9 +153,9 @@ fn get_symbol_hash<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
|
||||
debug!("get_symbol_hash(def_path={:?}, parameters={:?})",
|
||||
def_path, parameters);
|
||||
|
||||
let tcx = ccx.tcx();
|
||||
let tcx = scx.tcx();
|
||||
|
||||
let mut hash_state = ccx.symbol_hasher().borrow_mut();
|
||||
let mut hash_state = scx.symbol_hasher().borrow_mut();
|
||||
|
||||
hash_state.reset();
|
||||
|
||||
@ -187,22 +188,47 @@ fn get_symbol_hash<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn exported_name<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
|
||||
instance: &Instance<'tcx>)
|
||||
pub fn exported_name<'a, 'tcx>(scx: &SharedCrateContext<'a, 'tcx>,
|
||||
instance: Instance<'tcx>)
|
||||
-> String {
|
||||
let &Instance { def: mut def_id, ref substs } = instance;
|
||||
let Instance { def: def_id, ref substs } = instance;
|
||||
|
||||
debug!("exported_name(def_id={:?}, substs={:?})",
|
||||
def_id, substs);
|
||||
|
||||
if let Some(node_id) = ccx.tcx().map.as_local_node_id(def_id) {
|
||||
if let Some(&src_def_id) = ccx.external_srcs().borrow().get(&node_id) {
|
||||
def_id = src_def_id;
|
||||
let node_id = scx.tcx().map.as_local_node_id(instance.def);
|
||||
|
||||
if let Some(id) = node_id {
|
||||
if scx.sess().plugin_registrar_fn.get() == Some(id) {
|
||||
let svh = &scx.link_meta().crate_hash;
|
||||
let idx = instance.def.index;
|
||||
return scx.sess().generate_plugin_registrar_symbol(svh, idx);
|
||||
}
|
||||
}
|
||||
|
||||
let def_path = ccx.tcx().def_path(def_id);
|
||||
assert_eq!(def_path.krate, def_id.krate);
|
||||
// FIXME(eddyb) Precompute a custom symbol name based on attributes.
|
||||
let attrs;
|
||||
let attrs = if let Some(id) = node_id {
|
||||
scx.tcx().map.attrs(id)
|
||||
} else {
|
||||
attrs = scx.sess().cstore.item_attrs(def_id);
|
||||
&attrs[..]
|
||||
};
|
||||
|
||||
if let Some(name) = attr::find_export_name_attr(scx.sess().diagnostic(), attrs) {
|
||||
// Use provided name
|
||||
return name.to_string();
|
||||
}
|
||||
|
||||
if attr::contains_name(attrs, "no_mangle") {
|
||||
// Don't mangle
|
||||
return scx.tcx().item_name(instance.def).as_str().to_string()
|
||||
}
|
||||
if let Some(name) = weak_lang_items::link_name(attrs) {
|
||||
return name.to_string();
|
||||
}
|
||||
|
||||
let def_path = scx.tcx().def_path(def_id);
|
||||
|
||||
// We want to compute the "type" of this item. Unfortunately, some
|
||||
// kinds of items (e.g., closures) don't have an entry in the
|
||||
@ -211,11 +237,11 @@ pub fn exported_name<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
|
||||
let mut ty_def_id = def_id;
|
||||
let instance_ty;
|
||||
loop {
|
||||
let key = ccx.tcx().def_key(ty_def_id);
|
||||
let key = scx.tcx().def_key(ty_def_id);
|
||||
match key.disambiguated_data.data {
|
||||
DefPathData::TypeNs(_) |
|
||||
DefPathData::ValueNs(_) => {
|
||||
instance_ty = ccx.tcx().lookup_item_type(ty_def_id);
|
||||
instance_ty = scx.tcx().lookup_item_type(ty_def_id);
|
||||
break;
|
||||
}
|
||||
_ => {
|
||||
@ -232,9 +258,9 @@ pub fn exported_name<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
|
||||
|
||||
// Erase regions because they may not be deterministic when hashed
|
||||
// and should not matter anyhow.
|
||||
let instance_ty = ccx.tcx().erase_regions(&instance_ty.ty);
|
||||
let instance_ty = scx.tcx().erase_regions(&instance_ty.ty);
|
||||
|
||||
let hash = get_symbol_hash(ccx, &def_path, instance_ty, substs.types.as_slice());
|
||||
let hash = get_symbol_hash(scx, &def_path, instance_ty, substs.types.as_slice());
|
||||
|
||||
let mut buffer = SymbolPathBuffer {
|
||||
names: Vec::with_capacity(def_path.data.len())
|
||||
@ -271,7 +297,7 @@ pub fn internal_name_from_type_and_suffix<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>
|
||||
data: vec![],
|
||||
krate: cstore::LOCAL_CRATE,
|
||||
};
|
||||
let hash = get_symbol_hash(ccx, &def_path, t, &[]);
|
||||
let hash = get_symbol_hash(ccx.shared(), &def_path, t, &[]);
|
||||
mangle(path.iter().cloned(), Some(&hash[..]))
|
||||
}
|
||||
|
||||
|
@ -2437,47 +2437,6 @@ pub fn create_entry_wrapper(ccx: &CrateContext, sp: Span, main_llfn: ValueRef) {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn exported_name<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
|
||||
instance: Instance<'tcx>,
|
||||
attrs: &[ast::Attribute])
|
||||
-> String {
|
||||
let id = ccx.tcx().map.as_local_node_id(instance.def).unwrap();
|
||||
|
||||
if ccx.sess().plugin_registrar_fn.get() == Some(id) {
|
||||
let svh = &ccx.link_meta().crate_hash;
|
||||
let idx = instance.def.index;
|
||||
return ccx.sess().generate_plugin_registrar_symbol(svh, idx);
|
||||
}
|
||||
|
||||
match ccx.external_srcs().borrow().get(&id) {
|
||||
Some(&did) => {
|
||||
let sym = ccx.sess().cstore.item_symbol(did);
|
||||
debug!("found item {} in other crate...", sym);
|
||||
return sym;
|
||||
}
|
||||
None => {}
|
||||
}
|
||||
|
||||
match attr::find_export_name_attr(ccx.sess().diagnostic(), attrs) {
|
||||
// Use provided name
|
||||
Some(name) => name.to_string(),
|
||||
_ => {
|
||||
if attr::contains_name(attrs, "no_mangle") {
|
||||
// Don't mangle
|
||||
ccx.tcx().map.name(id).as_str().to_string()
|
||||
} else {
|
||||
match weak_lang_items::link_name(attrs) {
|
||||
Some(name) => name.to_string(),
|
||||
None => {
|
||||
// Usual name mangling
|
||||
symbol_names::exported_name(ccx, &instance)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn imported_name(name: ast::Name, attrs: &[ast::Attribute]) -> InternedString {
|
||||
match attr::first_attr_value_str_by_name(attrs, "link_name") {
|
||||
Some(ln) => ln.clone(),
|
||||
@ -2840,7 +2799,8 @@ pub fn trans_crate<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||
reachable_symbols.extend(syms.into_iter().filter(|did| {
|
||||
sess.cstore.is_extern_item(shared_ccx.tcx(), *did)
|
||||
}).map(|did| {
|
||||
sess.cstore.item_symbol(did)
|
||||
let instance = Instance::mono(shared_ccx.tcx(), did);
|
||||
symbol_names::exported_name(&shared_ccx, instance)
|
||||
}));
|
||||
}
|
||||
|
||||
|
@ -512,7 +512,7 @@ fn get_fn<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
|
||||
Some(hir_map::NodeImplItem(&hir::ImplItem {
|
||||
ref attrs, id, span, node: hir::ImplItemKind::Method(..), ..
|
||||
})) => {
|
||||
let sym = exported_name(ccx, instance, attrs);
|
||||
let sym = symbol_names::exported_name(ccx.shared(), instance);
|
||||
|
||||
if declare::get_defined_value(ccx, &sym).is_some() {
|
||||
ccx.sess().span_fatal(span,
|
||||
@ -530,7 +530,8 @@ fn get_fn<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
|
||||
|
||||
None => {
|
||||
attrs = ccx.sess().cstore.item_attrs(def_id);
|
||||
(ccx.sess().cstore.item_symbol(def_id), &attrs[..], None)
|
||||
let sym = symbol_names::exported_name(ccx.shared(), instance);
|
||||
(sym, &attrs[..], None)
|
||||
}
|
||||
|
||||
ref variant => {
|
||||
|
@ -150,7 +150,7 @@ fn get_or_create_closure_declaration<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
|
||||
return llfn;
|
||||
}
|
||||
|
||||
let symbol = symbol_names::exported_name(ccx, &instance);
|
||||
let symbol = symbol_names::exported_name(ccx.shared(), instance);
|
||||
|
||||
// Compute the rust-call form of the closure call method.
|
||||
let sig = &tcx.closure_type(closure_id, substs).sig;
|
||||
|
@ -19,7 +19,8 @@ use rustc::hir::def::Def;
|
||||
use rustc::hir::def_id::DefId;
|
||||
use rustc::hir::map as hir_map;
|
||||
use {abi, adt, closure, debuginfo, expr, machine};
|
||||
use base::{self, exported_name, imported_name, push_ctxt};
|
||||
use base::{self, imported_name, push_ctxt};
|
||||
use back::symbol_names;
|
||||
use callee::Callee;
|
||||
use collector;
|
||||
use trans_item::TransItem;
|
||||
@ -1021,13 +1022,13 @@ pub fn get_static<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, def_id: DefId)
|
||||
let llty = type_of::type_of(ccx, ty);
|
||||
match ccx.tcx().map.get(id) {
|
||||
hir_map::NodeItem(&hir::Item {
|
||||
ref attrs, span, node: hir::ItemStatic(..), ..
|
||||
span, node: hir::ItemStatic(..), ..
|
||||
}) => {
|
||||
// If this static came from an external crate, then
|
||||
// we need to get the symbol from metadata instead of
|
||||
// using the current crate's name/version
|
||||
// information in the hash of the symbol
|
||||
let sym = exported_name(ccx, instance, attrs);
|
||||
let sym = symbol_names::exported_name(ccx.shared(), instance);
|
||||
debug!("making {}", sym);
|
||||
|
||||
// Create the global before evaluating the initializer;
|
||||
@ -1104,7 +1105,7 @@ pub fn get_static<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, def_id: DefId)
|
||||
} else {
|
||||
// FIXME(nagisa): perhaps the map of externs could be offloaded to llvm somehow?
|
||||
// FIXME(nagisa): investigate whether it can be changed into define_global
|
||||
let name = ccx.sess().cstore.item_symbol(def_id);
|
||||
let name = symbol_names::exported_name(ccx.shared(), instance);
|
||||
let g = declare::declare_global(ccx, &name, type_of::type_of(ccx, ty));
|
||||
// Thread-local statics in some other crate need to *always* be linked
|
||||
// against in a thread-local fashion, so we need to be sure to apply the
|
||||
|
@ -504,6 +504,10 @@ impl<'b, 'tcx> SharedCrateContext<'b, 'tcx> {
|
||||
scheme.generics.regions.map(|_| ty::ReStatic)))
|
||||
}
|
||||
|
||||
pub fn symbol_hasher(&self) -> &RefCell<Sha256> {
|
||||
&self.symbol_hasher
|
||||
}
|
||||
|
||||
pub fn metadata_symbol_name(&self) -> String {
|
||||
format!("rust_metadata_{}_{}",
|
||||
self.link_meta().crate_name,
|
||||
|
@ -88,7 +88,7 @@ pub fn monomorphic_fn<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
|
||||
monomorphizing.insert(fn_id, depth + 1);
|
||||
}
|
||||
|
||||
let symbol = symbol_names::exported_name(ccx, &instance);
|
||||
let symbol = symbol_names::exported_name(ccx.shared(), instance);
|
||||
|
||||
debug!("monomorphize_fn mangled to {}", symbol);
|
||||
assert!(declare::get_defined_value(ccx, &symbol).is_none());
|
||||
|
@ -53,7 +53,7 @@ impl<'a, 'tcx> SymbolNamesTest<'a, 'tcx> {
|
||||
if attr.check_name(SYMBOL_NAME) {
|
||||
// for now, can only use on monomorphic names
|
||||
let instance = Instance::mono(self.ccx.shared(), def_id);
|
||||
let name = symbol_names::exported_name(self.ccx, &instance);
|
||||
let name = symbol_names::exported_name(self.ccx.shared(), instance);
|
||||
tcx.sess.span_err(attr.span, &format!("symbol-name({})", name));
|
||||
} else if attr.check_name(ITEM_PATH) {
|
||||
let path = tcx.item_path_str(def_id);
|
||||
|
Loading…
x
Reference in New Issue
Block a user