From 14133d33bcc2e6e3939fa4b485294334366bf162 Mon Sep 17 00:00:00 2001 From: Eduard Burtescu Date: Wed, 25 May 2016 01:34:17 +0300 Subject: [PATCH] trans: move exported_name's logic into symbol_names. --- src/librustc_trans/back/symbol_names.rs | 64 +++++++++++++++++-------- src/librustc_trans/base.rs | 44 +---------------- src/librustc_trans/callee.rs | 5 +- src/librustc_trans/closure.rs | 2 +- src/librustc_trans/consts.rs | 9 ++-- src/librustc_trans/context.rs | 4 ++ src/librustc_trans/monomorphize.rs | 2 +- src/librustc_trans/symbol_names_test.rs | 2 +- 8 files changed, 62 insertions(+), 70 deletions(-) diff --git a/src/librustc_trans/back/symbol_names.rs b/src/librustc_trans/back/symbol_names.rs index 0495cf5eb671..dffd0beafe51 100644 --- a/src/librustc_trans/back/symbol_names.rs +++ b/src/librustc_trans/back/symbol_names.rs @@ -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[..])) } diff --git a/src/librustc_trans/base.rs b/src/librustc_trans/base.rs index 451bfbc83bc1..f6a2b82fb166 100644 --- a/src/librustc_trans/base.rs +++ b/src/librustc_trans/base.rs @@ -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) })); } diff --git a/src/librustc_trans/callee.rs b/src/librustc_trans/callee.rs index c0c5ea818b2d..bdeb1a6270f9 100644 --- a/src/librustc_trans/callee.rs +++ b/src/librustc_trans/callee.rs @@ -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 => { diff --git a/src/librustc_trans/closure.rs b/src/librustc_trans/closure.rs index 1c393f8091ee..8d273dfe1953 100644 --- a/src/librustc_trans/closure.rs +++ b/src/librustc_trans/closure.rs @@ -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; diff --git a/src/librustc_trans/consts.rs b/src/librustc_trans/consts.rs index 3e876eb3d7de..6dca7fe5ed92 100644 --- a/src/librustc_trans/consts.rs +++ b/src/librustc_trans/consts.rs @@ -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 diff --git a/src/librustc_trans/context.rs b/src/librustc_trans/context.rs index 4d6c4cdcc6b0..95d56432e1e3 100644 --- a/src/librustc_trans/context.rs +++ b/src/librustc_trans/context.rs @@ -504,6 +504,10 @@ impl<'b, 'tcx> SharedCrateContext<'b, 'tcx> { scheme.generics.regions.map(|_| ty::ReStatic))) } + pub fn symbol_hasher(&self) -> &RefCell { + &self.symbol_hasher + } + pub fn metadata_symbol_name(&self) -> String { format!("rust_metadata_{}_{}", self.link_meta().crate_name, diff --git a/src/librustc_trans/monomorphize.rs b/src/librustc_trans/monomorphize.rs index dfaf84ecef02..e781468f96c9 100644 --- a/src/librustc_trans/monomorphize.rs +++ b/src/librustc_trans/monomorphize.rs @@ -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()); diff --git a/src/librustc_trans/symbol_names_test.rs b/src/librustc_trans/symbol_names_test.rs index 284a227276dd..6777e98d4b81 100644 --- a/src/librustc_trans/symbol_names_test.rs +++ b/src/librustc_trans/symbol_names_test.rs @@ -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);