Skip to content

Commit

Permalink
trans: move exported_name's logic into symbol_names.
Browse files Browse the repository at this point in the history
  • Loading branch information
eddyb committed May 24, 2016
1 parent 3918474 commit 14133d3
Show file tree
Hide file tree
Showing 8 changed files with 62 additions and 70 deletions.
64 changes: 45 additions & 19 deletions src/librustc_trans/back/symbol_names.rs
Expand Up @@ -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;

Expand All @@ -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,
Expand All @@ -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();

Expand Down Expand Up @@ -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
Expand All @@ -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;
}
_ => {
Expand All @@ -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())
Expand Down Expand Up @@ -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[..]))
}

Expand Down
44 changes: 2 additions & 42 deletions src/librustc_trans/base.rs
Expand Up @@ -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(),
Expand Down Expand Up @@ -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)
}));
}

Expand Down
5 changes: 3 additions & 2 deletions src/librustc_trans/callee.rs
Expand Up @@ -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,
Expand All @@ -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 => {
Expand Down
2 changes: 1 addition & 1 deletion src/librustc_trans/closure.rs
Expand Up @@ -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;
Expand Down
9 changes: 5 additions & 4 deletions src/librustc_trans/consts.rs
Expand Up @@ -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;
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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
Expand Down
4 changes: 4 additions & 0 deletions src/librustc_trans/context.rs
Expand Up @@ -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,
Expand Down
2 changes: 1 addition & 1 deletion src/librustc_trans/monomorphize.rs
Expand Up @@ -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());
Expand Down
2 changes: 1 addition & 1 deletion src/librustc_trans/symbol_names_test.rs
Expand Up @@ -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);
Expand Down

0 comments on commit 14133d3

Please sign in to comment.