Skip to content

Commit c9a10bd

Browse files
committed
trans: move exported_symbol to Instance::symbol_name.
1 parent a6a5e48 commit c9a10bd

File tree

12 files changed

+146
-126
lines changed

12 files changed

+146
-126
lines changed

src/librustc/middle/cstore.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -205,6 +205,7 @@ pub trait CrateStore<'tcx> {
205205
fn is_impl(&self, did: DefId) -> bool;
206206
fn is_default_impl(&self, impl_did: DefId) -> bool;
207207
fn is_extern_item<'a>(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>, did: DefId) -> bool;
208+
fn is_foreign_item(&self, did: DefId) -> bool;
208209
fn is_static_method(&self, did: DefId) -> bool;
209210
fn is_statically_included_foreign_item(&self, id: ast::NodeId) -> bool;
210211
fn is_typedef(&self, did: DefId) -> bool;
@@ -399,6 +400,7 @@ impl<'tcx> CrateStore<'tcx> for DummyCrateStore {
399400
fn is_default_impl(&self, impl_did: DefId) -> bool { bug!("is_default_impl") }
400401
fn is_extern_item<'a>(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>, did: DefId) -> bool
401402
{ bug!("is_extern_item") }
403+
fn is_foreign_item(&self, did: DefId) -> bool { bug!("is_foreign_item") }
402404
fn is_static_method(&self, did: DefId) -> bool { bug!("is_static_method") }
403405
fn is_statically_included_foreign_item(&self, id: ast::NodeId) -> bool { false }
404406
fn is_typedef(&self, did: DefId) -> bool { bug!("is_typedef") }

src/librustc_metadata/csearch.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -284,6 +284,11 @@ impl<'tcx> CrateStore<'tcx> for cstore::CStore {
284284
decoder::is_extern_item(&cdata, did.index, tcx)
285285
}
286286

287+
fn is_foreign_item(&self, did: DefId) -> bool {
288+
let cdata = self.get_crate_data(did.krate);
289+
decoder::is_foreign_item(&cdata, did.index)
290+
}
291+
287292
fn is_static_method(&self, def: DefId) -> bool
288293
{
289294
self.dep_graph.read(DepNode::MetaData(def));

src/librustc_metadata/decoder.rs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1634,6 +1634,16 @@ pub fn is_extern_item<'a, 'tcx>(cdata: Cmd,
16341634
}
16351635
}
16361636

1637+
pub fn is_foreign_item(cdata: Cmd, id: DefIndex) -> bool {
1638+
let item_doc = cdata.lookup_item(id);
1639+
let parent_item_id = match item_parent_item(cdata, item_doc) {
1640+
None => return false,
1641+
Some(item_id) => item_id,
1642+
};
1643+
let parent_item_doc = cdata.lookup_item(parent_item_id.index);
1644+
item_family(parent_item_doc) == ForeignMod
1645+
}
1646+
16371647
pub fn is_impl(cdata: Cmd, id: DefIndex) -> bool {
16381648
let item_doc = cdata.lookup_item(id);
16391649
match item_family(item_doc) {

src/librustc_metadata/encoder.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1354,6 +1354,8 @@ fn encode_info_for_foreign_item<'a, 'tcx>(ecx: &EncodeContext<'a, 'tcx>,
13541354
let _task = index.record(def_id, rbml_w);
13551355
rbml_w.start_tag(tag_items_data_item);
13561356
encode_def_id_and_key(ecx, rbml_w, def_id);
1357+
let parent_id = ecx.tcx.map.get_parent(nitem.id);
1358+
encode_parent_item(rbml_w, ecx.tcx.map.local_def_id(parent_id));
13571359
encode_visibility(rbml_w, &nitem.vis);
13581360
match nitem.node {
13591361
hir::ForeignItemFn(ref fndecl, _) => {

src/librustc_trans/back/symbol_names.rs

Lines changed: 80 additions & 68 deletions
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,7 @@ use util::sha2::{Digest, Sha256};
103103

104104
use rustc::middle::{cstore, weak_lang_items};
105105
use rustc::hir::def_id::DefId;
106+
use rustc::hir::map as hir_map;
106107
use rustc::ty::{self, TyCtxt, TypeFoldable};
107108
use rustc::ty::item_path::{self, ItemPathBuffer, RootMode};
108109
use rustc::hir::map::definitions::{DefPath, DefPathData};
@@ -192,89 +193,100 @@ fn get_symbol_hash<'a, 'tcx>(scx: &SharedCrateContext<'a, 'tcx>,
192193
}
193194
}
194195

195-
pub fn exported_name<'a, 'tcx>(scx: &SharedCrateContext<'a, 'tcx>,
196-
instance: Instance<'tcx>)
197-
-> String {
198-
let Instance { def: def_id, ref substs } = instance;
196+
impl<'a, 'tcx> Instance<'tcx> {
197+
pub fn symbol_name(self, scx: &SharedCrateContext<'a, 'tcx>) -> String {
198+
let Instance { def: def_id, ref substs } = self;
199199

200-
debug!("exported_name(def_id={:?}, substs={:?})",
201-
def_id, substs);
200+
debug!("symbol_name(def_id={:?}, substs={:?})",
201+
def_id, substs);
202202

203-
let node_id = scx.tcx().map.as_local_node_id(instance.def);
203+
let node_id = scx.tcx().map.as_local_node_id(def_id);
204204

205-
if let Some(id) = node_id {
206-
if scx.sess().plugin_registrar_fn.get() == Some(id) {
207-
let svh = &scx.link_meta().crate_hash;
208-
let idx = instance.def.index;
209-
return scx.sess().generate_plugin_registrar_symbol(svh, idx);
205+
if let Some(id) = node_id {
206+
if scx.sess().plugin_registrar_fn.get() == Some(id) {
207+
let svh = &scx.link_meta().crate_hash;
208+
let idx = def_id.index;
209+
return scx.sess().generate_plugin_registrar_symbol(svh, idx);
210+
}
210211
}
211-
}
212-
213-
// FIXME(eddyb) Precompute a custom symbol name based on attributes.
214-
let attrs;
215-
let attrs = if let Some(id) = node_id {
216-
scx.tcx().map.attrs(id)
217-
} else {
218-
attrs = scx.sess().cstore.item_attrs(def_id);
219-
&attrs[..]
220-
};
221212

222-
if let Some(name) = attr::find_export_name_attr(scx.sess().diagnostic(), attrs) {
223-
// Use provided name
224-
return name.to_string();
225-
}
213+
// FIXME(eddyb) Precompute a custom symbol name based on attributes.
214+
let attrs = scx.tcx().get_attrs(def_id);
215+
let is_foreign = if let Some(id) = node_id {
216+
match scx.tcx().map.get(id) {
217+
hir_map::NodeForeignItem(_) => true,
218+
_ => false
219+
}
220+
} else {
221+
scx.sess().cstore.is_foreign_item(def_id)
222+
};
226223

227-
if attr::contains_name(attrs, "no_mangle") {
228-
// Don't mangle
229-
return scx.tcx().item_name(instance.def).as_str().to_string()
230-
}
231-
if let Some(name) = weak_lang_items::link_name(attrs) {
232-
return name.to_string();
233-
}
224+
if let Some(name) = weak_lang_items::link_name(&attrs) {
225+
return name.to_string();
226+
}
234227

235-
let def_path = scx.tcx().def_path(def_id);
236-
237-
// We want to compute the "type" of this item. Unfortunately, some
238-
// kinds of items (e.g., closures) don't have an entry in the
239-
// item-type array. So walk back up the find the closest parent
240-
// that DOES have an entry.
241-
let mut ty_def_id = def_id;
242-
let instance_ty;
243-
loop {
244-
let key = scx.tcx().def_key(ty_def_id);
245-
match key.disambiguated_data.data {
246-
DefPathData::TypeNs(_) |
247-
DefPathData::ValueNs(_) => {
248-
instance_ty = scx.tcx().lookup_item_type(ty_def_id);
249-
break;
228+
if is_foreign {
229+
if let Some(name) = attr::first_attr_value_str_by_name(&attrs, "link_name") {
230+
return name.to_string();
250231
}
251-
_ => {
252-
// if we're making a symbol for something, there ought
253-
// to be a value or type-def or something in there
254-
// *somewhere*
255-
ty_def_id.index = key.parent.unwrap_or_else(|| {
256-
bug!("finding type for {:?}, encountered def-id {:?} with no \
257-
parent", def_id, ty_def_id);
258-
});
232+
// Don't mangle foreign items.
233+
return scx.tcx().item_name(def_id).as_str().to_string();
234+
}
235+
236+
if let Some(name) = attr::find_export_name_attr(scx.sess().diagnostic(), &attrs) {
237+
// Use provided name
238+
return name.to_string();
239+
}
240+
241+
if attr::contains_name(&attrs, "no_mangle") {
242+
// Don't mangle
243+
return scx.tcx().item_name(def_id).as_str().to_string();
244+
}
245+
246+
let def_path = scx.tcx().def_path(def_id);
247+
248+
// We want to compute the "type" of this item. Unfortunately, some
249+
// kinds of items (e.g., closures) don't have an entry in the
250+
// item-type array. So walk back up the find the closest parent
251+
// that DOES have an entry.
252+
let mut ty_def_id = def_id;
253+
let instance_ty;
254+
loop {
255+
let key = scx.tcx().def_key(ty_def_id);
256+
match key.disambiguated_data.data {
257+
DefPathData::TypeNs(_) |
258+
DefPathData::ValueNs(_) => {
259+
instance_ty = scx.tcx().lookup_item_type(ty_def_id);
260+
break;
261+
}
262+
_ => {
263+
// if we're making a symbol for something, there ought
264+
// to be a value or type-def or something in there
265+
// *somewhere*
266+
ty_def_id.index = key.parent.unwrap_or_else(|| {
267+
bug!("finding type for {:?}, encountered def-id {:?} with no \
268+
parent", def_id, ty_def_id);
269+
});
270+
}
259271
}
260272
}
261-
}
262273

263-
// Erase regions because they may not be deterministic when hashed
264-
// and should not matter anyhow.
265-
let instance_ty = scx.tcx().erase_regions(&instance_ty.ty);
274+
// Erase regions because they may not be deterministic when hashed
275+
// and should not matter anyhow.
276+
let instance_ty = scx.tcx().erase_regions(&instance_ty.ty);
266277

267-
let hash = get_symbol_hash(scx, &def_path, instance_ty, substs.types.as_slice());
278+
let hash = get_symbol_hash(scx, &def_path, instance_ty, substs.types.as_slice());
268279

269-
let mut buffer = SymbolPathBuffer {
270-
names: Vec::with_capacity(def_path.data.len())
271-
};
280+
let mut buffer = SymbolPathBuffer {
281+
names: Vec::with_capacity(def_path.data.len())
282+
};
272283

273-
item_path::with_forced_absolute_paths(|| {
274-
scx.tcx().push_item_path(&mut buffer, def_id);
275-
});
284+
item_path::with_forced_absolute_paths(|| {
285+
scx.tcx().push_item_path(&mut buffer, def_id);
286+
});
276287

277-
mangle(buffer.names.into_iter(), Some(&hash[..]))
288+
mangle(buffer.names.into_iter(), Some(&hash[..]))
289+
}
278290
}
279291

280292
struct SymbolPathBuffer {

src/librustc_trans/base.rs

Lines changed: 18 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ pub use self::ValueOrigin::*;
3030
use super::CrateTranslation;
3131
use super::ModuleTranslation;
3232

33-
use back::{link, symbol_names};
33+
use back::link;
3434
use lint;
3535
use llvm::{BasicBlockRef, Linkage, ValueRef, Vector, get_param};
3636
use llvm;
@@ -2635,10 +2635,7 @@ fn iter_functions(llmod: llvm::ModuleRef) -> ValueIter {
26352635
/// This list is later used by linkers to determine the set of symbols needed to
26362636
/// be exposed from a dynamic library and it's also encoded into the metadata.
26372637
pub fn filter_reachable_ids(scx: &SharedCrateContext) -> NodeSet {
2638-
scx.reachable().iter().map(|x| *x).filter(|id| {
2639-
// First, only worry about nodes which have a symbol name
2640-
scx.item_symbols().borrow().contains_key(id)
2641-
}).filter(|&id| {
2638+
scx.reachable().iter().map(|x| *x).filter(|&id| {
26422639
// Next, we want to ignore some FFI functions that are not exposed from
26432640
// this crate. Reachable FFI functions can be lumped into two
26442641
// categories:
@@ -2656,7 +2653,18 @@ pub fn filter_reachable_ids(scx: &SharedCrateContext) -> NodeSet {
26562653
hir_map::NodeForeignItem(..) => {
26572654
scx.sess().cstore.is_statically_included_foreign_item(id)
26582655
}
2659-
_ => true,
2656+
2657+
// Only consider nodes that actually have exported symbols.
2658+
hir_map::NodeItem(&hir::Item {
2659+
node: hir::ItemStatic(..), .. }) |
2660+
hir_map::NodeItem(&hir::Item {
2661+
node: hir::ItemFn(..), .. }) |
2662+
hir_map::NodeTraitItem(&hir::TraitItem {
2663+
node: hir::MethodTraitItem(_, Some(_)), .. }) |
2664+
hir_map::NodeImplItem(&hir::ImplItem {
2665+
node: hir::ImplItemKind::Method(..), .. }) => true,
2666+
2667+
_ => false
26602668
}
26612669
}).collect()
26622670
}
@@ -2775,8 +2783,9 @@ pub fn trans_crate<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
27752783
.collect();
27762784

27772785
let sess = shared_ccx.sess();
2778-
let mut reachable_symbols = reachable_symbol_ids.iter().map(|id| {
2779-
shared_ccx.item_symbols().borrow()[id].to_string()
2786+
let mut reachable_symbols = reachable_symbol_ids.iter().map(|&id| {
2787+
let def_id = shared_ccx.tcx().map.local_def_id(id);
2788+
Instance::mono(&shared_ccx, def_id).symbol_name(&shared_ccx)
27802789
}).collect::<Vec<_>>();
27812790
if sess.entry_fn.borrow().is_some() {
27822791
reachable_symbols.push("main".to_string());
@@ -2799,8 +2808,7 @@ pub fn trans_crate<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
27992808
reachable_symbols.extend(syms.into_iter().filter(|did| {
28002809
sess.cstore.is_extern_item(shared_ccx.tcx(), *did)
28012810
}).map(|did| {
2802-
let instance = Instance::mono(shared_ccx.tcx(), did);
2803-
symbol_names::exported_name(&shared_ccx, instance)
2811+
Instance::mono(&shared_ccx, did).symbol_name(&shared_ccx)
28042812
}));
28052813
}
28062814

src/librustc_trans/callee.rs

Lines changed: 16 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -499,44 +499,20 @@ fn get_fn<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
499499
return immediate_rvalue(llfn, fn_ptr_ty);
500500
}
501501

502-
let attrs;
503502
let local_id = ccx.tcx().map.as_local_node_id(def_id);
504-
let maybe_node = local_id.and_then(|id| tcx.map.find(id));
505-
let (sym, attrs, local_item) = match maybe_node {
503+
let local_item = match local_id.and_then(|id| tcx.map.find(id)) {
506504
Some(hir_map::NodeItem(&hir::Item {
507-
ref attrs, id, span, node: hir::ItemFn(..), ..
505+
span, node: hir::ItemFn(..), ..
508506
})) |
509507
Some(hir_map::NodeTraitItem(&hir::TraitItem {
510-
ref attrs, id, span, node: hir::MethodTraitItem(_, Some(_)), ..
508+
span, node: hir::MethodTraitItem(_, Some(_)), ..
511509
})) |
512510
Some(hir_map::NodeImplItem(&hir::ImplItem {
513-
ref attrs, id, span, node: hir::ImplItemKind::Method(..), ..
511+
span, node: hir::ImplItemKind::Method(..), ..
514512
})) => {
515-
let sym = symbol_names::exported_name(ccx.shared(), instance);
516-
517-
if declare::get_defined_value(ccx, &sym).is_some() {
518-
ccx.sess().span_fatal(span,
519-
&format!("symbol `{}` is already defined", sym));
520-
}
521-
522-
(sym, &attrs[..], Some(id))
523-
}
524-
525-
Some(hir_map::NodeForeignItem(&hir::ForeignItem {
526-
ref attrs, name, node: hir::ForeignItemFn(..), ..
527-
})) => {
528-
(imported_name(name, attrs).to_string(), &attrs[..], None)
529-
}
530-
531-
None => {
532-
attrs = ccx.sess().cstore.item_attrs(def_id);
533-
let sym = symbol_names::exported_name(ccx.shared(), instance);
534-
(sym, &attrs[..], None)
535-
}
536-
537-
ref variant => {
538-
bug!("get_fn: unexpected variant: {:?}", variant)
513+
Some(span)
539514
}
515+
_ => None
540516
};
541517

542518
// This is subtle and surprising, but sometimes we have to bitcast
@@ -563,8 +539,16 @@ fn get_fn<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
563539
// reference. It also occurs when testing libcore and in some
564540
// other weird situations. Annoying.
565541

542+
let sym = instance.symbol_name(ccx.shared());
566543
let llptrty = type_of::type_of(ccx, fn_ptr_ty);
567544
let llfn = if let Some(llfn) = declare::get_declared_value(ccx, &sym) {
545+
if let Some(span) = local_item {
546+
if declare::get_defined_value(ccx, &sym).is_some() {
547+
ccx.sess().span_fatal(span,
548+
&format!("symbol `{}` is already defined", sym));
549+
}
550+
}
551+
568552
if common::val_ty(llfn) != llptrty {
569553
if local_item.is_some() {
570554
bug!("symbol `{}` previously declared as {:?}, now wanted as {:?}",
@@ -581,7 +565,8 @@ fn get_fn<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
581565
assert_eq!(common::val_ty(llfn), llptrty);
582566
debug!("get_fn: not casting pointer!");
583567

584-
attributes::from_fn_attrs(ccx, attrs, llfn);
568+
let attrs = ccx.tcx().get_attrs(def_id);
569+
attributes::from_fn_attrs(ccx, &attrs, llfn);
585570
if local_item.is_some() {
586571
// FIXME(eddyb) Doubt all extern fn should allow unwinding.
587572
attributes::unwind(llfn, true);

src/librustc_trans/closure.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -150,7 +150,7 @@ fn get_or_create_closure_declaration<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
150150
return llfn;
151151
}
152152

153-
let symbol = symbol_names::exported_name(ccx.shared(), instance);
153+
let symbol = instance.symbol_name(ccx.shared());
154154

155155
// Compute the rust-call form of the closure call method.
156156
let sig = &tcx.closure_type(closure_id, substs).sig;

0 commit comments

Comments
 (0)