@@ -13,17 +13,17 @@ use decoder;
1313use encoder;
1414use loader;
1515
16- use middle:: cstore:: { CrateStore , CrateSource , ChildItem , ExternCrate , FoundAst } ;
16+ use middle:: cstore:: { CrateStore , CrateSource , ChildItem , ExternCrate , FoundAst , DefLike } ;
1717use middle:: cstore:: { NativeLibraryKind , LinkMeta , LinkagePreference } ;
1818use middle:: def;
1919use middle:: lang_items;
2020use rustc:: ty:: { self , Ty , TyCtxt , VariantKind } ;
21- use middle:: def_id:: { DefId , DefIndex } ;
21+ use middle:: def_id:: { DefId , DefIndex , CRATE_DEF_INDEX } ;
2222
2323use rustc:: front:: map as hir_map;
2424use rustc:: mir:: repr:: Mir ;
2525use rustc:: mir:: mir_map:: MirMap ;
26- use rustc:: util:: nodemap:: { FnvHashMap , NodeMap , NodeSet } ;
26+ use rustc:: util:: nodemap:: { FnvHashMap , NodeMap , NodeSet , DefIdMap } ;
2727
2828use std:: cell:: RefCell ;
2929use std:: rc:: Rc ;
@@ -544,4 +544,60 @@ impl<'tcx> CrateStore<'tcx> for cstore::CStore {
544544 {
545545 encoder:: metadata_encoding_version
546546 }
547+
548+ /// Returns a map from a sufficiently visible external item (i.e. an external item that is
549+ /// visible from at least one local module) to a sufficiently visible parent (considering
550+ /// modules that re-export the external item to be parents).
551+ fn visible_parent_map < ' a > ( & ' a self ) -> :: std:: cell:: RefMut < ' a , DefIdMap < DefId > > {
552+ let mut visible_parent_map = self . visible_parent_map . borrow_mut ( ) ;
553+ if !visible_parent_map. is_empty ( ) { return visible_parent_map; }
554+
555+ use rustc_front:: hir;
556+ use rustc:: middle:: cstore:: { CrateStore , ChildItem } ;
557+ use std:: collections:: vec_deque:: VecDeque ;
558+ use std:: collections:: hash_map:: Entry ;
559+ for cnum in 1 .. self . next_crate_num ( ) {
560+ let cdata = self . get_crate_data ( cnum) ;
561+
562+ match cdata. extern_crate . get ( ) {
563+ // Ignore crates without a corresponding local `extern crate` item.
564+ Some ( extern_crate) if !extern_crate. direct => continue ,
565+ _ => { } ,
566+ }
567+
568+ let mut bfs_queue = & mut VecDeque :: new ( ) ;
569+ let mut add_child = |bfs_queue : & mut VecDeque < _ > , child : ChildItem , parent : DefId | {
570+ let child = match child. def {
571+ DefLike :: DlDef ( def) if child. vis == hir:: Public => def. def_id ( ) ,
572+ _ => return ,
573+ } ;
574+
575+ match visible_parent_map. entry ( child) {
576+ Entry :: Occupied ( mut entry) => {
577+ // If `child` is defined in crate `cnum`, ensure
578+ // that it is mapped to a parent in `cnum`.
579+ if child. krate == cnum && entry. get ( ) . krate != cnum {
580+ entry. insert ( parent) ;
581+ }
582+ }
583+ Entry :: Vacant ( entry) => {
584+ entry. insert ( parent) ;
585+ bfs_queue. push_back ( child) ;
586+ }
587+ }
588+ } ;
589+
590+ let croot = DefId { krate : cnum, index : CRATE_DEF_INDEX } ;
591+ for child in self . crate_top_level_items ( cnum) {
592+ add_child ( bfs_queue, child, croot) ;
593+ }
594+ while let Some ( def) = bfs_queue. pop_front ( ) {
595+ for child in self . item_children ( def) {
596+ add_child ( bfs_queue, child, def) ;
597+ }
598+ }
599+ }
600+
601+ visible_parent_map
602+ }
547603}
0 commit comments