Auto merge of #33602 - eddyb:no-trans--check, r=michaelwoerister
Save metadata even with -Z no-trans (e.g. for multi-crate cargo check). Removes the item symbol map in metadata, as we can now generate them in a deterministic manner. The `-Z no-trans` change lets the LLVM passes and linking run, but with just metadata and no code. It fails while trying to link a binary because there's no `main` function, which is correct but not good UX. There's also no way to easily throw away all of the artifacts to rebuild with actual code generation. We might want `cargo check` to do that using cargo-internal information and then it would just work. cc @alexcrichton @nikomatsakis @Aatch @michaelwoerister
This commit is contained in:
commit
5229e0efb3
24 changed files with 377 additions and 356 deletions
|
|
@ -34,8 +34,7 @@ use mir::mir_map::MirMap;
|
|||
use session::Session;
|
||||
use session::config::PanicStrategy;
|
||||
use session::search_paths::PathKind;
|
||||
use util::nodemap::{FnvHashMap, NodeMap, NodeSet, DefIdMap};
|
||||
use std::cell::RefCell;
|
||||
use util::nodemap::{FnvHashMap, NodeSet, DefIdMap};
|
||||
use std::rc::Rc;
|
||||
use std::path::PathBuf;
|
||||
use syntax::ast;
|
||||
|
|
@ -169,7 +168,6 @@ pub trait CrateStore<'tcx> {
|
|||
fn item_super_predicates<'a>(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>, def: DefId)
|
||||
-> ty::GenericPredicates<'tcx>;
|
||||
fn item_attrs(&self, def_id: DefId) -> Vec<ast::Attribute>;
|
||||
fn item_symbol(&self, def: DefId) -> String;
|
||||
fn trait_def<'a>(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>, def: DefId)-> ty::TraitDef<'tcx>;
|
||||
fn adt_def<'a>(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>, def: DefId) -> ty::AdtDefMaster<'tcx>;
|
||||
fn method_arg_names(&self, did: DefId) -> Vec<String>;
|
||||
|
|
@ -205,6 +203,7 @@ pub trait CrateStore<'tcx> {
|
|||
fn is_impl(&self, did: DefId) -> bool;
|
||||
fn is_default_impl(&self, impl_did: DefId) -> bool;
|
||||
fn is_extern_item<'a>(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>, did: DefId) -> bool;
|
||||
fn is_foreign_item(&self, did: DefId) -> bool;
|
||||
fn is_static_method(&self, did: DefId) -> bool;
|
||||
fn is_statically_included_foreign_item(&self, id: ast::NodeId) -> bool;
|
||||
fn is_typedef(&self, did: DefId) -> bool;
|
||||
|
|
@ -274,7 +273,6 @@ pub trait CrateStore<'tcx> {
|
|||
fn extern_mod_stmt_cnum(&self, emod_id: ast::NodeId) -> Option<ast::CrateNum>;
|
||||
fn encode_metadata<'a>(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||
reexports: &def::ExportMap,
|
||||
item_symbols: &RefCell<NodeMap<String>>,
|
||||
link_meta: &LinkMeta,
|
||||
reachable: &NodeSet,
|
||||
mir_map: &MirMap<'tcx>,
|
||||
|
|
@ -352,7 +350,6 @@ impl<'tcx> CrateStore<'tcx> for DummyCrateStore {
|
|||
fn item_super_predicates<'a>(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>, def: DefId)
|
||||
-> ty::GenericPredicates<'tcx> { bug!("item_super_predicates") }
|
||||
fn item_attrs(&self, def_id: DefId) -> Vec<ast::Attribute> { bug!("item_attrs") }
|
||||
fn item_symbol(&self, def: DefId) -> String { bug!("item_symbol") }
|
||||
fn trait_def<'a>(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>, def: DefId)-> ty::TraitDef<'tcx>
|
||||
{ bug!("trait_def") }
|
||||
fn adt_def<'a>(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>, def: DefId) -> ty::AdtDefMaster<'tcx>
|
||||
|
|
@ -399,6 +396,7 @@ impl<'tcx> CrateStore<'tcx> for DummyCrateStore {
|
|||
fn is_default_impl(&self, impl_did: DefId) -> bool { bug!("is_default_impl") }
|
||||
fn is_extern_item<'a>(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>, did: DefId) -> bool
|
||||
{ bug!("is_extern_item") }
|
||||
fn is_foreign_item(&self, did: DefId) -> bool { bug!("is_foreign_item") }
|
||||
fn is_static_method(&self, did: DefId) -> bool { bug!("is_static_method") }
|
||||
fn is_statically_included_foreign_item(&self, id: ast::NodeId) -> bool { false }
|
||||
fn is_typedef(&self, did: DefId) -> bool { bug!("is_typedef") }
|
||||
|
|
@ -481,7 +479,6 @@ impl<'tcx> CrateStore<'tcx> for DummyCrateStore {
|
|||
fn extern_mod_stmt_cnum(&self, emod_id: ast::NodeId) -> Option<ast::CrateNum> { None }
|
||||
fn encode_metadata<'a>(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||
reexports: &def::ExportMap,
|
||||
item_symbols: &RefCell<NodeMap<String>>,
|
||||
link_meta: &LinkMeta,
|
||||
reachable: &NodeSet,
|
||||
mir_map: &MirMap<'tcx>,
|
||||
|
|
|
|||
|
|
@ -1104,7 +1104,7 @@ pub fn build_session_options(matches: &getopts::Matches) -> Options {
|
|||
let no_analysis = debugging_opts.no_analysis;
|
||||
|
||||
let mut output_types = HashMap::new();
|
||||
if !debugging_opts.parse_only && !no_trans {
|
||||
if !debugging_opts.parse_only {
|
||||
for list in matches.opt_strs("emit") {
|
||||
for output_type in list.split(',') {
|
||||
let mut parts = output_type.splitn(2, '=');
|
||||
|
|
|
|||
|
|
@ -9,6 +9,8 @@
|
|||
// except according to those terms.
|
||||
|
||||
use dep_graph::DepGraph;
|
||||
use hir::def_id::DefIndex;
|
||||
use hir::svh::Svh;
|
||||
use lint;
|
||||
use middle::cstore::CrateStore;
|
||||
use middle::dependency_format;
|
||||
|
|
@ -312,6 +314,14 @@ impl Session {
|
|||
pub fn nonzeroing_move_hints(&self) -> bool {
|
||||
self.opts.debugging_opts.enable_nonzeroing_move_hints
|
||||
}
|
||||
|
||||
/// Returns the symbol name for the registrar function,
|
||||
/// given the crate Svh and the function DefIndex.
|
||||
pub fn generate_plugin_registrar_symbol(&self, svh: &Svh, index: DefIndex)
|
||||
-> String {
|
||||
format!("__rustc_plugin_registrar__{}_{}", svh, index.as_usize())
|
||||
}
|
||||
|
||||
pub fn sysroot<'a>(&'a self) -> &'a Path {
|
||||
match self.opts.maybe_sysroot {
|
||||
Some (ref sysroot) => sysroot,
|
||||
|
|
|
|||
|
|
@ -14,12 +14,38 @@ use hir::def_id::{DefId, CRATE_DEF_INDEX};
|
|||
use ty::{self, Ty, TyCtxt};
|
||||
use syntax::ast;
|
||||
|
||||
use std::cell::Cell;
|
||||
|
||||
thread_local! {
|
||||
static FORCE_ABSOLUTE: Cell<bool> = Cell::new(false)
|
||||
}
|
||||
|
||||
/// Enforces that item_path_str always returns an absolute path.
|
||||
/// This is useful when building symbols that contain types,
|
||||
/// where we want the crate name to be part of the symbol.
|
||||
pub fn with_forced_absolute_paths<F: FnOnce() -> R, R>(f: F) -> R {
|
||||
FORCE_ABSOLUTE.with(|force| {
|
||||
let old = force.get();
|
||||
force.set(true);
|
||||
let result = f();
|
||||
force.set(old);
|
||||
result
|
||||
})
|
||||
}
|
||||
|
||||
impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
|
||||
/// Returns a string identifying this def-id. This string is
|
||||
/// suitable for user output. It is relative to the current crate
|
||||
/// root.
|
||||
/// root, unless with_forced_absolute_paths was used.
|
||||
pub fn item_path_str(self, def_id: DefId) -> String {
|
||||
let mut buffer = LocalPathBuffer::new(RootMode::Local);
|
||||
let mode = FORCE_ABSOLUTE.with(|force| {
|
||||
if force.get() {
|
||||
RootMode::Absolute
|
||||
} else {
|
||||
RootMode::Local
|
||||
}
|
||||
});
|
||||
let mut buffer = LocalPathBuffer::new(mode);
|
||||
self.push_item_path(&mut buffer, def_id);
|
||||
buffer.into_string()
|
||||
}
|
||||
|
|
@ -75,7 +101,11 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
|
|||
RootMode::Absolute => {
|
||||
// In absolute mode, just write the crate name
|
||||
// unconditionally.
|
||||
buffer.push(&self.crate_name(cnum));
|
||||
if cnum == LOCAL_CRATE {
|
||||
buffer.push(&self.crate_name(cnum));
|
||||
} else {
|
||||
buffer.push(&self.sess.cstore.original_crate_name(cnum));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -511,10 +511,6 @@ impl<'a> CompilerCalls<'a> for RustcDefaultCalls {
|
|||
control.after_write_deps.stop = Compilation::Stop;
|
||||
}
|
||||
|
||||
if sess.opts.no_trans {
|
||||
control.after_analysis.stop = Compilation::Stop;
|
||||
}
|
||||
|
||||
if !sess.opts.output_types.keys().any(|&i| i == OutputType::Exe) {
|
||||
control.after_llvm.stop = Compilation::Stop;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -33,7 +33,7 @@ pub const tag_items_data_item_family: usize = 0x24;
|
|||
|
||||
pub const tag_items_data_item_type: usize = 0x25;
|
||||
|
||||
pub const tag_items_data_item_symbol: usize = 0x26;
|
||||
// GAP 0x26
|
||||
|
||||
pub const tag_items_data_item_variant: usize = 0x27;
|
||||
|
||||
|
|
|
|||
|
|
@ -17,6 +17,7 @@ use cstore::{self, CStore, CrateSource, MetadataBlob};
|
|||
use decoder;
|
||||
use loader::{self, CratePaths};
|
||||
|
||||
use rustc::hir::def_id::DefIndex;
|
||||
use rustc::hir::svh::Svh;
|
||||
use rustc::dep_graph::{DepGraph, DepNode};
|
||||
use rustc::session::{config, Session};
|
||||
|
|
@ -610,9 +611,10 @@ impl<'a> CrateReader<'a> {
|
|||
macros
|
||||
}
|
||||
|
||||
/// Look for a plugin registrar. Returns library path and symbol name.
|
||||
/// Look for a plugin registrar. Returns library path, crate
|
||||
/// SVH and DefIndex of the registrar function.
|
||||
pub fn find_plugin_registrar(&mut self, span: Span, name: &str)
|
||||
-> Option<(PathBuf, String)> {
|
||||
-> Option<(PathBuf, Svh, DefIndex)> {
|
||||
let ekrate = self.read_extension_crate(span, &CrateInfo {
|
||||
name: name.to_string(),
|
||||
ident: name.to_string(),
|
||||
|
|
@ -630,12 +632,14 @@ impl<'a> CrateReader<'a> {
|
|||
span_fatal!(self.sess, span, E0456, "{}", &message[..]);
|
||||
}
|
||||
|
||||
let svh = decoder::get_crate_hash(ekrate.metadata.as_slice());
|
||||
let registrar =
|
||||
decoder::get_plugin_registrar_fn(ekrate.metadata.as_slice())
|
||||
.map(|id| decoder::get_symbol_from_buf(ekrate.metadata.as_slice(), id));
|
||||
decoder::get_plugin_registrar_fn(ekrate.metadata.as_slice());
|
||||
|
||||
match (ekrate.dylib.as_ref(), registrar) {
|
||||
(Some(dylib), Some(reg)) => Some((dylib.to_path_buf(), reg)),
|
||||
(Some(dylib), Some(reg)) => {
|
||||
Some((dylib.to_path_buf(), svh, reg))
|
||||
}
|
||||
(None, Some(_)) => {
|
||||
span_err!(self.sess, span, E0457,
|
||||
"plugin `{}` only found in rlib format, but must be available \
|
||||
|
|
|
|||
|
|
@ -25,7 +25,7 @@ use rustc::hir::map as hir_map;
|
|||
use rustc::hir::map::DefKey;
|
||||
use rustc::mir::repr::Mir;
|
||||
use rustc::mir::mir_map::MirMap;
|
||||
use rustc::util::nodemap::{FnvHashMap, NodeMap, NodeSet, DefIdMap};
|
||||
use rustc::util::nodemap::{FnvHashMap, NodeSet, DefIdMap};
|
||||
use rustc::session::config::PanicStrategy;
|
||||
|
||||
use std::cell::RefCell;
|
||||
|
|
@ -115,13 +115,6 @@ impl<'tcx> CrateStore<'tcx> for cstore::CStore {
|
|||
decoder::get_item_attrs(&cdata, def_id.index)
|
||||
}
|
||||
|
||||
fn item_symbol(&self, def: DefId) -> String
|
||||
{
|
||||
self.dep_graph.read(DepNode::MetaData(def));
|
||||
let cdata = self.get_crate_data(def.krate);
|
||||
decoder::get_symbol(&cdata, def.index)
|
||||
}
|
||||
|
||||
fn trait_def<'a>(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>, def: DefId) -> ty::TraitDef<'tcx>
|
||||
{
|
||||
self.dep_graph.read(DepNode::MetaData(def));
|
||||
|
|
@ -284,6 +277,11 @@ impl<'tcx> CrateStore<'tcx> for cstore::CStore {
|
|||
decoder::is_extern_item(&cdata, did.index, tcx)
|
||||
}
|
||||
|
||||
fn is_foreign_item(&self, did: DefId) -> bool {
|
||||
let cdata = self.get_crate_data(did.krate);
|
||||
decoder::is_foreign_item(&cdata, did.index)
|
||||
}
|
||||
|
||||
fn is_static_method(&self, def: DefId) -> bool
|
||||
{
|
||||
self.dep_graph.read(DepNode::MetaData(def));
|
||||
|
|
@ -564,7 +562,6 @@ impl<'tcx> CrateStore<'tcx> for cstore::CStore {
|
|||
|
||||
fn encode_metadata<'a>(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||
reexports: &def::ExportMap,
|
||||
item_symbols: &RefCell<NodeMap<String>>,
|
||||
link_meta: &LinkMeta,
|
||||
reachable: &NodeSet,
|
||||
mir_map: &MirMap<'tcx>,
|
||||
|
|
@ -574,7 +571,6 @@ impl<'tcx> CrateStore<'tcx> for cstore::CStore {
|
|||
diag: tcx.sess.diagnostic(),
|
||||
tcx: tcx,
|
||||
reexports: reexports,
|
||||
item_symbols: item_symbols,
|
||||
link_meta: link_meta,
|
||||
cstore: self,
|
||||
reachable: reachable,
|
||||
|
|
|
|||
|
|
@ -213,10 +213,6 @@ fn item_sort(item: rbml::Doc) -> Option<char> {
|
|||
})
|
||||
}
|
||||
|
||||
fn item_symbol(item: rbml::Doc) -> String {
|
||||
reader::get_doc(item, tag_items_data_item_symbol).as_str().to_string()
|
||||
}
|
||||
|
||||
fn untranslated_def_id(d: rbml::Doc) -> DefId {
|
||||
let id = reader::doc_as_u64(d);
|
||||
let index = DefIndex::new((id & 0xFFFF_FFFF) as usize);
|
||||
|
|
@ -640,18 +636,6 @@ pub fn get_impl_trait<'a, 'tcx>(cdata: Cmd,
|
|||
}
|
||||
}
|
||||
|
||||
pub fn get_symbol(cdata: Cmd, id: DefIndex) -> String {
|
||||
return item_symbol(cdata.lookup_item(id));
|
||||
}
|
||||
|
||||
/// If you have a crate_metadata, call get_symbol instead
|
||||
pub fn get_symbol_from_buf(data: &[u8], id: DefIndex) -> String {
|
||||
let index = load_index(data);
|
||||
let pos = index.lookup_item(data, id).unwrap();
|
||||
let doc = reader::doc_at(data, pos as usize).unwrap().doc;
|
||||
item_symbol(doc)
|
||||
}
|
||||
|
||||
/// Iterates over the language items in the given crate.
|
||||
pub fn each_lang_item<F>(cdata: Cmd, mut f: F) -> bool where
|
||||
F: FnMut(DefIndex, usize) -> bool,
|
||||
|
|
@ -1642,6 +1626,16 @@ pub fn is_extern_item<'a, 'tcx>(cdata: Cmd,
|
|||
}
|
||||
}
|
||||
|
||||
pub fn is_foreign_item(cdata: Cmd, id: DefIndex) -> bool {
|
||||
let item_doc = cdata.lookup_item(id);
|
||||
let parent_item_id = match item_parent_item(cdata, item_doc) {
|
||||
None => return false,
|
||||
Some(item_id) => item_id,
|
||||
};
|
||||
let parent_item_doc = cdata.lookup_item(parent_item_id.index);
|
||||
item_family(parent_item_doc) == ForeignMod
|
||||
}
|
||||
|
||||
pub fn is_impl(cdata: Cmd, id: DefIndex) -> bool {
|
||||
let item_doc = cdata.lookup_item(id);
|
||||
match item_family(item_doc) {
|
||||
|
|
|
|||
|
|
@ -34,7 +34,7 @@ use rustc::ty::util::IntTypeExt;
|
|||
use rustc::hir::svh::Svh;
|
||||
use rustc::mir::mir_map::MirMap;
|
||||
use rustc::session::config::{self, PanicStrategy};
|
||||
use rustc::util::nodemap::{FnvHashMap, NodeMap, NodeSet};
|
||||
use rustc::util::nodemap::{FnvHashMap, NodeSet};
|
||||
|
||||
use rustc_serialize::Encodable;
|
||||
use std::cell::RefCell;
|
||||
|
|
@ -59,7 +59,6 @@ pub struct EncodeContext<'a, 'tcx: 'a> {
|
|||
pub diag: &'a Handler,
|
||||
pub tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||
pub reexports: &'a def::ExportMap,
|
||||
pub item_symbols: &'a RefCell<NodeMap<String>>,
|
||||
pub link_meta: &'a LinkMeta,
|
||||
pub cstore: &'a cstore::CStore,
|
||||
pub type_abbrevs: tyencode::abbrev_map<'tcx>,
|
||||
|
|
@ -213,20 +212,6 @@ fn encode_region(ecx: &EncodeContext,
|
|||
rbml_w.end_tag();
|
||||
}
|
||||
|
||||
fn encode_symbol(ecx: &EncodeContext,
|
||||
rbml_w: &mut Encoder,
|
||||
id: NodeId) {
|
||||
match ecx.item_symbols.borrow().get(&id) {
|
||||
Some(x) => {
|
||||
debug!("encode_symbol(id={}, str={})", id, *x);
|
||||
rbml_w.wr_tagged_str(tag_items_data_item_symbol, x);
|
||||
}
|
||||
None => {
|
||||
bug!("encode_symbol: id not found {}", id);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn encode_disr_val(_: &EncodeContext,
|
||||
rbml_w: &mut Encoder,
|
||||
disr_val: ty::Disr) {
|
||||
|
|
@ -518,10 +503,6 @@ fn encode_info_for_struct_ctor<'a, 'tcx>(ecx: &EncodeContext<'a, 'tcx>,
|
|||
encode_name(rbml_w, name);
|
||||
encode_parent_item(rbml_w, ecx.tcx.map.local_def_id(struct_id));
|
||||
|
||||
if ecx.item_symbols.borrow().contains_key(&ctor_id) {
|
||||
encode_symbol(ecx, rbml_w, ctor_id);
|
||||
}
|
||||
|
||||
let stab = ecx.tcx.lookup_stability(ecx.tcx.map.local_def_id(ctor_id));
|
||||
let depr= ecx.tcx.lookup_deprecation(ecx.tcx.map.local_def_id(ctor_id));
|
||||
encode_stability(rbml_w, stab);
|
||||
|
|
@ -710,10 +691,6 @@ fn encode_info_for_method<'a, 'tcx>(ecx: &EncodeContext<'a, 'tcx>,
|
|||
}
|
||||
encode_constness(rbml_w, sig.constness);
|
||||
encode_defaultness(rbml_w, impl_item.defaultness);
|
||||
if !any_types {
|
||||
let m_id = ecx.local_id(m.def_id);
|
||||
encode_symbol(ecx, rbml_w, m_id);
|
||||
}
|
||||
encode_method_argument_names(rbml_w, &sig.decl);
|
||||
}
|
||||
}
|
||||
|
|
@ -894,7 +871,6 @@ fn encode_info_for_item<'a, 'tcx>(ecx: &EncodeContext<'a, 'tcx>,
|
|||
encode_family(rbml_w, 'c');
|
||||
}
|
||||
encode_bounds_and_type_for_item(rbml_w, ecx, index, item.id);
|
||||
encode_symbol(ecx, rbml_w, item.id);
|
||||
encode_name(rbml_w, item.name);
|
||||
encode_visibility(rbml_w, vis);
|
||||
encode_stability(rbml_w, stab);
|
||||
|
|
@ -931,9 +907,6 @@ fn encode_info_for_item<'a, 'tcx>(ecx: &EncodeContext<'a, 'tcx>,
|
|||
encode_inlined_item(ecx, rbml_w, InlinedItemRef::Item(item));
|
||||
encode_mir(ecx, rbml_w, item.id);
|
||||
}
|
||||
if tps_len == 0 {
|
||||
encode_symbol(ecx, rbml_w, item.id);
|
||||
}
|
||||
encode_constness(rbml_w, constness);
|
||||
encode_visibility(rbml_w, vis);
|
||||
encode_stability(rbml_w, stab);
|
||||
|
|
@ -1354,6 +1327,8 @@ fn encode_info_for_foreign_item<'a, 'tcx>(ecx: &EncodeContext<'a, 'tcx>,
|
|||
let _task = index.record(def_id, rbml_w);
|
||||
rbml_w.start_tag(tag_items_data_item);
|
||||
encode_def_id_and_key(ecx, rbml_w, def_id);
|
||||
let parent_id = ecx.tcx.map.get_parent(nitem.id);
|
||||
encode_parent_item(rbml_w, ecx.tcx.map.local_def_id(parent_id));
|
||||
encode_visibility(rbml_w, &nitem.vis);
|
||||
match nitem.node {
|
||||
hir::ForeignItemFn(ref fndecl, _) => {
|
||||
|
|
@ -1363,8 +1338,6 @@ fn encode_info_for_foreign_item<'a, 'tcx>(ecx: &EncodeContext<'a, 'tcx>,
|
|||
if abi == Abi::RustIntrinsic || abi == Abi::PlatformIntrinsic {
|
||||
encode_inlined_item(ecx, rbml_w, InlinedItemRef::Foreign(nitem));
|
||||
encode_mir(ecx, rbml_w, nitem.id);
|
||||
} else {
|
||||
encode_symbol(ecx, rbml_w, nitem.id);
|
||||
}
|
||||
encode_attributes(rbml_w, &nitem.attrs);
|
||||
let stab = ecx.tcx.lookup_stability(ecx.tcx.map.local_def_id(nitem.id));
|
||||
|
|
@ -1385,7 +1358,6 @@ fn encode_info_for_foreign_item<'a, 'tcx>(ecx: &EncodeContext<'a, 'tcx>,
|
|||
let depr = ecx.tcx.lookup_deprecation(ecx.tcx.map.local_def_id(nitem.id));
|
||||
encode_stability(rbml_w, stab);
|
||||
encode_deprecation(rbml_w, depr);
|
||||
encode_symbol(ecx, rbml_w, nitem.id);
|
||||
encode_name(rbml_w, nitem.name);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -101,7 +101,8 @@ impl<'a> PluginLoader<'a> {
|
|||
fn load_plugin(&mut self, span: Span, name: &str, args: Vec<P<ast::MetaItem>>) {
|
||||
let registrar = self.reader.find_plugin_registrar(span, name);
|
||||
|
||||
if let Some((lib, symbol)) = registrar {
|
||||
if let Some((lib, svh, index)) = registrar {
|
||||
let symbol = self.sess.generate_plugin_registrar_symbol(&svh, index);
|
||||
let fun = self.dylink_registrar(span, lib, symbol);
|
||||
self.plugins.push(PluginRegistrar {
|
||||
fun: fun,
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@
|
|||
// except according to those terms.
|
||||
|
||||
use super::archive::{ArchiveBuilder, ArchiveConfig};
|
||||
use super::linker::{Linker, GnuLinker, MsvcLinker};
|
||||
use super::linker::Linker;
|
||||
use super::rpath::RPathConfig;
|
||||
use super::rpath;
|
||||
use super::msvc;
|
||||
|
|
@ -188,6 +188,11 @@ pub fn link_binary(sess: &Session,
|
|||
|
||||
let mut out_filenames = Vec::new();
|
||||
for &crate_type in sess.crate_types.borrow().iter() {
|
||||
// Ignore executable crates if we have -Z no-trans, as they will error.
|
||||
if sess.opts.no_trans && crate_type == config::CrateTypeExecutable {
|
||||
continue;
|
||||
}
|
||||
|
||||
if invalid_output_for_target(sess, crate_type) {
|
||||
bug!("invalid output type `{:?}` for target os `{}`",
|
||||
crate_type, sess.opts.target_triple);
|
||||
|
|
@ -637,13 +642,9 @@ fn link_natively(sess: &Session,
|
|||
}
|
||||
|
||||
{
|
||||
let mut linker = if sess.target.target.options.is_like_msvc {
|
||||
Box::new(MsvcLinker { cmd: &mut cmd, sess: &sess }) as Box<Linker>
|
||||
} else {
|
||||
Box::new(GnuLinker { cmd: &mut cmd, sess: &sess }) as Box<Linker>
|
||||
};
|
||||
let mut linker = trans.linker_info.to_linker(&mut cmd, &sess);
|
||||
link_args(&mut *linker, sess, crate_type, tmpdir,
|
||||
objects, out_filename, trans, outputs);
|
||||
objects, out_filename, outputs);
|
||||
if !sess.target.target.options.no_compiler_rt {
|
||||
linker.link_staticlib("compiler-rt");
|
||||
}
|
||||
|
|
@ -712,7 +713,6 @@ fn link_args(cmd: &mut Linker,
|
|||
tmpdir: &Path,
|
||||
objects: &[PathBuf],
|
||||
out_filename: &Path,
|
||||
trans: &CrateTranslation,
|
||||
outputs: &OutputFilenames) {
|
||||
|
||||
// The default library location, we need this to find the runtime.
|
||||
|
|
@ -731,7 +731,7 @@ fn link_args(cmd: &mut Linker,
|
|||
// If we're building a dynamic library then some platforms need to make sure
|
||||
// that all symbols are exported correctly from the dynamic library.
|
||||
if crate_type != config::CrateTypeExecutable {
|
||||
cmd.export_symbols(sess, trans, tmpdir, crate_type);
|
||||
cmd.export_symbols(tmpdir, crate_type);
|
||||
}
|
||||
|
||||
// When linking a dynamic library, we put the metadata into a section of the
|
||||
|
|
|
|||
|
|
@ -15,13 +15,50 @@ use std::io::prelude::*;
|
|||
use std::path::{Path, PathBuf};
|
||||
use std::process::Command;
|
||||
|
||||
use context::SharedCrateContext;
|
||||
use monomorphize::Instance;
|
||||
|
||||
use back::archive;
|
||||
use middle::dependency_format::Linkage;
|
||||
use session::Session;
|
||||
use session::config::CrateType;
|
||||
use session::config;
|
||||
use syntax::ast;
|
||||
use CrateTranslation;
|
||||
|
||||
/// For all the linkers we support, and information they might
|
||||
/// need out of the shared crate context before we get rid of it.
|
||||
pub struct LinkerInfo {
|
||||
dylib_exports: Vec<String>,
|
||||
cdylib_exports: Vec<String>
|
||||
}
|
||||
|
||||
impl<'a, 'tcx> LinkerInfo {
|
||||
pub fn new(scx: &SharedCrateContext<'a, 'tcx>,
|
||||
reachable: &[String]) -> LinkerInfo {
|
||||
LinkerInfo {
|
||||
dylib_exports: exported_symbols(scx, reachable, CrateType::CrateTypeDylib),
|
||||
cdylib_exports: exported_symbols(scx, reachable, CrateType::CrateTypeCdylib)
|
||||
}
|
||||
}
|
||||
|
||||
pub fn to_linker(&'a self,
|
||||
cmd: &'a mut Command,
|
||||
sess: &'a Session) -> Box<Linker+'a> {
|
||||
if sess.target.target.options.is_like_msvc {
|
||||
Box::new(MsvcLinker {
|
||||
cmd: cmd,
|
||||
sess: sess,
|
||||
info: self
|
||||
}) as Box<Linker>
|
||||
} else {
|
||||
Box::new(GnuLinker {
|
||||
cmd: cmd,
|
||||
sess: sess,
|
||||
info: self
|
||||
}) as Box<Linker>
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Linker abstraction used by back::link to build up the command to invoke a
|
||||
/// linker.
|
||||
|
|
@ -53,16 +90,13 @@ pub trait Linker {
|
|||
fn hint_dynamic(&mut self);
|
||||
fn whole_archives(&mut self);
|
||||
fn no_whole_archives(&mut self);
|
||||
fn export_symbols(&mut self,
|
||||
sess: &Session,
|
||||
trans: &CrateTranslation,
|
||||
tmpdir: &Path,
|
||||
crate_type: CrateType);
|
||||
fn export_symbols(&mut self, tmpdir: &Path, crate_type: CrateType);
|
||||
}
|
||||
|
||||
pub struct GnuLinker<'a> {
|
||||
pub cmd: &'a mut Command,
|
||||
pub sess: &'a Session,
|
||||
cmd: &'a mut Command,
|
||||
sess: &'a Session,
|
||||
info: &'a LinkerInfo
|
||||
}
|
||||
|
||||
impl<'a> GnuLinker<'a> {
|
||||
|
|
@ -201,11 +235,7 @@ impl<'a> Linker for GnuLinker<'a> {
|
|||
self.cmd.arg("-Wl,-Bdynamic");
|
||||
}
|
||||
|
||||
fn export_symbols(&mut self,
|
||||
sess: &Session,
|
||||
trans: &CrateTranslation,
|
||||
tmpdir: &Path,
|
||||
crate_type: CrateType) {
|
||||
fn export_symbols(&mut self, tmpdir: &Path, crate_type: CrateType) {
|
||||
// If we're compiling a dylib, then we let symbol visibility in object
|
||||
// files to take care of whether they're exported or not.
|
||||
//
|
||||
|
|
@ -225,13 +255,13 @@ impl<'a> Linker for GnuLinker<'a> {
|
|||
};
|
||||
let res = (|| -> io::Result<()> {
|
||||
let mut f = BufWriter::new(File::create(&path)?);
|
||||
for sym in exported_symbols(sess, trans, crate_type) {
|
||||
for sym in &self.info.cdylib_exports {
|
||||
writeln!(f, "{}{}", prefix, sym)?;
|
||||
}
|
||||
Ok(())
|
||||
})();
|
||||
if let Err(e) = res {
|
||||
sess.fatal(&format!("failed to write lib.def file: {}", e));
|
||||
self.sess.fatal(&format!("failed to write lib.def file: {}", e));
|
||||
}
|
||||
let mut arg = OsString::new();
|
||||
if self.sess.target.target.options.is_like_osx {
|
||||
|
|
@ -245,8 +275,9 @@ impl<'a> Linker for GnuLinker<'a> {
|
|||
}
|
||||
|
||||
pub struct MsvcLinker<'a> {
|
||||
pub cmd: &'a mut Command,
|
||||
pub sess: &'a Session,
|
||||
cmd: &'a mut Command,
|
||||
sess: &'a Session,
|
||||
info: &'a LinkerInfo
|
||||
}
|
||||
|
||||
impl<'a> Linker for MsvcLinker<'a> {
|
||||
|
|
@ -366,8 +397,6 @@ impl<'a> Linker for MsvcLinker<'a> {
|
|||
// in which case they may continue to transitively be used and hence need
|
||||
// their symbols exported.
|
||||
fn export_symbols(&mut self,
|
||||
sess: &Session,
|
||||
trans: &CrateTranslation,
|
||||
tmpdir: &Path,
|
||||
crate_type: CrateType) {
|
||||
let path = tmpdir.join("lib.def");
|
||||
|
|
@ -378,15 +407,18 @@ impl<'a> Linker for MsvcLinker<'a> {
|
|||
// straight to exports.
|
||||
writeln!(f, "LIBRARY")?;
|
||||
writeln!(f, "EXPORTS")?;
|
||||
|
||||
for sym in exported_symbols(sess, trans, crate_type) {
|
||||
writeln!(f, " {}", sym)?;
|
||||
let symbols = if crate_type == CrateType::CrateTypeCdylib {
|
||||
&self.info.cdylib_exports
|
||||
} else {
|
||||
&self.info.dylib_exports
|
||||
};
|
||||
for symbol in symbols {
|
||||
writeln!(f, " {}", symbol)?;
|
||||
}
|
||||
|
||||
Ok(())
|
||||
})();
|
||||
if let Err(e) = res {
|
||||
sess.fatal(&format!("failed to write lib.def file: {}", e));
|
||||
self.sess.fatal(&format!("failed to write lib.def file: {}", e));
|
||||
}
|
||||
let mut arg = OsString::from("/DEF:");
|
||||
arg.push(path);
|
||||
|
|
@ -394,10 +426,23 @@ impl<'a> Linker for MsvcLinker<'a> {
|
|||
}
|
||||
}
|
||||
|
||||
fn exported_symbols(sess: &Session,
|
||||
trans: &CrateTranslation,
|
||||
crate_type: CrateType) -> Vec<String> {
|
||||
let mut symbols = trans.reachable.iter().cloned().collect::<Vec<_>>();
|
||||
fn exported_symbols(scx: &SharedCrateContext,
|
||||
reachable: &[String],
|
||||
crate_type: CrateType)
|
||||
-> Vec<String> {
|
||||
if !scx.sess().crate_types.borrow().contains(&crate_type) {
|
||||
return vec![];
|
||||
}
|
||||
|
||||
// See explanation in GnuLinker::export_symbols, for
|
||||
// why we don't ever need dylib symbols on non-MSVC.
|
||||
if crate_type == CrateType::CrateTypeDylib {
|
||||
if !scx.sess().target.target.options.is_like_msvc {
|
||||
return vec![];
|
||||
}
|
||||
}
|
||||
|
||||
let mut symbols = reachable.to_vec();
|
||||
|
||||
// If we're producing anything other than a dylib then the `reachable` array
|
||||
// above is the exhaustive set of symbols we should be exporting.
|
||||
|
|
@ -409,10 +454,10 @@ fn exported_symbols(sess: &Session,
|
|||
return symbols
|
||||
}
|
||||
|
||||
let cstore = &sess.cstore;
|
||||
let formats = sess.dependency_formats.borrow();
|
||||
let upstream_symbols = formats[&crate_type].iter();
|
||||
symbols.extend(upstream_symbols.enumerate().filter_map(|(i, f)| {
|
||||
let cstore = &scx.sess().cstore;
|
||||
let formats = scx.sess().dependency_formats.borrow();
|
||||
let deps = formats[&crate_type].iter();
|
||||
symbols.extend(deps.enumerate().filter_map(|(i, f)| {
|
||||
if *f == Linkage::Static {
|
||||
Some((i + 1) as ast::CrateNum)
|
||||
} else {
|
||||
|
|
@ -420,9 +465,8 @@ fn exported_symbols(sess: &Session,
|
|||
}
|
||||
}).flat_map(|cnum| {
|
||||
cstore.reachable_ids(cnum)
|
||||
}).map(|did| {
|
||||
cstore.item_symbol(did)
|
||||
}).map(|did| -> String {
|
||||
Instance::mono(scx, did).symbol_name(scx)
|
||||
}));
|
||||
|
||||
return symbols
|
||||
symbols
|
||||
}
|
||||
|
|
|
|||
|
|
@ -97,17 +97,19 @@
|
|||
//! 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::hir::map as hir_map;
|
||||
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;
|
||||
|
||||
|
|
@ -116,10 +118,14 @@ pub fn def_id_to_string<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId) ->
|
|||
def_path_to_string(tcx, &def_path)
|
||||
}
|
||||
|
||||
pub fn def_path_to_string<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_path: &DefPath) -> String {
|
||||
fn def_path_to_string<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_path: &DefPath) -> String {
|
||||
let mut s = String::with_capacity(def_path.data.len() * 16);
|
||||
|
||||
s.push_str(&tcx.crate_name(def_path.krate));
|
||||
if def_path.krate == cstore::LOCAL_CRATE {
|
||||
s.push_str(&tcx.crate_name(def_path.krate));
|
||||
} else {
|
||||
s.push_str(&tcx.sess.cstore.original_crate_name(def_path.krate));
|
||||
}
|
||||
s.push_str("/");
|
||||
s.push_str(&tcx.crate_disambiguator(def_path.krate));
|
||||
|
||||
|
|
@ -134,7 +140,7 @@ pub fn def_path_to_string<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_path: &DefP
|
|||
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 +158,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,66 +193,100 @@ fn get_symbol_hash<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
|
|||
}
|
||||
}
|
||||
|
||||
fn exported_name_with_opt_suffix<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
|
||||
instance: &Instance<'tcx>,
|
||||
suffix: Option<&str>)
|
||||
-> String {
|
||||
let &Instance { def: mut def_id, ref substs } = instance;
|
||||
impl<'a, 'tcx> Instance<'tcx> {
|
||||
pub fn symbol_name(self, scx: &SharedCrateContext<'a, 'tcx>) -> String {
|
||||
let Instance { def: def_id, ref substs } = self;
|
||||
|
||||
debug!("exported_name_with_opt_suffix(def_id={:?}, substs={:?}, suffix={:?})",
|
||||
def_id, substs, suffix);
|
||||
debug!("symbol_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(def_id);
|
||||
|
||||
let def_path = ccx.tcx().def_path(def_id);
|
||||
assert_eq!(def_path.krate, def_id.krate);
|
||||
|
||||
// We want to compute the "type" of this item. Unfortunately, some
|
||||
// kinds of items (e.g., closures) don't have an entry in the
|
||||
// item-type array. So walk back up the find the closest parent
|
||||
// that DOES have an entry.
|
||||
let mut ty_def_id = def_id;
|
||||
let instance_ty;
|
||||
loop {
|
||||
let key = ccx.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);
|
||||
break;
|
||||
}
|
||||
_ => {
|
||||
// if we're making a symbol for something, there ought
|
||||
// to be a value or type-def or something in there
|
||||
// *somewhere*
|
||||
ty_def_id.index = key.parent.unwrap_or_else(|| {
|
||||
bug!("finding type for {:?}, encountered def-id {:?} with no \
|
||||
parent", def_id, ty_def_id);
|
||||
});
|
||||
if let Some(id) = node_id {
|
||||
if scx.sess().plugin_registrar_fn.get() == Some(id) {
|
||||
let svh = &scx.link_meta().crate_hash;
|
||||
let idx = def_id.index;
|
||||
return scx.sess().generate_plugin_registrar_symbol(svh, idx);
|
||||
}
|
||||
}
|
||||
|
||||
// FIXME(eddyb) Precompute a custom symbol name based on attributes.
|
||||
let attrs = scx.tcx().get_attrs(def_id);
|
||||
let is_foreign = if let Some(id) = node_id {
|
||||
match scx.tcx().map.get(id) {
|
||||
hir_map::NodeForeignItem(_) => true,
|
||||
_ => false
|
||||
}
|
||||
} else {
|
||||
scx.sess().cstore.is_foreign_item(def_id)
|
||||
};
|
||||
|
||||
if let Some(name) = weak_lang_items::link_name(&attrs) {
|
||||
return name.to_string();
|
||||
}
|
||||
|
||||
if is_foreign {
|
||||
if let Some(name) = attr::first_attr_value_str_by_name(&attrs, "link_name") {
|
||||
return name.to_string();
|
||||
}
|
||||
// Don't mangle foreign items.
|
||||
return scx.tcx().item_name(def_id).as_str().to_string();
|
||||
}
|
||||
|
||||
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(def_id).as_str().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
|
||||
// item-type array. So walk back up the find the closest parent
|
||||
// that DOES have an entry.
|
||||
let mut ty_def_id = def_id;
|
||||
let instance_ty;
|
||||
loop {
|
||||
let key = scx.tcx().def_key(ty_def_id);
|
||||
match key.disambiguated_data.data {
|
||||
DefPathData::TypeNs(_) |
|
||||
DefPathData::ValueNs(_) => {
|
||||
instance_ty = scx.tcx().lookup_item_type(ty_def_id);
|
||||
break;
|
||||
}
|
||||
_ => {
|
||||
// if we're making a symbol for something, there ought
|
||||
// to be a value or type-def or something in there
|
||||
// *somewhere*
|
||||
ty_def_id.index = key.parent.unwrap_or_else(|| {
|
||||
bug!("finding type for {:?}, encountered def-id {:?} with no \
|
||||
parent", def_id, ty_def_id);
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Erase regions because they may not be deterministic when hashed
|
||||
// and should not matter anyhow.
|
||||
let instance_ty = scx.tcx().erase_regions(&instance_ty.ty);
|
||||
|
||||
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())
|
||||
};
|
||||
|
||||
item_path::with_forced_absolute_paths(|| {
|
||||
scx.tcx().push_item_path(&mut buffer, def_id);
|
||||
});
|
||||
|
||||
mangle(buffer.names.into_iter(), Some(&hash[..]))
|
||||
}
|
||||
|
||||
// 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 hash = get_symbol_hash(ccx, &def_path, instance_ty, substs.types.as_slice());
|
||||
|
||||
let mut buffer = SymbolPathBuffer {
|
||||
names: Vec::with_capacity(def_path.data.len())
|
||||
};
|
||||
ccx.tcx().push_item_path(&mut buffer, def_id);
|
||||
|
||||
if let Some(suffix) = suffix {
|
||||
buffer.push(suffix);
|
||||
}
|
||||
|
||||
mangle(buffer.names.into_iter(), Some(&hash[..]))
|
||||
}
|
||||
|
||||
struct SymbolPathBuffer {
|
||||
|
|
@ -264,19 +304,6 @@ impl ItemPathBuffer for SymbolPathBuffer {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn exported_name<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
|
||||
instance: &Instance<'tcx>)
|
||||
-> String {
|
||||
exported_name_with_opt_suffix(ccx, instance, None)
|
||||
}
|
||||
|
||||
pub fn exported_name_with_suffix<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
|
||||
instance: &Instance<'tcx>,
|
||||
suffix: &str)
|
||||
-> String {
|
||||
exported_name_with_opt_suffix(ccx, instance, Some(suffix))
|
||||
}
|
||||
|
||||
/// Only symbols that are invisible outside their compilation unit should use a
|
||||
/// name generated by this function.
|
||||
pub fn internal_name_from_type_and_suffix<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
|
||||
|
|
@ -289,7 +316,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[..]))
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -30,14 +30,14 @@ pub use self::ValueOrigin::*;
|
|||
use super::CrateTranslation;
|
||||
use super::ModuleTranslation;
|
||||
|
||||
use back::{link, symbol_names};
|
||||
use back::link;
|
||||
use back::linker::LinkerInfo;
|
||||
use lint;
|
||||
use llvm::{BasicBlockRef, Linkage, ValueRef, Vector, get_param};
|
||||
use llvm;
|
||||
use rustc::cfg;
|
||||
use rustc::hir::def_id::DefId;
|
||||
use middle::lang_items::{LangItem, ExchangeMallocFnLangItem, StartFnLangItem};
|
||||
use middle::weak_lang_items;
|
||||
use rustc::hir::pat_util::simple_name;
|
||||
use rustc::ty::subst::{self, Substs};
|
||||
use rustc::traits;
|
||||
|
|
@ -2344,15 +2344,6 @@ pub fn trans_item(ccx: &CrateContext, item: &hir::Item) {
|
|||
set_global_section(ccx, g, item);
|
||||
update_linkage(ccx, g, Some(item.id), OriginalTranslation);
|
||||
}
|
||||
hir::ItemForeignMod(ref m) => {
|
||||
if m.abi == Abi::RustIntrinsic || m.abi == Abi::PlatformIntrinsic {
|
||||
return;
|
||||
}
|
||||
for fi in &m.items {
|
||||
let lname = imported_name(fi.name, &fi.attrs).to_string();
|
||||
ccx.item_symbols().borrow_mut().insert(fi.id, lname);
|
||||
}
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
|
|
@ -2437,60 +2428,12 @@ 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();
|
||||
|
||||
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(),
|
||||
None => match weak_lang_items::link_name(attrs) {
|
||||
Some(name) => name,
|
||||
None => name.as_str(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn contains_null(s: &str) -> bool {
|
||||
s.bytes().any(|b| b == 0)
|
||||
}
|
||||
|
||||
pub fn write_metadata<'a, 'tcx>(cx: &SharedCrateContext<'a, 'tcx>,
|
||||
krate: &hir::Crate,
|
||||
reachable: &NodeSet,
|
||||
mir_map: &MirMap<'tcx>)
|
||||
-> Vec<u8> {
|
||||
fn write_metadata(cx: &SharedCrateContext,
|
||||
reachable_ids: &NodeSet) -> Vec<u8> {
|
||||
use flate;
|
||||
|
||||
let any_library = cx.sess()
|
||||
|
|
@ -2505,11 +2448,10 @@ pub fn write_metadata<'a, 'tcx>(cx: &SharedCrateContext<'a, 'tcx>,
|
|||
let cstore = &cx.tcx().sess.cstore;
|
||||
let metadata = cstore.encode_metadata(cx.tcx(),
|
||||
cx.export_map(),
|
||||
cx.item_symbols(),
|
||||
cx.link_meta(),
|
||||
reachable,
|
||||
mir_map,
|
||||
krate);
|
||||
reachable_ids,
|
||||
cx.mir_map(),
|
||||
cx.tcx().map.krate());
|
||||
let mut compressed = cstore.metadata_encoding_version().to_vec();
|
||||
compressed.extend_from_slice(&flate::deflate_bytes(&metadata));
|
||||
|
||||
|
|
@ -2670,10 +2612,7 @@ fn iter_functions(llmod: llvm::ModuleRef) -> ValueIter {
|
|||
/// This list is later used by linkers to determine the set of symbols needed to
|
||||
/// be exposed from a dynamic library and it's also encoded into the metadata.
|
||||
pub fn filter_reachable_ids(scx: &SharedCrateContext) -> NodeSet {
|
||||
scx.reachable().iter().map(|x| *x).filter(|id| {
|
||||
// First, only worry about nodes which have a symbol name
|
||||
scx.item_symbols().borrow().contains_key(id)
|
||||
}).filter(|&id| {
|
||||
scx.reachable().iter().map(|x| *x).filter(|&id| {
|
||||
// Next, we want to ignore some FFI functions that are not exposed from
|
||||
// this crate. Reachable FFI functions can be lumped into two
|
||||
// categories:
|
||||
|
|
@ -2691,7 +2630,20 @@ pub fn filter_reachable_ids(scx: &SharedCrateContext) -> NodeSet {
|
|||
hir_map::NodeForeignItem(..) => {
|
||||
scx.sess().cstore.is_statically_included_foreign_item(id)
|
||||
}
|
||||
_ => true,
|
||||
|
||||
// Only consider nodes that actually have exported symbols.
|
||||
hir_map::NodeItem(&hir::Item {
|
||||
node: hir::ItemStatic(..), .. }) |
|
||||
hir_map::NodeItem(&hir::Item {
|
||||
node: hir::ItemFn(..), .. }) |
|
||||
hir_map::NodeImplItem(&hir::ImplItem {
|
||||
node: hir::ImplItemKind::Method(..), .. }) => {
|
||||
let def_id = scx.tcx().map.local_def_id(id);
|
||||
let scheme = scx.tcx().lookup_item_type(def_id);
|
||||
scheme.generics.types.is_empty()
|
||||
}
|
||||
|
||||
_ => false
|
||||
}
|
||||
}).collect()
|
||||
}
|
||||
|
|
@ -2733,6 +2685,19 @@ pub fn trans_crate<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
|||
check_overflow,
|
||||
check_dropflag);
|
||||
|
||||
let reachable_symbol_ids = filter_reachable_ids(&shared_ccx);
|
||||
|
||||
// Translate the metadata.
|
||||
let metadata = time(tcx.sess.time_passes(), "write metadata", || {
|
||||
write_metadata(&shared_ccx, &reachable_symbol_ids)
|
||||
});
|
||||
|
||||
let metadata_module = ModuleTranslation {
|
||||
llcx: shared_ccx.metadata_llcx(),
|
||||
llmod: shared_ccx.metadata_llmod(),
|
||||
};
|
||||
let no_builtins = attr::contains_name(&krate.attrs, "no_builtins");
|
||||
|
||||
let codegen_units = collect_and_partition_translation_items(&shared_ccx);
|
||||
let codegen_unit_count = codegen_units.len();
|
||||
assert!(tcx.sess.opts.cg.codegen_units == codegen_unit_count ||
|
||||
|
|
@ -2740,6 +2705,24 @@ pub fn trans_crate<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
|||
|
||||
let crate_context_list = CrateContextList::new(&shared_ccx, codegen_units);
|
||||
|
||||
let modules = crate_context_list.iter()
|
||||
.map(|ccx| ModuleTranslation { llcx: ccx.llcx(), llmod: ccx.llmod() })
|
||||
.collect();
|
||||
|
||||
// Skip crate items and just output metadata in -Z no-trans mode.
|
||||
if tcx.sess.opts.no_trans {
|
||||
let linker_info = LinkerInfo::new(&shared_ccx, &[]);
|
||||
return CrateTranslation {
|
||||
modules: modules,
|
||||
metadata_module: metadata_module,
|
||||
link: link_meta,
|
||||
metadata: metadata,
|
||||
reachable: vec![],
|
||||
no_builtins: no_builtins,
|
||||
linker_info: linker_info
|
||||
};
|
||||
}
|
||||
|
||||
{
|
||||
let ccx = crate_context_list.get_ccx(0);
|
||||
|
||||
|
|
@ -2769,13 +2752,6 @@ pub fn trans_crate<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
|||
}
|
||||
}
|
||||
|
||||
let reachable_symbol_ids = filter_reachable_ids(&shared_ccx);
|
||||
|
||||
// Translate the metadata.
|
||||
let metadata = time(tcx.sess.time_passes(), "write metadata", || {
|
||||
write_metadata(&shared_ccx, krate, &reachable_symbol_ids, mir_map)
|
||||
});
|
||||
|
||||
if shared_ccx.sess().trans_stats() {
|
||||
let stats = shared_ccx.stats();
|
||||
println!("--- trans stats ---");
|
||||
|
|
@ -2805,13 +2781,10 @@ pub fn trans_crate<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
|||
}
|
||||
}
|
||||
|
||||
let modules = crate_context_list.iter()
|
||||
.map(|ccx| ModuleTranslation { llcx: ccx.llcx(), llmod: ccx.llmod() })
|
||||
.collect();
|
||||
|
||||
let sess = shared_ccx.sess();
|
||||
let mut reachable_symbols = reachable_symbol_ids.iter().map(|id| {
|
||||
shared_ccx.item_symbols().borrow()[id].to_string()
|
||||
let mut reachable_symbols = reachable_symbol_ids.iter().map(|&id| {
|
||||
let def_id = shared_ccx.tcx().map.local_def_id(id);
|
||||
Instance::mono(&shared_ccx, def_id).symbol_name(&shared_ccx)
|
||||
}).collect::<Vec<_>>();
|
||||
if sess.entry_fn.borrow().is_some() {
|
||||
reachable_symbols.push("main".to_string());
|
||||
|
|
@ -2834,7 +2807,7 @@ 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)
|
||||
Instance::mono(&shared_ccx, did).symbol_name(&shared_ccx)
|
||||
}));
|
||||
}
|
||||
|
||||
|
|
@ -2848,12 +2821,7 @@ pub fn trans_crate<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
|||
create_imps(&crate_context_list);
|
||||
}
|
||||
|
||||
let metadata_module = ModuleTranslation {
|
||||
llcx: shared_ccx.metadata_llcx(),
|
||||
llmod: shared_ccx.metadata_llmod(),
|
||||
};
|
||||
let no_builtins = attr::contains_name(&krate.attrs, "no_builtins");
|
||||
|
||||
let linker_info = LinkerInfo::new(&shared_ccx, &reachable_symbols);
|
||||
CrateTranslation {
|
||||
modules: modules,
|
||||
metadata_module: metadata_module,
|
||||
|
|
@ -2861,6 +2829,7 @@ pub fn trans_crate<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
|||
metadata: metadata,
|
||||
reachable: reachable_symbols,
|
||||
no_builtins: no_builtins,
|
||||
linker_info: linker_info
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -499,43 +499,20 @@ fn get_fn<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
|
|||
return immediate_rvalue(llfn, fn_ptr_ty);
|
||||
}
|
||||
|
||||
let attrs;
|
||||
let local_id = ccx.tcx().map.as_local_node_id(def_id);
|
||||
let maybe_node = local_id.and_then(|id| tcx.map.find(id));
|
||||
let (sym, attrs, local_item) = match maybe_node {
|
||||
let local_item = match local_id.and_then(|id| tcx.map.find(id)) {
|
||||
Some(hir_map::NodeItem(&hir::Item {
|
||||
ref attrs, id, span, node: hir::ItemFn(..), ..
|
||||
span, node: hir::ItemFn(..), ..
|
||||
})) |
|
||||
Some(hir_map::NodeTraitItem(&hir::TraitItem {
|
||||
ref attrs, id, span, node: hir::MethodTraitItem(_, Some(_)), ..
|
||||
span, node: hir::MethodTraitItem(_, Some(_)), ..
|
||||
})) |
|
||||
Some(hir_map::NodeImplItem(&hir::ImplItem {
|
||||
ref attrs, id, span, node: hir::ImplItemKind::Method(..), ..
|
||||
span, node: hir::ImplItemKind::Method(..), ..
|
||||
})) => {
|
||||
let sym = exported_name(ccx, instance, attrs);
|
||||
|
||||
if declare::get_defined_value(ccx, &sym).is_some() {
|
||||
ccx.sess().span_fatal(span,
|
||||
&format!("symbol `{}` is already defined", sym));
|
||||
}
|
||||
|
||||
(sym, &attrs[..], Some(id))
|
||||
}
|
||||
|
||||
Some(hir_map::NodeForeignItem(&hir::ForeignItem {
|
||||
ref attrs, name, node: hir::ForeignItemFn(..), ..
|
||||
})) => {
|
||||
(imported_name(name, attrs).to_string(), &attrs[..], None)
|
||||
}
|
||||
|
||||
None => {
|
||||
attrs = ccx.sess().cstore.item_attrs(def_id);
|
||||
(ccx.sess().cstore.item_symbol(def_id), &attrs[..], None)
|
||||
}
|
||||
|
||||
ref variant => {
|
||||
bug!("get_fn: unexpected variant: {:?}", variant)
|
||||
Some(span)
|
||||
}
|
||||
_ => None
|
||||
};
|
||||
|
||||
// This is subtle and surprising, but sometimes we have to bitcast
|
||||
|
|
@ -562,8 +539,16 @@ fn get_fn<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
|
|||
// reference. It also occurs when testing libcore and in some
|
||||
// other weird situations. Annoying.
|
||||
|
||||
let sym = instance.symbol_name(ccx.shared());
|
||||
let llptrty = type_of::type_of(ccx, fn_ptr_ty);
|
||||
let llfn = if let Some(llfn) = declare::get_declared_value(ccx, &sym) {
|
||||
if let Some(span) = local_item {
|
||||
if declare::get_defined_value(ccx, &sym).is_some() {
|
||||
ccx.sess().span_fatal(span,
|
||||
&format!("symbol `{}` is already defined", sym));
|
||||
}
|
||||
}
|
||||
|
||||
if common::val_ty(llfn) != llptrty {
|
||||
if local_item.is_some() {
|
||||
bug!("symbol `{}` previously declared as {:?}, now wanted as {:?}",
|
||||
|
|
@ -580,7 +565,8 @@ fn get_fn<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
|
|||
assert_eq!(common::val_ty(llfn), llptrty);
|
||||
debug!("get_fn: not casting pointer!");
|
||||
|
||||
attributes::from_fn_attrs(ccx, attrs, llfn);
|
||||
let attrs = ccx.tcx().get_attrs(def_id);
|
||||
attributes::from_fn_attrs(ccx, &attrs, llfn);
|
||||
if local_item.is_some() {
|
||||
// FIXME(eddyb) Doubt all extern fn should allow unwinding.
|
||||
attributes::unwind(llfn, true);
|
||||
|
|
@ -589,11 +575,6 @@ fn get_fn<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
|
|||
llfn
|
||||
};
|
||||
|
||||
// Always insert into item_symbols, in case this item is exported.
|
||||
if let Some(id) = local_item {
|
||||
ccx.item_symbols().borrow_mut().insert(id, sym);
|
||||
}
|
||||
|
||||
ccx.instances().borrow_mut().insert(instance, llfn);
|
||||
|
||||
immediate_rvalue(llfn, fn_ptr_ty)
|
||||
|
|
|
|||
|
|
@ -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 = instance.symbol_name(ccx.shared());
|
||||
|
||||
// Compute the rust-call form of the closure call method.
|
||||
let sig = &tcx.closure_type(closure_id, substs).sig;
|
||||
|
|
|
|||
|
|
@ -19,7 +19,7 @@ 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, push_ctxt};
|
||||
use callee::Callee;
|
||||
use collector;
|
||||
use trans_item::TransItem;
|
||||
|
|
@ -1017,34 +1017,31 @@ pub fn get_static<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, def_id: DefId)
|
|||
return Datum::new(g, ty, Lvalue::new("static"));
|
||||
}
|
||||
|
||||
let sym = instance.symbol_name(ccx.shared());
|
||||
|
||||
let g = if let Some(id) = ccx.tcx().map.as_local_node_id(def_id) {
|
||||
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);
|
||||
debug!("making {}", sym);
|
||||
|
||||
// Create the global before evaluating the initializer;
|
||||
// this is necessary to allow recursive statics.
|
||||
let g = declare::define_global(ccx, &sym, llty).unwrap_or_else(|| {
|
||||
declare::define_global(ccx, &sym, llty).unwrap_or_else(|| {
|
||||
ccx.sess().span_fatal(span,
|
||||
&format!("symbol `{}` is already defined", sym))
|
||||
});
|
||||
|
||||
ccx.item_symbols().borrow_mut().insert(id, sym);
|
||||
g
|
||||
})
|
||||
}
|
||||
|
||||
hir_map::NodeForeignItem(&hir::ForeignItem {
|
||||
ref attrs, name, span, node: hir::ForeignItemStatic(..), ..
|
||||
ref attrs, span, node: hir::ForeignItemStatic(..), ..
|
||||
}) => {
|
||||
let ident = imported_name(name, attrs);
|
||||
let g = if let Some(name) =
|
||||
attr::first_attr_value_str_by_name(&attrs, "linkage") {
|
||||
// If this is a static with a linkage specified, then we need to handle
|
||||
|
|
@ -1066,7 +1063,7 @@ pub fn get_static<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, def_id: DefId)
|
|||
};
|
||||
unsafe {
|
||||
// Declare a symbol `foo` with the desired linkage.
|
||||
let g1 = declare::declare_global(ccx, &ident, llty2);
|
||||
let g1 = declare::declare_global(ccx, &sym, llty2);
|
||||
llvm::SetLinkage(g1, linkage);
|
||||
|
||||
// Declare an internal global `extern_with_linkage_foo` which
|
||||
|
|
@ -1076,10 +1073,10 @@ pub fn get_static<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, def_id: DefId)
|
|||
// `extern_with_linkage_foo` will instead be initialized to
|
||||
// zero.
|
||||
let mut real_name = "_rust_extern_with_linkage_".to_string();
|
||||
real_name.push_str(&ident);
|
||||
real_name.push_str(&sym);
|
||||
let g2 = declare::define_global(ccx, &real_name, llty).unwrap_or_else(||{
|
||||
ccx.sess().span_fatal(span,
|
||||
&format!("symbol `{}` is already defined", ident))
|
||||
&format!("symbol `{}` is already defined", sym))
|
||||
});
|
||||
llvm::SetLinkage(g2, llvm::InternalLinkage);
|
||||
llvm::LLVMSetInitializer(g2, g1);
|
||||
|
|
@ -1087,7 +1084,7 @@ pub fn get_static<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, def_id: DefId)
|
|||
}
|
||||
} else {
|
||||
// Generate an external declaration.
|
||||
declare::declare_global(ccx, &ident, llty)
|
||||
declare::declare_global(ccx, &sym, llty)
|
||||
};
|
||||
|
||||
for attr in attrs {
|
||||
|
|
@ -1104,8 +1101,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 g = declare::declare_global(ccx, &name, type_of::type_of(ccx, ty));
|
||||
let g = declare::declare_global(ccx, &sym, 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
|
||||
// thread-local attribute locally if it was present remotely. If we
|
||||
|
|
|
|||
|
|
@ -71,7 +71,6 @@ pub struct SharedCrateContext<'a, 'tcx: 'a> {
|
|||
|
||||
export_map: ExportMap,
|
||||
reachable: NodeSet,
|
||||
item_symbols: RefCell<NodeMap<String>>,
|
||||
link_meta: LinkMeta,
|
||||
symbol_hasher: RefCell<Sha256>,
|
||||
tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||
|
|
@ -395,7 +394,6 @@ impl<'b, 'tcx> SharedCrateContext<'b, 'tcx> {
|
|||
metadata_llcx: metadata_llcx,
|
||||
export_map: export_map,
|
||||
reachable: reachable,
|
||||
item_symbols: RefCell::new(NodeMap()),
|
||||
link_meta: link_meta,
|
||||
symbol_hasher: RefCell::new(symbol_hasher),
|
||||
tcx: tcx,
|
||||
|
|
@ -439,10 +437,6 @@ impl<'b, 'tcx> SharedCrateContext<'b, 'tcx> {
|
|||
&self.reachable
|
||||
}
|
||||
|
||||
pub fn item_symbols<'a>(&'a self) -> &'a RefCell<NodeMap<String>> {
|
||||
&self.item_symbols
|
||||
}
|
||||
|
||||
pub fn trait_cache(&self) -> &RefCell<DepTrackingMap<TraitSelectionCache<'tcx>>> {
|
||||
&self.trait_cache
|
||||
}
|
||||
|
|
@ -504,6 +498,14 @@ impl<'b, 'tcx> SharedCrateContext<'b, 'tcx> {
|
|||
scheme.generics.regions.map(|_| ty::ReStatic)))
|
||||
}
|
||||
|
||||
pub fn symbol_hasher(&self) -> &RefCell<Sha256> {
|
||||
&self.symbol_hasher
|
||||
}
|
||||
|
||||
pub fn mir_map(&self) -> &MirMap<'tcx> {
|
||||
&self.mir_map
|
||||
}
|
||||
|
||||
pub fn metadata_symbol_name(&self) -> String {
|
||||
format!("rust_metadata_{}_{}",
|
||||
self.link_meta().crate_name,
|
||||
|
|
@ -716,10 +718,6 @@ impl<'b, 'tcx> CrateContext<'b, 'tcx> {
|
|||
&self.shared.reachable
|
||||
}
|
||||
|
||||
pub fn item_symbols<'a>(&'a self) -> &'a RefCell<NodeMap<String>> {
|
||||
&self.shared.item_symbols
|
||||
}
|
||||
|
||||
pub fn link_meta<'a>(&'a self) -> &'a LinkMeta {
|
||||
&self.shared.link_meta
|
||||
}
|
||||
|
|
|
|||
|
|
@ -145,6 +145,7 @@ pub struct CrateTranslation {
|
|||
pub metadata: Vec<u8>,
|
||||
pub reachable: Vec<String>,
|
||||
pub no_builtins: bool,
|
||||
pub linker_info: back::linker::LinkerInfo
|
||||
}
|
||||
|
||||
__build_diagnostic_array! { librustc_trans, DIAGNOSTICS }
|
||||
|
|
|
|||
|
|
@ -8,7 +8,6 @@
|
|||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
use back::symbol_names;
|
||||
use llvm::ValueRef;
|
||||
use llvm;
|
||||
use rustc::hir::def_id::DefId;
|
||||
|
|
@ -88,7 +87,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 = instance.symbol_name(ccx.shared());
|
||||
|
||||
debug!("monomorphize_fn mangled to {}", symbol);
|
||||
assert!(declare::get_defined_value(ccx, &symbol).is_none());
|
||||
|
|
|
|||
|
|
@ -14,7 +14,6 @@
|
|||
//! item-path. This is used for unit testing the code that generates
|
||||
//! paths etc in all kinds of annoying scenarios.
|
||||
|
||||
use back::symbol_names;
|
||||
use rustc::hir;
|
||||
use rustc::hir::intravisit::{self, Visitor};
|
||||
use syntax::ast;
|
||||
|
|
@ -53,7 +52,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 = instance.symbol_name(self.ccx.shared());
|
||||
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);
|
||||
|
|
|
|||
|
|
@ -25,7 +25,7 @@ mod bar {
|
|||
use foo::Foo;
|
||||
|
||||
impl Foo {
|
||||
#[rustc_symbol_name] //~ ERROR _ZN5impl13bar26_$LT$impl$u20$foo..Foo$GT$3baz
|
||||
#[rustc_symbol_name] //~ ERROR _ZN5impl13bar33_$LT$impl$u20$impl1..foo..Foo$GT$3baz
|
||||
#[rustc_item_path] //~ ERROR item-path(bar::<impl foo::Foo>::baz)
|
||||
fn baz() { }
|
||||
}
|
||||
|
|
|
|||
|
|
@ -371,9 +371,16 @@ actual:\n\
|
|||
} else {
|
||||
&*self.config.target
|
||||
};
|
||||
|
||||
let out_dir = self.output_base_name().with_extension("pretty-out");
|
||||
let _ = fs::remove_dir_all(&out_dir);
|
||||
self.create_dir_racy(&out_dir);
|
||||
|
||||
// FIXME (#9639): This needs to handle non-utf8 paths
|
||||
let mut args = vec!("-".to_owned(),
|
||||
"-Zno-trans".to_owned(),
|
||||
"--out-dir".to_owned(),
|
||||
out_dir.to_str().unwrap().to_owned(),
|
||||
format!("--target={}", target),
|
||||
"-L".to_owned(),
|
||||
self.config.build_base.to_str().unwrap().to_owned(),
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue