Ignore:
Timestamp:
Nov 19, 2015, 3:49:00 PM (8 years ago)
Author:
Aaron Moss <a3moss@…>
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:
05587c2, 63afee0, ed94eac
Parents:
a2eda27
Message:

Fixed InstantiateGeneric?'s handling of top-level declarations

File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/GenPoly/InstantiateGeneric.cc

    ra2eda27 r258eb5c9  
    3636namespace GenPoly {
    3737
    38         class Instantiate : public PolyMutator {
    39         public:
    40                 /// Key for a unique concrete type; generic base type paired with type parameter list
    41                 struct ConcreteType {
    42                         ConcreteType() : base(NULL), params() {}
    43 
    44                         ConcreteType(AggregateDecl *_base, const std::list< Type* >& _params) : base(_base), params() { cloneAll(_params, params); }
    45 
    46                         ConcreteType(const ConcreteType& that) : base(that.base), params() { cloneAll(that.params, params); }
    47 
    48                         /// Extracts types from a list of Expression* (which should be TypeExpr*)
    49                         ConcreteType(AggregateDecl *_base, const std::list< Expression* >& _params) : base(_base), params() {
    50                                 for ( std::list< Expression* >::const_iterator it = _params.begin(); it != _params.end(); ++it ) {
    51                                         TypeExpr *param = dynamic_cast< TypeExpr* >(*it);
    52                                         assert(param && "Aggregate parameters should be type expressions");
    53                                         params.push_back( param->get_type()->clone() );
     38        /// Key for a unique concrete type; generic base type paired with type parameter list
     39        struct ConcreteType {
     40                ConcreteType() : base(NULL), params() {}
     41
     42                ConcreteType(AggregateDecl *_base, const std::list< Type* >& _params) : base(_base), params() { cloneAll(_params, params); }
     43
     44                ConcreteType(const ConcreteType& that) : base(that.base), params() { cloneAll(that.params, params); }
     45
     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() );
     52                        }
     53                }
     54
     55                ConcreteType& operator= (const ConcreteType& that) {
     56                        deleteAll( params );
     57                        params.clear();
     58
     59                        base = that.base;
     60                        cloneAll( that.params, params );
     61
     62                        return *this;
     63                }
     64
     65                ~ConcreteType() { deleteAll( params ); }
     66
     67                bool operator== (const ConcreteType& that) const {
     68                        SymTab::Indexer dummy;
     69
     70                        if ( base != that.base ) return false;
     71                        if ( params.size() != that.params.size() ) return false;
     72                        for ( std::list< Type* >::const_iterator it = params.begin(), jt = that.params.begin(); it != params.end(); ++it, ++jt ) {
     73                                if ( ! ResolvExpr::typesCompatible( *it, *jt, dummy ) ) return false;
     74                        }
     75                        return true;
     76                }
     77
     78                AggregateDecl *base;        ///< Base generic type
     79                std::list< Type* > params;  ///< Instantiation parameters
     80        };
     81
     82        /// Maps a concrete type to the instantiated struct type, accounting for scope
     83        class InstantiationMap {
     84                /// Pair of concrete type and declaration that instantiates it
     85                typedef std::pair< ConcreteType, AggregateDecl* > Instantiation;
     86                /// Map of generic types to instantiations of them
     87                typedef std::map< AggregateDecl*, std::vector< Instantiation > > Scope;
     88
     89                std::vector< Scope > scopes;  ///< list of scopes, from outermost to innermost
     90
     91        public:
     92                /// Starts a new scope
     93                void beginScope() {
     94                        Scope scope;
     95                        scopes.push_back(scope);
     96                }
     97
     98                /// Ends a scope
     99                void endScope() {
     100                        scopes.pop_back();
     101                }
     102
     103                /// Default constructor initializes with one scope
     104                InstantiationMap() { beginScope(); }
     105
     106        private:
     107                /// Gets the declaration for the concrete instantiation of this type, assuming it has already been instantiated in the current scope.
     108                /// Returns NULL on none such.
     109                AggregateDecl* lookup( AggregateDecl *generic, std::list< Expression* >& params ) {
     110                        ConcreteType key(generic, params);
     111                        // scan scopes from innermost out
     112                        for ( std::vector< Scope >::const_reverse_iterator scope = scopes.rbegin(); scope != scopes.rend(); ++scope ) {
     113                                // skip scope if no instantiations of this generic type
     114                                Scope::const_iterator insts = scope->find( generic );
     115                                if ( insts == scope->end() ) continue;
     116                                // look through instantiations for matches to concrete type
     117                                for ( std::vector< Instantiation >::const_iterator inst = insts->second.begin(); inst != insts->second.end(); ++inst ) {
     118                                        if ( inst->first == key ) return inst->second;
    54119                                }
    55120                        }
    56 
    57                         ConcreteType& operator= (const ConcreteType& that) {
    58                                 deleteAll( params );
    59                                 params.clear();
    60                                
    61                                 base = that.base;
    62                                 cloneAll( that.params, params );
    63 
    64                                 return *this;
    65                         }
    66 
    67                         ~ConcreteType() { deleteAll( params ); }
    68                        
    69                         bool operator== (const ConcreteType& that) const {
    70                                 SymTab::Indexer dummy;
    71                                
    72                                 if ( base != that.base ) return false;
    73                                 if ( params.size() != that.params.size() ) return false;
    74                                 for ( std::list< Type* >::const_iterator it = params.begin(), jt = that.params.begin(); it != params.end(); ++it, ++jt ) {
    75                                         if ( ! ResolvExpr::typesCompatible( *it, *jt, dummy ) ) return false;
    76                                 }
    77                                 return true;
    78                         }
    79 
    80                         AggregateDecl *base;        ///< Base generic type
    81                         std::list< Type* > params;  ///< Instantiation parameters
    82                 };
     121                        // no matching instantiation found
     122                        return NULL;
     123                }
     124        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() ); }
     127
     128        private:
     129                /// Adds a declaration for a concrete type to the current scope
     130                void insert( AggregateDecl *generic, std::list< Expression* >& params, AggregateDecl *decl ) {
     131                        ConcreteType key(generic, params);
     132                        scopes.back()[generic].push_back( std::make_pair( key, decl ) );
     133                }
     134        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 ); }
     137        };
     138
     139        /// Mutator pass that replaces concrete instantiations of generic types with actual struct declarations, scoped appropriately
     140        class Instantiate : public PolyMutator {
     141                InstantiationMap instantiations;
     142                UniqueName typeNamer;
     143
     144        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 );
    83149               
    84                 /// Maps a concrete type to the instantiated struct type, accounting for scope
    85                 class InstantiationMap {
    86                         /// Pair of concrete type and declaration that instantiates it
    87                         typedef std::pair< ConcreteType, AggregateDecl* > Instantiation;
    88                         /// Map of generic types to instantiations of them
    89                         typedef std::map< AggregateDecl*, std::vector< Instantiation > > Scope;
    90 
    91                         std::vector< Scope > scopes;  ///< list of scopes, from outermost to innermost
    92 
    93                 public:
    94                         /// Starts a new scope
    95                         void beginScope() {
    96                                 Scope scope;
    97                                 scopes.push_back(scope);
    98                         }
    99 
    100                         /// Ends a scope
    101                         void endScope() {
    102                                 scopes.pop_back();
    103                         }
    104                        
    105                         /// Default constructor initializes with one scope
    106                         InstantiationMap() { beginScope(); }
    107 
    108                 private:
    109                         /// Gets the declaration for the concrete instantiation of this type, assuming it has already been instantiated in the current scope.
    110                         /// Returns NULL on none such.
    111                         AggregateDecl* lookup( AggregateDecl *generic, std::list< Expression* >& params ) {
    112                                 ConcreteType key(generic, params);
    113                                 // scan scopes from innermost out
    114                                 for ( std::vector< Scope >::const_reverse_iterator scope = scopes.rbegin(); scope != scopes.rend(); ++scope ) {
    115                                         // skip scope if no instantiations of this generic type
    116                                         Scope::const_iterator insts = scope->find( generic );
    117                                         if ( insts == scope->end() ) continue;
    118                                         // look through instantiations for matches to concrete type
    119                                         for ( std::vector< Instantiation >::const_iterator inst = insts->second.begin(); inst != insts->second.end(); ++inst ) {
    120                                                 if ( inst->first == key ) return inst->second;
    121                                         }
    122                                 }
    123                                 // no matching instantiation found
    124                                 return NULL;
    125                         }
    126                 public:
    127                         StructDecl* lookup( StructInstType *inst ) { return (StructDecl*)lookup( inst->get_baseStruct(), inst->get_parameters() ); }
    128                         UnionDecl* lookup( UnionInstType *inst ) { return (UnionDecl*)lookup( inst->get_baseUnion(), inst->get_parameters() ); }
    129 
    130                 private:
    131                         /// Adds a declaration for a concrete type to the current scope
    132                         void insert( AggregateDecl *generic, std::list< Expression* >& params, AggregateDecl *decl ) {
    133                                 ConcreteType key(generic, params);
    134                                 scopes.back()[generic].push_back( std::make_pair( key, decl ) );
    135                         }
    136                 public:
    137                         void insert( StructInstType *inst, StructDecl *decl ) { insert( inst->get_baseStruct(), inst->get_parameters(), decl ); }
    138                         void insert( UnionInstType *inst, UnionDecl *decl ) { insert( inst->get_baseUnion(), inst->get_parameters(), decl ); }
    139                 };
    140 
    141150                virtual Type* mutate( StructInstType *inst );
    142151                virtual Type* mutate( UnionInstType *inst );
     
    148157                /// Adds a declaration to the current environment and the statements to add
    149158                void addDeclaration( AggregateDecl *decl ) {
    150                         std::list< Label > labels;
    151                         DeclStmt *stmt = new DeclStmt( labels, decl );
     159                        std::list< Label > nolabels;
     160                        DeclStmt *stmt = new DeclStmt( nolabels, decl );
    152161                        PolyMutator::stmtsToAdd.push_back( stmt );
    153162                }
    154                
    155                 InstantiationMap instantiations;
    156                 UniqueName typeNamer;
    157163        };
    158164       
    159165        void instantiateGeneric( std::list< Declaration* >& translationUnit ) {
    160166                Instantiate instantiator;
    161                 mutateAll( translationUnit, 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
    162194        }
    163195
Note: See TracChangeset for help on using the changeset viewer.