Skip to content

Commit f7362ca

Browse files
committed
trans: move exported_symbol to Instance::symbol_name.
1 parent 073f289 commit f7362ca

File tree

12 files changed

+146
-127
lines changed

12 files changed

+146
-127
lines changed

src/librustc/middle/cstore.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -210,6 +210,7 @@ pub trait CrateStore<'tcx> : Any {
210210
fn is_impl(&self, did: DefId) -> bool;
211211
fn is_default_impl(&self, impl_did: DefId) -> bool;
212212
fn is_extern_item<'a>(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>, did: DefId) -> bool;
213+
fn is_foreign_item(&self, did: DefId) -> bool;
213214
fn is_static_method(&self, did: DefId) -> bool;
214215
fn is_statically_included_foreign_item(&self, id: ast::NodeId) -> bool;
215216
fn is_typedef(&self, did: DefId) -> bool;
@@ -394,6 +395,7 @@ impl<'tcx> CrateStore<'tcx> for DummyCrateStore {
394395
fn is_default_impl(&self, impl_did: DefId) -> bool { bug!("is_default_impl") }
395396
fn is_extern_item<'a>(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>, did: DefId) -> bool
396397
{ bug!("is_extern_item") }
398+
fn is_foreign_item(&self, did: DefId) -> bool { bug!("is_foreign_item") }
397399
fn is_static_method(&self, did: DefId) -> bool { bug!("is_static_method") }
398400
fn is_statically_included_foreign_item(&self, id: ast::NodeId) -> bool { false }
399401
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
@@ -252,6 +252,11 @@ impl<'tcx> CrateStore<'tcx> for cstore::CStore {
252252
decoder::is_extern_item(&cdata, did.index, tcx)
253253
}
254254

255+
fn is_foreign_item(&self, did: DefId) -> bool {
256+
let cdata = self.get_crate_data(did.krate);
257+
decoder::is_foreign_item(&cdata, did.index)
258+
}
259+
255260
fn is_static_method(&self, def: DefId) -> bool
256261
{
257262
let cdata = self.get_crate_data(def.krate);

src/librustc_metadata/decoder.rs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1603,6 +1603,16 @@ pub fn is_extern_item<'a, 'tcx>(cdata: Cmd,
16031603
}
16041604
}
16051605

1606+
pub fn is_foreign_item(cdata: Cmd, id: DefIndex) -> bool {
1607+
let item_doc = cdata.lookup_item(id);
1608+
let parent_item_id = match item_parent_item(cdata, item_doc) {
1609+
None => return false,
1610+
Some(item_id) => item_id,
1611+
};
1612+
let parent_item_doc = cdata.lookup_item(parent_item_id.index);
1613+
item_family(parent_item_doc) == ForeignMod
1614+
}
1615+
16061616
pub fn is_impl(cdata: Cmd, id: DefIndex) -> bool {
16071617
let item_doc = cdata.lookup_item(id);
16081618
match item_family(item_doc) {

src/librustc_metadata/encoder.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1344,6 +1344,8 @@ fn encode_info_for_foreign_item<'a, 'tcx>(ecx: &EncodeContext<'a, 'tcx>,
13441344
index.record(def_id, rbml_w);
13451345
rbml_w.start_tag(tag_items_data_item);
13461346
encode_def_id_and_key(ecx, rbml_w, def_id);
1347+
let parent_id = ecx.tcx.map.get_parent(nitem.id);
1348+
encode_parent_item(rbml_w, ecx.tcx.map.local_def_id(parent_id));
13471349
encode_visibility(rbml_w, &nitem.vis);
13481350
match nitem.node {
13491351
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};
@@ -188,89 +189,100 @@ fn get_symbol_hash<'a, 'tcx>(scx: &SharedCrateContext<'a, 'tcx>,
188189
}
189190
}
190191

191-
pub fn exported_name<'a, 'tcx>(scx: &SharedCrateContext<'a, 'tcx>,
192-
instance: Instance<'tcx>)
193-
-> String {
194-
let Instance { def: def_id, ref substs } = instance;
192+
impl<'a, 'tcx> Instance<'tcx> {
193+
pub fn symbol_name(self, scx: &SharedCrateContext<'a, 'tcx>) -> String {
194+
let Instance { def: def_id, ref substs } = self;
195195

196-
debug!("exported_name(def_id={:?}, substs={:?})",
197-
def_id, substs);
196+
debug!("symbol_name(def_id={:?}, substs={:?})",
197+
def_id, substs);
198198

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

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

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

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

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

259-
// Erase regions because they may not be deterministic when hashed
260-
// and should not matter anyhow.
261-
let instance_ty = scx.tcx().erase_regions(&instance_ty.ty);
270+
// Erase regions because they may not be deterministic when hashed
271+
// and should not matter anyhow.
272+
let instance_ty = scx.tcx().erase_regions(&instance_ty.ty);
262273

263-
let hash = get_symbol_hash(scx, &def_path, instance_ty, substs.types.as_slice());
274+
let hash = get_symbol_hash(scx, &def_path, instance_ty, substs.types.as_slice());
264275

265-
let mut buffer = SymbolPathBuffer {
266-
names: Vec::with_capacity(def_path.data.len())
267-
};
276+
let mut buffer = SymbolPathBuffer {
277+
names: Vec::with_capacity(def_path.data.len())
278+
};
268279

269-
item_path::with_forced_absolute_paths(|| {
270-
scx.tcx().push_item_path(&mut buffer, def_id);
271-
});
280+
item_path::with_forced_absolute_paths(|| {
281+
scx.tcx().push_item_path(&mut buffer, def_id);
282+
});
272283

273-
mangle(buffer.names.into_iter(), Some(&hash[..]))
284+
mangle(buffer.names.into_iter(), Some(&hash[..]))
285+
}
274286
}
275287

276288
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;
@@ -2629,10 +2629,7 @@ fn iter_functions(llmod: llvm::ModuleRef) -> ValueIter {
26292629
/// This list is later used by linkers to determine the set of symbols needed to
26302630
/// be exposed from a dynamic library and it's also encoded into the metadata.
26312631
pub fn filter_reachable_ids(scx: &SharedCrateContext) -> NodeSet {
2632-
scx.reachable().iter().map(|x| *x).filter(|id| {
2633-
// First, only worry about nodes which have a symbol name
2634-
scx.item_symbols().borrow().contains_key(id)
2635-
}).filter(|&id| {
2632+
scx.reachable().iter().map(|x| *x).filter(|&id| {
26362633
// Next, we want to ignore some FFI functions that are not exposed from
26372634
// this crate. Reachable FFI functions can be lumped into two
26382635
// categories:
@@ -2650,7 +2647,18 @@ pub fn filter_reachable_ids(scx: &SharedCrateContext) -> NodeSet {
26502647
hir_map::NodeForeignItem(..) => {
26512648
scx.sess().cstore.is_statically_included_foreign_item(id)
26522649
}
2653-
_ => true,
2650+
2651+
// Only consider nodes that actually have exported symbols.
2652+
hir_map::NodeItem(&hir::Item {
2653+
node: hir::ItemStatic(..), .. }) |
2654+
hir_map::NodeItem(&hir::Item {
2655+
node: hir::ItemFn(..), .. }) |
2656+
hir_map::NodeTraitItem(&hir::TraitItem {
2657+
node: hir::MethodTraitItem(_, Some(_)), .. }) |
2658+
hir_map::NodeImplItem(&hir::ImplItem {
2659+
node: hir::ImplItemKind::Method(..), .. }) => true,
2660+
2661+
_ => false
26542662
}
26552663
}).collect()
26562664
}
@@ -2769,8 +2777,9 @@ pub fn trans_crate<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
27692777
.collect();
27702778

27712779
let sess = shared_ccx.sess();
2772-
let mut reachable_symbols = reachable_symbol_ids.iter().map(|id| {
2773-
shared_ccx.item_symbols().borrow()[id].to_string()
2780+
let mut reachable_symbols = reachable_symbol_ids.iter().map(|&id| {
2781+
let def_id = shared_ccx.tcx().map.local_def_id(id);
2782+
Instance::mono(shared_ccx.tcx(), def_id).symbol_name(&shared_ccx)
27742783
}).collect::<Vec<_>>();
27752784
if sess.entry_fn.borrow().is_some() {
27762785
reachable_symbols.push("main".to_string());
@@ -2785,8 +2794,7 @@ pub fn trans_crate<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
27852794
reachable_symbols.extend(syms.into_iter().filter(|did| {
27862795
sess.cstore.is_extern_item(shared_ccx.tcx(), *did)
27872796
}).map(|did| {
2788-
let instance = Instance::mono(shared_ccx.tcx(), did);
2789-
symbol_names::exported_name(&shared_ccx, instance)
2797+
Instance::mono(shared_ccx.tcx(), did).symbol_name(&shared_ccx)
27902798
}));
27912799
}
27922800
}

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)