Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/GenPoly/InstantiateGeneric.cc

    rb940dc71 r2c57025  
    1818#include <utility>
    1919#include <vector>
    20 #include <unordered_map>
    2120
    2221#include "InstantiateGeneric.h"
     
    2524#include "GenPoly.h"
    2625#include "ScopedSet.h"
    27 #include "PolyMutator.h"
    2826
    2927#include "ResolvExpr/typeops.h"
     
    148146        }
    149147
    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 
    166148        /// Mutator pass that replaces concrete instantiations of generic types with actual struct declarations, scoped appropriately
    167149        class GenericInstantiator final : public DeclMutator {
     
    172154                /// Namer for concrete types
    173155                UniqueName typeNamer;
    174                 /// Reference to mapping of environments
    175                 const std::unordered_map< ReferenceToType *, TypeSubstitution * > & envMap;
     156
    176157        public:
    177                 GenericInstantiator( const std::unordered_map< ReferenceToType *, TypeSubstitution * > & envMap ) : DeclMutator(), instantiations(), dtypeStatics(), typeNamer("_conc_"), envMap( envMap ) {}
     158                GenericInstantiator() : DeclMutator(), instantiations(), dtypeStatics(), typeNamer("_conc_") {}
    178159
    179160                using DeclMutator::mutate;
     
    193174                void insert( UnionInstType *inst, const std::list< TypeExpr* > &typeSubs, UnionDecl *decl ) { instantiations.insert( inst->get_baseUnion(), typeSubs, decl ); }
    194175
    195                 void replaceParametersWithConcrete( std::list< Expression* >& params );
    196                 Type *replaceWithConcrete( Type *type, bool doClone );
    197 
    198176                /// Strips a dtype-static aggregate decl of its type parameters, marks it as stripped
    199177                void stripDtypeParams( AggregateDecl *base, std::list< TypeDecl* >& baseParams, const std::list< TypeExpr* >& typeSubs );
     
    201179
    202180        void instantiateGeneric( std::list< Declaration* > &translationUnit ) {
    203                 EnvFinder finder;
    204                 mutateAll( translationUnit, finder );
    205                 GenericInstantiator instantiator( finder.envMap );
     181                GenericInstantiator instantiator;
    206182                instantiator.mutateDeclarationList( translationUnit );
    207183        }
     
    233209                                // can pretend that any ftype is `void (*)(void)`
    234210                                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." );
    238211                                break;
    239212                        }
     
    280253        }
    281254
    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 
    318255        Type* GenericInstantiator::mutate( StructInstType *inst ) {
    319256                // mutate subtypes
     
    325262                if ( inst->get_parameters().empty() ) return inst;
    326263
    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 
    330264                // check for an already-instantiatiated dtype-static type
    331265                if ( dtypeStatics.find( inst->get_baseStruct() ) != dtypeStatics.end() ) {
     
    335269
    336270                // check if type can be concretely instantiated; put substitutions into typeSubs
    337                 assertf( inst->get_baseParameters(), "Base struct has parameters" );
     271                assert( inst->get_baseParameters() && "Base struct has parameters" );
    338272                std::list< TypeExpr* > typeSubs;
    339273                genericType gt = makeSubstitutions( *inst->get_baseParameters(), inst->get_parameters(), typeSubs );
Note: See TracChangeset for help on using the changeset viewer.