88// option. This file may not be copied, modified, or distributed
99// except according to those terms.
1010
11- use context:: SharedCrateContext ;
1211use monomorphize:: Instance ;
13- use rustc:: util:: nodemap:: FxHashMap ;
14- use rustc:: hir:: def_id:: { DefId , CrateNum , LOCAL_CRATE } ;
12+ use rustc:: util:: nodemap:: { FxHashMap , NodeSet } ;
13+ use rustc:: hir:: def_id:: { DefId , CrateNum , LOCAL_CRATE , INVALID_CRATE , CRATE_DEF_INDEX } ;
1514use rustc:: session:: config;
1615use rustc:: ty:: TyCtxt ;
1716use syntax:: attr;
@@ -28,59 +27,87 @@ pub enum SymbolExportLevel {
2827}
2928
3029/// The set of symbols exported from each crate in the crate graph.
30+ #[ derive( Debug ) ]
3131pub struct ExportedSymbols {
32- exports : FxHashMap < CrateNum , Vec < ( String , SymbolExportLevel ) > > ,
32+ pub export_threshold : SymbolExportLevel ,
33+ exports : FxHashMap < CrateNum , Vec < ( String , DefId , SymbolExportLevel ) > > ,
34+ local_exports : NodeSet ,
3335}
3436
3537impl ExportedSymbols {
3638 pub fn empty ( ) -> ExportedSymbols {
3739 ExportedSymbols {
40+ export_threshold : SymbolExportLevel :: C ,
3841 exports : FxHashMap ( ) ,
42+ local_exports : NodeSet ( ) ,
3943 }
4044 }
4145
42- pub fn compute < ' a , ' tcx > ( scx : & SharedCrateContext < ' a , ' tcx > ) -> ExportedSymbols {
43- let mut local_crate: Vec < _ > = scx
44- . exported_symbols ( )
46+ pub fn compute < ' a , ' tcx > ( tcx : TyCtxt < ' a , ' tcx , ' tcx > ,
47+ local_exported_symbols : & NodeSet )
48+ -> ExportedSymbols {
49+ let export_threshold = crates_export_threshold ( & tcx. sess . crate_types . borrow ( ) ) ;
50+
51+ let mut local_crate: Vec < _ > = local_exported_symbols
4552 . iter ( )
4653 . map ( |& node_id| {
47- scx . tcx ( ) . hir . local_def_id ( node_id)
54+ tcx. hir . local_def_id ( node_id)
4855 } )
4956 . map ( |def_id| {
50- let name = scx . tcx ( ) . symbol_name ( Instance :: mono ( scx . tcx ( ) , def_id) ) ;
51- let export_level = export_level ( scx , def_id) ;
57+ let name = tcx. symbol_name ( Instance :: mono ( tcx, def_id) ) ;
58+ let export_level = export_level ( tcx , def_id) ;
5259 debug ! ( "EXPORTED SYMBOL (local): {} ({:?})" , name, export_level) ;
53- ( str:: to_owned ( & name) , export_level)
60+ ( str:: to_owned ( & name) , def_id , export_level)
5461 } )
5562 . collect ( ) ;
5663
57- if scx. sess ( ) . entry_fn . borrow ( ) . is_some ( ) {
58- local_crate. push ( ( "main" . to_string ( ) , SymbolExportLevel :: C ) ) ;
64+ let mut local_exports = local_crate
65+ . iter ( )
66+ . filter_map ( |& ( _, def_id, level) | {
67+ if is_below_threshold ( level, export_threshold) {
68+ tcx. hir . as_local_node_id ( def_id)
69+ } else {
70+ None
71+ }
72+ } )
73+ . collect :: < NodeSet > ( ) ;
74+
75+ const INVALID_DEF_ID : DefId = DefId {
76+ krate : INVALID_CRATE ,
77+ index : CRATE_DEF_INDEX ,
78+ } ;
79+
80+ if let Some ( _) = * tcx. sess . entry_fn . borrow ( ) {
81+ local_crate. push ( ( "main" . to_string ( ) ,
82+ INVALID_DEF_ID ,
83+ SymbolExportLevel :: C ) ) ;
5984 }
6085
61- if let Some ( id) = scx . sess ( ) . derive_registrar_fn . get ( ) {
62- let def_id = scx . tcx ( ) . hir . local_def_id ( id) ;
86+ if let Some ( id) = tcx . sess . derive_registrar_fn . get ( ) {
87+ let def_id = tcx. hir . local_def_id ( id) ;
6388 let idx = def_id. index ;
64- let disambiguator = scx. sess ( ) . local_crate_disambiguator ( ) ;
65- let registrar = scx. sess ( ) . generate_derive_registrar_symbol ( disambiguator, idx) ;
66- local_crate. push ( ( registrar, SymbolExportLevel :: C ) ) ;
89+ let disambiguator = tcx. sess . local_crate_disambiguator ( ) ;
90+ let registrar = tcx. sess . generate_derive_registrar_symbol ( disambiguator, idx) ;
91+ local_crate. push ( ( registrar, def_id, SymbolExportLevel :: C ) ) ;
92+ local_exports. insert ( id) ;
6793 }
6894
69- if scx. sess ( ) . crate_types . borrow ( ) . contains ( & config:: CrateTypeDylib ) {
70- local_crate. push ( ( metadata_symbol_name ( scx. tcx ( ) ) ,
95+ if tcx. sess . crate_types . borrow ( ) . contains ( & config:: CrateTypeDylib ) {
96+ local_crate. push ( ( metadata_symbol_name ( tcx) ,
97+ INVALID_DEF_ID ,
7198 SymbolExportLevel :: Rust ) ) ;
7299 }
73100
74101 let mut exports = FxHashMap ( ) ;
75102 exports. insert ( LOCAL_CRATE , local_crate) ;
76103
77- for cnum in scx . sess ( ) . cstore . crates ( ) {
104+ for cnum in tcx . sess . cstore . crates ( ) {
78105 debug_assert ! ( cnum != LOCAL_CRATE ) ;
79106
80107 // If this crate is a plugin and/or a custom derive crate, then
81108 // we're not even going to link those in so we skip those crates.
82- if scx . sess ( ) . cstore . plugin_registrar_fn ( cnum) . is_some ( ) ||
83- scx . sess ( ) . cstore . derive_registrar_fn ( cnum) . is_some ( ) {
109+ if tcx . sess . cstore . plugin_registrar_fn ( cnum) . is_some ( ) ||
110+ tcx . sess . cstore . derive_registrar_fn ( cnum) . is_some ( ) {
84111 continue ;
85112 }
86113
@@ -92,16 +119,16 @@ impl ExportedSymbols {
92119 // Down below we'll hardwire all of the symbols to the `Rust` export
93120 // level instead.
94121 let special_runtime_crate =
95- scx . tcx ( ) . is_panic_runtime ( cnum. as_def_id ( ) ) ||
96- scx . sess ( ) . cstore . is_compiler_builtins ( cnum) ;
122+ tcx. is_panic_runtime ( cnum. as_def_id ( ) ) ||
123+ tcx . sess . cstore . is_compiler_builtins ( cnum) ;
97124
98- let crate_exports = scx
99- . sess ( )
125+ let crate_exports = tcx
126+ . sess
100127 . cstore
101128 . exported_symbols ( cnum)
102129 . iter ( )
103130 . map ( |& def_id| {
104- let name = scx . tcx ( ) . symbol_name ( Instance :: mono ( scx . tcx ( ) , def_id) ) ;
131+ let name = tcx. symbol_name ( Instance :: mono ( tcx, def_id) ) ;
105132 let export_level = if special_runtime_crate {
106133 // We can probably do better here by just ensuring that
107134 // it has hidden visibility rather than public
@@ -118,35 +145,41 @@ impl ExportedSymbols {
118145 SymbolExportLevel :: Rust
119146 }
120147 } else {
121- export_level ( scx , def_id)
148+ export_level ( tcx , def_id)
122149 } ;
123150 debug ! ( "EXPORTED SYMBOL (re-export): {} ({:?})" , name, export_level) ;
124- ( str:: to_owned ( & name) , export_level)
151+ ( str:: to_owned ( & name) , def_id , export_level)
125152 } )
126153 . collect ( ) ;
127154
128155 exports. insert ( cnum, crate_exports) ;
129156 }
130157
131158 return ExportedSymbols {
132- exports : exports
159+ export_threshold,
160+ exports,
161+ local_exports,
133162 } ;
134163
135- fn export_level ( scx : & SharedCrateContext ,
164+ fn export_level ( tcx : TyCtxt ,
136165 sym_def_id : DefId )
137166 -> SymbolExportLevel {
138- let attrs = scx . tcx ( ) . get_attrs ( sym_def_id) ;
139- if attr:: contains_extern_indicator ( scx . sess ( ) . diagnostic ( ) , & attrs) {
167+ let attrs = tcx. get_attrs ( sym_def_id) ;
168+ if attr:: contains_extern_indicator ( tcx . sess . diagnostic ( ) , & attrs) {
140169 SymbolExportLevel :: C
141170 } else {
142171 SymbolExportLevel :: Rust
143172 }
144173 }
145174 }
146175
176+ pub fn local_exports ( & self ) -> & NodeSet {
177+ & self . local_exports
178+ }
179+
147180 pub fn exported_symbols ( & self ,
148181 cnum : CrateNum )
149- -> & [ ( String , SymbolExportLevel ) ] {
182+ -> & [ ( String , DefId , SymbolExportLevel ) ] {
150183 match self . exports . get ( & cnum) {
151184 Some ( exports) => exports,
152185 None => & [ ]
@@ -155,13 +188,12 @@ impl ExportedSymbols {
155188
156189 pub fn for_each_exported_symbol < F > ( & self ,
157190 cnum : CrateNum ,
158- export_threshold : SymbolExportLevel ,
159191 mut f : F )
160- where F : FnMut ( & str , SymbolExportLevel )
192+ where F : FnMut ( & str , DefId , SymbolExportLevel )
161193 {
162- for & ( ref name, export_level) in self . exported_symbols ( cnum) {
163- if is_below_threshold ( export_level, export_threshold) {
164- f ( & name, export_level)
194+ for & ( ref name, def_id , export_level) in self . exported_symbols ( cnum) {
195+ if is_below_threshold ( export_level, self . export_threshold ) {
196+ f ( & name, def_id , export_level)
165197 }
166198 }
167199 }
0 commit comments