Changeset 7527e63 for src/GenPoly/Box.cc


Ignore:
Timestamp:
Aug 16, 2016, 3:20:06 PM (9 years ago)
Author:
Thierry Delisle <tdelisle@…>
Branches:
ADT, aaron-thesis, arm-eh, ast-experimental, 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:
1f6d4624
Parents:
950f7a7 (diff), 7880579 (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:software/cfa/cfa-cc

File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/GenPoly/Box.cc

    r950f7a7 r7527e63  
    6262
    6363                FunctionType *makeAdapterType( FunctionType *adaptee, const TyVarMap &tyVars );
    64 
    65                 /// Abstracts type equality for a list of parameter types
    66                 struct TypeList {
    67                         TypeList() : params() {}
    68                         TypeList( const std::list< Type* > &_params ) : params() { cloneAll(_params, params); }
    69                         TypeList( std::list< Type* > &&_params ) : params( _params ) {}
    70 
    71                         TypeList( const TypeList &that ) : params() { cloneAll(that.params, params); }
    72                         TypeList( TypeList &&that ) : params( std::move( that.params ) ) {}
    73 
    74                         /// Extracts types from a list of TypeExpr*
    75                         TypeList( const std::list< TypeExpr* >& _params ) : params() {
    76                                 for ( std::list< TypeExpr* >::const_iterator param = _params.begin(); param != _params.end(); ++param ) {
    77                                         params.push_back( (*param)->get_type()->clone() );
    78                                 }
    79                         }
    80 
    81                         TypeList& operator= ( const TypeList &that ) {
    82                                 deleteAll( params );
    83 
    84                                 params.clear();
    85                                 cloneAll( that.params, params );
    86 
    87                                 return *this;
    88                         }
    89 
    90                         TypeList& operator= ( TypeList &&that ) {
    91                                 deleteAll( params );
    92 
    93                                 params = std::move( that.params );
    94 
    95                                 return *this;
    96                         }
    97 
    98                         ~TypeList() { deleteAll( params ); }
    99 
    100                         bool operator== ( const TypeList& that ) const {
    101                                 if ( params.size() != that.params.size() ) return false;
    102 
    103                                 SymTab::Indexer dummy;
    104                                 for ( std::list< Type* >::const_iterator it = params.begin(), jt = that.params.begin(); it != params.end(); ++it, ++jt ) {
    105                                         if ( ! ResolvExpr::typesCompatible( *it, *jt, dummy ) ) return false;
    106                                 }
    107                                 return true;
    108                         }
    109 
    110                         std::list< Type* > params;  ///< Instantiation parameters
    111                 };
    112 
    113                 /// Maps a key and a TypeList to the some value, accounting for scope
    114                 template< typename Key, typename Value >
    115                 class InstantiationMap {
    116                         /// Wraps value for a specific (Key, TypeList) combination
    117                         typedef std::pair< TypeList, Value* > Instantiation;
    118                         /// List of TypeLists paired with their appropriate values
    119                         typedef std::vector< Instantiation > ValueList;
    120                         /// Underlying map type; maps keys to a linear list of corresponding TypeLists and values
    121                         typedef ScopedMap< Key*, ValueList > InnerMap;
    122 
    123                         InnerMap instantiations;  ///< instantiations
    124 
    125                 public:
    126                         /// Starts a new scope
    127                         void beginScope() { instantiations.beginScope(); }
    128 
    129                         /// Ends a scope
    130                         void endScope() { instantiations.endScope(); }
    131 
    132                         /// Gets the value for the (key, typeList) pair, returns NULL on none such.
    133                         Value *lookup( Key *key, const std::list< TypeExpr* >& params ) const {
    134                                 TypeList typeList( params );
    135 
    136                                 // scan scopes for matches to the key
    137                                 for ( typename InnerMap::const_iterator insts = instantiations.find( key ); insts != instantiations.end(); insts = instantiations.findNext( insts, key ) ) {
    138                                         for ( typename ValueList::const_reverse_iterator inst = insts->second.rbegin(); inst != insts->second.rend(); ++inst ) {
    139                                                 if ( inst->first == typeList ) return inst->second;
    140                                         }
    141                                 }
    142                                 // no matching instantiations found
    143                                 return 0;
    144                         }
    145 
    146                         /// Adds a value for a (key, typeList) pair to the current scope
    147                         void insert( Key *key, const std::list< TypeExpr* > &params, Value *value ) {
    148                                 instantiations[ key ].push_back( Instantiation( TypeList( params ), value ) );
    149                         }
    150                 };
    15164
    15265                /// Adds layout-generation functions to polymorphic types
     
    191104                        Type *replaceWithConcrete( ApplicationExpr *appExpr, Type *type, bool doClone = true );
    192105                        /// wraps a function application returning a polymorphic type with a new temporary for the out-parameter return value
    193                         Expression *addPolyRetParam( ApplicationExpr *appExpr, FunctionType *function, ReferenceToType *polyType, std::list< Expression *>::iterator &arg );
     106                        Expression *addDynRetParam( ApplicationExpr *appExpr, FunctionType *function, ReferenceToType *polyType, std::list< Expression *>::iterator &arg );
    194107                        Expression *applyAdapter( ApplicationExpr *appExpr, FunctionType *function, std::list< Expression *>::iterator &arg, const TyVarMap &exprTyVars );
    195108                        void boxParam( Type *formal, Expression *&arg, const TyVarMap &exprTyVars );
     
    237150
    238151                        std::map< UniqueId, std::string > adapterName;
    239                 };
    240 
    241                 /// Mutator pass that replaces concrete instantiations of generic types with actual struct declarations, scoped appropriately
    242                 class GenericInstantiator : public DeclMutator {
    243                         /// Map of (generic type, parameter list) pairs to concrete type instantiations
    244                         InstantiationMap< AggregateDecl, AggregateDecl > instantiations;
    245                         /// Namer for concrete types
    246                         UniqueName typeNamer;
    247 
    248                 public:
    249                         GenericInstantiator() : DeclMutator(), instantiations(), typeNamer("_conc_") {}
    250 
    251                         virtual Type* mutate( StructInstType *inst );
    252                         virtual Type* mutate( UnionInstType *inst );
    253 
    254         //              virtual Expression* mutate( MemberExpr *memberExpr );
    255 
    256                         virtual void doBeginScope();
    257                         virtual void doEndScope();
    258                 private:
    259                         /// Wrap instantiation lookup for structs
    260                         StructDecl* lookup( StructInstType *inst, const std::list< TypeExpr* > &typeSubs ) { return (StructDecl*)instantiations.lookup( inst->get_baseStruct(), typeSubs ); }
    261                         /// Wrap instantiation lookup for unions
    262                         UnionDecl* lookup( UnionInstType *inst, const std::list< TypeExpr* > &typeSubs ) { return (UnionDecl*)instantiations.lookup( inst->get_baseUnion(), typeSubs ); }
    263                         /// Wrap instantiation insertion for structs
    264                         void insert( StructInstType *inst, const std::list< TypeExpr* > &typeSubs, StructDecl *decl ) { instantiations.insert( inst->get_baseStruct(), typeSubs, decl ); }
    265                         /// Wrap instantiation insertion for unions
    266                         void insert( UnionInstType *inst, const std::list< TypeExpr* > &typeSubs, UnionDecl *decl ) { instantiations.insert( inst->get_baseUnion(), typeSubs, decl ); }
    267152                };
    268153
     
    354239                Pass1 pass1;
    355240                Pass2 pass2;
    356                 GenericInstantiator instantiator;
    357241                PolyGenericCalculator polyCalculator;
    358242                Pass3 pass3;
     
    361245                mutateTranslationUnit/*All*/( translationUnit, pass1 );
    362246                mutateTranslationUnit/*All*/( translationUnit, pass2 );
    363                 instantiator.mutateDeclarationList( translationUnit );
    364247                mutateTranslationUnit/*All*/( translationUnit, polyCalculator );
    365248                mutateTranslationUnit/*All*/( translationUnit, pass3 );
     
    619502                        return 0;
    620503                }
    621                
     504
    622505                /// Returns T if the given declaration is a function with parameters (T*, T) for some TypeInstType T, NULL otherwise
    623506                TypeInstType *isTypeInstPtrValFn( DeclarationWithType *decl ) {
     
    637520                        return 0;
    638521                }
    639                
     522
    640523                /// Returns T if the given declaration is (*?=?)(T *, T) for some TypeInstType T (return not checked, but maybe should be), NULL otherwise
    641524                TypeInstType *isTypeInstAssignment( DeclarationWithType *decl ) {
     
    677560                        return 0;
    678561                }
    679                
     562
    680563                /// Returns T if the given declaration is a function with parameters (T*, T) for some type T, where neither parameter is cv-qualified,
    681564                /// NULL otherwise
     
    772655                                copyOps.beginScope();
    773656                                dtorOps.beginScope();
    774                                
     657
    775658                                DeclarationWithType *oldRetval = retval;
    776659                                bool oldUseRetval = useRetval;
     
    778661                                // process polymorphic return value
    779662                                retval = 0;
    780                                 if ( isPolyRet( functionDecl->get_functionType() ) && functionDecl->get_linkage() == LinkageSpec::Cforall ) {
     663                                if ( isDynRet( functionDecl->get_functionType() ) && functionDecl->get_linkage() == LinkageSpec::Cforall ) {
    781664                                        retval = functionDecl->get_functionType()->get_returnVals().front();
    782665
     
    889772                                                arg++;
    890773                                        } else {
    891                                                 /// xxx - should this be an assertion?
     774                                                // xxx - should this be an assertion?
    892775                                                throw SemanticError( "unbound type variable: " + tyParm->first + " in application ", appExpr );
    893776                                        } // if
     
    902785                        std::list< DeclarationWithType* >::const_iterator fnParm = funcType->get_parameters().begin();
    903786                        std::list< Expression* >::const_iterator fnArg = arg;
    904                         std::set< std::string > seenTypes; //< names for generic types we've seen
     787                        std::set< std::string > seenTypes; ///< names for generic types we've seen
    905788
    906789                        // a polymorphic return type may need to be added to the argument list
     
    985868                }
    986869
    987                 Expression *Pass1::addPolyRetParam( ApplicationExpr *appExpr, FunctionType *function, ReferenceToType *polyType, std::list< Expression *>::iterator &arg ) {
     870                Expression *Pass1::addDynRetParam( ApplicationExpr *appExpr, FunctionType *function, ReferenceToType *dynType, std::list< Expression *>::iterator &arg ) {
    988871                        assert( env );
    989                         Type *concrete = replaceWithConcrete( appExpr, polyType );
     872                        Type *concrete = replaceWithConcrete( appExpr, dynType );
    990873                        // add out-parameter for return value
    991874                        return addRetParam( appExpr, function, concrete, arg );
     
    994877                Expression *Pass1::applyAdapter( ApplicationExpr *appExpr, FunctionType *function, std::list< Expression *>::iterator &arg, const TyVarMap &tyVars ) {
    995878                        Expression *ret = appExpr;
    996                         if ( ! function->get_returnVals().empty() && isPolyType( function->get_returnVals().front()->get_type(), tyVars ) ) {
     879//                      if ( ! function->get_returnVals().empty() && isPolyType( function->get_returnVals().front()->get_type(), tyVars ) ) {
     880                        if ( isDynRet( function, tyVars ) ) {
    997881                                ret = addRetParam( appExpr, function, function->get_returnVals().front()->get_type(), arg );
    998882                        } // if
     
    1042926                /// this gets rid of warnings from gcc.
    1043927                void addCast( Expression *&actual, Type *formal, const TyVarMap &tyVars ) {
    1044                         Type * newType = formal->clone();
    1045                         if ( getFunctionType( newType ) ) {
     928                        if ( getFunctionType( formal ) ) {
     929                                Type * newType = formal->clone();
    1046930                                newType = ScrubTyVars::scrub( newType, tyVars );
    1047931                                actual = new CastExpr( actual, newType );
     
    1085969                        // actually make the adapter type
    1086970                        FunctionType *adapter = adaptee->clone();
    1087                         if ( ! adapter->get_returnVals().empty() && isPolyType( adapter->get_returnVals().front()->get_type(), tyVars ) ) {
     971//                      if ( ! adapter->get_returnVals().empty() && isPolyType( adapter->get_returnVals().front()->get_type(), tyVars ) ) {
     972                        if ( isDynRet( adapter, tyVars ) ) {
    1088973                                makeRetParm( adapter );
    1089974                        } // if
     
    11471032                                addAdapterParams( adapteeApp, arg, param, adapterType->get_parameters().end(), realParam, tyVars );
    11481033                                bodyStmt = new ExprStmt( noLabels, adapteeApp );
    1149                         } else if ( isPolyType( adaptee->get_returnVals().front()->get_type(), tyVars ) ) {
     1034//                      } else if ( isPolyType( adaptee->get_returnVals().front()->get_type(), tyVars ) ) {
     1035                        } else if ( isDynType( adaptee->get_returnVals().front()->get_type(), tyVars ) ) {
    11501036                                // return type T
    11511037                                if ( (*param)->get_name() == "" ) {
     
    13941280                        TyVarMap exprTyVars( (TypeDecl::Kind)-1 );
    13951281                        makeTyVarMap( function, exprTyVars );
    1396                         ReferenceToType *polyRetType = isPolyRet( function );
    1397 
    1398                         if ( polyRetType ) {
    1399                                 ret = addPolyRetParam( appExpr, function, polyRetType, arg );
     1282                        ReferenceToType *dynRetType = isDynRet( function, exprTyVars );
     1283
     1284                        if ( dynRetType ) {
     1285                                ret = addDynRetParam( appExpr, function, dynRetType, arg );
    14001286                        } else if ( needsAdapter( function, scopeTyVars ) ) {
    14011287                                // std::cerr << "needs adapter: ";
     
    14071293                        arg = appExpr->get_args().begin();
    14081294
    1409                         passTypeVars( appExpr, polyRetType, arg, exprTyVars );
     1295                        passTypeVars( appExpr, dynRetType, arg, exprTyVars );
    14101296                        addInferredParams( appExpr, function, arg, exprTyVars );
    14111297
     
    14711357                VariableExpr *wrapFunctionDecl( DeclarationWithType *functionDecl ) {
    14721358                        // line below cloned from FixFunction.cc
     1359                        // xxx - functionObj is never added to a list of declarations...
    14731360                        ObjectDecl *functionObj = new ObjectDecl( functionDecl->get_name(), functionDecl->get_storageClass(), functionDecl->get_linkage(), 0,
    14741361                                                                  new PointerType( Type::Qualifiers(), functionDecl->get_type()->clone() ), 0 );
    14751362                        functionObj->set_mangleName( functionDecl->get_mangleName() );
     1363                        functionObj->set_scopeLevel( functionDecl->get_scopeLevel() );
    14761364                        return new VariableExpr( functionObj );
    14771365                }
     
    14921380                                        = ParamEntry( assertOp->get_uniqueId(), assertOp->get_type()->clone(), actualDecl->get_type()->clone(), wrapFunctionDecl( assertOp ) );
    14931381                }
    1494                
     1382
    14951383                Statement * Pass1::mutate( ReturnStmt *returnStmt ) {
    14961384                        if ( retval && returnStmt->get_expr() ) {
     
    15541442                                                DeclarationWithType *assertDtor = findOpForType( formalType, dtorOps, scopedDtorOps );
    15551443                                                if ( ! assertDtor ) throw SemanticError( "No destructor found for ", formalType );
    1556                                                
     1444
    15571445                                                // add inferred parameters for otype operators to assignment expression
    15581446                                                // NOTE: Code here assumes that first four assertions are assign op, ctor, copy ctor, dtor, in that order
     
    15681456                                                ++actualIt;
    15691457                                                addAssertionFor( assignExpr, *actualIt, assertDtor );
    1570                                                
    1571                                                 //DeclarationWithType *actualDecl = asserts.front();
    1572                                                 //assignExpr->get_inferParams()[ actualDecl->get_uniqueId() ]
    1573                                                 //      = ParamEntry( assertAssign->get_uniqueId(), assertAssign->get_type()->clone(), actualDecl->get_type()->clone(), wrapFunctionDecl( assertAssign ) );
     1458
    15741459                                        }
    15751460                                }
     
    16951580
    16961581                        // move polymorphic return type to parameter list
    1697                         if ( isPolyRet( funcType ) ) {
     1582                        if ( isDynRet( funcType ) ) {
    16981583                                DeclarationWithType *ret = funcType->get_returnVals().front();
    16991584                                ret->set_type( new PointerType( Type::Qualifiers(), ret->get_type() ) );
     
    17761661                }
    17771662
    1778 //////////////////////////////////////// GenericInstantiator //////////////////////////////////////////////////
    1779 
    1780                 /// Makes substitutions of params into baseParams; returns true if all parameters substituted for a concrete type
    1781                 bool makeSubstitutions( const std::list< TypeDecl* >& baseParams, const std::list< Expression* >& params, std::list< TypeExpr* >& out ) {
    1782                         bool allConcrete = true;  // will finish the substitution list even if they're not all concrete
    1783 
    1784                         // substitute concrete types for given parameters, and incomplete types for placeholders
    1785                         std::list< TypeDecl* >::const_iterator baseParam = baseParams.begin();
    1786                         std::list< Expression* >::const_iterator param = params.begin();
    1787                         for ( ; baseParam != baseParams.end() && param != params.end(); ++baseParam, ++param ) {
    1788         //                      switch ( (*baseParam)->get_kind() ) {
    1789         //                      case TypeDecl::Any: {   // any type is a valid substitution here; complete types can be used to instantiate generics
    1790                                         TypeExpr *paramType = dynamic_cast< TypeExpr* >( *param );
    1791                                         assert(paramType && "Aggregate parameters should be type expressions");
    1792                                         out.push_back( paramType->clone() );
    1793                                         // check that the substituted type isn't a type variable itself
    1794                                         if ( dynamic_cast< TypeInstType* >( paramType->get_type() ) ) {
    1795                                                 allConcrete = false;
    1796                                         }
    1797         //                              break;
    1798         //                      }
    1799         //                      case TypeDecl::Dtype:  // dtype can be consistently replaced with void [only pointers, which become void*]
    1800         //                              out.push_back( new TypeExpr( new VoidType( Type::Qualifiers() ) ) );
    1801         //                              break;
    1802         //                      case TypeDecl::Ftype:  // pointer-to-ftype can be consistently replaced with void (*)(void) [similar to dtype]
    1803         //                              out.push_back( new TypeExpr( new FunctionType( Type::Qualifiers(), false ) ) );
    1804         //                              break;
    1805         //                      }
    1806                         }
    1807 
    1808                         // if any parameters left over, not done
    1809                         if ( baseParam != baseParams.end() ) return false;
    1810         //              // if not enough parameters given, substitute remaining incomplete types for placeholders
    1811         //              for ( ; baseParam != baseParams.end(); ++baseParam ) {
    1812         //                      switch ( (*baseParam)->get_kind() ) {
    1813         //                      case TypeDecl::Any:    // no more substitutions here, fail early
    1814         //                              return false;
    1815         //                      case TypeDecl::Dtype:  // dtype can be consistently replaced with void [only pointers, which become void*]
    1816         //                              out.push_back( new TypeExpr( new VoidType( Type::Qualifiers() ) ) );
    1817         //                              break;
    1818         //                      case TypeDecl::Ftype:  // pointer-to-ftype can be consistently replaced with void (*)(void) [similar to dtype]
    1819         //                              out.push_back( new TypeExpr( new FunctionType( Type::Qualifiers(), false ) ) );
    1820         //                              break;
    1821         //                      }
    1822         //              }
    1823 
    1824                         return allConcrete;
    1825                 }
    1826 
    1827                 /// Substitutes types of members of in according to baseParams => typeSubs, appending the result to out
    1828                 void substituteMembers( const std::list< Declaration* >& in, const std::list< TypeDecl* >& baseParams, const std::list< TypeExpr* >& typeSubs,
    1829                                                                 std::list< Declaration* >& out ) {
    1830                         // substitute types into new members
    1831                         TypeSubstitution subs( baseParams.begin(), baseParams.end(), typeSubs.begin() );
    1832                         for ( std::list< Declaration* >::const_iterator member = in.begin(); member != in.end(); ++member ) {
    1833                                 Declaration *newMember = (*member)->clone();
    1834                                 subs.apply(newMember);
    1835                                 out.push_back( newMember );
    1836                         }
    1837                 }
    1838 
    1839                 Type* GenericInstantiator::mutate( StructInstType *inst ) {
    1840                         // mutate subtypes
    1841                         Type *mutated = Mutator::mutate( inst );
    1842                         inst = dynamic_cast< StructInstType* >( mutated );
    1843                         if ( ! inst ) return mutated;
    1844 
    1845                         // exit early if no need for further mutation
    1846                         if ( inst->get_parameters().empty() ) return inst;
    1847                         assert( inst->get_baseParameters() && "Base struct has parameters" );
    1848 
    1849                         // check if type can be concretely instantiated; put substitutions into typeSubs
    1850                         std::list< TypeExpr* > typeSubs;
    1851                         if ( ! makeSubstitutions( *inst->get_baseParameters(), inst->get_parameters(), typeSubs ) ) {
    1852                                 deleteAll( typeSubs );
    1853                                 return inst;
    1854                         }
    1855 
    1856                         // make concrete instantiation of generic type
    1857                         StructDecl *concDecl = lookup( inst, typeSubs );
    1858                         if ( ! concDecl ) {
    1859                                 // set concDecl to new type, insert type declaration into statements to add
    1860                                 concDecl = new StructDecl( typeNamer.newName( inst->get_name() ) );
    1861                                 substituteMembers( inst->get_baseStruct()->get_members(), *inst->get_baseParameters(), typeSubs,        concDecl->get_members() );
    1862                                 DeclMutator::addDeclaration( concDecl );
    1863                                 insert( inst, typeSubs, concDecl );
    1864                         }
    1865                         StructInstType *newInst = new StructInstType( inst->get_qualifiers(), concDecl->get_name() );
    1866                         newInst->set_baseStruct( concDecl );
    1867 
    1868                         deleteAll( typeSubs );
    1869                         delete inst;
    1870                         return newInst;
    1871                 }
    1872 
    1873                 Type* GenericInstantiator::mutate( UnionInstType *inst ) {
    1874                         // mutate subtypes
    1875                         Type *mutated = Mutator::mutate( inst );
    1876                         inst = dynamic_cast< UnionInstType* >( mutated );
    1877                         if ( ! inst ) return mutated;
    1878 
    1879                         // exit early if no need for further mutation
    1880                         if ( inst->get_parameters().empty() ) return inst;
    1881                         assert( inst->get_baseParameters() && "Base union has parameters" );
    1882 
    1883                         // check if type can be concretely instantiated; put substitutions into typeSubs
    1884                         std::list< TypeExpr* > typeSubs;
    1885                         if ( ! makeSubstitutions( *inst->get_baseParameters(), inst->get_parameters(), typeSubs ) ) {
    1886                                 deleteAll( typeSubs );
    1887                                 return inst;
    1888                         }
    1889 
    1890                         // make concrete instantiation of generic type
    1891                         UnionDecl *concDecl = lookup( inst, typeSubs );
    1892                         if ( ! concDecl ) {
    1893                                 // set concDecl to new type, insert type declaration into statements to add
    1894                                 concDecl = new UnionDecl( typeNamer.newName( inst->get_name() ) );
    1895                                 substituteMembers( inst->get_baseUnion()->get_members(), *inst->get_baseParameters(), typeSubs, concDecl->get_members() );
    1896                                 DeclMutator::addDeclaration( concDecl );
    1897                                 insert( inst, typeSubs, concDecl );
    1898                         }
    1899                         UnionInstType *newInst = new UnionInstType( inst->get_qualifiers(), concDecl->get_name() );
    1900                         newInst->set_baseUnion( concDecl );
    1901 
    1902                         deleteAll( typeSubs );
    1903                         delete inst;
    1904                         return newInst;
    1905                 }
    1906 
    1907         //      /// Gets the base struct or union declaration for a member expression; NULL if not applicable
    1908         //      AggregateDecl* getMemberBaseDecl( MemberExpr *memberExpr ) {
    1909         //              // get variable for member aggregate
    1910         //              VariableExpr *varExpr = dynamic_cast< VariableExpr* >( memberExpr->get_aggregate() );
    1911         //              if ( ! varExpr ) return NULL;
    1912         //
    1913         //              // get object for variable
    1914         //              ObjectDecl *objectDecl = dynamic_cast< ObjectDecl* >( varExpr->get_var() );
    1915         //              if ( ! objectDecl ) return NULL;
    1916         //
    1917         //              // get base declaration from object type
    1918         //              Type *objectType = objectDecl->get_type();
    1919         //              StructInstType *structType = dynamic_cast< StructInstType* >( objectType );
    1920         //              if ( structType ) return structType->get_baseStruct();
    1921         //              UnionInstType *unionType = dynamic_cast< UnionInstType* >( objectType );
    1922         //              if ( unionType ) return unionType->get_baseUnion();
    1923         //
    1924         //              return NULL;
    1925         //      }
    1926         //
    1927         //      /// Finds the declaration with the given name, returning decls.end() if none such
    1928         //      std::list< Declaration* >::const_iterator findDeclNamed( const std::list< Declaration* > &decls, const std::string &name ) {
    1929         //              for( std::list< Declaration* >::const_iterator decl = decls.begin(); decl != decls.end(); ++decl ) {
    1930         //                      if ( (*decl)->get_name() == name ) return decl;
    1931         //              }
    1932         //              return decls.end();
    1933         //      }
    1934         //
    1935         //      Expression* Instantiate::mutate( MemberExpr *memberExpr ) {
    1936         //              // mutate, exiting early if no longer MemberExpr
    1937         //              Expression *expr = Mutator::mutate( memberExpr );
    1938         //              memberExpr = dynamic_cast< MemberExpr* >( expr );
    1939         //              if ( ! memberExpr ) return expr;
    1940         //
    1941         //              // get declaration of member and base declaration of member, exiting early if not found
    1942         //              AggregateDecl *memberBase = getMemberBaseDecl( memberExpr );
    1943         //              if ( ! memberBase ) return memberExpr;
    1944         //              DeclarationWithType *memberDecl = memberExpr->get_member();
    1945         //              std::list< Declaration* >::const_iterator baseIt = findDeclNamed( memberBase->get_members(), memberDecl->get_name() );
    1946         //              if ( baseIt == memberBase->get_members().end() ) return memberExpr;
    1947         //              DeclarationWithType *baseDecl = dynamic_cast< DeclarationWithType* >( *baseIt );
    1948         //              if ( ! baseDecl ) return memberExpr;
    1949         //
    1950         //              // check if stated type of the member is not the type of the member's declaration; if so, need a cast
    1951         //              // this *SHOULD* be safe, I don't think anything but the void-replacements I put in for dtypes would make it past the typechecker
    1952         //              SymTab::Indexer dummy;
    1953         //              if ( ResolvExpr::typesCompatible( memberDecl->get_type(), baseDecl->get_type(), dummy ) ) return memberExpr;
    1954         //              else return new CastExpr( memberExpr, memberDecl->get_type() );
    1955         //      }
    1956 
    1957                 void GenericInstantiator::doBeginScope() {
    1958                         DeclMutator::doBeginScope();
    1959                         instantiations.beginScope();
    1960                 }
    1961 
    1962                 void GenericInstantiator::doEndScope() {
    1963                         DeclMutator::doEndScope();
    1964                         instantiations.endScope();
    1965                 }
    1966 
    19671663////////////////////////////////////////// PolyGenericCalculator ////////////////////////////////////////////////////
    19681664
     
    21081804                        findGeneric( objectType ); // ensure layout for this type is available
    21091805
     1806                        // replace member expression with dynamically-computed layout expression
    21101807                        Expression *newMemberExpr = 0;
    21111808                        if ( StructInstType *structType = dynamic_cast< StructInstType* >( objectType ) ) {
     
    21811878                bool PolyGenericCalculator::findGeneric( Type *ty ) {
    21821879                        ty = replaceTypeInst( ty, env );
    2183                        
     1880
    21841881                        if ( TypeInstType *typeInst = dynamic_cast< TypeInstType* >( ty ) ) {
    21851882                                if ( scopeTyVars.find( typeInst->get_name() ) != scopeTyVars.end() ) {
Note: See TracChangeset for help on using the changeset viewer.