Ignore:
Timestamp:
Aug 8, 2016, 3:44:56 PM (7 years ago)
Author:
Aaron Moss <a3moss@…>
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
Message:

Dtypes now erased on dtype-only generic types, tests pass, build produces many warnings

File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/GenPoly/InstantiateGeneric.cc

    r752dc70 r3bb195cb  
    2424#include "GenPoly.h"
    2525#include "ScopedMap.h"
     26#include "ScopedSet.h"
    2627
    2728#include "ResolvExpr/typeops.h"
     
    122123                }
    123124        };
     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        }
    124147       
    125148        /// Mutator pass that replaces concrete instantiations of generic types with actual struct declarations, scoped appropriately
     
    127150                /// Map of (generic type, parameter list) pairs to concrete type instantiations
    128151                InstantiationMap< AggregateDecl, AggregateDecl > instantiations;
     152                /// Set of types which are dtype-only generic (and therefore have static layout)
     153                ScopedSet< AggregateDecl* > dtypeStatics;
    129154                /// Namer for concrete types
    130155                UniqueName typeNamer;
    131156
    132157        public:
    133                 GenericInstantiator() : DeclMutator(), instantiations(), typeNamer("_conc_") {}
     158                GenericInstantiator() : DeclMutator(), instantiations(), dtypeStatics(), typeNamer("_conc_") {}
    134159
    135160                virtual Type* mutate( StructInstType *inst );
     
    147172                /// Wrap instantiation insertion for unions
    148173                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 );
    149180        };
    150181
     
    154185        }
    155186
    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
    181189        genericType makeSubstitutions( const std::list< TypeDecl* >& baseParams, const std::list< Expression* >& params, std::list< TypeExpr* >& out ) {
    182190                genericType gt = genericType::dtypeStatic;
     
    223231        }
    224232
     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
    225260        Type* GenericInstantiator::mutate( StructInstType *inst ) {
    226261                // mutate subtypes
     
    231266                // exit early if no need for further mutation
    232267                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
    233273                assert( inst->get_baseParameters() && "Base struct has parameters" );
    234 
    235                 // check if type can be concretely instantiated; put substitutions into typeSubs
    236274                std::list< TypeExpr* > typeSubs;
    237275                genericType gt = makeSubstitutions( *inst->get_baseParameters(), inst->get_parameters(), typeSubs );
    238276                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: {
    242282                        // make concrete instantiation of generic type
    243283                        StructDecl *concDecl = lookup( inst, typeSubs );
     
    274314                // exit early if no need for further mutation
    275315                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
    276321                assert( inst->get_baseParameters() && "Base union has parameters" );
    277 
    278                 // check if type can be concretely instantiated; put substitutions into typeSubs
    279322                std::list< TypeExpr* > typeSubs;
    280323                genericType gt = makeSubstitutions( *inst->get_baseParameters(), inst->get_parameters(), typeSubs );
    281324                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                       
    283329                case genericType::concrete:
    284330                {
     
    311357                DeclMutator::doBeginScope();
    312358                instantiations.beginScope();
     359                dtypeStatics.beginScope();
    313360        }
    314361
     
    316363                DeclMutator::doEndScope();
    317364                instantiations.endScope();
     365                dtypeStatics.endScope();
    318366        }
    319367
Note: See TracChangeset for help on using the changeset viewer.