Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/GenPoly/InstantiateGeneric.cc

    rf18a711 rea5daeb  
    2424#include "GenPoly.h"
    2525#include "ScopedMap.h"
    26 #include "ScopedSet.h"
    2726
    2827#include "ResolvExpr/typeops.h"
     
    123122                }
    124123        };
    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         }
    147124       
    148125        /// Mutator pass that replaces concrete instantiations of generic types with actual struct declarations, scoped appropriately
     
    150127                /// Map of (generic type, parameter list) pairs to concrete type instantiations
    151128                InstantiationMap< AggregateDecl, AggregateDecl > instantiations;
    152                 /// Set of types which are dtype-only generic (and therefore have static layout)
    153                 ScopedSet< AggregateDecl* > dtypeStatics;
    154129                /// Namer for concrete types
    155130                UniqueName typeNamer;
    156131
    157132        public:
    158                 GenericInstantiator() : DeclMutator(), instantiations(), dtypeStatics(), typeNamer("_conc_") {}
     133                GenericInstantiator() : DeclMutator(), instantiations(), typeNamer("_conc_") {}
    159134
    160135                virtual Type* mutate( StructInstType *inst );
     
    172147                /// Wrap instantiation insertion for unions
    173148                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 stripped
    176                 void stripDtypeParams( AggregateDecl *base, std::list< TypeDecl* >& baseParams, const std::list< TypeExpr* >& typeSubs );
    177149        };
    178150
     
    182154        }
    183155
    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
    186181        genericType makeSubstitutions( const std::list< TypeDecl* >& baseParams, const std::list< Expression* >& params, std::list< TypeExpr* >& out ) {
    187182                genericType gt = genericType::dtypeStatic;
     
    228223        }
    229224
    230         /// Substitutes types of members according to baseParams => typeSubs, working in-place
    231         void substituteMembers( std::list< Declaration* >& members, const std::list< TypeDecl* >& baseParams, const std::list< TypeExpr* >& typeSubs ) {
    232                 // substitute types into new members
    233                 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 parameters
    240         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 
    254225        Type* GenericInstantiator::mutate( StructInstType *inst ) {
    255226                // mutate subtypes
     
    260231                // exit early if no need for further mutation
    261232                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
    269235                // check if type can be concretely instantiated; put substitutions into typeSubs
    270                 assert( inst->get_baseParameters() && "Base struct has parameters" );
    271236                std::list< TypeExpr* > typeSubs;
    272237                genericType gt = makeSubstitutions( *inst->get_baseParameters(), inst->get_parameters(), typeSubs );
    273238                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                {
    280242                        // make concrete instantiation of generic type
    281243                        StructDecl *concDecl = lookup( inst, typeSubs );
     
    312274                // exit early if no need for further mutation
    313275                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" );
    320277
    321278                // check if type can be concretely instantiated; put substitutions into typeSubs
    322                 assert( inst->get_baseParameters() && "Base union has parameters" );
    323279                std::list< TypeExpr* > typeSubs;
    324280                genericType gt = makeSubstitutions( *inst->get_baseParameters(), inst->get_parameters(), typeSubs );
    325281                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
    331283                case genericType::concrete:
    332284                {
     
    359311                DeclMutator::doBeginScope();
    360312                instantiations.beginScope();
    361                 dtypeStatics.beginScope();
    362313        }
    363314
     
    365316                DeclMutator::doEndScope();
    366317                instantiations.endScope();
    367                 dtypeStatics.endScope();
    368318        }
    369319
Note: See TracChangeset for help on using the changeset viewer.