From dba3ddd8d4e037db390f54536b4cb77ea988eab1 Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Tue, 12 Sep 2017 09:32:37 -0700 Subject: [PATCH] rustc: Calculate `ExportedSymbols` in a query This commit moves the definition of the `ExportedSymbols` structure to the `rustc` crate and then creates a query that'll be used to construct the `ExportedSymbols` set. This in turn uses the reachablity query exposed in the previous commit. --- src/librustc/dep_graph/dep_node.rs | 3 +- src/librustc/lib.rs | 1 + src/librustc/middle/exported_symbols.rs | 77 ++++++ src/librustc/ty/context.rs | 6 + src/librustc/ty/maps.rs | 19 +- src/librustc_driver/driver.rs | 4 +- src/librustc_metadata/cstore_impl.rs | 2 +- src/librustc_trans/back/linker.rs | 2 +- src/librustc_trans/back/lto.rs | 3 +- src/librustc_trans/back/symbol_export.rs | 297 +++++++++-------------- src/librustc_trans/back/write.rs | 2 +- src/librustc_trans/base.rs | 40 +-- src/librustc_trans/collector.rs | 2 +- src/librustc_trans/context.rs | 2 +- src/librustc_trans/lib.rs | 19 +- src/librustc_trans/partitioning.rs | 2 +- 16 files changed, 266 insertions(+), 215 deletions(-) create mode 100644 src/librustc/middle/exported_symbols.rs diff --git a/src/librustc/dep_graph/dep_node.rs b/src/librustc/dep_graph/dep_node.rs index 27561bddd29..757a256164e 100644 --- a/src/librustc/dep_graph/dep_node.rs +++ b/src/librustc/dep_graph/dep_node.rs @@ -535,7 +535,7 @@ define_dep_nodes!( <'tcx> [] GetPanicStrategy(CrateNum), [] IsNoBuiltins(CrateNum), [] ImplDefaultness(DefId), - [] ExportedSymbols(CrateNum), + [] ExportedSymbolIds(CrateNum), [] NativeLibraries(CrateNum), [] PluginRegistrarFn(CrateNum), [] DeriveRegistrarFn(CrateNum), @@ -575,6 +575,7 @@ define_dep_nodes!( <'tcx> [] MaybeUnusedExternCrates, [] StabilityIndex, [] AllCrateNums, + [] ExportedSymbols, ); trait DepNodeParams<'a, 'gcx: 'tcx + 'a, 'tcx: 'a> : fmt::Debug { diff --git a/src/librustc/lib.rs b/src/librustc/lib.rs index df97f2fb8bc..59edc9fb083 100644 --- a/src/librustc/lib.rs +++ b/src/librustc/lib.rs @@ -92,6 +92,7 @@ pub mod middle { pub mod dependency_format; pub mod effect; pub mod entry; + pub mod exported_symbols; pub mod free_region; pub mod intrinsicck; pub mod lang_items; diff --git a/src/librustc/middle/exported_symbols.rs b/src/librustc/middle/exported_symbols.rs new file mode 100644 index 00000000000..7f03f8a5a29 --- /dev/null +++ b/src/librustc/middle/exported_symbols.rs @@ -0,0 +1,77 @@ +// Copyright 2016 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +use util::nodemap::{FxHashMap, NodeSet}; +use hir::def_id::{DefId, CrateNum}; + +/// The SymbolExportLevel of a symbols specifies from which kinds of crates +/// the symbol will be exported. `C` symbols will be exported from any +/// kind of crate, including cdylibs which export very few things. +/// `Rust` will only be exported if the crate produced is a Rust +/// dylib. +#[derive(Eq, PartialEq, Debug, Copy, Clone)] +pub enum SymbolExportLevel { + C, + Rust, +} + +/// The set of symbols exported from each crate in the crate graph. +#[derive(Debug)] +pub struct ExportedSymbols { + pub export_threshold: SymbolExportLevel, + exports: FxHashMap>, + local_exports: NodeSet, +} + +impl ExportedSymbols { + pub fn new(export_threshold: SymbolExportLevel, + exports: FxHashMap>, + local_exports: NodeSet) -> ExportedSymbols { + ExportedSymbols { + export_threshold, + exports, + local_exports, + } + } + + pub fn local_exports(&self) -> &NodeSet { + &self.local_exports + } + + pub fn exported_symbols(&self, cnum: CrateNum) + -> &[(String, DefId, SymbolExportLevel)] + { + match self.exports.get(&cnum) { + Some(exports) => exports, + None => &[] + } + } + + pub fn for_each_exported_symbol(&self, cnum: CrateNum, mut f: F) + where F: FnMut(&str, DefId, SymbolExportLevel) + { + for &(ref name, def_id, export_level) in self.exported_symbols(cnum) { + if is_below_threshold(export_level, self.export_threshold) { + f(&name, def_id, export_level) + } + } + } +} + +pub fn is_below_threshold(level: SymbolExportLevel, + threshold: SymbolExportLevel) + -> bool { + if threshold == SymbolExportLevel::Rust { + // We export everything from Rust dylibs + true + } else { + level == SymbolExportLevel::C + } +} diff --git a/src/librustc/ty/context.rs b/src/librustc/ty/context.rs index fb0cdab0b6a..af5c37e0f16 100644 --- a/src/librustc/ty/context.rs +++ b/src/librustc/ty/context.rs @@ -27,6 +27,7 @@ use middle::cstore::EncodedMetadata; use middle::free_region::FreeRegionMap; use middle::lang_items; use middle::resolve_lifetime::{self, ObjectLifetimeDefault}; +use middle::exported_symbols::ExportedSymbols; use middle::stability; use mir::Mir; use mir::transform::Passes; @@ -64,6 +65,7 @@ use std::mem; use std::ops::Deref; use std::iter; use std::rc::Rc; +use std::sync::Arc; use syntax::abi; use syntax::ast::{self, Name, NodeId}; use syntax::attr; @@ -1218,6 +1220,10 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { pub fn crate_data_as_rc_any(self, cnum: CrateNum) -> Rc { self.cstore.crate_data_as_rc_any(cnum) } + + pub fn exported_symbols(self) -> Arc { + self.exported_symbol_set(LOCAL_CRATE) + } } impl<'a, 'tcx> TyCtxt<'a, 'tcx, 'tcx> { diff --git a/src/librustc/ty/maps.rs b/src/librustc/ty/maps.rs index 18c59d405a2..2d3dc6cd65b 100644 --- a/src/librustc/ty/maps.rs +++ b/src/librustc/ty/maps.rs @@ -23,6 +23,7 @@ use middle::region; use middle::resolve_lifetime::{Region, ObjectLifetimeDefault}; use middle::stability::{self, DeprecationEntry}; use middle::lang_items::{LanguageItems, LangItem}; +use middle::exported_symbols::ExportedSymbols; use mir; use mir::transform::{MirSuite, MirPassIndex}; use session::CompileResult; @@ -48,6 +49,7 @@ use std::mem; use std::collections::BTreeMap; use std::ops::Deref; use std::rc::Rc; +use std::sync::Arc; use syntax_pos::{Span, DUMMY_SP}; use syntax::attr; use syntax::ast; @@ -595,7 +597,7 @@ impl<'tcx> QueryDescription for queries::is_sanitizer_runtime<'tcx> { } } -impl<'tcx> QueryDescription for queries::exported_symbols<'tcx> { +impl<'tcx> QueryDescription for queries::exported_symbol_ids<'tcx> { fn describe(_tcx: TyCtxt, _: CrateNum) -> String { format!("looking up the exported symbols of a crate") } @@ -745,6 +747,12 @@ impl<'tcx> QueryDescription for queries::all_crate_nums<'tcx> { } } +impl<'tcx> QueryDescription for queries::exported_symbol_set<'tcx> { + fn describe(_tcx: TyCtxt, _: CrateNum) -> String { + format!("exported symbol set") + } +} + // If enabled, send a message to the profile-queries thread macro_rules! profq_msg { ($tcx:expr, $msg:expr) => { @@ -1322,7 +1330,7 @@ define_maps! { <'tcx> [] fn lint_levels: lint_levels_node(CrateNum) -> Rc, [] fn impl_defaultness: ImplDefaultness(DefId) -> hir::Defaultness, - [] fn exported_symbols: ExportedSymbols(CrateNum) -> Rc>, + [] fn exported_symbol_ids: ExportedSymbolIds(CrateNum) -> Rc>, [] fn native_libraries: NativeLibraries(CrateNum) -> Rc>, [] fn plugin_registrar_fn: PluginRegistrarFn(CrateNum) -> Option, [] fn derive_registrar_fn: DeriveRegistrarFn(CrateNum) -> Option, @@ -1371,6 +1379,9 @@ define_maps! { <'tcx> [] fn stability_index: stability_index_node(CrateNum) -> Rc>, [] fn all_crate_nums: all_crate_nums_node(CrateNum) -> Rc>, + + [] fn exported_symbol_set: exported_symbol_set_node(CrateNum) + -> Arc, } fn type_param_predicates<'tcx>((item_id, param_id): (DefId, DefId)) -> DepConstructor<'tcx> { @@ -1484,3 +1495,7 @@ fn stability_index_node<'tcx>(_: CrateNum) -> DepConstructor<'tcx> { fn all_crate_nums_node<'tcx>(_: CrateNum) -> DepConstructor<'tcx> { DepConstructor::AllCrateNums } + +fn exported_symbol_set_node<'tcx>(_: CrateNum) -> DepConstructor<'tcx> { + DepConstructor::ExportedSymbols +} diff --git a/src/librustc_driver/driver.rs b/src/librustc_driver/driver.rs index b01179c4311..9f7cb06488d 100644 --- a/src/librustc_driver/driver.rs +++ b/src/librustc_driver/driver.rs @@ -956,7 +956,7 @@ pub fn phase_3_run_analysis_passes<'tcx, F, R>(sess: &'tcx Session, mir::provide(&mut local_providers); reachable::provide(&mut local_providers); rustc_privacy::provide(&mut local_providers); - trans::provide(&mut local_providers); + trans::provide_local(&mut local_providers); typeck::provide(&mut local_providers); ty::provide(&mut local_providers); traits::provide(&mut local_providers); @@ -968,7 +968,7 @@ pub fn phase_3_run_analysis_passes<'tcx, F, R>(sess: &'tcx Session, let mut extern_providers = ty::maps::Providers::default(); cstore::provide(&mut extern_providers); - trans::provide(&mut extern_providers); + trans::provide_extern(&mut extern_providers); ty::provide_extern(&mut extern_providers); traits::provide_extern(&mut extern_providers); // FIXME(eddyb) get rid of this once we replace const_eval with miri. diff --git a/src/librustc_metadata/cstore_impl.rs b/src/librustc_metadata/cstore_impl.rs index 74e4ffcdfff..3a116160bca 100644 --- a/src/librustc_metadata/cstore_impl.rs +++ b/src/librustc_metadata/cstore_impl.rs @@ -175,7 +175,7 @@ provide! { <'tcx> tcx, def_id, other, cdata, extern_crate => { Rc::new(cdata.extern_crate.get()) } is_no_builtins => { cdata.is_no_builtins() } impl_defaultness => { cdata.get_impl_defaultness(def_id.index) } - exported_symbols => { Rc::new(cdata.get_exported_symbols()) } + exported_symbol_ids => { Rc::new(cdata.get_exported_symbols()) } native_libraries => { Rc::new(cdata.get_native_libraries()) } plugin_registrar_fn => { cdata.root.plugin_registrar_fn.map(|index| { diff --git a/src/librustc_trans/back/linker.rs b/src/librustc_trans/back/linker.rs index 487d9e05945..ec436bcb241 100644 --- a/src/librustc_trans/back/linker.rs +++ b/src/librustc_trans/back/linker.rs @@ -19,8 +19,8 @@ use context::SharedCrateContext; use back::archive; use back::command::Command; -use back::symbol_export::ExportedSymbols; use rustc::middle::dependency_format::Linkage; +use rustc::middle::exported_symbols::ExportedSymbols; use rustc::hir::def_id::{LOCAL_CRATE, CrateNum}; use rustc_back::LinkerFlavor; use rustc::session::Session; diff --git a/src/librustc_trans/back/lto.rs b/src/librustc_trans/back/lto.rs index 3e2d9f5c32e..125b07a9505 100644 --- a/src/librustc_trans/back/lto.rs +++ b/src/librustc_trans/back/lto.rs @@ -16,6 +16,7 @@ use errors::{FatalError, Handler}; use llvm; use llvm::archive_ro::ArchiveRO; use llvm::{ModuleRef, TargetMachineRef, True, False}; +use rustc::middle::exported_symbols; use rustc::util::common::time; use rustc::util::common::path2cstr; use rustc::hir::def_id::LOCAL_CRATE; @@ -68,7 +69,7 @@ pub fn run(cgcx: &CodegenContext, symbol_export::crates_export_threshold(&cgcx.crate_types); let symbol_filter = &|&(ref name, _, level): &(String, _, _)| { - if symbol_export::is_below_threshold(level, export_threshold) { + if exported_symbols::is_below_threshold(level, export_threshold) { let mut bytes = Vec::with_capacity(name.len() + 1); bytes.extend(name.bytes()); Some(CString::new(bytes).unwrap()) diff --git a/src/librustc_trans/back/symbol_export.rs b/src/librustc_trans/back/symbol_export.rs index b546059b4c5..b47d6f8ac2d 100644 --- a/src/librustc_trans/back/symbol_export.rs +++ b/src/librustc_trans/back/symbol_export.rs @@ -8,199 +8,143 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. +use base; use monomorphize::Instance; use rustc::util::nodemap::{FxHashMap, NodeSet}; -use rustc::hir::def_id::{DefId, CrateNum, LOCAL_CRATE, INVALID_CRATE, CRATE_DEF_INDEX}; +use rustc::hir::def_id::{DefId, LOCAL_CRATE, INVALID_CRATE, CRATE_DEF_INDEX}; use rustc::session::config; use rustc::ty::TyCtxt; use rustc_allocator::ALLOCATOR_METHODS; +use rustc::middle::exported_symbols::{ExportedSymbols, SymbolExportLevel}; +use rustc::middle::exported_symbols::is_below_threshold; use syntax::attr; -/// The SymbolExportLevel of a symbols specifies from which kinds of crates -/// the symbol will be exported. `C` symbols will be exported from any -/// kind of crate, including cdylibs which export very few things. -/// `Rust` will only be exported if the crate produced is a Rust -/// dylib. -#[derive(Eq, PartialEq, Debug, Copy, Clone)] -pub enum SymbolExportLevel { - C, - Rust, -} +pub fn compute<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>) -> ExportedSymbols { + let export_threshold = crates_export_threshold(&tcx.sess.crate_types.borrow()); + let local_exported_symbols = base::find_exported_symbols(tcx); -/// The set of symbols exported from each crate in the crate graph. -#[derive(Debug)] -pub struct ExportedSymbols { - pub export_threshold: SymbolExportLevel, - exports: FxHashMap>, - local_exports: NodeSet, -} + let mut local_crate: Vec<_> = local_exported_symbols + .iter() + .map(|&node_id| { + tcx.hir.local_def_id(node_id) + }) + .map(|def_id| { + let name = tcx.symbol_name(Instance::mono(tcx, def_id)); + let export_level = export_level(tcx, def_id); + debug!("EXPORTED SYMBOL (local): {} ({:?})", name, export_level); + (str::to_owned(&name), def_id, export_level) + }) + .collect(); -impl ExportedSymbols { - pub fn empty() -> ExportedSymbols { - ExportedSymbols { - export_threshold: SymbolExportLevel::C, - exports: FxHashMap(), - local_exports: NodeSet(), + let mut local_exports = local_crate + .iter() + .filter_map(|&(_, def_id, level)| { + if is_below_threshold(level, export_threshold) { + tcx.hir.as_local_node_id(def_id) + } else { + None + } + }) + .collect::(); + + const INVALID_DEF_ID: DefId = DefId { + krate: INVALID_CRATE, + index: CRATE_DEF_INDEX, + }; + + if let Some(_) = *tcx.sess.entry_fn.borrow() { + local_crate.push(("main".to_string(), + INVALID_DEF_ID, + SymbolExportLevel::C)); + } + + if tcx.sess.allocator_kind.get().is_some() { + for method in ALLOCATOR_METHODS { + local_crate.push((format!("__rust_{}", method.name), + INVALID_DEF_ID, + SymbolExportLevel::Rust)); } } - pub fn compute<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, - local_exported_symbols: &NodeSet) - -> ExportedSymbols { - let export_threshold = crates_export_threshold(&tcx.sess.crate_types.borrow()); + if let Some(id) = tcx.sess.derive_registrar_fn.get() { + let def_id = tcx.hir.local_def_id(id); + let idx = def_id.index; + let disambiguator = tcx.sess.local_crate_disambiguator(); + let registrar = tcx.sess.generate_derive_registrar_symbol(disambiguator, idx); + local_crate.push((registrar, def_id, SymbolExportLevel::C)); + local_exports.insert(id); + } - let mut local_crate: Vec<_> = local_exported_symbols + if tcx.sess.crate_types.borrow().contains(&config::CrateTypeDylib) { + local_crate.push((metadata_symbol_name(tcx), + INVALID_DEF_ID, + SymbolExportLevel::Rust)); + } + + let mut exports = FxHashMap(); + exports.insert(LOCAL_CRATE, local_crate); + + for &cnum in tcx.crates().iter() { + debug_assert!(cnum != LOCAL_CRATE); + + // If this crate is a plugin and/or a custom derive crate, then + // we're not even going to link those in so we skip those crates. + if tcx.plugin_registrar_fn(cnum).is_some() || + tcx.derive_registrar_fn(cnum).is_some() { + continue; + } + + // Check to see if this crate is a "special runtime crate". These + // crates, implementation details of the standard library, typically + // have a bunch of `pub extern` and `#[no_mangle]` functions as the + // ABI between them. We don't want their symbols to have a `C` + // export level, however, as they're just implementation details. + // Down below we'll hardwire all of the symbols to the `Rust` export + // level instead. + let special_runtime_crate = + tcx.is_panic_runtime(cnum) || tcx.is_compiler_builtins(cnum); + + let crate_exports = tcx + .exported_symbol_ids(cnum) .iter() - .map(|&node_id| { - tcx.hir.local_def_id(node_id) - }) - .map(|def_id| { + .map(|&def_id| { let name = tcx.symbol_name(Instance::mono(tcx, def_id)); - let export_level = export_level(tcx, def_id); - debug!("EXPORTED SYMBOL (local): {} ({:?})", name, export_level); + let export_level = if special_runtime_crate { + // We can probably do better here by just ensuring that + // it has hidden visibility rather than public + // visibility, as this is primarily here to ensure it's + // not stripped during LTO. + // + // In general though we won't link right if these + // symbols are stripped, and LTO currently strips them. + if &*name == "rust_eh_personality" || + &*name == "rust_eh_register_frames" || + &*name == "rust_eh_unregister_frames" { + SymbolExportLevel::C + } else { + SymbolExportLevel::Rust + } + } else { + export_level(tcx, def_id) + }; + debug!("EXPORTED SYMBOL (re-export): {} ({:?})", name, export_level); (str::to_owned(&name), def_id, export_level) }) .collect(); - let mut local_exports = local_crate - .iter() - .filter_map(|&(_, def_id, level)| { - if is_below_threshold(level, export_threshold) { - tcx.hir.as_local_node_id(def_id) - } else { - None - } - }) - .collect::(); - - const INVALID_DEF_ID: DefId = DefId { - krate: INVALID_CRATE, - index: CRATE_DEF_INDEX, - }; - - if let Some(_) = *tcx.sess.entry_fn.borrow() { - local_crate.push(("main".to_string(), - INVALID_DEF_ID, - SymbolExportLevel::C)); - } - - if tcx.sess.allocator_kind.get().is_some() { - for method in ALLOCATOR_METHODS { - local_crate.push((format!("__rust_{}", method.name), - INVALID_DEF_ID, - SymbolExportLevel::Rust)); - } - } - - if let Some(id) = tcx.sess.derive_registrar_fn.get() { - let def_id = tcx.hir.local_def_id(id); - let idx = def_id.index; - let disambiguator = tcx.sess.local_crate_disambiguator(); - let registrar = tcx.sess.generate_derive_registrar_symbol(disambiguator, idx); - local_crate.push((registrar, def_id, SymbolExportLevel::C)); - local_exports.insert(id); - } - - if tcx.sess.crate_types.borrow().contains(&config::CrateTypeDylib) { - local_crate.push((metadata_symbol_name(tcx), - INVALID_DEF_ID, - SymbolExportLevel::Rust)); - } - - let mut exports = FxHashMap(); - exports.insert(LOCAL_CRATE, local_crate); - - for &cnum in tcx.crates().iter() { - debug_assert!(cnum != LOCAL_CRATE); - - // If this crate is a plugin and/or a custom derive crate, then - // we're not even going to link those in so we skip those crates. - if tcx.plugin_registrar_fn(cnum).is_some() || - tcx.derive_registrar_fn(cnum).is_some() { - continue; - } - - // Check to see if this crate is a "special runtime crate". These - // crates, implementation details of the standard library, typically - // have a bunch of `pub extern` and `#[no_mangle]` functions as the - // ABI between them. We don't want their symbols to have a `C` - // export level, however, as they're just implementation details. - // Down below we'll hardwire all of the symbols to the `Rust` export - // level instead. - let special_runtime_crate = - tcx.is_panic_runtime(cnum) || tcx.is_compiler_builtins(cnum); - - let crate_exports = tcx - .exported_symbols(cnum) - .iter() - .map(|&def_id| { - let name = tcx.symbol_name(Instance::mono(tcx, def_id)); - let export_level = if special_runtime_crate { - // We can probably do better here by just ensuring that - // it has hidden visibility rather than public - // visibility, as this is primarily here to ensure it's - // not stripped during LTO. - // - // In general though we won't link right if these - // symbols are stripped, and LTO currently strips them. - if &*name == "rust_eh_personality" || - &*name == "rust_eh_register_frames" || - &*name == "rust_eh_unregister_frames" { - SymbolExportLevel::C - } else { - SymbolExportLevel::Rust - } - } else { - export_level(tcx, def_id) - }; - debug!("EXPORTED SYMBOL (re-export): {} ({:?})", name, export_level); - (str::to_owned(&name), def_id, export_level) - }) - .collect(); - - exports.insert(cnum, crate_exports); - } - - return ExportedSymbols { - export_threshold, - exports, - local_exports, - }; - - fn export_level(tcx: TyCtxt, - sym_def_id: DefId) - -> SymbolExportLevel { - let attrs = tcx.get_attrs(sym_def_id); - if attr::contains_extern_indicator(tcx.sess.diagnostic(), &attrs) { - SymbolExportLevel::C - } else { - SymbolExportLevel::Rust - } - } + exports.insert(cnum, crate_exports); } - pub fn local_exports(&self) -> &NodeSet { - &self.local_exports - } + return ExportedSymbols::new(export_threshold, exports, local_exports); - pub fn exported_symbols(&self, - cnum: CrateNum) - -> &[(String, DefId, SymbolExportLevel)] { - match self.exports.get(&cnum) { - Some(exports) => exports, - None => &[] - } - } - - pub fn for_each_exported_symbol(&self, - cnum: CrateNum, - mut f: F) - where F: FnMut(&str, DefId, SymbolExportLevel) - { - for &(ref name, def_id, export_level) in self.exported_symbols(cnum) { - if is_below_threshold(export_level, self.export_threshold) { - f(&name, def_id, export_level) - } + fn export_level(tcx: TyCtxt, + sym_def_id: DefId) + -> SymbolExportLevel { + let attrs = tcx.get_attrs(sym_def_id); + if attr::contains_extern_indicator(tcx.sess.diagnostic(), &attrs) { + SymbolExportLevel::C + } else { + SymbolExportLevel::Rust } } } @@ -233,14 +177,3 @@ pub fn crates_export_threshold(crate_types: &[config::CrateType]) SymbolExportLevel::C } } - -pub fn is_below_threshold(level: SymbolExportLevel, - threshold: SymbolExportLevel) - -> bool { - if threshold == SymbolExportLevel::Rust { - // We export everything from Rust dylibs - true - } else { - level == SymbolExportLevel::C - } -} diff --git a/src/librustc_trans/back/write.rs b/src/librustc_trans/back/write.rs index 68140011e7e..d241edca0ea 100644 --- a/src/librustc_trans/back/write.rs +++ b/src/librustc_trans/back/write.rs @@ -11,7 +11,7 @@ use back::lto; use back::link::{self, get_linker, remove}; use back::linker::LinkerInfo; -use back::symbol_export::ExportedSymbols; +use rustc::middle::exported_symbols::ExportedSymbols; use rustc_incremental::{save_trans_partition, in_incr_comp_dir}; use rustc::dep_graph::DepGraph; use rustc::middle::cstore::{LinkMeta, EncodedMetadata}; diff --git a/src/librustc_trans/base.rs b/src/librustc_trans/base.rs index 1ea38eadb75..5f8e95b6ca9 100644 --- a/src/librustc_trans/base.rs +++ b/src/librustc_trans/base.rs @@ -31,7 +31,7 @@ use super::ModuleKind; use assert_module_sources; use back::link; use back::linker::LinkerInfo; -use back::symbol_export::{self, ExportedSymbols}; +use back::symbol_export; use back::write::{self, OngoingCrateTranslation}; use llvm::{ContextRef, Linkage, ModuleRef, ValueRef, Vector, get_param}; use llvm; @@ -42,6 +42,7 @@ use rustc::middle::cstore::{EncodedMetadata, EncodedMetadataHashes}; use rustc::ty::{self, Ty, TyCtxt}; use rustc::dep_graph::AssertDepGraphSafe; use rustc::middle::cstore::{self, LinkMeta, LinkagePreference}; +use rustc::middle::exported_symbols::{ExportedSymbols, SymbolExportLevel}; use rustc::hir::map as hir_map; use rustc::util::common::{time, print_time_passes_entry}; use rustc::session::config::{self, NoDebugInfo, OutputFilenames, OutputType}; @@ -973,7 +974,11 @@ pub fn trans_crate<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, // Skip crate items and just output metadata in -Z no-trans mode. if tcx.sess.opts.debugging_opts.no_trans || !tcx.sess.opts.output_types.should_trans() { - let empty_exported_symbols = ExportedSymbols::empty(); + let empty_exported_symbols = ExportedSymbols::new( + SymbolExportLevel::C, + Default::default(), + Default::default(), + ); let linker_info = LinkerInfo::new(&shared_ccx, &empty_exported_symbols); let ongoing_translation = write::start_async_translation( tcx.sess, @@ -1001,13 +1006,12 @@ pub fn trans_crate<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, return ongoing_translation; } - let exported_symbols = Arc::new(ExportedSymbols::compute(tcx, - &exported_symbol_node_ids)); + let exported_symbols = tcx.exported_symbols(); // Run the translation item collector and partition the collected items into // codegen units. let (translation_items, codegen_units) = - collect_and_partition_translation_items(&shared_ccx, &exported_symbols); + collect_and_partition_translation_items(shared_ccx.tcx(), &exported_symbols); assert!(codegen_units.len() <= 1 || !tcx.sess.lto()); @@ -1394,13 +1398,13 @@ fn assert_symbols_are_distinct<'a, 'tcx, I>(tcx: TyCtxt<'a, 'tcx, 'tcx>, trans_i } } -fn collect_and_partition_translation_items<'a, 'tcx>(scx: &SharedCrateContext<'a, 'tcx>, +fn collect_and_partition_translation_items<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, exported_symbols: &ExportedSymbols) -> (FxHashSet>, Vec>) { - let time_passes = scx.sess().time_passes(); + let time_passes = tcx.sess.time_passes(); - let collection_mode = match scx.sess().opts.debugging_opts.print_trans_items { + let collection_mode = match tcx.sess.opts.debugging_opts.print_trans_items { Some(ref s) => { let mode_string = s.to_lowercase(); let mode_string = mode_string.trim(); @@ -1411,7 +1415,7 @@ fn collect_and_partition_translation_items<'a, 'tcx>(scx: &SharedCrateContext<'a let message = format!("Unknown codegen-item collection mode '{}'. \ Falling back to 'lazy' mode.", mode_string); - scx.sess().warn(&message); + tcx.sess.warn(&message); } TransItemCollectionMode::Lazy @@ -1422,33 +1426,33 @@ fn collect_and_partition_translation_items<'a, 'tcx>(scx: &SharedCrateContext<'a let (items, inlining_map) = time(time_passes, "translation item collection", || { - collector::collect_crate_translation_items(scx.tcx(), + collector::collect_crate_translation_items(tcx, exported_symbols, collection_mode) }); - assert_symbols_are_distinct(scx.tcx(), items.iter()); + assert_symbols_are_distinct(tcx, items.iter()); - let strategy = if scx.sess().opts.debugging_opts.incremental.is_some() { + let strategy = if tcx.sess.opts.debugging_opts.incremental.is_some() { PartitioningStrategy::PerModule } else { - PartitioningStrategy::FixedUnitCount(scx.sess().opts.cg.codegen_units) + PartitioningStrategy::FixedUnitCount(tcx.sess.opts.cg.codegen_units) }; let codegen_units = time(time_passes, "codegen unit partitioning", || { - partitioning::partition(scx.tcx(), + partitioning::partition(tcx, items.iter().cloned(), strategy, &inlining_map, exported_symbols) }); - assert!(scx.tcx().sess.opts.cg.codegen_units == codegen_units.len() || - scx.tcx().sess.opts.debugging_opts.incremental.is_some()); + assert!(tcx.sess.opts.cg.codegen_units == codegen_units.len() || + tcx.sess.opts.debugging_opts.incremental.is_some()); let translation_items: FxHashSet> = items.iter().cloned().collect(); - if scx.sess().opts.debugging_opts.print_trans_items.is_some() { + if tcx.sess.opts.debugging_opts.print_trans_items.is_some() { let mut item_to_cgus = FxHashMap(); for cgu in &codegen_units { @@ -1462,7 +1466,7 @@ fn collect_and_partition_translation_items<'a, 'tcx>(scx: &SharedCrateContext<'a let mut item_keys: Vec<_> = items .iter() .map(|i| { - let mut output = i.to_string(scx.tcx()); + let mut output = i.to_string(tcx); output.push_str(" @@"); let mut empty = Vec::new(); let cgus = item_to_cgus.get_mut(i).unwrap_or(&mut empty); diff --git a/src/librustc_trans/collector.rs b/src/librustc_trans/collector.rs index bda035fc343..ff550d10c6d 100644 --- a/src/librustc_trans/collector.rs +++ b/src/librustc_trans/collector.rs @@ -194,6 +194,7 @@ use rustc::hir::itemlikevisit::ItemLikeVisitor; use rustc::hir::map as hir_map; use rustc::hir::def_id::DefId; use rustc::middle::const_val::ConstVal; +use rustc::middle::exported_symbols::ExportedSymbols; use rustc::middle::lang_items::{ExchangeMallocFnLangItem}; use rustc::traits; use rustc::ty::subst::Substs; @@ -209,7 +210,6 @@ use rustc::util::nodemap::{FxHashSet, FxHashMap, DefIdMap}; use trans_item::{TransItem, DefPathBasedNames, InstantiationMode}; use rustc_data_structures::bitvec::BitVector; -use back::symbol_export::ExportedSymbols; #[derive(PartialEq, Eq, Hash, Clone, Copy, Debug)] pub enum TransItemCollectionMode { diff --git a/src/librustc_trans/context.rs b/src/librustc_trans/context.rs index 3ad96d482f1..94695b4e046 100644 --- a/src/librustc_trans/context.rs +++ b/src/librustc_trans/context.rs @@ -14,10 +14,10 @@ use llvm::{ContextRef, ModuleRef, ValueRef}; use rustc::dep_graph::{DepGraph, DepGraphSafe}; use rustc::hir; use rustc::hir::def_id::DefId; +use rustc::middle::exported_symbols::ExportedSymbols; use rustc::traits; use debuginfo; use callee; -use back::symbol_export::ExportedSymbols; use base; use declare; use monomorphize::Instance; diff --git a/src/librustc_trans/lib.rs b/src/librustc_trans/lib.rs index 256200a6e95..8c8bd6a5e50 100644 --- a/src/librustc_trans/lib.rs +++ b/src/librustc_trans/lib.rs @@ -64,16 +64,17 @@ extern crate serialize; extern crate gcc; // Used to locate MSVC, not gcc :) pub use base::trans_crate; -pub use back::symbol_names::provide; pub use metadata::LlvmMetadataLoader; pub use llvm_util::{init, target_features, print_version, print_passes, print, enable_llvm_debug}; use std::rc::Rc; +use std::sync::Arc; -use rustc::hir::def_id::CrateNum; -use rustc::util::nodemap::{FxHashSet, FxHashMap}; +use rustc::hir::def_id::{CrateNum, LOCAL_CRATE}; use rustc::middle::cstore::{NativeLibrary, CrateSource, LibSource}; +use rustc::ty::maps::Providers; +use rustc::util::nodemap::{FxHashSet, FxHashMap}; pub mod back { mod archive; @@ -247,3 +248,15 @@ pub struct CrateInfo { } __build_diagnostic_array! { librustc_trans, DIAGNOSTICS } + +pub fn provide_local(providers: &mut Providers) { + back::symbol_names::provide(providers); + providers.exported_symbol_set = |tcx, cnum| { + assert_eq!(cnum, LOCAL_CRATE); + Arc::new(back::symbol_export::compute(tcx)) + }; +} + +pub fn provide_extern(providers: &mut Providers) { + back::symbol_names::provide(providers); +} diff --git a/src/librustc_trans/partitioning.rs b/src/librustc_trans/partitioning.rs index d436d0d8b6a..d47739b906c 100644 --- a/src/librustc_trans/partitioning.rs +++ b/src/librustc_trans/partitioning.rs @@ -102,7 +102,6 @@ //! source-level module, functions from the same module will be available for //! inlining, even when they are not marked #[inline]. -use back::symbol_export::ExportedSymbols; use collector::InliningMap; use common; use context::SharedCrateContext; @@ -110,6 +109,7 @@ use llvm; use rustc::dep_graph::{DepNode, WorkProductId}; use rustc::hir::def_id::DefId; use rustc::hir::map::DefPathData; +use rustc::middle::exported_symbols::ExportedSymbols; use rustc::session::config::NUMBERED_CODEGEN_UNIT_MARKER; use rustc::ty::{self, TyCtxt, InstanceDef}; use rustc::ty::item_path::characteristic_def_id_of_type;