- File:
-
- 1 edited
-
src/GenPoly/InstantiateGeneric.cc (modified) (10 diffs)
Legend:
- Unmodified
- Added
- Removed
-
src/GenPoly/InstantiateGeneric.cc
rb940dc71 r2c57025 18 18 #include <utility> 19 19 #include <vector> 20 #include <unordered_map>21 20 22 21 #include "InstantiateGeneric.h" … … 25 24 #include "GenPoly.h" 26 25 #include "ScopedSet.h" 27 #include "PolyMutator.h"28 26 29 27 #include "ResolvExpr/typeops.h" … … 148 146 } 149 147 150 // collect the environments of each TypeInstType so that type variables can be replaced151 // 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 166 148 /// Mutator pass that replaces concrete instantiations of generic types with actual struct declarations, scoped appropriately 167 149 class GenericInstantiator final : public DeclMutator { … … 172 154 /// Namer for concrete types 173 155 UniqueName typeNamer; 174 /// Reference to mapping of environments 175 const std::unordered_map< ReferenceToType *, TypeSubstitution * > & envMap; 156 176 157 public: 177 GenericInstantiator( const std::unordered_map< ReferenceToType *, TypeSubstitution * > & envMap ) : DeclMutator(), instantiations(), dtypeStatics(), typeNamer("_conc_"), envMap( envMap) {}158 GenericInstantiator() : DeclMutator(), instantiations(), dtypeStatics(), typeNamer("_conc_") {} 178 159 179 160 using DeclMutator::mutate; … … 193 174 void insert( UnionInstType *inst, const std::list< TypeExpr* > &typeSubs, UnionDecl *decl ) { instantiations.insert( inst->get_baseUnion(), typeSubs, decl ); } 194 175 195 void replaceParametersWithConcrete( std::list< Expression* >& params );196 Type *replaceWithConcrete( Type *type, bool doClone );197 198 176 /// Strips a dtype-static aggregate decl of its type parameters, marks it as stripped 199 177 void stripDtypeParams( AggregateDecl *base, std::list< TypeDecl* >& baseParams, const std::list< TypeExpr* >& typeSubs ); … … 201 179 202 180 void instantiateGeneric( std::list< Declaration* > &translationUnit ) { 203 EnvFinder finder; 204 mutateAll( translationUnit, finder ); 205 GenericInstantiator instantiator( finder.envMap ); 181 GenericInstantiator instantiator; 206 182 instantiator.mutateDeclarationList( translationUnit ); 207 183 } … … 233 209 // can pretend that any ftype is `void (*)(void)` 234 210 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." );238 211 break; 239 212 } … … 280 253 } 281 254 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 318 255 Type* GenericInstantiator::mutate( StructInstType *inst ) { 319 256 // mutate subtypes … … 325 262 if ( inst->get_parameters().empty() ) return inst; 326 263 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 330 264 // check for an already-instantiatiated dtype-static type 331 265 if ( dtypeStatics.find( inst->get_baseStruct() ) != dtypeStatics.end() ) { … … 335 269 336 270 // check if type can be concretely instantiated; put substitutions into typeSubs 337 assert f( inst->get_baseParameters(),"Base struct has parameters" );271 assert( inst->get_baseParameters() && "Base struct has parameters" ); 338 272 std::list< TypeExpr* > typeSubs; 339 273 genericType gt = makeSubstitutions( *inst->get_baseParameters(), inst->get_parameters(), typeSubs );
Note:
See TracChangeset
for help on using the changeset viewer.