- File:
-
- 1 edited
-
src/GenPoly/InstantiateGeneric.cc (modified) (10 diffs)
Legend:
- Unmodified
- Added
- Removed
-
src/GenPoly/InstantiateGeneric.cc
rf18a711 rea5daeb 24 24 #include "GenPoly.h" 25 25 #include "ScopedMap.h" 26 #include "ScopedSet.h"27 26 28 27 #include "ResolvExpr/typeops.h" … … 123 122 } 124 123 }; 125 126 /// Possible options for a given specialization of a generic type127 enum class genericType {128 dtypeStatic, ///< Concrete instantiation based solely on {d,f}type-to-void conversions129 concrete, ///< Concrete instantiation requiring at least one parameter type130 dynamic ///< No concrete instantiation131 };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 possible143 break;144 }145 return gt;146 }147 124 148 125 /// Mutator pass that replaces concrete instantiations of generic types with actual struct declarations, scoped appropriately … … 150 127 /// Map of (generic type, parameter list) pairs to concrete type instantiations 151 128 InstantiationMap< AggregateDecl, AggregateDecl > instantiations; 152 /// Set of types which are dtype-only generic (and therefore have static layout)153 ScopedSet< AggregateDecl* > dtypeStatics;154 129 /// Namer for concrete types 155 130 UniqueName typeNamer; 156 131 157 132 public: 158 GenericInstantiator() : DeclMutator(), instantiations(), dtypeStatics(),typeNamer("_conc_") {}133 GenericInstantiator() : DeclMutator(), instantiations(), typeNamer("_conc_") {} 159 134 160 135 virtual Type* mutate( StructInstType *inst ); … … 172 147 /// Wrap instantiation insertion for unions 173 148 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 stripped176 void stripDtypeParams( AggregateDecl *base, std::list< TypeDecl* >& baseParams, const std::list< TypeExpr* >& typeSubs );177 149 }; 178 150 … … 182 154 } 183 155 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 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 186 181 genericType makeSubstitutions( const std::list< TypeDecl* >& baseParams, const std::list< Expression* >& params, std::list< TypeExpr* >& out ) { 187 182 genericType gt = genericType::dtypeStatic; … … 228 223 } 229 224 230 /// Substitutes types of members according to baseParams => typeSubs, working in-place231 void substituteMembers( std::list< Declaration* >& members, const std::list< TypeDecl* >& baseParams, const std::list< TypeExpr* >& typeSubs ) {232 // substitute types into new members233 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 parameters240 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 254 225 Type* GenericInstantiator::mutate( StructInstType *inst ) { 255 226 // mutate subtypes … … 260 231 // exit early if no need for further mutation 261 232 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 233 assert( inst->get_baseParameters() && "Base struct has parameters" ); 234 269 235 // check if type can be concretely instantiated; put substitutions into typeSubs 270 assert( inst->get_baseParameters() && "Base struct has parameters" );271 236 std::list< TypeExpr* > typeSubs; 272 237 genericType gt = makeSubstitutions( *inst->get_baseParameters(), inst->get_parameters(), typeSubs ); 273 238 switch ( gt ) { 274 case genericType::dtypeStatic: 275 stripDtypeParams( inst->get_baseStruct(), *inst->get_baseParameters(), typeSubs ); 276 stripInstParams( inst ); 277 break; 278 279 case genericType::concrete: { 239 case genericType::dtypeStatic: // TODO strip params off original decl and reuse here 240 case genericType::concrete: 241 { 280 242 // make concrete instantiation of generic type 281 243 StructDecl *concDecl = lookup( inst, typeSubs ); … … 312 274 // exit early if no need for further mutation 313 275 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 } 276 assert( inst->get_baseParameters() && "Base union has parameters" ); 320 277 321 278 // check if type can be concretely instantiated; put substitutions into typeSubs 322 assert( inst->get_baseParameters() && "Base union has parameters" );323 279 std::list< TypeExpr* > typeSubs; 324 280 genericType gt = makeSubstitutions( *inst->get_baseParameters(), inst->get_parameters(), typeSubs ); 325 281 switch ( gt ) { 326 case genericType::dtypeStatic: 327 stripDtypeParams( inst->get_baseUnion(), *inst->get_baseParameters(), typeSubs ); 328 stripInstParams( inst ); 329 break; 330 282 case genericType::dtypeStatic: // TODO strip params off original decls and reuse here 331 283 case genericType::concrete: 332 284 { … … 359 311 DeclMutator::doBeginScope(); 360 312 instantiations.beginScope(); 361 dtypeStatics.beginScope();362 313 } 363 314 … … 365 316 DeclMutator::doEndScope(); 366 317 instantiations.endScope(); 367 dtypeStatics.endScope();368 318 } 369 319
Note:
See TracChangeset
for help on using the changeset viewer.