- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
src/GenPoly/InstantiateGeneric.cc
rea5daeb rf18a711 24 24 #include "GenPoly.h" 25 25 #include "ScopedMap.h" 26 #include "ScopedSet.h" 26 27 27 28 #include "ResolvExpr/typeops.h" … … 122 123 } 123 124 }; 125 126 /// Possible options for a given specialization of a generic type 127 enum class genericType { 128 dtypeStatic, ///< Concrete instantiation based solely on {d,f}type-to-void conversions 129 concrete, ///< Concrete instantiation requiring at least one parameter type 130 dynamic ///< No concrete instantiation 131 }; 132 133 genericType& operator |= ( genericType& gt, const genericType& ht ) { 134 switch ( gt ) { 135 case genericType::dtypeStatic: 136 gt = ht; 137 break; 138 case genericType::concrete: 139 if ( ht == genericType::dynamic ) { gt = genericType::dynamic; } 140 break; 141 case genericType::dynamic: 142 // nothing possible 143 break; 144 } 145 return gt; 146 } 124 147 125 148 /// Mutator pass that replaces concrete instantiations of generic types with actual struct declarations, scoped appropriately … … 127 150 /// Map of (generic type, parameter list) pairs to concrete type instantiations 128 151 InstantiationMap< AggregateDecl, AggregateDecl > instantiations; 152 /// Set of types which are dtype-only generic (and therefore have static layout) 153 ScopedSet< AggregateDecl* > dtypeStatics; 129 154 /// Namer for concrete types 130 155 UniqueName typeNamer; 131 156 132 157 public: 133 GenericInstantiator() : DeclMutator(), instantiations(), typeNamer("_conc_") {}158 GenericInstantiator() : DeclMutator(), instantiations(), dtypeStatics(), typeNamer("_conc_") {} 134 159 135 160 virtual Type* mutate( StructInstType *inst ); … … 147 172 /// Wrap instantiation insertion for unions 148 173 void insert( UnionInstType *inst, const std::list< TypeExpr* > &typeSubs, UnionDecl *decl ) { instantiations.insert( inst->get_baseUnion(), typeSubs, decl ); } 174 175 /// Strips a dtype-static aggregate decl of its type parameters, marks it as stripped 176 void stripDtypeParams( AggregateDecl *base, std::list< TypeDecl* >& baseParams, const std::list< TypeExpr* >& typeSubs ); 149 177 }; 150 178 … … 154 182 } 155 183 156 //////////////////////////////////////// GenericInstantiator ////////////////////////////////////////////////// 157 158 /// Possible options for a given specialization of a generic type 159 enum class genericType { 160 dtypeStatic, ///< Concrete instantiation based solely on {d,f}type-to-void conversions 161 concrete, ///< Concrete instantiation requiring at least one parameter type 162 dynamic ///< No concrete instantiation 163 }; 164 165 genericType& operator |= ( genericType& gt, const genericType& ht ) { 166 switch ( gt ) { 167 case genericType::dtypeStatic: 168 gt = ht; 169 break; 170 case genericType::concrete: 171 if ( ht == genericType::dynamic ) { gt = genericType::dynamic; } 172 break; 173 case genericType::dynamic: 174 // nothing possible 175 break; 176 } 177 return gt; 178 } 179 180 /// Makes substitutions of params into baseParams; returns true if all parameters substituted for a concrete type 184 /// Makes substitutions of params into baseParams; returns dtypeStatic if there is a concrete instantiation based only on {d,f}type-to-void conversions, 185 /// concrete if there is a concrete instantiation requiring at least one parameter type, and dynamic if there is no concrete instantiation 181 186 genericType makeSubstitutions( const std::list< TypeDecl* >& baseParams, const std::list< Expression* >& params, std::list< TypeExpr* >& out ) { 182 187 genericType gt = genericType::dtypeStatic; … … 223 228 } 224 229 230 /// Substitutes types of members according to baseParams => typeSubs, working in-place 231 void substituteMembers( std::list< Declaration* >& members, const std::list< TypeDecl* >& baseParams, const std::list< TypeExpr* >& typeSubs ) { 232 // substitute types into new members 233 TypeSubstitution subs( baseParams.begin(), baseParams.end(), typeSubs.begin() ); 234 for ( std::list< Declaration* >::iterator member = members.begin(); member != members.end(); ++member ) { 235 subs.apply(*member); 236 } 237 } 238 239 /// Strips the instances's type parameters 240 void stripInstParams( ReferenceToType *inst ) { 241 deleteAll( inst->get_parameters() ); 242 inst->get_parameters().clear(); 243 } 244 245 void GenericInstantiator::stripDtypeParams( AggregateDecl *base, std::list< TypeDecl* >& baseParams, const std::list< TypeExpr* >& typeSubs ) { 246 substituteMembers( base->get_members(), baseParams, typeSubs ); 247 248 deleteAll( baseParams ); 249 baseParams.clear(); 250 251 dtypeStatics.insert( base ); 252 } 253 225 254 Type* GenericInstantiator::mutate( StructInstType *inst ) { 226 255 // mutate subtypes … … 231 260 // exit early if no need for further mutation 232 261 if ( inst->get_parameters().empty() ) return inst; 262 263 // check for an already-instantiatiated dtype-static type 264 if ( dtypeStatics.find( inst->get_baseStruct() ) != dtypeStatics.end() ) { 265 stripInstParams( inst ); 266 return inst; 267 } 268 269 // check if type can be concretely instantiated; put substitutions into typeSubs 233 270 assert( inst->get_baseParameters() && "Base struct has parameters" ); 234 235 // check if type can be concretely instantiated; put substitutions into typeSubs236 271 std::list< TypeExpr* > typeSubs; 237 272 genericType gt = makeSubstitutions( *inst->get_baseParameters(), inst->get_parameters(), typeSubs ); 238 273 switch ( gt ) { 239 case genericType::dtypeStatic: // TODO strip params off original decl and reuse here 240 case genericType::concrete: 241 { 274 case genericType::dtypeStatic: 275 stripDtypeParams( inst->get_baseStruct(), *inst->get_baseParameters(), typeSubs ); 276 stripInstParams( inst ); 277 break; 278 279 case genericType::concrete: { 242 280 // make concrete instantiation of generic type 243 281 StructDecl *concDecl = lookup( inst, typeSubs ); … … 274 312 // exit early if no need for further mutation 275 313 if ( inst->get_parameters().empty() ) return inst; 314 315 // check for an already-instantiatiated dtype-static type 316 if ( dtypeStatics.find( inst->get_baseUnion() ) != dtypeStatics.end() ) { 317 stripInstParams( inst ); 318 return inst; 319 } 320 321 // check if type can be concretely instantiated; put substitutions into typeSubs 276 322 assert( inst->get_baseParameters() && "Base union has parameters" ); 277 278 // check if type can be concretely instantiated; put substitutions into typeSubs279 323 std::list< TypeExpr* > typeSubs; 280 324 genericType gt = makeSubstitutions( *inst->get_baseParameters(), inst->get_parameters(), typeSubs ); 281 325 switch ( gt ) { 282 case genericType::dtypeStatic: // TODO strip params off original decls and reuse here 326 case genericType::dtypeStatic: 327 stripDtypeParams( inst->get_baseUnion(), *inst->get_baseParameters(), typeSubs ); 328 stripInstParams( inst ); 329 break; 330 283 331 case genericType::concrete: 284 332 { … … 311 359 DeclMutator::doBeginScope(); 312 360 instantiations.beginScope(); 361 dtypeStatics.beginScope(); 313 362 } 314 363 … … 316 365 DeclMutator::doEndScope(); 317 366 instantiations.endScope(); 367 dtypeStatics.endScope(); 318 368 } 319 369
Note:
See TracChangeset
for help on using the changeset viewer.