Changeset b940dc71 for src/GenPoly/InstantiateGeneric.cc
- Timestamp:
- Dec 21, 2016, 4:15:47 PM (6 years ago)
- Branches:
- aaron-thesis, arm-eh, cleanup-dtors, deferred_resn, demangler, enum, forall-pointer-decay, jacob/cs343-translation, jenkins-sandbox, master, new-ast, new-ast-unique-expr, new-env, no_list, persistent-indexer, pthread-emulation, qualifiedEnum, resolv-new, with_gc
- Children:
- 53e3b4a
- Parents:
- 626dbc10
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
src/GenPoly/InstantiateGeneric.cc
r626dbc10 rb940dc71 18 18 #include <utility> 19 19 #include <vector> 20 #include <unordered_map> 20 21 21 22 #include "InstantiateGeneric.h" … … 24 25 #include "GenPoly.h" 25 26 #include "ScopedSet.h" 27 #include "PolyMutator.h" 26 28 27 29 #include "ResolvExpr/typeops.h" … … 146 148 } 147 149 150 // collect the environments of each TypeInstType so that type variables can be replaced 151 // xxx - possibly temporary solution. Access to type environments is required in GenericInstantiator, but it needs to be a DeclMutator which does not provide easy access to the type environments. 152 class EnvFinder final : public GenPoly::PolyMutator { 153 public: 154 virtual Type * mutate( TypeInstType * inst ) override { 155 if ( env ) envMap[inst] = env; 156 return inst; 157 } 158 159 // don't want to associate an environment with TypeInstTypes that occur in function types - this may actually only apply to function types belonging to DeclarationWithTypes (or even just FunctionDecl)? 160 virtual Type * mutate( FunctionType * ftype ) override { 161 return ftype; 162 } 163 std::unordered_map< ReferenceToType *, TypeSubstitution * > envMap; 164 }; 165 148 166 /// Mutator pass that replaces concrete instantiations of generic types with actual struct declarations, scoped appropriately 149 167 class GenericInstantiator final : public DeclMutator { … … 154 172 /// Namer for concrete types 155 173 UniqueName typeNamer; 156 174 /// Reference to mapping of environments 175 const std::unordered_map< ReferenceToType *, TypeSubstitution * > & envMap; 157 176 public: 158 GenericInstantiator( ) : DeclMutator(), instantiations(), dtypeStatics(), typeNamer("_conc_") {}177 GenericInstantiator( const std::unordered_map< ReferenceToType *, TypeSubstitution * > & envMap ) : DeclMutator(), instantiations(), dtypeStatics(), typeNamer("_conc_"), envMap( envMap ) {} 159 178 160 179 using DeclMutator::mutate; … … 174 193 void insert( UnionInstType *inst, const std::list< TypeExpr* > &typeSubs, UnionDecl *decl ) { instantiations.insert( inst->get_baseUnion(), typeSubs, decl ); } 175 194 195 void replaceParametersWithConcrete( std::list< Expression* >& params ); 196 Type *replaceWithConcrete( Type *type, bool doClone ); 197 176 198 /// Strips a dtype-static aggregate decl of its type parameters, marks it as stripped 177 199 void stripDtypeParams( AggregateDecl *base, std::list< TypeDecl* >& baseParams, const std::list< TypeExpr* >& typeSubs ); … … 179 201 180 202 void instantiateGeneric( std::list< Declaration* > &translationUnit ) { 181 GenericInstantiator instantiator; 203 EnvFinder finder; 204 mutateAll( translationUnit, finder ); 205 GenericInstantiator instantiator( finder.envMap ); 182 206 instantiator.mutateDeclarationList( translationUnit ); 183 207 } … … 209 233 // can pretend that any ftype is `void (*)(void)` 210 234 out.push_back( new TypeExpr( new FunctionType( Type::Qualifiers(), false ) ) ); 235 break; 236 case TypeDecl::Ttype: 237 assertf( false, "Ttype parameters are not currently allowed as parameters to generic types." ); 211 238 break; 212 239 } … … 253 280 } 254 281 282 /// xxx - more or less copied from box -- these should be merged with those somehow... 283 void GenericInstantiator::replaceParametersWithConcrete( std::list< Expression* >& params ) { 284 for ( std::list< Expression* >::iterator param = params.begin(); param != params.end(); ++param ) { 285 TypeExpr *paramType = dynamic_cast< TypeExpr* >( *param ); 286 assertf(paramType, "Aggregate parameters should be type expressions"); 287 paramType->set_type( replaceWithConcrete( paramType->get_type(), false ) ); 288 } 289 } 290 291 Type *GenericInstantiator::replaceWithConcrete( Type *type, bool doClone ) { 292 if ( TypeInstType *typeInst = dynamic_cast< TypeInstType * >( type ) ) { 293 if ( envMap.count( typeInst ) ) { 294 TypeSubstitution * env = envMap.at( typeInst ); 295 Type *concrete = env->lookup( typeInst->get_name() ); 296 if ( concrete ) { 297 return concrete->clone(); 298 } 299 else return typeInst->clone(); 300 } 301 } else if ( StructInstType *structType = dynamic_cast< StructInstType* >( type ) ) { 302 if ( doClone ) { 303 structType = structType->clone(); 304 } 305 replaceParametersWithConcrete( structType->get_parameters() ); 306 return structType; 307 } else if ( UnionInstType *unionType = dynamic_cast< UnionInstType* >( type ) ) { 308 if ( doClone ) { 309 unionType = unionType->clone(); 310 } 311 replaceParametersWithConcrete( unionType->get_parameters() ); 312 return unionType; 313 } 314 return type; 315 } 316 317 255 318 Type* GenericInstantiator::mutate( StructInstType *inst ) { 256 319 // mutate subtypes … … 262 325 if ( inst->get_parameters().empty() ) return inst; 263 326 327 // need to replace type variables to ensure that generic types are instantiated for the return values of polymorphic functions (in particular, for thunks, because they are not [currently] copy constructed). 328 replaceWithConcrete( inst, false ); 329 264 330 // check for an already-instantiatiated dtype-static type 265 331 if ( dtypeStatics.find( inst->get_baseStruct() ) != dtypeStatics.end() ) { … … 269 335 270 336 // check if type can be concretely instantiated; put substitutions into typeSubs 271 assert ( inst->get_baseParameters() &&"Base struct has parameters" );337 assertf( inst->get_baseParameters(), "Base struct has parameters" ); 272 338 std::list< TypeExpr* > typeSubs; 273 339 genericType gt = makeSubstitutions( *inst->get_baseParameters(), inst->get_parameters(), typeSubs );
Note: See TracChangeset
for help on using the changeset viewer.