Changeset e58be8e for src/GenPoly


Ignore:
Timestamp:
Dec 2, 2015, 12:14:24 PM (9 years ago)
Author:
Rob Schluntz <rschlunt@…>
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:
000b914
Parents:
f2b2029 (diff), 5bf4712 (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:

Merge branch 'master' of plg.uwaterloo.ca:/u/cforall/software/cfa/cfa-cc

Location:
src/GenPoly
Files:
2 added
2 edited

Legend:

Unmodified
Added
Removed
  • src/GenPoly/InstantiateGeneric.cc

    rf2b2029 re58be8e  
    55// file "LICENCE" distributed with Cforall.
    66//
    7 // InstantiateGeneric.h --
     7// InstantiateGeneric.cc --
    88//
    99// Author           : Aaron B. Moss
     
    2121
    2222#include "InstantiateGeneric.h"
    23 #include "PolyMutator.h"
     23#include "DeclMutator.h"
    2424
    2525#include "ResolvExpr/typeops.h"
     
    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 ) {
     
    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
    140         class Instantiate : public PolyMutator {
     144        class Instantiate : public DeclMutator {
    141145                InstantiationMap instantiations;
    142146                UniqueName typeNamer;
    143147
    144148        public:
    145                 Instantiate() : instantiations(), typeNamer("_conc_") {}
    146 
    147                 /// Mutates the whole translation unit, inserting new struct declarations as appropriate
    148                 void mutateAll( std::list< Declaration* >& translationUnit );
    149                
     149                Instantiate() : DeclMutator(), instantiations(), typeNamer("_conc_") {}
     150
     151//              virtual Declaration* mutate( StructDecl *aggregateDecl );
     152//              virtual Declaration* mutate( UnionDecl *aggregateDecl );
     153
    150154                virtual Type* mutate( StructInstType *inst );
    151155                virtual Type* mutate( UnionInstType *inst );
     
    153157                virtual void doBeginScope();
    154158                virtual void doEndScope();
    155 
    156         private:
    157                 /// Adds a declaration to the current environment and the statements to add
    158                 void addDeclaration( AggregateDecl *decl ) {
    159                         std::list< Label > nolabels;
    160                         DeclStmt *stmt = new DeclStmt( nolabels, decl );
    161                         PolyMutator::stmtsToAdd.push_back( stmt );
    162                 }
    163159        };
    164160       
    165161        void instantiateGeneric( std::list< Declaration* >& translationUnit ) {
    166162                Instantiate instantiator;
    167 //              mutateAll( translationUnit, instantiator );
    168                 instantiator.mutateAll( translationUnit );
    169         }
    170 
    171         void Instantiate::mutateAll( std::list< Declaration* >& translationUnit ) {
    172                 // below copied and modified from Mutator.h:mutateAll()
    173                 SemanticError errors;
    174                 for ( std::list< Declaration* >::iterator decl = translationUnit.begin(); decl != translationUnit.end(); ++decl ) {
    175                         try {
    176                                 if ( *decl ) {
    177                                         *decl = dynamic_cast< Declaration* >( (*decl)->acceptMutator( *this ) );
    178                                         assert( *decl );
    179                                         // account for missing top-level declarations
    180                                         for ( std::list< Statement* >::const_iterator stmt = PolyMutator::stmtsToAdd.begin(); stmt != PolyMutator::stmtsToAdd.end(); ++stmt ) {
    181                                                 DeclStmt *declStmt = dynamic_cast< DeclStmt* >( *stmt );
    182                                                 assert( declStmt );
    183                                                 translationUnit.insert( decl, declStmt->get_decl() );
    184                                         }
    185                                         PolyMutator::stmtsToAdd.clear();
    186                                 } // if
    187                         } catch( SemanticError &e ) {
    188                                 errors.append( e );
    189                         } // try
    190                 } // for
    191                 if ( ! errors.isEmpty() ) {
    192                         throw errors;
    193                 } // if
    194         }
    195 
    196         /// Substitutes types of members of in according to baseParams => params, appending the result to out
    197         void substituteMembers( const std::list< Declaration* >& in,
    198                                                         const std::list< TypeDecl * >& baseParams, const std::list< Expression* >& params,
     163                instantiator.mutateDeclarationList( translationUnit );
     164        }
     165
     166        /// Makes substitutions of params into baseParams; returns true if all parameters substituted for a concrete type
     167        bool makeSubstitutions( const std::list< TypeDecl* >& baseParams, const std::list< Expression* >& params, std::list< TypeExpr* >& out ) {
     168                bool allConcrete = true;  // will finish the substitution list even if they're not all concrete
     169
     170                // substitute concrete types for given parameters, and incomplete types for placeholders
     171                std::list< TypeDecl* >::const_iterator baseParam = baseParams.begin();
     172                std::list< Expression* >::const_iterator param = params.begin();
     173                for ( ; baseParam != baseParams.end() && param != params.end(); ++baseParam, ++param ) {
     174                        switch ( (*baseParam)->get_kind() ) {
     175                        case TypeDecl::Any: {   // any type is a valid substitution here; complete types can be used to instantiate generics
     176                                TypeExpr *paramType = dynamic_cast< TypeExpr* >( *param );
     177                                assert(paramType && "Aggregate parameters should be type expressions");
     178                                out.push_back( paramType->clone() );
     179                                // check that the substituted type isn't a type variable itself
     180                                if ( dynamic_cast< TypeInstType* >( paramType->get_type() ) ) {
     181                                        allConcrete = false;
     182                                }
     183                                break;
     184                        }
     185                        case TypeDecl::Dtype:  // dtype can be consistently replaced with void [only pointers, which become void*]
     186                                out.push_back( new TypeExpr( new VoidType( Type::Qualifiers() ) ) );
     187                                break;
     188                        case TypeDecl::Ftype:  // pointer-to-ftype can be consistently replaced with void (*)(void) [similar to dtype]
     189                                out.push_back( new TypeExpr( new FunctionType( Type::Qualifiers(), false ) ) );
     190                                break;
     191                        }
     192                }
     193
     194                // if not enough parameters given, substitute remaining incomplete types for placeholders
     195                for ( ; baseParam != baseParams.end(); ++baseParam ) {
     196                        switch ( (*baseParam)->get_kind() ) {
     197                        case TypeDecl::Any:    // no more substitutions here, fail early
     198                                return false;
     199                        case TypeDecl::Dtype:  // dtype can be consistently replaced with void [only pointers, which become void*]
     200                                out.push_back( new TypeExpr( new VoidType( Type::Qualifiers() ) ) );
     201                                break;
     202                        case TypeDecl::Ftype:  // pointer-to-ftype can be consistently replaced with void (*)(void) [similar to dtype]
     203                                out.push_back( new TypeExpr( new FunctionType( Type::Qualifiers(), false ) ) );
     204                                break;
     205                        }
     206                }
     207
     208                return allConcrete;
     209        }
     210       
     211        /// Substitutes types of members of in according to baseParams => typeSubs, appending the result to out
     212        void substituteMembers( const std::list< Declaration* >& in, const std::list< TypeDecl* >& baseParams, const std::list< TypeExpr* >& typeSubs,
    199213                                                    std::list< Declaration* >& out ) {
    200214                // substitute types into new members
    201                 TypeSubstitution subs( baseParams.begin(), baseParams.end(), params.begin() );
     215                TypeSubstitution subs( baseParams.begin(), baseParams.end(), typeSubs.begin() );
    202216                for ( std::list< Declaration* >::const_iterator member = in.begin(); member != in.end(); ++member ) {
    203217                        Declaration *newMember = (*member)->clone();
     
    215229                // exit early if no need for further mutation
    216230                if ( inst->get_parameters().empty() ) return inst;
     231                assert( inst->get_baseParameters() && "Base struct has parameters" );
     232
     233                // check if type can be concretely instantiated; put substitutions into typeSubs
     234                std::list< TypeExpr* > typeSubs;
     235                if ( ! makeSubstitutions( *inst->get_baseParameters(), inst->get_parameters(), typeSubs ) ) {
     236                        deleteAll( typeSubs );
     237                        return inst;
     238                }
    217239               
    218240                // make concrete instantiation of generic type
    219                 StructDecl *concDecl = instantiations.lookup( inst );
     241                StructDecl *concDecl = instantiations.lookup( inst, typeSubs );
    220242                if ( ! concDecl ) {
    221                         assert( inst->get_baseParameters() && "Base struct has parameters" );
    222243                        // set concDecl to new type, insert type declaration into statements to add
    223244                        concDecl = new StructDecl( typeNamer.newName( inst->get_name() ) );
    224                         substituteMembers( inst->get_baseStruct()->get_members(),
    225                                                                 *inst->get_baseParameters(), inst->get_parameters(),
    226                                                                 concDecl->get_members() );
    227                         addDeclaration( concDecl );
    228                         instantiations.insert( inst, concDecl );
     245                        substituteMembers( inst->get_baseStruct()->get_members(), *inst->get_baseParameters(), typeSubs,        concDecl->get_members() );
     246                        DeclMutator::addDeclaration( concDecl );
     247                        instantiations.insert( inst, typeSubs, concDecl );
    229248                }
    230249                StructInstType *newInst = new StructInstType( inst->get_qualifiers(), concDecl->get_name() );
    231250                newInst->set_baseStruct( concDecl );
     251
     252                deleteAll( typeSubs );
    232253                delete inst;
    233254                return newInst;
     
    242263                // exit early if no need for further mutation
    243264                if ( inst->get_parameters().empty() ) return inst;
    244 
     265                assert( inst->get_baseParameters() && "Base union has parameters" );
     266
     267                // check if type can be concretely instantiated; put substitutions into typeSubs
     268                std::list< TypeExpr* > typeSubs;
     269                if ( ! makeSubstitutions( *inst->get_baseParameters(), inst->get_parameters(), typeSubs ) ) {
     270                        deleteAll( typeSubs );
     271                        return inst;
     272                }
     273               
    245274                // make concrete instantiation of generic type
    246                 UnionDecl *concDecl = instantiations.lookup( inst );
     275                UnionDecl *concDecl = instantiations.lookup( inst, typeSubs );
    247276                if ( ! concDecl ) {
    248277                        // set concDecl to new type, insert type declaration into statements to add
    249                         assert( inst->get_baseParameters() && "Base union has parameters" );
    250278                        concDecl = new UnionDecl( typeNamer.newName( inst->get_name() ) );
    251                         substituteMembers( inst->get_baseUnion()->get_members(),
    252                                                                 *inst->get_baseParameters(), inst->get_parameters(),
    253                                                                 concDecl->get_members() );
    254                         addDeclaration( concDecl );
    255                         instantiations.insert( inst, concDecl );
     279                        substituteMembers( inst->get_baseUnion()->get_members(), *inst->get_baseParameters(), typeSubs, concDecl->get_members() );
     280                        DeclMutator::addDeclaration( concDecl );
     281                        instantiations.insert( inst, typeSubs, concDecl );
    256282                }
    257283                UnionInstType *newInst = new UnionInstType( inst->get_qualifiers(), concDecl->get_name() );
    258284                newInst->set_baseUnion( concDecl );
     285
     286                deleteAll( typeSubs );
    259287                delete inst;
    260288                return newInst;
     
    262290       
    263291        void Instantiate::doBeginScope() {
     292                DeclMutator::doBeginScope();
    264293                // push a new concrete type scope
    265294                instantiations.beginScope();
     
    267296
    268297        void Instantiate::doEndScope() {
     298                DeclMutator::doEndScope();
    269299                // pop the last concrete type scope
    270300                instantiations.endScope();
  • src/GenPoly/module.mk

    rf2b2029 re58be8e  
    2323       GenPoly/CopyParams.cc \
    2424       GenPoly/FindFunction.cc \
    25        GenPoly/InstantiateGeneric.cc
     25       GenPoly/InstantiateGeneric.cc \
     26       GenPoly/DeclMutator.cc
Note: See TracChangeset for help on using the changeset viewer.