Changeset 3bb195cb for src/GenPoly/InstantiateGeneric.cc
- Timestamp:
- Aug 8, 2016, 3:44:56 PM (7 years ago)
- Branches:
- ADT, aaron-thesis, arm-eh, cleanup-dtors, ctor, deferred_resn, demangler, enum, forall-pointer-decay, jacob/cs343-translation, jenkins-sandbox, master, memory, new-ast, new-ast-unique-expr, new-env, no_list, persistent-indexer, pthread-emulation, qualifiedEnum, resolv-new, with_gc
- Children:
- ce76eb9
- Parents:
- 752dc70
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
src/GenPoly/InstantiateGeneric.cc
r752dc70 r3bb195cb 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 /// If this is an instance of a type already determined to be dtype-static, strips the instances's type parameters and returns true 176 bool stripInstParams( AggregateDecl *base, ReferenceToType *inst ); 177 178 /// Strips a dtype-static aggregate decl of its type parameters, marks it as stripped 179 void stripDtypeParams( AggregateDecl *base, std::list< TypeDecl* >& baseParams, const std::list< TypeExpr* >& typeSubs ); 149 180 }; 150 181 … … 154 185 } 155 186 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 187 /// Makes substitutions of params into baseParams; returns dtypeStatic if there is a concrete instantiation based only on {d,f}type-to-void conversions, 188 /// concrete if there is a concrete instantiation requiring at least one parameter type, and dynamic if there is no concrete instantiation 181 189 genericType makeSubstitutions( const std::list< TypeDecl* >& baseParams, const std::list< Expression* >& params, std::list< TypeExpr* >& out ) { 182 190 genericType gt = genericType::dtypeStatic; … … 223 231 } 224 232 233 /// Substitutes types of members according to baseParams => typeSubs, working in-place 234 void substituteMembers( std::list< Declaration* >& members, const std::list< TypeDecl* >& baseParams, const std::list< TypeExpr* >& typeSubs ) { 235 // substitute types into new members 236 TypeSubstitution subs( baseParams.begin(), baseParams.end(), typeSubs.begin() ); 237 for ( std::list< Declaration* >::iterator member = members.begin(); member != members.end(); ++member ) { 238 subs.apply(*member); 239 } 240 } 241 242 bool GenericInstantiator::stripInstParams( AggregateDecl *base, ReferenceToType *inst ) { 243 if ( dtypeStatics.find( base ) == dtypeStatics.end() ) return false; 244 245 deleteAll( inst->get_parameters() ); 246 inst->get_parameters().clear(); 247 248 return true; 249 } 250 251 void GenericInstantiator::stripDtypeParams( AggregateDecl *base, std::list< TypeDecl* >& baseParams, const std::list< TypeExpr* >& typeSubs ) { 252 substituteMembers( base->get_members(), baseParams, typeSubs ); 253 254 deleteAll( baseParams ); 255 baseParams.clear(); 256 257 dtypeStatics.insert( base ); 258 } 259 225 260 Type* GenericInstantiator::mutate( StructInstType *inst ) { 226 261 // mutate subtypes … … 231 266 // exit early if no need for further mutation 232 267 if ( inst->get_parameters().empty() ) return inst; 268 269 // check for an already-instantiatiated dtype-static type 270 if ( stripInstParams( inst->get_baseStruct(), inst ) ) return inst; 271 272 // check if type can be concretely instantiated; put substitutions into typeSubs 233 273 assert( inst->get_baseParameters() && "Base struct has parameters" ); 234 235 // check if type can be concretely instantiated; put substitutions into typeSubs236 274 std::list< TypeExpr* > typeSubs; 237 275 genericType gt = makeSubstitutions( *inst->get_baseParameters(), inst->get_parameters(), typeSubs ); 238 276 switch ( gt ) { 239 case genericType::dtypeStatic: // TODO strip params off original decl and reuse here 240 case genericType::concrete: 241 { 277 case genericType::dtypeStatic: 278 stripDtypeParams( inst->get_baseStruct(), *inst->get_baseParameters(), typeSubs ); 279 break; 280 281 case genericType::concrete: { 242 282 // make concrete instantiation of generic type 243 283 StructDecl *concDecl = lookup( inst, typeSubs ); … … 274 314 // exit early if no need for further mutation 275 315 if ( inst->get_parameters().empty() ) return inst; 316 317 // check for an already-instantiatiated dtype-static type 318 if ( stripInstParams( inst->get_baseUnion(), inst ) ) return inst; 319 320 // check if type can be concretely instantiated; put substitutions into typeSubs 276 321 assert( inst->get_baseParameters() && "Base union has parameters" ); 277 278 // check if type can be concretely instantiated; put substitutions into typeSubs279 322 std::list< TypeExpr* > typeSubs; 280 323 genericType gt = makeSubstitutions( *inst->get_baseParameters(), inst->get_parameters(), typeSubs ); 281 324 switch ( gt ) { 282 case genericType::dtypeStatic: // TODO strip params off original decls and reuse here 325 case genericType::dtypeStatic: 326 stripDtypeParams( inst->get_baseUnion(), *inst->get_baseParameters(), typeSubs ); 327 break; 328 283 329 case genericType::concrete: 284 330 { … … 311 357 DeclMutator::doBeginScope(); 312 358 instantiations.beginScope(); 359 dtypeStatics.beginScope(); 313 360 } 314 361 … … 316 363 DeclMutator::doEndScope(); 317 364 instantiations.endScope(); 365 dtypeStatics.endScope(); 318 366 } 319 367
Note: See TracChangeset
for help on using the changeset viewer.