@@ -103,6 +103,7 @@ use util::sha2::{Digest, Sha256};
103103
104104use rustc:: middle:: { cstore, weak_lang_items} ;
105105use rustc:: hir:: def_id:: DefId ;
106+ use rustc:: hir:: map as hir_map;
106107use rustc:: ty:: { self , TyCtxt , TypeFoldable } ;
107108use rustc:: ty:: item_path:: { self , ItemPathBuffer , RootMode } ;
108109use rustc:: hir:: map:: definitions:: { DefPath , DefPathData } ;
@@ -192,89 +193,100 @@ fn get_symbol_hash<'a, 'tcx>(scx: &SharedCrateContext<'a, 'tcx>,
192193 }
193194}
194195
195- pub fn exported_name < ' a , ' tcx > ( scx : & SharedCrateContext < ' a , ' tcx > ,
196- instance : Instance < ' tcx > )
197- -> String {
198- let Instance { def : def_id, ref substs } = instance;
196+ impl < ' a , ' tcx > Instance < ' tcx > {
197+ pub fn symbol_name ( self , scx : & SharedCrateContext < ' a , ' tcx > ) -> String {
198+ let Instance { def : def_id, ref substs } = self ;
199199
200- debug ! ( "exported_name (def_id={:?}, substs={:?})" ,
201- def_id, substs) ;
200+ debug ! ( "symbol_name (def_id={:?}, substs={:?})" ,
201+ def_id, substs) ;
202202
203- let node_id = scx. tcx ( ) . map . as_local_node_id ( instance . def ) ;
203+ let node_id = scx. tcx ( ) . map . as_local_node_id ( def_id ) ;
204204
205- if let Some ( id) = node_id {
206- if scx. sess ( ) . plugin_registrar_fn . get ( ) == Some ( id) {
207- let svh = & scx. link_meta ( ) . crate_hash ;
208- let idx = instance. def . index ;
209- return scx. sess ( ) . generate_plugin_registrar_symbol ( svh, idx) ;
205+ if let Some ( id) = node_id {
206+ if scx. sess ( ) . plugin_registrar_fn . get ( ) == Some ( id) {
207+ let svh = & scx. link_meta ( ) . crate_hash ;
208+ let idx = def_id. index ;
209+ return scx. sess ( ) . generate_plugin_registrar_symbol ( svh, idx) ;
210+ }
210211 }
211- }
212-
213- // FIXME(eddyb) Precompute a custom symbol name based on attributes.
214- let attrs;
215- let attrs = if let Some ( id) = node_id {
216- scx. tcx ( ) . map . attrs ( id)
217- } else {
218- attrs = scx. sess ( ) . cstore . item_attrs ( def_id) ;
219- & attrs[ ..]
220- } ;
221212
222- if let Some ( name) = attr:: find_export_name_attr ( scx. sess ( ) . diagnostic ( ) , attrs) {
223- // Use provided name
224- return name. to_string ( ) ;
225- }
213+ // FIXME(eddyb) Precompute a custom symbol name based on attributes.
214+ let attrs = scx. tcx ( ) . get_attrs ( def_id) ;
215+ let is_foreign = if let Some ( id) = node_id {
216+ match scx. tcx ( ) . map . get ( id) {
217+ hir_map:: NodeForeignItem ( _) => true ,
218+ _ => false
219+ }
220+ } else {
221+ scx. sess ( ) . cstore . is_foreign_item ( def_id)
222+ } ;
226223
227- if attr:: contains_name ( attrs, "no_mangle" ) {
228- // Don't mangle
229- return scx. tcx ( ) . item_name ( instance. def ) . as_str ( ) . to_string ( )
230- }
231- if let Some ( name) = weak_lang_items:: link_name ( attrs) {
232- return name. to_string ( ) ;
233- }
224+ if let Some ( name) = weak_lang_items:: link_name ( & attrs) {
225+ return name. to_string ( ) ;
226+ }
234227
235- let def_path = scx. tcx ( ) . def_path ( def_id) ;
236-
237- // We want to compute the "type" of this item. Unfortunately, some
238- // kinds of items (e.g., closures) don't have an entry in the
239- // item-type array. So walk back up the find the closest parent
240- // that DOES have an entry.
241- let mut ty_def_id = def_id;
242- let instance_ty;
243- loop {
244- let key = scx. tcx ( ) . def_key ( ty_def_id) ;
245- match key. disambiguated_data . data {
246- DefPathData :: TypeNs ( _) |
247- DefPathData :: ValueNs ( _) => {
248- instance_ty = scx. tcx ( ) . lookup_item_type ( ty_def_id) ;
249- break ;
228+ if is_foreign {
229+ if let Some ( name) = attr:: first_attr_value_str_by_name ( & attrs, "link_name" ) {
230+ return name. to_string ( ) ;
250231 }
251- _ => {
252- // if we're making a symbol for something, there ought
253- // to be a value or type-def or something in there
254- // *somewhere*
255- ty_def_id. index = key. parent . unwrap_or_else ( || {
256- bug ! ( "finding type for {:?}, encountered def-id {:?} with no \
257- parent", def_id, ty_def_id) ;
258- } ) ;
232+ // Don't mangle foreign items.
233+ return scx. tcx ( ) . item_name ( def_id) . as_str ( ) . to_string ( ) ;
234+ }
235+
236+ if let Some ( name) = attr:: find_export_name_attr ( scx. sess ( ) . diagnostic ( ) , & attrs) {
237+ // Use provided name
238+ return name. to_string ( ) ;
239+ }
240+
241+ if attr:: contains_name ( & attrs, "no_mangle" ) {
242+ // Don't mangle
243+ return scx. tcx ( ) . item_name ( def_id) . as_str ( ) . to_string ( ) ;
244+ }
245+
246+ let def_path = scx. tcx ( ) . def_path ( def_id) ;
247+
248+ // We want to compute the "type" of this item. Unfortunately, some
249+ // kinds of items (e.g., closures) don't have an entry in the
250+ // item-type array. So walk back up the find the closest parent
251+ // that DOES have an entry.
252+ let mut ty_def_id = def_id;
253+ let instance_ty;
254+ loop {
255+ let key = scx. tcx ( ) . def_key ( ty_def_id) ;
256+ match key. disambiguated_data . data {
257+ DefPathData :: TypeNs ( _) |
258+ DefPathData :: ValueNs ( _) => {
259+ instance_ty = scx. tcx ( ) . lookup_item_type ( ty_def_id) ;
260+ break ;
261+ }
262+ _ => {
263+ // if we're making a symbol for something, there ought
264+ // to be a value or type-def or something in there
265+ // *somewhere*
266+ ty_def_id. index = key. parent . unwrap_or_else ( || {
267+ bug ! ( "finding type for {:?}, encountered def-id {:?} with no \
268+ parent", def_id, ty_def_id) ;
269+ } ) ;
270+ }
259271 }
260272 }
261- }
262273
263- // Erase regions because they may not be deterministic when hashed
264- // and should not matter anyhow.
265- let instance_ty = scx. tcx ( ) . erase_regions ( & instance_ty. ty ) ;
274+ // Erase regions because they may not be deterministic when hashed
275+ // and should not matter anyhow.
276+ let instance_ty = scx. tcx ( ) . erase_regions ( & instance_ty. ty ) ;
266277
267- let hash = get_symbol_hash ( scx, & def_path, instance_ty, substs. types . as_slice ( ) ) ;
278+ let hash = get_symbol_hash ( scx, & def_path, instance_ty, substs. types . as_slice ( ) ) ;
268279
269- let mut buffer = SymbolPathBuffer {
270- names : Vec :: with_capacity ( def_path. data . len ( ) )
271- } ;
280+ let mut buffer = SymbolPathBuffer {
281+ names : Vec :: with_capacity ( def_path. data . len ( ) )
282+ } ;
272283
273- item_path:: with_forced_absolute_paths ( || {
274- scx. tcx ( ) . push_item_path ( & mut buffer, def_id) ;
275- } ) ;
284+ item_path:: with_forced_absolute_paths ( || {
285+ scx. tcx ( ) . push_item_path ( & mut buffer, def_id) ;
286+ } ) ;
276287
277- mangle ( buffer. names . into_iter ( ) , Some ( & hash[ ..] ) )
288+ mangle ( buffer. names . into_iter ( ) , Some ( & hash[ ..] ) )
289+ }
278290}
279291
280292struct SymbolPathBuffer {
0 commit comments