@@ -376,6 +376,16 @@ pub struct SymbolStorage {
376376 pub variable_symbols : HashMap < ZeroSpan , SymbolRef > ,
377377}
378378
379+ impl SymbolStorage {
380+ pub fn all_symbols < ' a > ( & ' a self ) -> impl Iterator < Item = & ' a SymbolRef > {
381+ self . template_symbols . values ( )
382+ . chain ( self . param_symbols . values ( ) . flat_map ( |h|h. values ( ) ) )
383+ . chain ( self . object_symbols . values ( ) )
384+ . chain ( self . method_symbols . values ( ) )
385+ . chain ( self . variable_symbols . values ( ) )
386+ }
387+ }
388+
379389// This maps non-auth symbol decls to auth decl
380390// and references to the symbol decl they ref
381391type ReferenceStorage = HashMap < ZeroSpan , Vec < SymbolRef > > ;
@@ -2030,6 +2040,78 @@ fn add_new_method_scope_symbols(method: &Arc<DMLMethodRef>,
20302040
20312041
20322042impl DeviceAnalysis {
2043+ fn make_templates_traits ( start_of_file : & ZeroSpan ,
2044+ rank_maker : & mut RankMaker ,
2045+ unique_templates : & HashMap <
2046+ & str , & ObjectDecl < Template > > ,
2047+ files : & HashMap < & str , & TopLevel > ,
2048+ imp_map : & HashMap < Import , String > ,
2049+ errors : & mut Vec < DMLError > )
2050+ -> TemplateTraitInfo {
2051+ info ! ( "Rank templates" ) ;
2052+ let ( templates, order, invalid_isimps, rank_struct)
2053+ = rank_templates ( unique_templates, files, imp_map, errors) ;
2054+ info ! ( "Templates+traits" ) ;
2055+ create_templates_traits (
2056+ start_of_file,
2057+ rank_maker, templates, order,
2058+ invalid_isimps, imp_map, rank_struct, errors)
2059+ }
2060+
2061+ fn match_references ( & mut self ,
2062+ bases : & Vec < IsolatedAnalysis > ,
2063+ method_structure : & HashMap < ZeroSpan , RangeEntry > ,
2064+ errors : & mut Vec < DMLError > ) {
2065+ info ! ( "Match references" ) ;
2066+ let reference_cache: Mutex < ReferenceCache > = Mutex :: default ( ) ;
2067+ for scope_chain in all_scopes ( bases) {
2068+ self . match_references_in_scope ( scope_chain,
2069+ errors,
2070+ method_structure,
2071+ & reference_cache) ;
2072+ }
2073+ }
2074+
2075+ fn inverse_references ( & mut self ) {
2076+ info ! ( "Inverse map" ) ;
2077+ // Set up the inverse map of references->symbols
2078+ for symbol in self . symbol_info . all_symbols ( ) {
2079+ debug ! ( "Inverse of {:?}" , symbol) ;
2080+ for ref_loc in & symbol. lock ( ) . unwrap ( ) . references {
2081+ self . reference_info . entry ( * ref_loc)
2082+ . or_default ( ) . push ( Arc :: clone ( symbol) ) ;
2083+ }
2084+ }
2085+ }
2086+
2087+ fn template_object_map ( tt_info : & TemplateTraitInfo ,
2088+ container : & StructureContainer )
2089+ -> HashMap < ZeroSpan , Vec < StructureKey > > {
2090+ // Tie objects to their implemented templates, and vice-versa
2091+ // NOTE: This cannot be inside DMLTemplates, because due to RC
2092+ // references they are immutable once created
2093+ trace ! ( "template->object map" ) ;
2094+ // maps template declaration loc to objects
2095+ let mut template_object_implementation_map: HashMap < ZeroSpan ,
2096+ Vec < StructureKey > >
2097+ = HashMap :: new ( ) ;
2098+ for template in tt_info. templates . values ( ) {
2099+ if let Some ( loc) = template. location . as_ref ( ) {
2100+ template_object_implementation_map. insert ( * loc, vec ! [ ] ) ;
2101+ }
2102+ }
2103+ for object in container. values ( ) {
2104+ for template in object. templates . values ( ) {
2105+ if let Some ( loc) = template. location . as_ref ( ) {
2106+ template_object_implementation_map
2107+ . entry ( * loc)
2108+ . or_default ( ) . push ( object. key ) ;
2109+ }
2110+ }
2111+ }
2112+ template_object_implementation_map
2113+ }
2114+
20332115 pub fn new ( root : IsolatedAnalysis ,
20342116 timed_bases : Vec < TimestampedStorage < IsolatedAnalysis > > ,
20352117 imp_map : HashMap < Import , String > )
@@ -2106,15 +2188,13 @@ impl DeviceAnalysis {
21062188 trace ! ( "Tracked file {} as template" ,
21072189 base. path. to_str( ) . unwrap_or( "no path" ) ) ;
21082190 }
2109- info ! ( "Rank templates" ) ;
2110- let ( templates, order, invalid_isimps, rank_struct)
2111- = rank_templates ( & unique_templates, & files, & imp_map, & mut errors) ;
2112- let mut rankmaker = RankMaker :: new ( ) ;
2113- info ! ( "Templates+traits" ) ;
2114- let tt_info = create_templates_traits (
2115- & root. toplevel . start_of_file ,
2116- & mut rankmaker, templates, order,
2117- invalid_isimps, & imp_map, rank_struct, & mut errors) ;
2191+ let mut rank_maker = RankMaker :: new ( ) ;
2192+ let tt_info = Self :: make_templates_traits ( & root. toplevel . start_of_file ,
2193+ & mut rank_maker,
2194+ & unique_templates,
2195+ & files,
2196+ & imp_map,
2197+ & mut errors) ;
21182198
21192199 // TODO: catch typedef/traitname overlaps
21202200
@@ -2123,37 +2203,19 @@ impl DeviceAnalysis {
21232203 info ! ( "Make device" ) ;
21242204 let device_key = make_device ( root. path . as_str ( ) , & root. toplevel ,
21252205 & tt_info, imp_map, & mut container,
2126- & mut rankmaker, & mut errors) . key ;
2127- // Tie objects to their implemented templates, and vice-versa
2128- // NOTE: This cannot be inside DMLTemplates, because due to RC
2129- // references they are immutable once created
2130- trace ! ( "template->object map" ) ;
2206+ & mut rank_maker, & mut errors) . key ;
2207+
21312208 // maps template declaration loc to objects
2132- let mut template_object_implementation_map: HashMap < ZeroSpan ,
2133- Vec < StructureKey > >
2134- = HashMap :: new ( ) ;
2135- for template in tt_info. templates . values ( ) {
2136- if let Some ( loc) = template. location . as_ref ( ) {
2137- template_object_implementation_map. insert ( * loc, vec ! [ ] ) ;
2138- }
2139- }
2140- for object in container. values ( ) {
2141- for template in object. templates . values ( ) {
2142- if let Some ( loc) = template. location . as_ref ( ) {
2143- template_object_implementation_map
2144- . entry ( * loc)
2145- . or_default ( ) . push ( object. key ) ;
2146- }
2147- }
2148- }
2209+ let template_object_implementation_map =
2210+ Self :: template_object_map ( & tt_info, & container) ;
21492211
21502212 info ! ( "Generate symbols" ) ;
21512213 // Used to handle scoping in methods when looking up local symbols,
21522214 // NOTE: if this meta-information becomes relevant later, move this
21532215 // structure to symbol storage
21542216 // The zerospan here is the span corresponding to the span of the
21552217 // NAME of the methoddecl
2156- let mut method_structure: HashMap < ZeroSpan , RangeEntry >
2218+ let mut method_structure: HashMap < ZeroSpan , RangeEntry >
21572219 = HashMap :: default ( ) ;
21582220
21592221 let mut symbol_info = objects_to_symbols ( & container,
@@ -2177,42 +2239,10 @@ impl DeviceAnalysis {
21772239 dependant_files : bases. iter ( ) . map ( |b|& b. path ) . cloned ( ) . collect ( ) ,
21782240 } ;
21792241
2180- info ! ( "Match references" ) ;
2181- let reference_cache: Mutex < ReferenceCache > = Mutex :: default ( ) ;
2182- for scope_chain in all_scopes ( & bases) {
2183- device. match_references_in_scope ( scope_chain,
2184- & mut errors,
2185- & method_structure,
2186- & reference_cache) ;
2187- }
2242+ device. match_references ( & bases, & method_structure, & mut errors) ;
21882243
2189- info ! ( "Inverse map" ) ;
2190- // Set up the inverse map of references->symbols
2191- for symbol in device. symbol_info . template_symbols . values ( )
2192- . chain ( device. symbol_info . param_symbols
2193- . values ( ) . flat_map ( |h|h. values ( ) ) )
2194- . chain ( device. symbol_info . object_symbols . values ( ) )
2195- . chain ( device. symbol_info . method_symbols . values ( ) )
2196- . chain ( device. symbol_info . variable_symbols . values ( ) ) {
2197- debug ! ( "Inverse of {:?}" , symbol) ;
2198- for ref_loc in & symbol. lock ( ) . unwrap ( ) . references {
2199- device. reference_info . entry ( * ref_loc)
2200- . or_default ( ) . push ( Arc :: clone ( symbol) ) ;
2201- }
2202- }
2244+ device. inverse_references ( ) ;
22032245
2204- info ! ( "Implementation map" ) ;
2205- for ( templ_loc, objects) in & device. template_object_implementation_map {
2206- if let Some ( templ) = device. symbol_info
2207- . template_symbols . get ( templ_loc) {
2208- let mut sym_mut = templ. lock ( ) . unwrap ( ) ;
2209- sym_mut. implementations . extend (
2210- objects. iter ( ) . flat_map (
2211- |obj|device. objects . get ( * obj) . unwrap ( )
2212- . all_decls . iter ( ) . map (
2213- |spec|* spec. loc_span ( ) ) ) ) ;
2214- }
2215- }
22162246 info ! ( "Invariant check" ) ;
22172247 for obj in device. objects . values ( ) {
22182248 device. param_invariants ( obj, & mut errors) ;
0 commit comments