Changeset 4e284ea6 for src/GenPoly


Ignore:
Timestamp:
Mar 8, 2016, 10:32:47 AM (9 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:
e8032b0
Parents:
6635c74
Message:

Move InstantiateGeneric? into Box.cc to share impl details

Location:
src/GenPoly
Files:
2 deleted
2 edited

Legend:

Unmodified
Added
Removed
  • src/GenPoly/Box.cc

    r6635c74 r4e284ea6  
    1414//
    1515
     16#include <algorithm>
     17#include <iterator>
     18#include <list>
     19#include <map>
    1620#include <set>
    1721#include <stack>
    1822#include <string>
    19 #include <iterator>
    20 #include <algorithm>
     23#include <utility>
     24#include <vector>
    2125#include <cassert>
    2226
    2327#include "Box.h"
    2428#include "DeclMutator.h"
    25 #include "InstantiateGeneric.h"
    2629#include "PolyMutator.h"
    2730#include "FindFunction.h"
     
    3235
    3336#include "SynTree/Constant.h"
    34 #include "SynTree/Type.h"
     37#include "SynTree/Declaration.h"
    3538#include "SynTree/Expression.h"
    3639#include "SynTree/Initializer.h"
     40#include "SynTree/Mutator.h"
    3741#include "SynTree/Statement.h"
    38 #include "SynTree/Mutator.h"
     42#include "SynTree/Type.h"
     43#include "SynTree/TypeSubstitution.h"
    3944
    4045#include "ResolvExpr/TypeEnvironment.h"
     
    4247#include "ResolvExpr/typeops.h"
    4348
     49#include "SymTab/Indexer.h"
    4450#include "SymTab/Mangler.h"
    4551
     
    5561
    5662                FunctionType *makeAdapterType( FunctionType *adaptee, const TyVarMap &tyVars );
     63
     64                /// Key for a unique concrete type; generic base type paired with type parameter list
     65                struct ConcreteType {
     66                        ConcreteType() : base(NULL), params() {}
     67
     68                        ConcreteType(AggregateDecl *_base, const std::list< Type* >& _params) : base(_base), params() { cloneAll(_params, params); }
     69
     70                        ConcreteType(const ConcreteType& that) : base(that.base), params() { cloneAll(that.params, params); }
     71
     72                        /// Extracts types from a list of TypeExpr*
     73                        ConcreteType(AggregateDecl *_base, const std::list< TypeExpr* >& _params) : base(_base), params() {
     74                                for ( std::list< TypeExpr* >::const_iterator param = _params.begin(); param != _params.end(); ++param ) {
     75                                        params.push_back( (*param)->get_type()->clone() );
     76                                }
     77                        }
     78
     79                        ConcreteType& operator= (const ConcreteType& that) {
     80                                deleteAll( params );
     81                                params.clear();
     82
     83                                base = that.base;
     84                                cloneAll( that.params, params );
     85
     86                                return *this;
     87                        }
     88
     89                        ~ConcreteType() { deleteAll( params ); }
     90
     91                        bool operator== (const ConcreteType& that) const {
     92                                if ( base != that.base ) return false;
     93
     94                                SymTab::Indexer dummy;
     95                                if ( params.size() != that.params.size() ) return false;
     96                                for ( std::list< Type* >::const_iterator it = params.begin(), jt = that.params.begin(); it != params.end(); ++it, ++jt ) {
     97                                        if ( ! ResolvExpr::typesCompatible( *it, *jt, dummy ) ) return false;
     98                                }
     99                                return true;
     100                        }
     101
     102                        AggregateDecl *base;        ///< Base generic type
     103                        std::list< Type* > params;  ///< Instantiation parameters
     104                };
     105
     106                /// Maps a concrete type to the some value, accounting for scope
     107                template< typename Value >
     108                class InstantiationMap {
     109                        /// Information about a specific instantiation of a generic type
     110                        struct Instantiation {
     111                                ConcreteType key;  ///< Instantiation parameters for this type
     112                                Value *value;      ///< Value for this instantiation
     113
     114                                Instantiation() : key(), value(0) {}
     115                                Instantiation(const ConcreteType &_key, Value *_value) : key(_key), value(_value) {}
     116                        };
     117                        /// Map of generic types to instantiations of them
     118                        typedef std::map< AggregateDecl*, std::vector< Instantiation > > Scope;
     119
     120                        std::vector< Scope > scopes;  ///< list of scopes, from outermost to innermost
     121
     122                public:
     123                        /// Starts a new scope
     124                        void beginScope() {
     125                                Scope scope;
     126                                scopes.push_back(scope);
     127                        }
     128
     129                        /// Ends a scope
     130                        void endScope() {
     131                                scopes.pop_back();
     132                        }
     133
     134                        /// Default constructor initializes with one scope
     135                        InstantiationMap() { beginScope(); }
     136
     137//              private:
     138                        /// Gets the value for the concrete instantiation of this type, assuming it has already been instantiated in the current scope.
     139                        /// Returns NULL on none such.
     140                        Value *lookup( AggregateDecl *generic, const std::list< TypeExpr* >& params ) {
     141                                ConcreteType key(generic, params);
     142                                // scan scopes from innermost out
     143                                for ( typename std::vector< Scope >::const_reverse_iterator scope = scopes.rbegin(); scope != scopes.rend(); ++scope ) {
     144                                        // skip scope if no instantiations of this generic type
     145                                        typename Scope::const_iterator insts = scope->find( generic );
     146                                        if ( insts == scope->end() ) continue;
     147                                        // look through instantiations for matches to concrete type
     148                                        for ( typename std::vector< Instantiation >::const_iterator inst = insts->second.begin(); inst != insts->second.end(); ++inst ) {
     149                                                if ( inst->key == key ) return inst->value;
     150                                        }
     151                                }
     152                                // no matching instantiation found
     153                                return 0;
     154                        }
     155                public:
     156//                      StructDecl* lookup( StructInstType *inst, const std::list< TypeExpr* > &typeSubs ) { return (StructDecl*)lookup( inst->get_baseStruct(), typeSubs ); }
     157//                      UnionDecl* lookup( UnionInstType *inst, const std::list< TypeExpr* > &typeSubs ) { return (UnionDecl*)lookup( inst->get_baseUnion(), typeSubs ); }
     158
     159//              private:
     160                        /// Adds a value for a concrete type to the current scope
     161                        void insert( AggregateDecl *generic, const std::list< TypeExpr* > &params, Value *value ) {
     162                                ConcreteType key(generic, params);
     163                                scopes.back()[generic].push_back( Instantiation( key, value ) );
     164                        }
     165//              public:
     166//                      void insert( StructInstType *inst, const std::list< TypeExpr* > &typeSubs, StructDecl *decl ) { insert( inst->get_baseStruct(), typeSubs, decl ); }
     167//                      void insert( UnionInstType *inst, const std::list< TypeExpr* > &typeSubs, UnionDecl *decl ) { insert( inst->get_baseUnion(), typeSubs, decl ); }
     168                };
    57169
    58170                /// Adds layout-generation functions to polymorphic types
     
    138250                };
    139251
     252                /// Mutator pass that replaces concrete instantiations of generic types with actual struct declarations, scoped appropriately
     253                class GenericInstantiator : public DeclMutator {
     254                        /// Map of (generic type, parameter list) pairs to concrete type instantiations
     255                        InstantiationMap< AggregateDecl > instantiations;
     256                        /// Namer for concrete types
     257                        UniqueName typeNamer;
     258
     259                public:
     260                        GenericInstantiator() : DeclMutator(), instantiations(), typeNamer("_conc_") {}
     261
     262                        virtual Type* mutate( StructInstType *inst );
     263                        virtual Type* mutate( UnionInstType *inst );
     264
     265        //              virtual Expression* mutate( MemberExpr *memberExpr );
     266
     267                        virtual void doBeginScope();
     268                        virtual void doEndScope();
     269                private:
     270                        /// Wrap instantiation lookup for structs
     271                        StructDecl* lookup( StructInstType *inst, const std::list< TypeExpr* > &typeSubs ) { return (StructDecl*)instantiations.lookup( inst->get_baseStruct(), typeSubs ); }
     272                        /// Wrap instantiation lookup for unions
     273                        UnionDecl* lookup( UnionInstType *inst, const std::list< TypeExpr* > &typeSubs ) { return (UnionDecl*)instantiations.lookup( inst->get_baseUnion(), typeSubs ); }
     274                        /// Wrap instantiation insertion for structs
     275                        void insert( StructInstType *inst, const std::list< TypeExpr* > &typeSubs, StructDecl *decl ) { instantiations.insert( inst->get_baseStruct(), typeSubs, decl ); }
     276                        /// Wrap instantiation insertion for unions
     277                        void insert( UnionInstType *inst, const std::list< TypeExpr* > &typeSubs, UnionDecl *decl ) { instantiations.insert( inst->get_baseUnion(), typeSubs, decl ); }
     278                };
     279
    140280                /// Replaces member expressions for polymorphic types with calculated add-field-offset-and-dereference;
    141281                /// also fixes offsetof expressions.
     
    201341                Pass1 pass1;
    202342                Pass2 pass2;
     343                GenericInstantiator instantiator;
    203344                MemberExprFixer memberFixer;
    204345                Pass3 pass3;
     346               
    205347                layoutBuilder.mutateDeclarationList( translationUnit );
    206348                mutateTranslationUnit/*All*/( translationUnit, pass1 );
    207349                mutateTranslationUnit/*All*/( translationUnit, pass2 );
    208                 instantiateGeneric( translationUnit );
     350//              instantiateGeneric( translationUnit );
     351                instantiator.mutateDeclarationList( translationUnit );
    209352                mutateTranslationUnit/*All*/( translationUnit, memberFixer );
    210353                mutateTranslationUnit/*All*/( translationUnit, pass3 );
     
    15091652                }
    15101653
     1654//////////////////////////////////////// GenericInstantiator //////////////////////////////////////////////////
     1655
     1656                /// Makes substitutions of params into baseParams; returns true if all parameters substituted for a concrete type
     1657                bool makeSubstitutions( const std::list< TypeDecl* >& baseParams, const std::list< Expression* >& params, std::list< TypeExpr* >& out ) {
     1658                        bool allConcrete = true;  // will finish the substitution list even if they're not all concrete
     1659
     1660                        // substitute concrete types for given parameters, and incomplete types for placeholders
     1661                        std::list< TypeDecl* >::const_iterator baseParam = baseParams.begin();
     1662                        std::list< Expression* >::const_iterator param = params.begin();
     1663                        for ( ; baseParam != baseParams.end() && param != params.end(); ++baseParam, ++param ) {
     1664        //                      switch ( (*baseParam)->get_kind() ) {
     1665        //                      case TypeDecl::Any: {   // any type is a valid substitution here; complete types can be used to instantiate generics
     1666                                        TypeExpr *paramType = dynamic_cast< TypeExpr* >( *param );
     1667                                        assert(paramType && "Aggregate parameters should be type expressions");
     1668                                        out.push_back( paramType->clone() );
     1669                                        // check that the substituted type isn't a type variable itself
     1670                                        if ( dynamic_cast< TypeInstType* >( paramType->get_type() ) ) {
     1671                                                allConcrete = false;
     1672                                        }
     1673        //                              break;
     1674        //                      }
     1675        //                      case TypeDecl::Dtype:  // dtype can be consistently replaced with void [only pointers, which become void*]
     1676        //                              out.push_back( new TypeExpr( new VoidType( Type::Qualifiers() ) ) );
     1677        //                              break;
     1678        //                      case TypeDecl::Ftype:  // pointer-to-ftype can be consistently replaced with void (*)(void) [similar to dtype]
     1679        //                              out.push_back( new TypeExpr( new FunctionType( Type::Qualifiers(), false ) ) );
     1680        //                              break;
     1681        //                      }
     1682                        }
     1683
     1684                        // if any parameters left over, not done
     1685                        if ( baseParam != baseParams.end() ) return false;
     1686        //              // if not enough parameters given, substitute remaining incomplete types for placeholders
     1687        //              for ( ; baseParam != baseParams.end(); ++baseParam ) {
     1688        //                      switch ( (*baseParam)->get_kind() ) {
     1689        //                      case TypeDecl::Any:    // no more substitutions here, fail early
     1690        //                              return false;
     1691        //                      case TypeDecl::Dtype:  // dtype can be consistently replaced with void [only pointers, which become void*]
     1692        //                              out.push_back( new TypeExpr( new VoidType( Type::Qualifiers() ) ) );
     1693        //                              break;
     1694        //                      case TypeDecl::Ftype:  // pointer-to-ftype can be consistently replaced with void (*)(void) [similar to dtype]
     1695        //                              out.push_back( new TypeExpr( new FunctionType( Type::Qualifiers(), false ) ) );
     1696        //                              break;
     1697        //                      }
     1698        //              }
     1699
     1700                        return allConcrete;
     1701                }
     1702
     1703                /// Substitutes types of members of in according to baseParams => typeSubs, appending the result to out
     1704                void substituteMembers( const std::list< Declaration* >& in, const std::list< TypeDecl* >& baseParams, const std::list< TypeExpr* >& typeSubs,
     1705                                                                std::list< Declaration* >& out ) {
     1706                        // substitute types into new members
     1707                        TypeSubstitution subs( baseParams.begin(), baseParams.end(), typeSubs.begin() );
     1708                        for ( std::list< Declaration* >::const_iterator member = in.begin(); member != in.end(); ++member ) {
     1709                                Declaration *newMember = (*member)->clone();
     1710                                subs.apply(newMember);
     1711                                out.push_back( newMember );
     1712                        }
     1713                }
     1714
     1715                Type* GenericInstantiator::mutate( StructInstType *inst ) {
     1716                        // mutate subtypes
     1717                        Type *mutated = Mutator::mutate( inst );
     1718                        inst = dynamic_cast< StructInstType* >( mutated );
     1719                        if ( ! inst ) return mutated;
     1720
     1721                        // exit early if no need for further mutation
     1722                        if ( inst->get_parameters().empty() ) return inst;
     1723                        assert( inst->get_baseParameters() && "Base struct has parameters" );
     1724
     1725                        // check if type can be concretely instantiated; put substitutions into typeSubs
     1726                        std::list< TypeExpr* > typeSubs;
     1727                        if ( ! makeSubstitutions( *inst->get_baseParameters(), inst->get_parameters(), typeSubs ) ) {
     1728                                deleteAll( typeSubs );
     1729                                return inst;
     1730                        }
     1731
     1732                        // make concrete instantiation of generic type
     1733                        StructDecl *concDecl = lookup( inst, typeSubs );
     1734                        if ( ! concDecl ) {
     1735                                // set concDecl to new type, insert type declaration into statements to add
     1736                                concDecl = new StructDecl( typeNamer.newName( inst->get_name() ) );
     1737                                substituteMembers( inst->get_baseStruct()->get_members(), *inst->get_baseParameters(), typeSubs,        concDecl->get_members() );
     1738                                DeclMutator::addDeclaration( concDecl );
     1739                                insert( inst, typeSubs, concDecl );
     1740                        }
     1741                        StructInstType *newInst = new StructInstType( inst->get_qualifiers(), concDecl->get_name() );
     1742                        newInst->set_baseStruct( concDecl );
     1743
     1744                        deleteAll( typeSubs );
     1745                        delete inst;
     1746                        return newInst;
     1747                }
     1748
     1749                Type* GenericInstantiator::mutate( UnionInstType *inst ) {
     1750                        // mutate subtypes
     1751                        Type *mutated = Mutator::mutate( inst );
     1752                        inst = dynamic_cast< UnionInstType* >( mutated );
     1753                        if ( ! inst ) return mutated;
     1754
     1755                        // exit early if no need for further mutation
     1756                        if ( inst->get_parameters().empty() ) return inst;
     1757                        assert( inst->get_baseParameters() && "Base union has parameters" );
     1758
     1759                        // check if type can be concretely instantiated; put substitutions into typeSubs
     1760                        std::list< TypeExpr* > typeSubs;
     1761                        if ( ! makeSubstitutions( *inst->get_baseParameters(), inst->get_parameters(), typeSubs ) ) {
     1762                                deleteAll( typeSubs );
     1763                                return inst;
     1764                        }
     1765
     1766                        // make concrete instantiation of generic type
     1767                        UnionDecl *concDecl = lookup( inst, typeSubs );
     1768                        if ( ! concDecl ) {
     1769                                // set concDecl to new type, insert type declaration into statements to add
     1770                                concDecl = new UnionDecl( typeNamer.newName( inst->get_name() ) );
     1771                                substituteMembers( inst->get_baseUnion()->get_members(), *inst->get_baseParameters(), typeSubs, concDecl->get_members() );
     1772                                DeclMutator::addDeclaration( concDecl );
     1773                                insert( inst, typeSubs, concDecl );
     1774                        }
     1775                        UnionInstType *newInst = new UnionInstType( inst->get_qualifiers(), concDecl->get_name() );
     1776                        newInst->set_baseUnion( concDecl );
     1777
     1778                        deleteAll( typeSubs );
     1779                        delete inst;
     1780                        return newInst;
     1781                }
     1782
     1783        //      /// Gets the base struct or union declaration for a member expression; NULL if not applicable
     1784        //      AggregateDecl* getMemberBaseDecl( MemberExpr *memberExpr ) {
     1785        //              // get variable for member aggregate
     1786        //              VariableExpr *varExpr = dynamic_cast< VariableExpr* >( memberExpr->get_aggregate() );
     1787        //              if ( ! varExpr ) return NULL;
     1788        //
     1789        //              // get object for variable
     1790        //              ObjectDecl *objectDecl = dynamic_cast< ObjectDecl* >( varExpr->get_var() );
     1791        //              if ( ! objectDecl ) return NULL;
     1792        //
     1793        //              // get base declaration from object type
     1794        //              Type *objectType = objectDecl->get_type();
     1795        //              StructInstType *structType = dynamic_cast< StructInstType* >( objectType );
     1796        //              if ( structType ) return structType->get_baseStruct();
     1797        //              UnionInstType *unionType = dynamic_cast< UnionInstType* >( objectType );
     1798        //              if ( unionType ) return unionType->get_baseUnion();
     1799        //
     1800        //              return NULL;
     1801        //      }
     1802        //
     1803        //      /// Finds the declaration with the given name, returning decls.end() if none such
     1804        //      std::list< Declaration* >::const_iterator findDeclNamed( const std::list< Declaration* > &decls, const std::string &name ) {
     1805        //              for( std::list< Declaration* >::const_iterator decl = decls.begin(); decl != decls.end(); ++decl ) {
     1806        //                      if ( (*decl)->get_name() == name ) return decl;
     1807        //              }
     1808        //              return decls.end();
     1809        //      }
     1810        //
     1811        //      Expression* Instantiate::mutate( MemberExpr *memberExpr ) {
     1812        //              // mutate, exiting early if no longer MemberExpr
     1813        //              Expression *expr = Mutator::mutate( memberExpr );
     1814        //              memberExpr = dynamic_cast< MemberExpr* >( expr );
     1815        //              if ( ! memberExpr ) return expr;
     1816        //
     1817        //              // get declaration of member and base declaration of member, exiting early if not found
     1818        //              AggregateDecl *memberBase = getMemberBaseDecl( memberExpr );
     1819        //              if ( ! memberBase ) return memberExpr;
     1820        //              DeclarationWithType *memberDecl = memberExpr->get_member();
     1821        //              std::list< Declaration* >::const_iterator baseIt = findDeclNamed( memberBase->get_members(), memberDecl->get_name() );
     1822        //              if ( baseIt == memberBase->get_members().end() ) return memberExpr;
     1823        //              DeclarationWithType *baseDecl = dynamic_cast< DeclarationWithType* >( *baseIt );
     1824        //              if ( ! baseDecl ) return memberExpr;
     1825        //
     1826        //              // check if stated type of the member is not the type of the member's declaration; if so, need a cast
     1827        //              // this *SHOULD* be safe, I don't think anything but the void-replacements I put in for dtypes would make it past the typechecker
     1828        //              SymTab::Indexer dummy;
     1829        //              if ( ResolvExpr::typesCompatible( memberDecl->get_type(), baseDecl->get_type(), dummy ) ) return memberExpr;
     1830        //              else return new CastExpr( memberExpr, memberDecl->get_type() );
     1831        //      }
     1832
     1833                void GenericInstantiator::doBeginScope() {
     1834                        DeclMutator::doBeginScope();
     1835                        instantiations.beginScope();
     1836                }
     1837
     1838                void GenericInstantiator::doEndScope() {
     1839                        DeclMutator::doEndScope();
     1840                        instantiations.endScope();
     1841                }
     1842
    15111843////////////////////////////////////////// MemberExprFixer ////////////////////////////////////////////////////
    15121844
  • src/GenPoly/module.mk

    r6635c74 r4e284ea6  
    2323       GenPoly/CopyParams.cc \
    2424       GenPoly/FindFunction.cc \
    25        GenPoly/InstantiateGeneric.cc \
    2625       GenPoly/DeclMutator.cc
Note: See TracChangeset for help on using the changeset viewer.