Ignore:
Timestamp:
Dec 15, 2015, 4:14:01 PM (10 years ago)
Author:
Peter A. Buhr <pabuhr@…>
Branches:
ADT, aaron-thesis, arm-eh, ast-experimental, cleanup-dtors, ctor, deferred_resn, demangler, enum, forall-pointer-decay, gc_noraii, jacob/cs343-translation, jenkins-sandbox, master, memory, new-ast, new-ast-unique-expr, new-env, no_list, persistent-indexer, pthread-emulation, qualifiedEnum, resolv-new, string, with_gc
Children:
5f6c42c
Parents:
cf16f94 (diff), 78dd0da (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the (diff) links above to see all the changes relative to each parent.
Message:

fix comment

File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/GenPoly/InstantiateGeneric.cc

    rcf16f94 r4389966  
    4444                ConcreteType(const ConcreteType& that) : base(that.base), params() { cloneAll(that.params, params); }
    4545
    46                 /// Extracts types from a list of Expression* (which should be TypeExpr*)
    47                 ConcreteType(AggregateDecl *_base, const std::list< Expression* >& _params) : base(_base), params() {
    48                         for ( std::list< Expression* >::const_iterator it = _params.begin(); it != _params.end(); ++it ) {
    49                                 TypeExpr *param = dynamic_cast< TypeExpr* >(*it);
    50                                 assert(param && "Aggregate parameters should be type expressions");
    51                                 params.push_back( param->get_type()->clone() );
     46                /// Extracts types from a list of TypeExpr*
     47                ConcreteType(AggregateDecl *_base, const std::list< TypeExpr* >& _params) : base(_base), params() {
     48                        for ( std::list< TypeExpr* >::const_iterator param = _params.begin(); param != _params.end(); ++param ) {
     49                                params.push_back( (*param)->get_type()->clone() );
    5250                        }
    5351                }
     
    6664
    6765                bool operator== (const ConcreteType& that) const {
     66                        if ( base != that.base ) return false;
     67
    6868                        SymTab::Indexer dummy;
    69 
    70                         if ( base != that.base ) return false;
    7169                        if ( params.size() != that.params.size() ) return false;
    7270                        for ( std::list< Type* >::const_iterator it = params.begin(), jt = that.params.begin(); it != params.end(); ++it, ++jt ) {
     
    7977                std::list< Type* > params;  ///< Instantiation parameters
    8078        };
    81 
     79       
    8280        /// Maps a concrete type to the instantiated struct type, accounting for scope
    8381        class InstantiationMap {
    84                 /// Pair of concrete type and declaration that instantiates it
    85                 typedef std::pair< ConcreteType, AggregateDecl* > Instantiation;
     82                /// Instantiation of a generic type, with key information to find it
     83                struct Instantiation {
     84                        ConcreteType key;     ///< Instantiation parameters for this type
     85                        AggregateDecl *decl;  ///< Declaration of the instantiated generic type
     86
     87                        Instantiation() : key(), decl(0) {}
     88                        Instantiation(const ConcreteType &_key, AggregateDecl *_decl) : key(_key), decl(_decl) {}
     89                };
    8690                /// Map of generic types to instantiations of them
    8791                typedef std::map< AggregateDecl*, std::vector< Instantiation > > Scope;
     
    107111                /// Gets the declaration for the concrete instantiation of this type, assuming it has already been instantiated in the current scope.
    108112                /// Returns NULL on none such.
    109                 AggregateDecl* lookup( AggregateDecl *generic, std::list< Expression* >& params ) {
     113                AggregateDecl* lookup( AggregateDecl *generic, const std::list< TypeExpr* >& params ) {
    110114                        ConcreteType key(generic, params);
    111115                        // scan scopes from innermost out
     
    116120                                // look through instantiations for matches to concrete type
    117121                                for ( std::vector< Instantiation >::const_iterator inst = insts->second.begin(); inst != insts->second.end(); ++inst ) {
    118                                         if ( inst->first == key ) return inst->second;
     122                                        if ( inst->key == key ) return inst->decl;
    119123                                }
    120124                        }
     
    123127                }
    124128        public:
    125                 StructDecl* lookup( StructInstType *inst ) { return (StructDecl*)lookup( inst->get_baseStruct(), inst->get_parameters() ); }
    126                 UnionDecl* lookup( UnionInstType *inst ) { return (UnionDecl*)lookup( inst->get_baseUnion(), inst->get_parameters() ); }
     129                StructDecl* lookup( StructInstType *inst, const std::list< TypeExpr* > &typeSubs ) { return (StructDecl*)lookup( inst->get_baseStruct(), typeSubs ); }
     130                UnionDecl* lookup( UnionInstType *inst, const std::list< TypeExpr* > &typeSubs ) { return (UnionDecl*)lookup( inst->get_baseUnion(), typeSubs ); }
    127131
    128132        private:
    129133                /// Adds a declaration for a concrete type to the current scope
    130                 void insert( AggregateDecl *generic, std::list< Expression* >& params, AggregateDecl *decl ) {
     134                void insert( AggregateDecl *generic, const std::list< TypeExpr* > &params, AggregateDecl *decl ) {
    131135                        ConcreteType key(generic, params);
    132                         scopes.back()[generic].push_back( std::make_pair( key, decl ) );
     136                        scopes.back()[generic].push_back( Instantiation( key, decl ) );
    133137                }
    134138        public:
    135                 void insert( StructInstType *inst, StructDecl *decl ) { insert( inst->get_baseStruct(), inst->get_parameters(), decl ); }
    136                 void insert( UnionInstType *inst, UnionDecl *decl ) { insert( inst->get_baseUnion(), inst->get_parameters(), decl ); }
     139                void insert( StructInstType *inst, const std::list< TypeExpr* > &typeSubs, StructDecl *decl ) { insert( inst->get_baseStruct(), typeSubs, decl ); }
     140                void insert( UnionInstType *inst, const std::list< TypeExpr* > &typeSubs, UnionDecl *decl ) { insert( inst->get_baseUnion(), typeSubs, decl ); }
    137141        };
    138142
    139143        /// Mutator pass that replaces concrete instantiations of generic types with actual struct declarations, scoped appropriately
    140144        class Instantiate : public DeclMutator {
     145                /// Map of (generic type, parameter list) pairs to concrete type instantiations
    141146                InstantiationMap instantiations;
     147                /// Namer for concrete types
    142148                UniqueName typeNamer;
    143149
     
    147153                virtual Type* mutate( StructInstType *inst );
    148154                virtual Type* mutate( UnionInstType *inst );
     155
     156//              virtual Expression* mutate( MemberExpr *memberExpr );
    149157               
    150158                virtual void doBeginScope();
     
    157165        }
    158166
    159         /// Substitutes types of members of in according to baseParams => params, appending the result to out
    160         void substituteMembers( const std::list< Declaration* >& in,
    161                                                         const std::list< TypeDecl * >& baseParams, const std::list< Expression* >& params,
     167        /// Makes substitutions of params into baseParams; returns true if all parameters substituted for a concrete type
     168        bool makeSubstitutions( const std::list< TypeDecl* >& baseParams, const std::list< Expression* >& params, std::list< TypeExpr* >& out ) {
     169                bool allConcrete = true;  // will finish the substitution list even if they're not all concrete
     170
     171                // substitute concrete types for given parameters, and incomplete types for placeholders
     172                std::list< TypeDecl* >::const_iterator baseParam = baseParams.begin();
     173                std::list< Expression* >::const_iterator param = params.begin();
     174                for ( ; baseParam != baseParams.end() && param != params.end(); ++baseParam, ++param ) {
     175//                      switch ( (*baseParam)->get_kind() ) {
     176//                      case TypeDecl::Any: {   // any type is a valid substitution here; complete types can be used to instantiate generics
     177                                TypeExpr *paramType = dynamic_cast< TypeExpr* >( *param );
     178                                assert(paramType && "Aggregate parameters should be type expressions");
     179                                out.push_back( paramType->clone() );
     180                                // check that the substituted type isn't a type variable itself
     181                                if ( dynamic_cast< TypeInstType* >( paramType->get_type() ) ) {
     182                                        allConcrete = false;
     183                                }
     184//                              break;
     185//                      }
     186//                      case TypeDecl::Dtype:  // dtype can be consistently replaced with void [only pointers, which become void*]
     187//                              out.push_back( new TypeExpr( new VoidType( Type::Qualifiers() ) ) );
     188//                              break;
     189//                      case TypeDecl::Ftype:  // pointer-to-ftype can be consistently replaced with void (*)(void) [similar to dtype]
     190//                              out.push_back( new TypeExpr( new FunctionType( Type::Qualifiers(), false ) ) );
     191//                              break;
     192//                      }
     193                }
     194
     195                // if any parameters left over, not done
     196                if ( baseParam != baseParams.end() ) return false;
     197//              // if not enough parameters given, substitute remaining incomplete types for placeholders
     198//              for ( ; baseParam != baseParams.end(); ++baseParam ) {
     199//                      switch ( (*baseParam)->get_kind() ) {
     200//                      case TypeDecl::Any:    // no more substitutions here, fail early
     201//                              return false;
     202//                      case TypeDecl::Dtype:  // dtype can be consistently replaced with void [only pointers, which become void*]
     203//                              out.push_back( new TypeExpr( new VoidType( Type::Qualifiers() ) ) );
     204//                              break;
     205//                      case TypeDecl::Ftype:  // pointer-to-ftype can be consistently replaced with void (*)(void) [similar to dtype]
     206//                              out.push_back( new TypeExpr( new FunctionType( Type::Qualifiers(), false ) ) );
     207//                              break;
     208//                      }
     209//              }
     210
     211                return allConcrete;
     212        }
     213
     214        /// Substitutes types of members of in according to baseParams => typeSubs, appending the result to out
     215        void substituteMembers( const std::list< Declaration* >& in, const std::list< TypeDecl* >& baseParams, const std::list< TypeExpr* >& typeSubs,
    162216                                                    std::list< Declaration* >& out ) {
    163217                // substitute types into new members
    164                 TypeSubstitution subs( baseParams.begin(), baseParams.end(), params.begin() );
     218                TypeSubstitution subs( baseParams.begin(), baseParams.end(), typeSubs.begin() );
    165219                for ( std::list< Declaration* >::const_iterator member = in.begin(); member != in.end(); ++member ) {
    166220                        Declaration *newMember = (*member)->clone();
     
    178232                // exit early if no need for further mutation
    179233                if ( inst->get_parameters().empty() ) return inst;
     234                assert( inst->get_baseParameters() && "Base struct has parameters" );
     235
     236                // check if type can be concretely instantiated; put substitutions into typeSubs
     237                std::list< TypeExpr* > typeSubs;
     238                if ( ! makeSubstitutions( *inst->get_baseParameters(), inst->get_parameters(), typeSubs ) ) {
     239                        deleteAll( typeSubs );
     240                        return inst;
     241                }
    180242               
    181243                // make concrete instantiation of generic type
    182                 StructDecl *concDecl = instantiations.lookup( inst );
     244                StructDecl *concDecl = instantiations.lookup( inst, typeSubs );
    183245                if ( ! concDecl ) {
    184                         assert( inst->get_baseParameters() && "Base struct has parameters" );
    185246                        // set concDecl to new type, insert type declaration into statements to add
    186247                        concDecl = new StructDecl( typeNamer.newName( inst->get_name() ) );
    187                         substituteMembers( inst->get_baseStruct()->get_members(),
    188                                                                 *inst->get_baseParameters(), inst->get_parameters(),
    189                                                                 concDecl->get_members() );
     248                        substituteMembers( inst->get_baseStruct()->get_members(), *inst->get_baseParameters(), typeSubs,        concDecl->get_members() );
    190249                        DeclMutator::addDeclaration( concDecl );
    191                         instantiations.insert( inst, concDecl );
     250                        instantiations.insert( inst, typeSubs, concDecl );
    192251                }
    193252                StructInstType *newInst = new StructInstType( inst->get_qualifiers(), concDecl->get_name() );
    194253                newInst->set_baseStruct( concDecl );
     254
     255                deleteAll( typeSubs );
    195256                delete inst;
    196257                return newInst;
     
    205266                // exit early if no need for further mutation
    206267                if ( inst->get_parameters().empty() ) return inst;
    207 
     268                assert( inst->get_baseParameters() && "Base union has parameters" );
     269
     270                // check if type can be concretely instantiated; put substitutions into typeSubs
     271                std::list< TypeExpr* > typeSubs;
     272                if ( ! makeSubstitutions( *inst->get_baseParameters(), inst->get_parameters(), typeSubs ) ) {
     273                        deleteAll( typeSubs );
     274                        return inst;
     275                }
     276               
    208277                // make concrete instantiation of generic type
    209                 UnionDecl *concDecl = instantiations.lookup( inst );
     278                UnionDecl *concDecl = instantiations.lookup( inst, typeSubs );
    210279                if ( ! concDecl ) {
    211280                        // set concDecl to new type, insert type declaration into statements to add
    212                         assert( inst->get_baseParameters() && "Base union has parameters" );
    213281                        concDecl = new UnionDecl( typeNamer.newName( inst->get_name() ) );
    214                         substituteMembers( inst->get_baseUnion()->get_members(),
    215                                                                 *inst->get_baseParameters(), inst->get_parameters(),
    216                                                                 concDecl->get_members() );
     282                        substituteMembers( inst->get_baseUnion()->get_members(), *inst->get_baseParameters(), typeSubs, concDecl->get_members() );
    217283                        DeclMutator::addDeclaration( concDecl );
    218                         instantiations.insert( inst, concDecl );
     284                        instantiations.insert( inst, typeSubs, concDecl );
    219285                }
    220286                UnionInstType *newInst = new UnionInstType( inst->get_qualifiers(), concDecl->get_name() );
    221287                newInst->set_baseUnion( concDecl );
     288
     289                deleteAll( typeSubs );
    222290                delete inst;
    223291                return newInst;
    224292        }
     293
     294//      /// Gets the base struct or union declaration for a member expression; NULL if not applicable
     295//      AggregateDecl* getMemberBaseDecl( MemberExpr *memberExpr ) {
     296//              // get variable for member aggregate
     297//              VariableExpr *varExpr = dynamic_cast< VariableExpr* >( memberExpr->get_aggregate() );
     298//              if ( ! varExpr ) return NULL;
     299//
     300//              // get object for variable
     301//              ObjectDecl *objectDecl = dynamic_cast< ObjectDecl* >( varExpr->get_var() );
     302//              if ( ! objectDecl ) return NULL;
     303//
     304//              // get base declaration from object type
     305//              Type *objectType = objectDecl->get_type();
     306//              StructInstType *structType = dynamic_cast< StructInstType* >( objectType );
     307//              if ( structType ) return structType->get_baseStruct();
     308//              UnionInstType *unionType = dynamic_cast< UnionInstType* >( objectType );
     309//              if ( unionType ) return unionType->get_baseUnion();
     310//
     311//              return NULL;
     312//      }
     313//
     314//      /// Finds the declaration with the given name, returning decls.end() if none such
     315//      std::list< Declaration* >::const_iterator findDeclNamed( const std::list< Declaration* > &decls, const std::string &name ) {
     316//              for( std::list< Declaration* >::const_iterator decl = decls.begin(); decl != decls.end(); ++decl ) {
     317//                      if ( (*decl)->get_name() == name ) return decl;
     318//              }
     319//              return decls.end();
     320//      }
     321//     
     322//      Expression* Instantiate::mutate( MemberExpr *memberExpr ) {
     323//              // mutate, exiting early if no longer MemberExpr
     324//              Expression *expr = Mutator::mutate( memberExpr );
     325//              memberExpr = dynamic_cast< MemberExpr* >( expr );
     326//              if ( ! memberExpr ) return expr;
     327//
     328//              // get declaration of member and base declaration of member, exiting early if not found
     329//              AggregateDecl *memberBase = getMemberBaseDecl( memberExpr );
     330//              if ( ! memberBase ) return memberExpr;
     331//              DeclarationWithType *memberDecl = memberExpr->get_member();
     332//              std::list< Declaration* >::const_iterator baseIt = findDeclNamed( memberBase->get_members(), memberDecl->get_name() );
     333//              if ( baseIt == memberBase->get_members().end() ) return memberExpr;
     334//              DeclarationWithType *baseDecl = dynamic_cast< DeclarationWithType* >( *baseIt );
     335//              if ( ! baseDecl ) return memberExpr;
     336//
     337//              // check if stated type of the member is not the type of the member's declaration; if so, need a cast
     338//              // this *SHOULD* be safe, I don't think anything but the void-replacements I put in for dtypes would make it past the typechecker
     339//              SymTab::Indexer dummy;
     340//              if ( ResolvExpr::typesCompatible( memberDecl->get_type(), baseDecl->get_type(), dummy ) ) return memberExpr;
     341//              else return new CastExpr( memberExpr, memberDecl->get_type() );
     342//      }
    225343       
    226344        void Instantiate::doBeginScope() {
    227345                DeclMutator::doBeginScope();
    228                 // push a new concrete type scope
    229346                instantiations.beginScope();
    230347        }
     
    232349        void Instantiate::doEndScope() {
    233350                DeclMutator::doEndScope();
    234                 // pop the last concrete type scope
    235351                instantiations.endScope();
    236352        }
Note: See TracChangeset for help on using the changeset viewer.