Changeset 6c3744e for translator/GenPoly


Ignore:
Timestamp:
Jan 19, 2015, 6:29:10 PM (11 years ago)
Author:
Peter A. Buhr <pabuhr@…>
Branches:
ADT, aaron-thesis, arm-eh, ast-experimental, cleanup-dtors, ctor, deferred_resn, demangler, enum, forall-pointer-decay, gc_noraii, jacob/cs343-translation, jenkins-sandbox, master, memory, new-ast, new-ast-unique-expr, new-env, no_list, persistent-indexer, pthread-emulation, qualifiedEnum, resolv-new, string, with_gc
Children:
f7f6785
Parents:
0b8cd722
Message:

add list initializer, formatting changes

File:
1 edited

Legend:

Unmodified
Added
Removed
  • translator/GenPoly/Box.cc

    r0b8cd722 r6c3744e  
    3333
    3434namespace GenPoly {
    35 
    36 namespace {
    37 
    38 const std::list<Label> noLabels;
    39 
    40 class Pass1 : public PolyMutator
    41 {
    42 public:
    43   Pass1();
    44   virtual Expression *mutate( ApplicationExpr *appExpr );
    45   virtual Expression *mutate( AddressExpr *addrExpr );
    46   virtual Expression *mutate( UntypedExpr *expr );
    47   virtual DeclarationWithType* mutate( FunctionDecl *functionDecl );
    48   virtual TypeDecl* mutate( TypeDecl *typeDecl );
    49   virtual Expression *mutate( CommaExpr *commaExpr );
    50   virtual Expression *mutate( ConditionalExpr *condExpr );
    51   virtual Statement* mutate(ReturnStmt *catchStmt);
    52   virtual Type* mutate( PointerType *pointerType );
    53   virtual Type* mutate( FunctionType *pointerType );
    54  
    55   virtual void doEndScope();
    56  
    57 private:
    58   void passTypeVars( ApplicationExpr* appExpr, std::list< Expression* >::iterator &arg, const TyVarMap &exprTyVars );
    59   Expression* addRetParam( ApplicationExpr* appExpr, FunctionType *function, Type *retType, std::list< Expression* >::iterator &arg );
    60   Expression* addPolyRetParam( ApplicationExpr* appExpr, FunctionType *function, std::string typeName, std::list< Expression* >::iterator &arg );
    61   Expression* applyAdapter( ApplicationExpr* appExpr, FunctionType *function, std::list< Expression* >::iterator &arg, const TyVarMap &exprTyVars );
    62   void boxParam( Type *formal, Expression *&arg, const TyVarMap &exprTyVars );
    63   void boxParams( ApplicationExpr* appExpr, FunctionType *function, std::list< Expression* >::iterator &arg, const TyVarMap &exprTyVars );
    64   void addInferredParams( ApplicationExpr *appExpr, FunctionType *functionType, std::list< Expression* >::iterator &arg, const TyVarMap &tyVars );
    65   void findAssignOps( const std::list< TypeDecl* > &forall );
    66   void passAdapters( ApplicationExpr *appExpr, FunctionType *functionType, const TyVarMap &exprTyVars );
    67   FunctionDecl *makeAdapter( FunctionType *adaptee, FunctionType *realType, const std::string &mangleName, const TyVarMap &tyVars );
    68   Expression *handleIntrinsics( ApplicationExpr *appExpr );
    69   ObjectDecl *makeTemporary( Type *type );
    70  
    71   std::map< std::string, DeclarationWithType* > assignOps;
    72   std::map< std::string, FunctionDecl* > adapters;
    73   DeclarationWithType* retval;
    74   bool useRetval;
    75   UniqueName tempNamer;
    76 };
    77 
    78 class Pass2 : public PolyMutator
    79 {
    80 public:
    81   Pass2();
    82   template< typename DeclClass >
    83   DeclClass* handleDecl( DeclClass *decl, Type *type );
    84   virtual DeclarationWithType* mutate( FunctionDecl *functionDecl );
    85   virtual ObjectDecl* mutate( ObjectDecl *objectDecl );
    86   virtual TypeDecl* mutate( TypeDecl *typeDecl );
    87   virtual TypedefDecl* mutate( TypedefDecl *typedefDecl );
    88   virtual Type* mutate( PointerType *pointerType );
    89   virtual Type* mutate( FunctionType *funcType );
    90 
    91 private:
    92   void addAdapters( FunctionType *functionType );
    93  
    94   std::map< UniqueId, std::string > adapterName;
    95 };
    96 
    97 class Pass3 : public PolyMutator
    98 {
    99 public:
    100   template< typename DeclClass >
    101   DeclClass* handleDecl( DeclClass *decl, Type *type );
    102   virtual DeclarationWithType* mutate( FunctionDecl *functionDecl );
    103   virtual ObjectDecl* mutate( ObjectDecl *objectDecl );
    104   virtual TypedefDecl* mutate( TypedefDecl *objectDecl );
    105   virtual TypeDecl* mutate( TypeDecl *objectDecl );
    106   virtual Statement* mutate( DeclStmt *declStmt );
    107   virtual Type* mutate( PointerType *pointerType );
    108   virtual Type* mutate( FunctionType *funcType );
    109 
    110 private:
    111 };
    112 
    113 } // anonymous namespace
    114 
    115 void
    116 printAllNotBuiltin( const std::list< Declaration* >& translationUnit, std::ostream &os )
    117 {
    118   for( std::list< Declaration* >::const_iterator i = translationUnit.begin(); i != translationUnit.end(); ++i ) {
    119     if( !LinkageSpec::isBuiltin( (*i)->get_linkage() ) ) {
    120       (*i)->print( os );
    121       os << std::endl;
     35    namespace {
     36        const std::list<Label> noLabels;
     37
     38        class Pass1 : public PolyMutator {
     39          public:
     40            Pass1();
     41            virtual Expression *mutate( ApplicationExpr *appExpr );
     42            virtual Expression *mutate( AddressExpr *addrExpr );
     43            virtual Expression *mutate( UntypedExpr *expr );
     44            virtual DeclarationWithType* mutate( FunctionDecl *functionDecl );
     45            virtual TypeDecl *mutate( TypeDecl *typeDecl );
     46            virtual Expression *mutate( CommaExpr *commaExpr );
     47            virtual Expression *mutate( ConditionalExpr *condExpr );
     48            virtual Statement *mutate(ReturnStmt *catchStmt);
     49            virtual Type *mutate( PointerType *pointerType );
     50            virtual Type *mutate( FunctionType *pointerType );
     51 
     52            virtual void doEndScope();
     53          private:
     54            void passTypeVars( ApplicationExpr *appExpr, std::list< Expression *>::iterator &arg, const TyVarMap &exprTyVars );
     55            Expression *addRetParam( ApplicationExpr *appExpr, FunctionType *function, Type *retType, std::list< Expression *>::iterator &arg );
     56            Expression *addPolyRetParam( ApplicationExpr *appExpr, FunctionType *function, std::string typeName, std::list< Expression *>::iterator &arg );
     57            Expression *applyAdapter( ApplicationExpr *appExpr, FunctionType *function, std::list< Expression *>::iterator &arg, const TyVarMap &exprTyVars );
     58            void boxParam( Type *formal, Expression *&arg, const TyVarMap &exprTyVars );
     59            void boxParams( ApplicationExpr *appExpr, FunctionType *function, std::list< Expression *>::iterator &arg, const TyVarMap &exprTyVars );
     60            void addInferredParams( ApplicationExpr *appExpr, FunctionType *functionType, std::list< Expression *>::iterator &arg, const TyVarMap &tyVars );
     61            void findAssignOps( const std::list< TypeDecl *> &forall );
     62            void passAdapters( ApplicationExpr *appExpr, FunctionType *functionType, const TyVarMap &exprTyVars );
     63            FunctionDecl *makeAdapter( FunctionType *adaptee, FunctionType *realType, const std::string &mangleName, const TyVarMap &tyVars );
     64            Expression *handleIntrinsics( ApplicationExpr *appExpr );
     65            ObjectDecl *makeTemporary( Type *type );
     66 
     67            std::map< std::string, DeclarationWithType *> assignOps;
     68            std::map< std::string, FunctionDecl *> adapters;
     69            DeclarationWithType *retval;
     70            bool useRetval;
     71            UniqueName tempNamer;
     72        };
     73
     74        class Pass2 : public PolyMutator {
     75          public:
     76            Pass2();
     77            template< typename DeclClass >
     78            DeclClass *handleDecl( DeclClass *decl, Type *type );
     79            virtual DeclarationWithType *mutate( FunctionDecl *functionDecl );
     80            virtual ObjectDecl *mutate( ObjectDecl *objectDecl );
     81            virtual TypeDecl *mutate( TypeDecl *typeDecl );
     82            virtual TypedefDecl *mutate( TypedefDecl *typedefDecl );
     83            virtual Type *mutate( PointerType *pointerType );
     84            virtual Type *mutate( FunctionType *funcType );
     85          private:
     86            void addAdapters( FunctionType *functionType );
     87 
     88            std::map< UniqueId, std::string > adapterName;
     89        };
     90
     91        class Pass3 : public PolyMutator {
     92          public:
     93            template< typename DeclClass >
     94            DeclClass *handleDecl( DeclClass *decl, Type *type );
     95            virtual DeclarationWithType *mutate( FunctionDecl *functionDecl );
     96            virtual ObjectDecl *mutate( ObjectDecl *objectDecl );
     97            virtual TypedefDecl *mutate( TypedefDecl *objectDecl );
     98            virtual TypeDecl *mutate( TypeDecl *objectDecl );
     99            virtual Statement *mutate( DeclStmt *declStmt );
     100            virtual Type *mutate( PointerType *pointerType );
     101            virtual Type *mutate( FunctionType *funcType );
     102          private:
     103        };
     104
     105    } // anonymous namespace
     106
     107    void printAllNotBuiltin( const std::list< Declaration *>& translationUnit, std::ostream &os ) {
     108        for ( std::list< Declaration *>::const_iterator i = translationUnit.begin(); i != translationUnit.end(); ++i ) {
     109            if ( !LinkageSpec::isBuiltin( (*i)->get_linkage() ) ) {
     110                (*i)->print( os );
     111                os << std::endl;
     112            } // if
     113        } // for
    122114    }
    123   }
    124 }
    125 
    126 void
    127 box( std::list< Declaration* >& translationUnit )
    128 {
    129   Pass1 pass1;
    130   Pass2 pass2;
    131   Pass3 pass3;
    132   mutateAll( translationUnit, pass1 );
    133   mutateAll( translationUnit, pass2 );
    134   mutateAll( translationUnit, pass3 );
    135 }
     115
     116    void box( std::list< Declaration *>& translationUnit ) {
     117        Pass1 pass1;
     118        Pass2 pass2;
     119        Pass3 pass3;
     120        mutateAll( translationUnit, pass1 );
     121        mutateAll( translationUnit, pass2 );
     122        mutateAll( translationUnit, pass3 );
     123    }
    136124
    137125////////////////////////////////////////// Pass1 ////////////////////////////////////////////////////
    138126
    139 namespace {
    140 
    141 bool
    142 isPolyRet( FunctionType *function, std::string &name, const TyVarMap &otherTyVars )
    143 {
    144   bool doTransform = false;
    145   if( !function->get_returnVals().empty() ) {
    146     if( TypeInstType *typeInst = dynamic_cast< TypeInstType* >( function->get_returnVals().front()->get_type() ) ) {
     127    namespace {
     128        bool isPolyRet( FunctionType *function, std::string &name, const TyVarMap &otherTyVars ) {
     129            bool doTransform = false;
     130            if ( !function->get_returnVals().empty() ) {
     131                if ( TypeInstType *typeInst = dynamic_cast< TypeInstType *>( function->get_returnVals().front()->get_type() ) ) {
    147132   
    148       // figure out if the return type is specified by a type parameter
    149       for( std::list< TypeDecl* >::const_iterator tyVar = function->get_forall().begin(); tyVar != function->get_forall().end(); ++tyVar ) {
    150         if( (*tyVar)->get_name() == typeInst->get_name() ) {
    151           doTransform = true;
    152           name = typeInst->get_name();
    153           break;
    154         }
    155       }
    156       if( !doTransform && otherTyVars.find( typeInst->get_name() ) != otherTyVars.end() ) {
    157         doTransform = true;
    158       }
    159     }
    160   }
    161   return doTransform;
    162 }
    163 
    164 bool
    165 isPolyRet( FunctionType *function, std::string &name )
    166 {
    167   TyVarMap dummyTyVars;
    168   return isPolyRet( function, name, dummyTyVars );
    169 }
    170 
    171 Pass1::Pass1()
    172   : useRetval( false ), tempNamer( "_temp" )
    173 {
    174 }
    175 
    176 bool
    177 checkAssignment( DeclarationWithType *decl, std::string &name )
    178 {
    179   if( decl->get_name() == "?=?" ) {
    180     if( PointerType *ptrType = dynamic_cast< PointerType* >( decl->get_type() ) ) {
    181       if( FunctionType *funType = dynamic_cast< FunctionType* >( ptrType->get_base() ) ) {
    182         if( funType->get_parameters().size() == 2 ) {
    183           if( PointerType *pointer = dynamic_cast< PointerType* >( funType->get_parameters().front()->get_type() ) ) {
    184             if( TypeInstType *typeInst = dynamic_cast< TypeInstType* >( pointer->get_base() ) ) {
    185               name = typeInst->get_name();
    186               return true;
    187             }
    188           }
    189         }
    190       }
    191     }
    192   }
    193   return false;
    194 }
    195 
    196 void
    197 Pass1::findAssignOps( const std::list< TypeDecl* > &forall )
    198 {
    199   assignOps.clear();
    200   for( std::list< TypeDecl* >::const_iterator i = forall.begin(); i != forall.end(); ++i ) {
    201     for( std::list< DeclarationWithType* >::const_iterator assert = (*i)->get_assertions().begin(); assert != (*i)->get_assertions().end(); ++assert ) {
    202       std::string typeName;
    203       if( checkAssignment( *assert, typeName ) ) {
    204         assignOps[ typeName ] = *assert;
    205       }
    206     }
    207   }
    208 }
    209 
    210 DeclarationWithType*
    211 Pass1::mutate( FunctionDecl *functionDecl )
    212 {
    213   if( functionDecl->get_statements() ) {
    214     TyVarMap oldtyVars = scopeTyVars;
    215     DeclarationWithType *oldRetval = retval;
    216     bool oldUseRetval = useRetval;
     133                    // figure out if the return type is specified by a type parameter
     134                    for ( std::list< TypeDecl *>::const_iterator tyVar = function->get_forall().begin(); tyVar != function->get_forall().end(); ++tyVar ) {
     135                        if ( (*tyVar)->get_name() == typeInst->get_name() ) {
     136                            doTransform = true;
     137                            name = typeInst->get_name();
     138                            break;
     139                        } // if
     140                    } // for
     141                    if ( !doTransform && otherTyVars.find( typeInst->get_name() ) != otherTyVars.end() ) {
     142                        doTransform = true;
     143                    } // if
     144                } // if
     145            } // if
     146            return doTransform;
     147        }
     148
     149        bool isPolyRet( FunctionType *function, std::string &name ) {
     150            TyVarMap dummyTyVars;
     151            return isPolyRet( function, name, dummyTyVars );
     152        }
     153
     154        Pass1::Pass1()
     155            : useRetval( false ), tempNamer( "_temp" ) {
     156        }
     157
     158        bool checkAssignment( DeclarationWithType *decl, std::string &name ) {
     159            if ( decl->get_name() == "?=?" ) {
     160                if ( PointerType *ptrType = dynamic_cast< PointerType *>( decl->get_type() ) ) {
     161                    if ( FunctionType *funType = dynamic_cast< FunctionType *>( ptrType->get_base() ) ) {
     162                        if ( funType->get_parameters().size() == 2 ) {
     163                            if ( PointerType *pointer = dynamic_cast< PointerType *>( funType->get_parameters().front()->get_type() ) ) {
     164                                if ( TypeInstType *typeInst = dynamic_cast< TypeInstType *>( pointer->get_base() ) ) {
     165                                    name = typeInst->get_name();
     166                                    return true;
     167                                } // if
     168                            } // if
     169                        } // if
     170                    } // if
     171                } // if
     172            } // if
     173            return false;
     174        }
     175
     176        void Pass1::findAssignOps( const std::list< TypeDecl *> &forall ) {
     177            assignOps.clear();
     178            for ( std::list< TypeDecl *>::const_iterator i = forall.begin(); i != forall.end(); ++i ) {
     179                for ( std::list< DeclarationWithType *>::const_iterator assert = (*i)->get_assertions().begin(); assert != (*i)->get_assertions().end(); ++assert ) {
     180                    std::string typeName;
     181                    if ( checkAssignment( *assert, typeName ) ) {
     182                        assignOps[ typeName ] = *assert;
     183                    } // if
     184                } // for
     185            } // for
     186        }
     187
     188        DeclarationWithType *
     189        Pass1::mutate( FunctionDecl *functionDecl ) {
     190            if ( functionDecl->get_statements() ) {
     191                TyVarMap oldtyVars = scopeTyVars;
     192                DeclarationWithType *oldRetval = retval;
     193                bool oldUseRetval = useRetval;
    217194   
    218     retval = 0;
    219     std::string typeName;
    220     if( isPolyRet( functionDecl->get_functionType(), typeName ) && functionDecl->get_linkage() == LinkageSpec::Cforall ) {
    221       retval = functionDecl->get_functionType()->get_returnVals().front();
    222  
    223       // give names to unnamed return values
    224       if( retval->get_name() == "" ) {
    225         retval->set_name( "_retparm" );
    226         retval->set_linkage( LinkageSpec::C );
    227       }
    228     }
     195                retval = 0;
     196                std::string typeName;
     197                if ( isPolyRet( functionDecl->get_functionType(), typeName ) && functionDecl->get_linkage() == LinkageSpec::Cforall ) {
     198                    retval = functionDecl->get_functionType()->get_returnVals().front();
     199 
     200                    // give names to unnamed return values
     201                    if ( retval->get_name() == "" ) {
     202                        retval->set_name( "_retparm" );
     203                        retval->set_linkage( LinkageSpec::C );
     204                    } // if
     205                } // if
    229206   
    230     scopeTyVars.clear();
     207                scopeTyVars.clear();
    231208///     std::cerr << "clear\n";
    232     makeTyVarMap( functionDecl->get_functionType(), scopeTyVars );
    233     findAssignOps( functionDecl->get_functionType()->get_forall() );
    234     functionDecl->set_statements( functionDecl->get_statements()->acceptMutator( *this ) );
    235  
    236     scopeTyVars = oldtyVars;
     209                makeTyVarMap( functionDecl->get_functionType(), scopeTyVars );
     210                findAssignOps( functionDecl->get_functionType()->get_forall() );
     211                functionDecl->set_statements( functionDecl->get_statements()->acceptMutator( *this ) );
     212 
     213                scopeTyVars = oldtyVars;
    237214///     std::cerr << "end FunctionDecl: ";
    238 ///     for( TyVarMap::iterator i = scopeTyVars.begin(); i != scopeTyVars.end(); ++i ) {
     215///     for ( TyVarMap::iterator i = scopeTyVars.begin(); i != scopeTyVars.end(); ++i ) {
    239216///       std::cerr << i->first << " ";
    240217///     }
    241218///     std::cerr << "\n";
    242     retval = oldRetval;
    243     useRetval = oldUseRetval;
    244     doEndScope();
    245   }
    246   return functionDecl;
    247 }
    248 
    249 TypeDecl*
    250 Pass1::mutate( TypeDecl *typeDecl )
    251 {
     219                retval = oldRetval;
     220                useRetval = oldUseRetval;
     221                doEndScope();
     222            } // if
     223            return functionDecl;
     224        }
     225
     226        TypeDecl *Pass1::mutate( TypeDecl *typeDecl ) {
    252227///     std::cerr << "add " << typeDecl->get_name() << "\n";
    253   scopeTyVars[ typeDecl->get_name() ] = typeDecl->get_kind();
    254   return Mutator::mutate( typeDecl );
    255 }
    256 
    257 Expression *
    258 Pass1::mutate( CommaExpr *commaExpr )
    259 {
    260   bool oldUseRetval = useRetval;
    261   useRetval = false;
    262   commaExpr->set_arg1( maybeMutate( commaExpr->get_arg1(), *this ) );
    263   useRetval = oldUseRetval;
    264   commaExpr->set_arg2( maybeMutate( commaExpr->get_arg2(), *this ) );
    265   return commaExpr;
    266 }
    267 
    268 Expression *
    269 Pass1::mutate( ConditionalExpr *condExpr )
    270 {
    271   bool oldUseRetval = useRetval;
    272   useRetval = false;
    273   condExpr->set_arg1( maybeMutate( condExpr->get_arg1(), *this ) );
    274   useRetval = oldUseRetval;
    275   condExpr->set_arg2( maybeMutate( condExpr->get_arg2(), *this ) );
    276   condExpr->set_arg3( maybeMutate( condExpr->get_arg3(), *this ) );
    277   return condExpr;
    278 
    279 }
    280 
    281 void
    282 Pass1::passTypeVars( ApplicationExpr* appExpr, std::list< Expression* >::iterator &arg, const TyVarMap &exprTyVars )
    283 {
    284   for( TyVarMap::const_iterator tyParm = exprTyVars.begin(); tyParm != exprTyVars.end(); ++tyParm ) {
    285     ResolvExpr::EqvClass eqvClass;
    286     assert( env );
    287     if( tyParm->second == TypeDecl::Any ) {
    288       Type *concrete = env->lookup( tyParm->first );
    289       if( concrete ) {
    290         arg = appExpr->get_args().insert( arg, new SizeofExpr( concrete->clone() ) );
    291         arg++;
    292       } else {
    293         throw SemanticError( "unbound type variable in application ", appExpr );
    294       }
    295     }
    296   }
    297 }
    298 
    299 ObjectDecl*
    300 Pass1::makeTemporary( Type *type )
    301 {
    302   ObjectDecl *newObj = new ObjectDecl( tempNamer.newName(), Declaration::NoStorageClass, LinkageSpec::C, 0, type, 0 );
    303   stmtsToAdd.push_back( new DeclStmt( noLabels, newObj ) );
    304   return newObj;
    305 }
    306 
    307 TypeInstType *
    308 isPolyType( Type *type, const TypeSubstitution *env, const TyVarMap &tyVars )
    309 {
    310   if( TypeInstType *typeInst = dynamic_cast< TypeInstType* >( type ) ) {
    311     if( env ) {
    312       if( Type *newType = env->lookup( typeInst->get_name() ) ) {
    313         return isPolyType( newType, env, tyVars );
    314       }
    315     }
    316     if( tyVars.find( typeInst->get_name() ) != tyVars.end() ) {
    317       return typeInst;
    318     } else {
    319       return 0;
    320     }
    321   } else {
    322     return 0;
    323   }
    324 }
    325 
    326 Expression*
    327 Pass1::addRetParam( ApplicationExpr* appExpr, FunctionType *function, Type *retType, std::list< Expression* >::iterator &arg )
    328 {
    329   if( useRetval ) {
    330     assert( retval );
    331     arg = appExpr->get_args().insert( arg, new VariableExpr( retval ) );
    332     arg++;
    333   } else {
    334     ObjectDecl *newObj = makeTemporary( retType->clone() );
    335     Expression *paramExpr = new VariableExpr( newObj );
    336     if( !isPolyType( newObj->get_type(), env, scopeTyVars ) ) {
    337       paramExpr = new AddressExpr( paramExpr );
    338     }
    339     arg = appExpr->get_args().insert( arg, paramExpr );
    340     arg++;
     228            scopeTyVars[ typeDecl->get_name() ] = typeDecl->get_kind();
     229            return Mutator::mutate( typeDecl );
     230        }
     231
     232        Expression *Pass1::mutate( CommaExpr *commaExpr ) {
     233            bool oldUseRetval = useRetval;
     234            useRetval = false;
     235            commaExpr->set_arg1( maybeMutate( commaExpr->get_arg1(), *this ) );
     236            useRetval = oldUseRetval;
     237            commaExpr->set_arg2( maybeMutate( commaExpr->get_arg2(), *this ) );
     238            return commaExpr;
     239        }
     240
     241        Expression *Pass1::mutate( ConditionalExpr *condExpr ) {
     242            bool oldUseRetval = useRetval;
     243            useRetval = false;
     244            condExpr->set_arg1( maybeMutate( condExpr->get_arg1(), *this ) );
     245            useRetval = oldUseRetval;
     246            condExpr->set_arg2( maybeMutate( condExpr->get_arg2(), *this ) );
     247            condExpr->set_arg3( maybeMutate( condExpr->get_arg3(), *this ) );
     248            return condExpr;
     249
     250        }
     251
     252        void Pass1::passTypeVars( ApplicationExpr *appExpr, std::list< Expression *>::iterator &arg, const TyVarMap &exprTyVars ) {
     253            for ( TyVarMap::const_iterator tyParm = exprTyVars.begin(); tyParm != exprTyVars.end(); ++tyParm ) {
     254                ResolvExpr::EqvClass eqvClass;
     255                assert( env );
     256                if ( tyParm->second == TypeDecl::Any ) {
     257                    Type *concrete = env->lookup( tyParm->first );
     258                    if ( concrete ) {
     259                        arg = appExpr->get_args().insert( arg, new SizeofExpr( concrete->clone() ) );
     260                        arg++;
     261                    } else {
     262                        throw SemanticError( "unbound type variable in application ", appExpr );
     263                    } // if
     264                } // if
     265            } // for
     266        }
     267
     268        ObjectDecl *Pass1::makeTemporary( Type *type ) {
     269            ObjectDecl *newObj = new ObjectDecl( tempNamer.newName(), Declaration::NoStorageClass, LinkageSpec::C, 0, type, 0 );
     270            stmtsToAdd.push_back( new DeclStmt( noLabels, newObj ) );
     271            return newObj;
     272        }
     273
     274        TypeInstType *isPolyType( Type *type, const TypeSubstitution *env, const TyVarMap &tyVars ) {
     275            if ( TypeInstType *typeInst = dynamic_cast< TypeInstType *>( type ) ) {
     276                if ( env ) {
     277                    if ( Type *newType = env->lookup( typeInst->get_name() ) ) {
     278                        return isPolyType( newType, env, tyVars );
     279                    } // if
     280                } // if
     281                if ( tyVars.find( typeInst->get_name() ) != tyVars.end() ) {
     282                    return typeInst;
     283                } else {
     284                    return 0;
     285                } // if
     286            } else {
     287                return 0;
     288            } // if
     289        }
     290
     291        Expression *Pass1::addRetParam( ApplicationExpr *appExpr, FunctionType *function, Type *retType, std::list< Expression *>::iterator &arg ) {
     292            if ( useRetval ) {
     293                assert( retval );
     294                arg = appExpr->get_args().insert( arg, new VariableExpr( retval ) );
     295                arg++;
     296            } else {
     297                ObjectDecl *newObj = makeTemporary( retType->clone() );
     298                Expression *paramExpr = new VariableExpr( newObj );
     299                if ( !isPolyType( newObj->get_type(), env, scopeTyVars ) ) {
     300                    paramExpr = new AddressExpr( paramExpr );
     301                } // if
     302                arg = appExpr->get_args().insert( arg, paramExpr );
     303                arg++;
    341304///     stmtsToAdd.push_back( new ExprStmt( noLabels, appExpr ) );
    342     CommaExpr *commaExpr = new CommaExpr( appExpr, new VariableExpr( newObj ) );
    343     commaExpr->set_env( appExpr->get_env() );
    344     appExpr->set_env( 0 );
    345     return commaExpr;
    346   }
    347   return appExpr;
    348 }
    349 
    350 Expression*
    351 Pass1::addPolyRetParam( ApplicationExpr* appExpr, FunctionType *function, std::string typeName, std::list< Expression* >::iterator &arg )
    352 {
    353   ResolvExpr::EqvClass eqvClass;
    354   assert( env );
    355   Type *concrete = env->lookup( typeName );
    356   if( concrete == 0 ) {
    357     throw SemanticError( "Unbound type variable " + typeName + " in", appExpr );
    358   }
    359   return addRetParam( appExpr, function, concrete, arg );
    360 }
    361 
    362 Expression*
    363 Pass1::applyAdapter( ApplicationExpr* appExpr, FunctionType *function, std::list< Expression* >::iterator &arg, const TyVarMap &tyVars )
    364 {
    365   Expression *ret = appExpr;
    366   if( !function->get_returnVals().empty() && isPolyVal( function->get_returnVals().front()->get_type(), tyVars ) ) {
    367     ret = addRetParam( appExpr, function, function->get_returnVals().front()->get_type(), arg );
    368   }
    369   appExpr->get_args().push_front( appExpr->get_function() );
    370   appExpr->set_function( new NameExpr( "_adapter" + SymTab::Mangler::mangle( function ) ) );
    371  
    372   return ret;
    373 }
    374 
    375 void
    376 Pass1::boxParam( Type *param, Expression *&arg, const TyVarMap &exprTyVars )
    377 {
    378   assert( !arg->get_results().empty() );
    379 ///   if( !dynamic_cast< PointerType* >( arg->get_results().front() ) ) {
    380     TypeInstType *typeInst = dynamic_cast< TypeInstType* >( param );
    381     if( typeInst && exprTyVars.find( typeInst->get_name() ) != exprTyVars.end() ) {
    382       if( arg->get_results().front()->get_isLvalue() ) {
    383         arg = new AddressExpr( arg );
    384       } else {
    385         ObjectDecl *newObj = new ObjectDecl( tempNamer.newName(), Declaration::NoStorageClass, LinkageSpec::C, 0, arg->get_results().front()->clone(), 0 );
    386         newObj->get_type()->get_qualifiers() = Type::Qualifiers();
    387         stmtsToAdd.push_back( new DeclStmt( noLabels, newObj ) );
    388         UntypedExpr *assign = new UntypedExpr( new NameExpr( "?=?" ) );
    389         assign->get_args().push_back( new VariableExpr( newObj ) );
    390         assign->get_args().push_back( arg );
    391         stmtsToAdd.push_back( new ExprStmt( noLabels, assign ) );
    392         arg = new AddressExpr( new VariableExpr( newObj ) );
    393       }
    394     }
     305                CommaExpr *commaExpr = new CommaExpr( appExpr, new VariableExpr( newObj ) );
     306                commaExpr->set_env( appExpr->get_env() );
     307                appExpr->set_env( 0 );
     308                return commaExpr;
     309            } // if
     310            return appExpr;
     311        }
     312
     313        Expression *Pass1::addPolyRetParam( ApplicationExpr *appExpr, FunctionType *function, std::string typeName, std::list< Expression *>::iterator &arg ) {
     314            ResolvExpr::EqvClass eqvClass;
     315            assert( env );
     316            Type *concrete = env->lookup( typeName );
     317            if ( concrete == 0 ) {
     318                throw SemanticError( "Unbound type variable " + typeName + " in", appExpr );
     319            } // if
     320            return addRetParam( appExpr, function, concrete, arg );
     321        }
     322
     323        Expression *Pass1::applyAdapter( ApplicationExpr *appExpr, FunctionType *function, std::list< Expression *>::iterator &arg, const TyVarMap &tyVars ) {
     324            Expression *ret = appExpr;
     325            if ( !function->get_returnVals().empty() && isPolyVal( function->get_returnVals().front()->get_type(), tyVars ) ) {
     326                ret = addRetParam( appExpr, function, function->get_returnVals().front()->get_type(), arg );
     327            } // if
     328            appExpr->get_args().push_front( appExpr->get_function() );
     329            appExpr->set_function( new NameExpr( "_adapter" + SymTab::Mangler::mangle( function ) ) );
     330 
     331            return ret;
     332        }
     333
     334        void Pass1::boxParam( Type *param, Expression *&arg, const TyVarMap &exprTyVars ) {
     335            assert( !arg->get_results().empty() );
     336///   if ( !dynamic_cast< PointerType *>( arg->get_results().front() ) ) {
     337            TypeInstType *typeInst = dynamic_cast< TypeInstType *>( param );
     338            if ( typeInst && exprTyVars.find( typeInst->get_name() ) != exprTyVars.end() ) {
     339                if ( arg->get_results().front()->get_isLvalue() ) {
     340                    arg = new AddressExpr( arg );
     341                } else {
     342                    ObjectDecl *newObj = new ObjectDecl( tempNamer.newName(), Declaration::NoStorageClass, LinkageSpec::C, 0, arg->get_results().front()->clone(), 0 );
     343                    newObj->get_type()->get_qualifiers() = Type::Qualifiers();
     344                    stmtsToAdd.push_back( new DeclStmt( noLabels, newObj ) );
     345                    UntypedExpr *assign = new UntypedExpr( new NameExpr( "?=?" ) );
     346                    assign->get_args().push_back( new VariableExpr( newObj ) );
     347                    assign->get_args().push_back( arg );
     348                    stmtsToAdd.push_back( new ExprStmt( noLabels, assign ) );
     349                    arg = new AddressExpr( new VariableExpr( newObj ) );
     350                } // if
     351            } // if
    395352///   }
    396 }
    397 
    398 void
    399 addCast( Expression *&actual, Type *formal, const TyVarMap &tyVars )
    400 {
    401   Type *newType = formal->clone();
    402   std::list< FunctionType* > functions;
    403   // instead of functions needing adapters, this really ought to look for
    404   // any function mentioning a polymorphic type
    405   findAndReplaceFunction( newType, functions, tyVars, needsAdapter );
    406   if( !functions.empty() ) {
    407     actual = new CastExpr( actual, newType );
    408   } else {
    409     delete newType;
    410   }
    411 }
    412 
    413 void
    414 Pass1::boxParams( ApplicationExpr* appExpr, FunctionType *function, std::list< Expression* >::iterator &arg, const TyVarMap &exprTyVars )
    415 {
     353        }
     354
     355        void addCast( Expression *&actual, Type *formal, const TyVarMap &tyVars ) {
     356            Type *newType = formal->clone();
     357            std::list< FunctionType *> functions;
     358            // instead of functions needing adapters, this really ought to look for
     359            // any function mentioning a polymorphic type
     360            findAndReplaceFunction( newType, functions, tyVars, needsAdapter );
     361            if ( !functions.empty() ) {
     362                actual = new CastExpr( actual, newType );
     363            } else {
     364                delete newType;
     365            } // if
     366        }
     367
     368        void Pass1::boxParams( ApplicationExpr *appExpr, FunctionType *function, std::list< Expression *>::iterator &arg, const TyVarMap &exprTyVars ) {
    416369///   std::cout << "function is ";
    417370///   function->print( std::cout );
    418   for( std::list< DeclarationWithType* >::const_iterator param = function->get_parameters().begin(); param != function->get_parameters().end(); ++param, ++arg ) {
     371            for ( std::list< DeclarationWithType *>::const_iterator param = function->get_parameters().begin(); param != function->get_parameters().end(); ++param, ++arg ) {
    419372///     std::cout << "parameter is ";
    420373///     (*param)->print( std::cout );
    421374///     std::cout << std::endl << "argument is ";
    422375///     (*arg)->print( std::cout );
    423     assert( arg != appExpr->get_args().end() );
    424     addCast( *arg, (*param)->get_type(), exprTyVars );
    425     boxParam( (*param)->get_type(), *arg, exprTyVars );
    426   }
    427 }
    428 
    429 void
    430 Pass1::addInferredParams( ApplicationExpr *appExpr, FunctionType *functionType, std::list< Expression* >::iterator &arg, const TyVarMap &tyVars )
    431 {
    432   std::list< Expression* >::iterator cur = arg;
    433   for( std::list< TypeDecl* >::iterator tyVar = functionType->get_forall().begin(); tyVar != functionType->get_forall().end(); ++tyVar ) {
    434     for( std::list< DeclarationWithType* >::iterator assert = (*tyVar)->get_assertions().begin(); assert != (*tyVar)->get_assertions().end(); ++assert ) {
    435       InferredParams::const_iterator inferParam = appExpr->get_inferParams().find( (*assert)->get_uniqueId() );
    436       assert( inferParam != appExpr->get_inferParams().end() );
    437       Expression *newExpr = inferParam->second.expr->clone();
    438       addCast( newExpr, (*assert)->get_type(), tyVars );
    439       boxParam( (*assert)->get_type(), newExpr, tyVars );
    440       appExpr->get_args().insert( cur, newExpr );
    441     }
    442   }
    443 }
    444 
    445 void
    446 makeRetParm( FunctionType *funcType )
    447 {
    448   DeclarationWithType *retParm = funcType->get_returnVals().front();
    449 
    450   // make a new parameter that is a pointer to the type of the old return value
    451   retParm->set_type( new PointerType( Type::Qualifiers(), retParm->get_type() ) );
    452   funcType->get_parameters().push_front( retParm );
    453 
    454   // we don't need the return value any more
    455   funcType->get_returnVals().clear();
    456 }
    457 
    458 FunctionType *
    459 makeAdapterType( FunctionType *adaptee, const TyVarMap &tyVars )
    460 {
    461   // actually make the adapter type
    462   FunctionType *adapter = adaptee->clone();
    463   if( !adapter->get_returnVals().empty() && isPolyVal( adapter->get_returnVals().front()->get_type(), tyVars ) ) {
    464     makeRetParm( adapter );
    465   }
    466   adapter->get_parameters().push_front( new ObjectDecl( "", Declaration::NoStorageClass, LinkageSpec::C, 0, new PointerType( Type::Qualifiers(), new FunctionType( Type::Qualifiers(), true ) ), 0 ) );
    467   return adapter;
    468 }
    469 
    470 Expression*
    471 makeAdapterArg( DeclarationWithType *param, DeclarationWithType *arg, DeclarationWithType *realParam, const TyVarMap &tyVars )
    472 {
    473   assert( param );
    474   assert( arg );
     376                assert( arg != appExpr->get_args().end() );
     377                addCast( *arg, (*param)->get_type(), exprTyVars );
     378                boxParam( (*param)->get_type(), *arg, exprTyVars );
     379            } // for
     380        }
     381
     382        void Pass1::addInferredParams( ApplicationExpr *appExpr, FunctionType *functionType, std::list< Expression *>::iterator &arg, const TyVarMap &tyVars ) {
     383            std::list< Expression *>::iterator cur = arg;
     384            for ( std::list< TypeDecl *>::iterator tyVar = functionType->get_forall().begin(); tyVar != functionType->get_forall().end(); ++tyVar ) {
     385                for ( std::list< DeclarationWithType *>::iterator assert = (*tyVar)->get_assertions().begin(); assert != (*tyVar)->get_assertions().end(); ++assert ) {
     386                    InferredParams::const_iterator inferParam = appExpr->get_inferParams().find( (*assert)->get_uniqueId() );
     387                    assert( inferParam != appExpr->get_inferParams().end() );
     388                    Expression *newExpr = inferParam->second.expr->clone();
     389                    addCast( newExpr, (*assert)->get_type(), tyVars );
     390                    boxParam( (*assert)->get_type(), newExpr, tyVars );
     391                    appExpr->get_args().insert( cur, newExpr );
     392                } // for
     393            } // for
     394        }
     395
     396        void makeRetParm( FunctionType *funcType ) {
     397            DeclarationWithType *retParm = funcType->get_returnVals().front();
     398
     399            // make a new parameter that is a pointer to the type of the old return value
     400            retParm->set_type( new PointerType( Type::Qualifiers(), retParm->get_type() ) );
     401            funcType->get_parameters().push_front( retParm );
     402
     403            // we don't need the return value any more
     404            funcType->get_returnVals().clear();
     405        }
     406
     407        FunctionType *makeAdapterType( FunctionType *adaptee, const TyVarMap &tyVars ) {
     408            // actually make the adapter type
     409            FunctionType *adapter = adaptee->clone();
     410            if ( !adapter->get_returnVals().empty() && isPolyVal( adapter->get_returnVals().front()->get_type(), tyVars ) ) {
     411                makeRetParm( adapter );
     412            } // if
     413            adapter->get_parameters().push_front( new ObjectDecl( "", Declaration::NoStorageClass, LinkageSpec::C, 0, new PointerType( Type::Qualifiers(), new FunctionType( Type::Qualifiers(), true ) ), 0 ) );
     414            return adapter;
     415        }
     416
     417        Expression *makeAdapterArg( DeclarationWithType *param, DeclarationWithType *arg, DeclarationWithType *realParam, const TyVarMap &tyVars ) {
     418            assert( param );
     419            assert( arg );
    475420///   std::cout << "arg type is ";
    476421///   arg->get_type()->print( std::cout );
     
    479424///   std::cout << " tyVars are: ";
    480425///   printTyVarMap( std::cout, tyVars );
    481   if( isPolyVal( realParam->get_type(), tyVars ) ) {
    482 ///     if( dynamic_cast< PointerType* >( arg->get_type() ) ) {
     426            if ( isPolyVal( realParam->get_type(), tyVars ) ) {
     427///     if ( dynamic_cast< PointerType *>( arg->get_type() ) ) {
    483428///       return new CastExpr( new VariableExpr( param ), arg->get_type()->clone() );
    484429///     } else {
    485       UntypedExpr *deref = new UntypedExpr( new NameExpr( "*?" ) );
    486       deref->get_args().push_back( new CastExpr( new VariableExpr( param ), new PointerType( Type::Qualifiers(), arg->get_type()->clone() ) ) );
    487       deref->get_results().push_back( arg->get_type()->clone() );
    488       return deref;
     430                UntypedExpr *deref = new UntypedExpr( new NameExpr( "*?" ) );
     431                deref->get_args().push_back( new CastExpr( new VariableExpr( param ), new PointerType( Type::Qualifiers(), arg->get_type()->clone() ) ) );
     432                deref->get_results().push_back( arg->get_type()->clone() );
     433                return deref;
    489434///     }
    490   }
    491   return new VariableExpr( param );
    492 }
    493 
    494 void
    495 addAdapterParams( ApplicationExpr *adapteeApp, std::list< DeclarationWithType* >::iterator arg, std::list< DeclarationWithType* >::iterator param, std::list< DeclarationWithType* >::iterator paramEnd, std::list< DeclarationWithType* >::iterator realParam, const TyVarMap &tyVars )
    496 {
    497   UniqueName paramNamer( "_p" );
    498   for( ; param != paramEnd; ++param, ++arg, ++realParam ) {
    499     if( (*param)->get_name() == "" ) {
    500       (*param)->set_name( paramNamer.newName() );
    501       (*param)->set_linkage( LinkageSpec::C );
    502     }
    503     adapteeApp->get_args().push_back( makeAdapterArg( *param, *arg, *realParam, tyVars ) );
    504   }
    505 }
    506 
    507 FunctionDecl *
    508 Pass1::makeAdapter( FunctionType *adaptee, FunctionType *realType, const std::string &mangleName, const TyVarMap &tyVars )
    509 {
    510   FunctionType *adapterType = makeAdapterType( adaptee, tyVars );
    511   adapterType = ScrubTyVars::scrub( adapterType, tyVars );
    512   DeclarationWithType *adapteeDecl = adapterType->get_parameters().front();
    513   adapteeDecl->set_name( "_adaptee" );
    514   ApplicationExpr *adapteeApp = new ApplicationExpr( new CastExpr( new VariableExpr( adapteeDecl ), new PointerType( Type::Qualifiers(), realType ) ) );
    515   Statement *bodyStmt;
    516  
    517   std::list< TypeDecl* >::iterator tyArg = realType->get_forall().begin();
    518   std::list< TypeDecl* >::iterator tyParam = adapterType->get_forall().begin();
    519   std::list< TypeDecl* >::iterator realTyParam = adaptee->get_forall().begin();
    520   for( ; tyParam != adapterType->get_forall().end(); ++tyArg, ++tyParam, ++realTyParam ) {
    521     assert( tyArg != realType->get_forall().end() );
    522     std::list< DeclarationWithType* >::iterator assertArg = (*tyArg)->get_assertions().begin();
    523     std::list< DeclarationWithType* >::iterator assertParam = (*tyParam)->get_assertions().begin();
    524     std::list< DeclarationWithType* >::iterator realAssertParam = (*realTyParam)->get_assertions().begin();
    525     for( ; assertParam != (*tyParam)->get_assertions().end(); ++assertArg, ++assertParam, ++realAssertParam ) {
    526       assert( assertArg != (*tyArg)->get_assertions().end() );
    527       adapteeApp->get_args().push_back( makeAdapterArg( *assertParam, *assertArg, *realAssertParam, tyVars ) );
    528     }
    529   }
    530  
    531   std::list< DeclarationWithType* >::iterator arg = realType->get_parameters().begin();
    532   std::list< DeclarationWithType* >::iterator param = adapterType->get_parameters().begin();
    533   std::list< DeclarationWithType* >::iterator realParam = adaptee->get_parameters().begin();
    534   param++;              // skip adaptee parameter
    535   if( realType->get_returnVals().empty() ) {
    536     addAdapterParams( adapteeApp, arg, param, adapterType->get_parameters().end(), realParam, tyVars );
    537     bodyStmt = new ExprStmt( noLabels, adapteeApp );
    538   } else if( isPolyVal( adaptee->get_returnVals().front()->get_type(), tyVars ) ) {
    539     if( (*param)->get_name() == "" ) {
    540       (*param)->set_name( "_ret" );
    541       (*param)->set_linkage( LinkageSpec::C );
    542     }
    543     UntypedExpr *assign = new UntypedExpr( new NameExpr( "?=?" ) );
    544     UntypedExpr *deref = new UntypedExpr( new NameExpr( "*?" ) );
    545     deref->get_args().push_back( new CastExpr( new VariableExpr( *param++ ), new PointerType( Type::Qualifiers(), realType->get_returnVals().front()->get_type()->clone() ) ) );
    546     assign->get_args().push_back( deref );
    547     addAdapterParams( adapteeApp, arg, param, adapterType->get_parameters().end(), realParam, tyVars );
    548     assign->get_args().push_back( adapteeApp );
    549     bodyStmt = new ExprStmt( noLabels, assign );
    550   } else {
    551     // adapter for a function that returns a monomorphic value
    552     addAdapterParams( adapteeApp, arg, param, adapterType->get_parameters().end(), realParam, tyVars );
    553     bodyStmt = new ReturnStmt( noLabels, adapteeApp );
    554   }
    555   CompoundStmt *adapterBody = new CompoundStmt( noLabels );
    556   adapterBody->get_kids().push_back( bodyStmt );
    557   return new FunctionDecl( "_adapter" + mangleName, Declaration::NoStorageClass, LinkageSpec::C, adapterType, adapterBody, false );
    558 }
    559 
    560 void
    561 Pass1::passAdapters( ApplicationExpr *appExpr, FunctionType *functionType, const TyVarMap &exprTyVars )
    562 {
    563   std::list< DeclarationWithType* > &paramList = functionType->get_parameters();
    564   std::list< FunctionType* > functions;
    565   for( std::list< TypeDecl* >::iterator tyVar = functionType->get_forall().begin(); tyVar != functionType->get_forall().end(); ++tyVar ) {
    566     for( std::list< DeclarationWithType* >::iterator assert = (*tyVar)->get_assertions().begin(); assert != (*tyVar)->get_assertions().end(); ++assert ) {
    567       findFunction( (*assert)->get_type(), functions, exprTyVars, needsAdapter );
    568     }
    569   }
    570   for( std::list< DeclarationWithType* >::iterator arg = paramList.begin(); arg != paramList.end(); ++arg ) {
    571     findFunction( (*arg)->get_type(), functions, exprTyVars, needsAdapter );
    572   }
    573   std::set< std::string > adaptersDone;
    574   for( std::list< FunctionType* >::iterator funType = functions.begin(); funType != functions.end(); ++funType ) {
    575     FunctionType *realFunction = (*funType)->clone();
    576     assert( env );
    577     env->apply( realFunction );
    578     std::string mangleName = SymTab::Mangler::mangle( realFunction );
    579     if( adaptersDone.find( mangleName ) == adaptersDone.end() ) {
    580       std::map< std::string, FunctionDecl* >::iterator adapter = adapters.find( mangleName );
    581       if( adapter == adapters.end() ) {
    582         FunctionDecl *newAdapter = makeAdapter( *funType, realFunction, mangleName, exprTyVars );
    583         adapter = adapters.insert( adapters.begin(), std::pair< std::string, FunctionDecl* >( mangleName, newAdapter ) );
    584         stmtsToAdd.push_back( new DeclStmt( noLabels, newAdapter ) );
    585       }
    586       assert( adapter != adapters.end() );
    587       appExpr->get_args().push_front( new VariableExpr( adapter->second ) );
    588       adaptersDone.insert( adaptersDone.begin(), mangleName );
    589     }
    590   }
    591 }
    592 
    593 TypeInstType*
    594 isPolyPtr( Type *type, const TypeSubstitution *env, const TyVarMap &tyVars )
    595 {
    596   if( PointerType *ptr = dynamic_cast< PointerType* >( type ) ) {
    597     return isPolyType( ptr->get_base(), env, tyVars );
    598   } else if( env ) {
    599     if( TypeInstType *typeInst = dynamic_cast< TypeInstType* >( type ) ) {
    600       if( Type *newType = env->lookup( typeInst->get_name() ) ) {
    601         return isPolyPtr( newType, env, tyVars );
    602       }
    603     }
    604   }
    605   return 0;
    606 }
    607 
    608 TypeInstType*
    609 isPolyPtrPtr( Type *type, const TypeSubstitution *env, const TyVarMap &tyVars )
    610 {
    611   if( PointerType *ptr = dynamic_cast< PointerType* >( type ) ) {
    612     return isPolyPtr( ptr->get_base(), env, tyVars );
    613   } else if( env ) {
    614     if( TypeInstType *typeInst = dynamic_cast< TypeInstType* >( type ) ) {
    615       if( Type *newType = env->lookup( typeInst->get_name() ) ) {
    616         return isPolyPtrPtr( newType, env, tyVars );
    617       }
    618     }
    619   }
    620   return 0;
    621 }
    622 
    623 Expression *
    624 makeIncrDecrExpr( ApplicationExpr *appExpr, std::string polyName, bool isIncr )
    625 {
    626   NameExpr *opExpr;
    627   if( isIncr ) {
    628     opExpr = new NameExpr( "?+=?" );
    629   } else {
    630     opExpr = new NameExpr( "?-=?" );
    631   }
    632   UntypedExpr *addAssign = new UntypedExpr( opExpr );
    633   if( AddressExpr *address = dynamic_cast< AddressExpr* >( appExpr->get_args().front() ) ) {
    634     addAssign->get_args().push_back( address->get_arg() );
    635   } else {
    636     addAssign->get_args().push_back( appExpr->get_args().front() );
    637   }
    638   addAssign->get_args().push_back( new NameExpr( polyName ) );
    639   addAssign->get_results().front() = appExpr->get_results().front()->clone();
    640   if( appExpr->get_env() ) {
    641     addAssign->set_env( appExpr->get_env() );
    642     appExpr->set_env( 0 );
    643   }
    644   appExpr->get_args().clear();
    645   delete appExpr;
    646   return addAssign;
    647 }
    648 
    649 Expression*
    650 Pass1::handleIntrinsics( ApplicationExpr *appExpr )
    651 {
    652   if( VariableExpr *varExpr = dynamic_cast< VariableExpr* >( appExpr->get_function() ) ) {
    653     if( varExpr->get_var()->get_linkage() == LinkageSpec::Intrinsic ) {
    654       if( varExpr->get_var()->get_name() == "?[?]" ) {
    655         assert( !appExpr->get_results().empty() );
    656         assert( appExpr->get_args().size() == 2 );
    657         TypeInstType *typeInst1 = isPolyPtr( appExpr->get_args().front()->get_results().front(), env, scopeTyVars );
    658         TypeInstType *typeInst2 = isPolyPtr( appExpr->get_args().back()->get_results().front(), env, scopeTyVars );
    659         assert( !typeInst1 || !typeInst2 );
    660         UntypedExpr *ret = 0;
    661         if( typeInst1 || typeInst2 ) {
    662           ret = new UntypedExpr( new NameExpr( "?+?" ) );
    663         }
    664         if( typeInst1 ) {
    665           UntypedExpr *multiply = new UntypedExpr( new NameExpr( "?*?" ) );
    666           multiply->get_args().push_back( appExpr->get_args().back() );
    667           multiply->get_args().push_back( new NameExpr( typeInst1->get_name() ) );
    668           ret->get_args().push_back( appExpr->get_args().front() );
    669           ret->get_args().push_back( multiply );
    670         } else if( typeInst2 ) {
    671           UntypedExpr *multiply = new UntypedExpr( new NameExpr( "?*?" ) );
    672           multiply->get_args().push_back( appExpr->get_args().front() );
    673           multiply->get_args().push_back( new NameExpr( typeInst2->get_name() ) );
    674           ret->get_args().push_back( multiply );
    675           ret->get_args().push_back( appExpr->get_args().back() );
    676         }
    677         if( typeInst1 || typeInst2 ) {
    678           ret->get_results().push_front( appExpr->get_results().front()->clone() );
    679           if( appExpr->get_env() ) {
    680             ret->set_env( appExpr->get_env() );
    681             appExpr->set_env( 0 );
    682           }
    683           appExpr->get_args().clear();
    684           delete appExpr;
    685           return ret;
    686         }
    687       } else if( varExpr->get_var()->get_name() == "*?" ) {
    688         assert( !appExpr->get_results().empty() );
    689         assert( !appExpr->get_args().empty() );
    690         if( isPolyType( appExpr->get_results().front(), env, scopeTyVars ) ) {
    691           Expression *ret = appExpr->get_args().front();
    692           delete ret->get_results().front();
    693           ret->get_results().front() = appExpr->get_results().front()->clone();
    694           if( appExpr->get_env() ) {
    695             ret->set_env( appExpr->get_env() );
    696             appExpr->set_env( 0 );
    697           }
    698           appExpr->get_args().clear();
    699           delete appExpr;
    700           return ret;
    701         }
    702       } else if( varExpr->get_var()->get_name() == "?++" || varExpr->get_var()->get_name() == "?--" ) {
    703         assert( !appExpr->get_results().empty() );
    704         assert( appExpr->get_args().size() == 1 );
    705         if( TypeInstType *typeInst = isPolyPtr( appExpr->get_results().front(), env, scopeTyVars ) ) {
    706           Type *tempType = appExpr->get_results().front()->clone();
    707           if( env ) {
    708             env->apply( tempType );
    709           }
    710           ObjectDecl *newObj = makeTemporary( tempType );
    711           VariableExpr *tempExpr = new VariableExpr( newObj );
    712           UntypedExpr *assignExpr = new UntypedExpr( new NameExpr( "?=?" ) );
    713           assignExpr->get_args().push_back( tempExpr->clone() );
    714           if( AddressExpr *address = dynamic_cast< AddressExpr* >( appExpr->get_args().front() ) ) {
    715             assignExpr->get_args().push_back( address->get_arg()->clone() );
    716           } else {
    717             assignExpr->get_args().push_back( appExpr->get_args().front()->clone() );
    718           }
    719           CommaExpr *firstComma = new CommaExpr( assignExpr, makeIncrDecrExpr( appExpr, typeInst->get_name(), varExpr->get_var()->get_name() == "?++" ) );
    720           return new CommaExpr( firstComma, tempExpr );
    721         }
    722       } else if( varExpr->get_var()->get_name() == "++?" || varExpr->get_var()->get_name() == "--?" ) {
    723         assert( !appExpr->get_results().empty() );
    724         assert( appExpr->get_args().size() == 1 );
    725         if( TypeInstType *typeInst = isPolyPtr( appExpr->get_results().front(), env, scopeTyVars ) ) {
    726            return makeIncrDecrExpr( appExpr, typeInst->get_name(), varExpr->get_var()->get_name() == "++?" );
    727         }
    728       } else if( varExpr->get_var()->get_name() == "?+?" || varExpr->get_var()->get_name() == "?-?" ) {
    729         assert( !appExpr->get_results().empty() );
    730         assert( appExpr->get_args().size() == 2 );
    731         TypeInstType *typeInst1 = isPolyPtr( appExpr->get_args().front()->get_results().front(), env, scopeTyVars );
    732         TypeInstType *typeInst2 = isPolyPtr( appExpr->get_args().back()->get_results().front(), env, scopeTyVars );
    733         if( typeInst1 && typeInst2 ) {
    734           UntypedExpr *divide = new UntypedExpr( new NameExpr( "?/?" ) );
    735           divide->get_args().push_back( appExpr );
    736           divide->get_args().push_back( new NameExpr( typeInst1->get_name() ) );
    737           divide->get_results().push_front( appExpr->get_results().front()->clone() );
    738           if( appExpr->get_env() ) {
    739             divide->set_env( appExpr->get_env() );
    740             appExpr->set_env( 0 );
    741           }
    742           return divide;
    743         } else if( typeInst1 ) {
    744           UntypedExpr *multiply = new UntypedExpr( new NameExpr( "?*?" ) );
    745           multiply->get_args().push_back( appExpr->get_args().back() );
    746           multiply->get_args().push_back( new NameExpr( typeInst1->get_name() ) );
    747           appExpr->get_args().back() = multiply;
    748         } else if( typeInst2 ) {
    749           UntypedExpr *multiply = new UntypedExpr( new NameExpr( "?*?" ) );
    750           multiply->get_args().push_back( appExpr->get_args().front() );
    751           multiply->get_args().push_back( new NameExpr( typeInst2->get_name() ) );
    752           appExpr->get_args().front() = multiply;
    753         }
    754       } else if( varExpr->get_var()->get_name() == "?+=?" || varExpr->get_var()->get_name() == "?-=?" ) {
    755         assert( !appExpr->get_results().empty() );
    756         assert( appExpr->get_args().size() == 2 );
    757         TypeInstType *typeInst = isPolyPtr( appExpr->get_results().front(), env, scopeTyVars );
    758         if( typeInst ) {
    759           UntypedExpr *multiply = new UntypedExpr( new NameExpr( "?*?" ) );
    760           multiply->get_args().push_back( appExpr->get_args().back() );
    761           multiply->get_args().push_back( new NameExpr( typeInst->get_name() ) );
    762           appExpr->get_args().back() = multiply;
    763         }
    764       }
    765       return appExpr;
    766     }
    767   }
    768   return 0;
    769 }
    770 
    771 Expression*
    772 Pass1::mutate( ApplicationExpr *appExpr )
    773 {
     435            } // if
     436            return new VariableExpr( param );
     437        }
     438
     439        void addAdapterParams( ApplicationExpr *adapteeApp, std::list< DeclarationWithType *>::iterator arg, std::list< DeclarationWithType *>::iterator param, std::list< DeclarationWithType *>::iterator paramEnd, std::list< DeclarationWithType *>::iterator realParam, const TyVarMap &tyVars ) {
     440            UniqueName paramNamer( "_p" );
     441            for ( ; param != paramEnd; ++param, ++arg, ++realParam ) {
     442                if ( (*param)->get_name() == "" ) {
     443                    (*param)->set_name( paramNamer.newName() );
     444                    (*param)->set_linkage( LinkageSpec::C );
     445                } // if
     446                adapteeApp->get_args().push_back( makeAdapterArg( *param, *arg, *realParam, tyVars ) );
     447            } // for
     448        }
     449
     450        FunctionDecl *Pass1::makeAdapter( FunctionType *adaptee, FunctionType *realType, const std::string &mangleName, const TyVarMap &tyVars ) {
     451            FunctionType *adapterType = makeAdapterType( adaptee, tyVars );
     452            adapterType = ScrubTyVars::scrub( adapterType, tyVars );
     453            DeclarationWithType *adapteeDecl = adapterType->get_parameters().front();
     454            adapteeDecl->set_name( "_adaptee" );
     455            ApplicationExpr *adapteeApp = new ApplicationExpr( new CastExpr( new VariableExpr( adapteeDecl ), new PointerType( Type::Qualifiers(), realType ) ) );
     456            Statement *bodyStmt;
     457 
     458            std::list< TypeDecl *>::iterator tyArg = realType->get_forall().begin();
     459            std::list< TypeDecl *>::iterator tyParam = adapterType->get_forall().begin();
     460            std::list< TypeDecl *>::iterator realTyParam = adaptee->get_forall().begin();
     461            for ( ; tyParam != adapterType->get_forall().end(); ++tyArg, ++tyParam, ++realTyParam ) {
     462                assert( tyArg != realType->get_forall().end() );
     463                std::list< DeclarationWithType *>::iterator assertArg = (*tyArg)->get_assertions().begin();
     464                std::list< DeclarationWithType *>::iterator assertParam = (*tyParam)->get_assertions().begin();
     465                std::list< DeclarationWithType *>::iterator realAssertParam = (*realTyParam)->get_assertions().begin();
     466                for ( ; assertParam != (*tyParam)->get_assertions().end(); ++assertArg, ++assertParam, ++realAssertParam ) {
     467                    assert( assertArg != (*tyArg)->get_assertions().end() );
     468                    adapteeApp->get_args().push_back( makeAdapterArg( *assertParam, *assertArg, *realAssertParam, tyVars ) );
     469                } // for
     470            } // for
     471 
     472            std::list< DeclarationWithType *>::iterator arg = realType->get_parameters().begin();
     473            std::list< DeclarationWithType *>::iterator param = adapterType->get_parameters().begin();
     474            std::list< DeclarationWithType *>::iterator realParam = adaptee->get_parameters().begin();
     475            param++;            // skip adaptee parameter
     476            if ( realType->get_returnVals().empty() ) {
     477                addAdapterParams( adapteeApp, arg, param, adapterType->get_parameters().end(), realParam, tyVars );
     478                bodyStmt = new ExprStmt( noLabels, adapteeApp );
     479            } else if ( isPolyVal( adaptee->get_returnVals().front()->get_type(), tyVars ) ) {
     480                if ( (*param)->get_name() == "" ) {
     481                    (*param)->set_name( "_ret" );
     482                    (*param)->set_linkage( LinkageSpec::C );
     483                } // if
     484                UntypedExpr *assign = new UntypedExpr( new NameExpr( "?=?" ) );
     485                UntypedExpr *deref = new UntypedExpr( new NameExpr( "*?" ) );
     486                deref->get_args().push_back( new CastExpr( new VariableExpr( *param++ ), new PointerType( Type::Qualifiers(), realType->get_returnVals().front()->get_type()->clone() ) ) );
     487                assign->get_args().push_back( deref );
     488                addAdapterParams( adapteeApp, arg, param, adapterType->get_parameters().end(), realParam, tyVars );
     489                assign->get_args().push_back( adapteeApp );
     490                bodyStmt = new ExprStmt( noLabels, assign );
     491            } else {
     492                // adapter for a function that returns a monomorphic value
     493                addAdapterParams( adapteeApp, arg, param, adapterType->get_parameters().end(), realParam, tyVars );
     494                bodyStmt = new ReturnStmt( noLabels, adapteeApp );
     495            } // if
     496            CompoundStmt *adapterBody = new CompoundStmt( noLabels );
     497            adapterBody->get_kids().push_back( bodyStmt );
     498            return new FunctionDecl( "_adapter" + mangleName, Declaration::NoStorageClass, LinkageSpec::C, adapterType, adapterBody, false );
     499        }
     500
     501        void Pass1::passAdapters( ApplicationExpr *appExpr, FunctionType *functionType, const TyVarMap &exprTyVars ) {
     502            std::list< DeclarationWithType *> &paramList = functionType->get_parameters();
     503            std::list< FunctionType *> functions;
     504            for ( std::list< TypeDecl *>::iterator tyVar = functionType->get_forall().begin(); tyVar != functionType->get_forall().end(); ++tyVar ) {
     505                for ( std::list< DeclarationWithType *>::iterator assert = (*tyVar)->get_assertions().begin(); assert != (*tyVar)->get_assertions().end(); ++assert ) {
     506                    findFunction( (*assert)->get_type(), functions, exprTyVars, needsAdapter );
     507                } // for
     508            } // for
     509            for ( std::list< DeclarationWithType *>::iterator arg = paramList.begin(); arg != paramList.end(); ++arg ) {
     510                findFunction( (*arg)->get_type(), functions, exprTyVars, needsAdapter );
     511            } // for
     512            std::set< std::string > adaptersDone;
     513            for ( std::list< FunctionType *>::iterator funType = functions.begin(); funType != functions.end(); ++funType ) {
     514                FunctionType *realFunction = (*funType)->clone();
     515                assert( env );
     516                env->apply( realFunction );
     517                std::string mangleName = SymTab::Mangler::mangle( realFunction );
     518                if ( adaptersDone.find( mangleName ) == adaptersDone.end() ) {
     519                    std::map< std::string, FunctionDecl *>::iterator adapter = adapters.find( mangleName );
     520                    if ( adapter == adapters.end() ) {
     521                        FunctionDecl *newAdapter = makeAdapter( *funType, realFunction, mangleName, exprTyVars );
     522                        adapter = adapters.insert( adapters.begin(), std::pair< std::string, FunctionDecl *>( mangleName, newAdapter ) );
     523                        stmtsToAdd.push_back( new DeclStmt( noLabels, newAdapter ) );
     524                    } // if
     525                    assert( adapter != adapters.end() );
     526                    appExpr->get_args().push_front( new VariableExpr( adapter->second ) );
     527                    adaptersDone.insert( adaptersDone.begin(), mangleName );
     528                } // if
     529            } // for
     530        }
     531
     532        TypeInstType *isPolyPtr( Type *type, const TypeSubstitution *env, const TyVarMap &tyVars ) {
     533            if ( PointerType *ptr = dynamic_cast< PointerType *>( type ) ) {
     534                return isPolyType( ptr->get_base(), env, tyVars );
     535            } else if ( env ) {
     536                if ( TypeInstType *typeInst = dynamic_cast< TypeInstType *>( type ) ) {
     537                    if ( Type *newType = env->lookup( typeInst->get_name() ) ) {
     538                        return isPolyPtr( newType, env, tyVars );
     539                    } // if
     540                } // if
     541            } // if
     542            return 0;
     543        }
     544
     545        TypeInstType *isPolyPtrPtr( Type *type, const TypeSubstitution *env, const TyVarMap &tyVars ) {
     546            if ( PointerType *ptr = dynamic_cast< PointerType *>( type ) ) {
     547                return isPolyPtr( ptr->get_base(), env, tyVars );
     548            } else if ( env ) {
     549                if ( TypeInstType *typeInst = dynamic_cast< TypeInstType *>( type ) ) {
     550                    if ( Type *newType = env->lookup( typeInst->get_name() ) ) {
     551                        return isPolyPtrPtr( newType, env, tyVars );
     552                    } // if
     553                } // if
     554            } // if
     555            return 0;
     556        }
     557
     558        Expression *makeIncrDecrExpr( ApplicationExpr *appExpr, std::string polyName, bool isIncr ) {
     559            NameExpr *opExpr;
     560            if ( isIncr ) {
     561                opExpr = new NameExpr( "?+=?" );
     562            } else {
     563                opExpr = new NameExpr( "?-=?" );
     564            } // if
     565            UntypedExpr *addAssign = new UntypedExpr( opExpr );
     566            if ( AddressExpr *address = dynamic_cast< AddressExpr *>( appExpr->get_args().front() ) ) {
     567                addAssign->get_args().push_back( address->get_arg() );
     568            } else {
     569                addAssign->get_args().push_back( appExpr->get_args().front() );
     570            } // if
     571            addAssign->get_args().push_back( new NameExpr( polyName ) );
     572            addAssign->get_results().front() = appExpr->get_results().front()->clone();
     573            if ( appExpr->get_env() ) {
     574                addAssign->set_env( appExpr->get_env() );
     575                appExpr->set_env( 0 );
     576            } // if
     577            appExpr->get_args().clear();
     578            delete appExpr;
     579            return addAssign;
     580        }
     581
     582        Expression *Pass1::handleIntrinsics( ApplicationExpr *appExpr ) {
     583            if ( VariableExpr *varExpr = dynamic_cast< VariableExpr *>( appExpr->get_function() ) ) {
     584                if ( varExpr->get_var()->get_linkage() == LinkageSpec::Intrinsic ) {
     585                    if ( varExpr->get_var()->get_name() == "?[?]" ) {
     586                        assert( !appExpr->get_results().empty() );
     587                        assert( appExpr->get_args().size() == 2 );
     588                        TypeInstType *typeInst1 = isPolyPtr( appExpr->get_args().front()->get_results().front(), env, scopeTyVars );
     589                        TypeInstType *typeInst2 = isPolyPtr( appExpr->get_args().back()->get_results().front(), env, scopeTyVars );
     590                        assert( !typeInst1 || !typeInst2 );
     591                        UntypedExpr *ret = 0;
     592                        if ( typeInst1 || typeInst2 ) {
     593                            ret = new UntypedExpr( new NameExpr( "?+?" ) );
     594                        } // if
     595                        if ( typeInst1 ) {
     596                            UntypedExpr *multiply = new UntypedExpr( new NameExpr( "?*?" ) );
     597                            multiply->get_args().push_back( appExpr->get_args().back() );
     598                            multiply->get_args().push_back( new NameExpr( typeInst1->get_name() ) );
     599                            ret->get_args().push_back( appExpr->get_args().front() );
     600                            ret->get_args().push_back( multiply );
     601                        } else if ( typeInst2 ) {
     602                            UntypedExpr *multiply = new UntypedExpr( new NameExpr( "?*?" ) );
     603                            multiply->get_args().push_back( appExpr->get_args().front() );
     604                            multiply->get_args().push_back( new NameExpr( typeInst2->get_name() ) );
     605                            ret->get_args().push_back( multiply );
     606                            ret->get_args().push_back( appExpr->get_args().back() );
     607                        } // if
     608                        if ( typeInst1 || typeInst2 ) {
     609                            ret->get_results().push_front( appExpr->get_results().front()->clone() );
     610                            if ( appExpr->get_env() ) {
     611                                ret->set_env( appExpr->get_env() );
     612                                appExpr->set_env( 0 );
     613                            } // if
     614                            appExpr->get_args().clear();
     615                            delete appExpr;
     616                            return ret;
     617                        } // if
     618                    } else if ( varExpr->get_var()->get_name() == "*?" ) {
     619                        assert( !appExpr->get_results().empty() );
     620                        assert( !appExpr->get_args().empty() );
     621                        if ( isPolyType( appExpr->get_results().front(), env, scopeTyVars ) ) {
     622                            Expression *ret = appExpr->get_args().front();
     623                            delete ret->get_results().front();
     624                            ret->get_results().front() = appExpr->get_results().front()->clone();
     625                            if ( appExpr->get_env() ) {
     626                                ret->set_env( appExpr->get_env() );
     627                                appExpr->set_env( 0 );
     628                            } // if
     629                            appExpr->get_args().clear();
     630                            delete appExpr;
     631                            return ret;
     632                        } // if
     633                    } else if ( varExpr->get_var()->get_name() == "?++" || varExpr->get_var()->get_name() == "?--" ) {
     634                        assert( !appExpr->get_results().empty() );
     635                        assert( appExpr->get_args().size() == 1 );
     636                        if ( TypeInstType *typeInst = isPolyPtr( appExpr->get_results().front(), env, scopeTyVars ) ) {
     637                            Type *tempType = appExpr->get_results().front()->clone();
     638                            if ( env ) {
     639                                env->apply( tempType );
     640                            } // if
     641                            ObjectDecl *newObj = makeTemporary( tempType );
     642                            VariableExpr *tempExpr = new VariableExpr( newObj );
     643                            UntypedExpr *assignExpr = new UntypedExpr( new NameExpr( "?=?" ) );
     644                            assignExpr->get_args().push_back( tempExpr->clone() );
     645                            if ( AddressExpr *address = dynamic_cast< AddressExpr *>( appExpr->get_args().front() ) ) {
     646                                assignExpr->get_args().push_back( address->get_arg()->clone() );
     647                            } else {
     648                                assignExpr->get_args().push_back( appExpr->get_args().front()->clone() );
     649                            } // if
     650                            CommaExpr *firstComma = new CommaExpr( assignExpr, makeIncrDecrExpr( appExpr, typeInst->get_name(), varExpr->get_var()->get_name() == "?++" ) );
     651                            return new CommaExpr( firstComma, tempExpr );
     652                        } // if
     653                    } else if ( varExpr->get_var()->get_name() == "++?" || varExpr->get_var()->get_name() == "--?" ) {
     654                        assert( !appExpr->get_results().empty() );
     655                        assert( appExpr->get_args().size() == 1 );
     656                        if ( TypeInstType *typeInst = isPolyPtr( appExpr->get_results().front(), env, scopeTyVars ) ) {
     657                            return makeIncrDecrExpr( appExpr, typeInst->get_name(), varExpr->get_var()->get_name() == "++?" );
     658                        } // if
     659                    } else if ( varExpr->get_var()->get_name() == "?+?" || varExpr->get_var()->get_name() == "?-?" ) {
     660                        assert( !appExpr->get_results().empty() );
     661                        assert( appExpr->get_args().size() == 2 );
     662                        TypeInstType *typeInst1 = isPolyPtr( appExpr->get_args().front()->get_results().front(), env, scopeTyVars );
     663                        TypeInstType *typeInst2 = isPolyPtr( appExpr->get_args().back()->get_results().front(), env, scopeTyVars );
     664                        if ( typeInst1 && typeInst2 ) {
     665                            UntypedExpr *divide = new UntypedExpr( new NameExpr( "?/?" ) );
     666                            divide->get_args().push_back( appExpr );
     667                            divide->get_args().push_back( new NameExpr( typeInst1->get_name() ) );
     668                            divide->get_results().push_front( appExpr->get_results().front()->clone() );
     669                            if ( appExpr->get_env() ) {
     670                                divide->set_env( appExpr->get_env() );
     671                                appExpr->set_env( 0 );
     672                            } // if
     673                            return divide;
     674                        } else if ( typeInst1 ) {
     675                            UntypedExpr *multiply = new UntypedExpr( new NameExpr( "?*?" ) );
     676                            multiply->get_args().push_back( appExpr->get_args().back() );
     677                            multiply->get_args().push_back( new NameExpr( typeInst1->get_name() ) );
     678                            appExpr->get_args().back() = multiply;
     679                        } else if ( typeInst2 ) {
     680                            UntypedExpr *multiply = new UntypedExpr( new NameExpr( "?*?" ) );
     681                            multiply->get_args().push_back( appExpr->get_args().front() );
     682                            multiply->get_args().push_back( new NameExpr( typeInst2->get_name() ) );
     683                            appExpr->get_args().front() = multiply;
     684                        } // if
     685                    } else if ( varExpr->get_var()->get_name() == "?+=?" || varExpr->get_var()->get_name() == "?-=?" ) {
     686                        assert( !appExpr->get_results().empty() );
     687                        assert( appExpr->get_args().size() == 2 );
     688                        TypeInstType *typeInst = isPolyPtr( appExpr->get_results().front(), env, scopeTyVars );
     689                        if ( typeInst ) {
     690                            UntypedExpr *multiply = new UntypedExpr( new NameExpr( "?*?" ) );
     691                            multiply->get_args().push_back( appExpr->get_args().back() );
     692                            multiply->get_args().push_back( new NameExpr( typeInst->get_name() ) );
     693                            appExpr->get_args().back() = multiply;
     694                        } // if
     695                    } // if
     696                    return appExpr;
     697                } // if
     698            } // if
     699            return 0;
     700        }
     701
     702        Expression *Pass1::mutate( ApplicationExpr *appExpr ) {
    774703///     std::cerr << "mutate appExpr: ";
    775 ///     for( TyVarMap::iterator i = scopeTyVars.begin(); i != scopeTyVars.end(); ++i ) {
     704///     for ( TyVarMap::iterator i = scopeTyVars.begin(); i != scopeTyVars.end(); ++i ) {
    776705///       std::cerr << i->first << " ";
    777706///     }
    778707///     std::cerr << "\n";
    779   bool oldUseRetval = useRetval;
    780   useRetval = false;
    781   appExpr->get_function()->acceptMutator( *this );
    782   mutateAll( appExpr->get_args(), *this );
    783   useRetval = oldUseRetval;
    784  
    785   assert( !appExpr->get_function()->get_results().empty() );
    786   PointerType *pointer = dynamic_cast< PointerType* >( appExpr->get_function()->get_results().front() );
    787   assert( pointer );
    788   FunctionType *function = dynamic_cast< FunctionType* >( pointer->get_base() );
    789   assert( function );
    790  
    791   if( Expression *newExpr = handleIntrinsics( appExpr ) ) {
    792     return newExpr;
    793   }
    794  
    795   Expression *ret = appExpr;
    796  
    797   std::list< Expression* >::iterator arg = appExpr->get_args().begin();
    798   std::list< Expression* >::iterator paramBegin = appExpr->get_args().begin();
    799  
    800   std::string typeName;
    801   if( isPolyRet( function, typeName ) ) {
    802     ret = addPolyRetParam( appExpr, function, typeName, arg );
    803   } else if( needsAdapter( function, scopeTyVars ) ) {
     708            bool oldUseRetval = useRetval;
     709            useRetval = false;
     710            appExpr->get_function()->acceptMutator( *this );
     711            mutateAll( appExpr->get_args(), *this );
     712            useRetval = oldUseRetval;
     713 
     714            assert( !appExpr->get_function()->get_results().empty() );
     715            PointerType *pointer = dynamic_cast< PointerType *>( appExpr->get_function()->get_results().front() );
     716            assert( pointer );
     717            FunctionType *function = dynamic_cast< FunctionType *>( pointer->get_base() );
     718            assert( function );
     719 
     720            if ( Expression *newExpr = handleIntrinsics( appExpr ) ) {
     721                return newExpr;
     722            } // if
     723 
     724            Expression *ret = appExpr;
     725 
     726            std::list< Expression *>::iterator arg = appExpr->get_args().begin();
     727            std::list< Expression *>::iterator paramBegin = appExpr->get_args().begin();
     728 
     729            std::string typeName;
     730            if ( isPolyRet( function, typeName ) ) {
     731                ret = addPolyRetParam( appExpr, function, typeName, arg );
     732            } else if ( needsAdapter( function, scopeTyVars ) ) {
    804733///     std::cerr << "needs adapter: ";
    805 ///     for( TyVarMap::iterator i = scopeTyVars.begin(); i != scopeTyVars.end(); ++i ) {
     734///     for ( TyVarMap::iterator i = scopeTyVars.begin(); i != scopeTyVars.end(); ++i ) {
    806735///       std::cerr << i->first << " ";
    807736///     }
    808737///     std::cerr << "\n";
    809     // change the application so it calls the adapter rather than the passed function
    810     ret = applyAdapter( appExpr, function, arg, scopeTyVars );
    811   }
    812   arg = appExpr->get_args().begin();
    813  
    814   TyVarMap exprTyVars;
    815   makeTyVarMap( function, exprTyVars );
    816  
    817   passTypeVars( appExpr, arg, exprTyVars );
    818   addInferredParams( appExpr, function, arg, exprTyVars );
    819 
    820   arg = paramBegin;
    821  
    822   boxParams( appExpr, function, arg, exprTyVars );
    823 
    824   passAdapters( appExpr, function, exprTyVars );
    825 
    826   return ret;
    827 }
    828 
    829 Expression *
    830 Pass1::mutate( UntypedExpr *expr )
    831 {
    832   if( !expr->get_results().empty() && isPolyType( expr->get_results().front(), env, scopeTyVars ) ) {
    833     if( NameExpr *name = dynamic_cast< NameExpr* >( expr->get_function() ) ) {
    834       if( name->get_name() == "*?" ) {
    835         Expression *ret = expr->get_args().front();
    836         expr->get_args().clear();
    837         delete expr;
    838         return ret->acceptMutator( *this );
    839       }
    840     }
    841   }
    842   return PolyMutator::mutate( expr );
    843 }
    844 
    845 Expression *
    846 Pass1::mutate( AddressExpr *addrExpr )
    847 {
    848   assert( !addrExpr->get_arg()->get_results().empty() );
    849   mutateExpression( addrExpr->get_arg() );
    850   if( isPolyType( addrExpr->get_arg()->get_results().front(), env, scopeTyVars ) ) {
    851     Expression *ret = addrExpr->get_arg();
    852     delete ret->get_results().front();
    853     ret->get_results().front() = addrExpr->get_results().front()->clone();
    854     addrExpr->set_arg( 0 );
    855     delete addrExpr;
    856     return ret;
    857   } else {
    858     return addrExpr;
    859   }
    860 }
    861 
    862 Statement*
    863 Pass1::mutate(ReturnStmt *retStmt)
    864 {
    865   // a cast expr on a polymorphic return value is either redundant or invalid
    866   while( CastExpr *castExpr = dynamic_cast< CastExpr* >( retStmt->get_expr() ) ) {
    867     retStmt->set_expr( castExpr->get_arg() );
    868     retStmt->get_expr()->set_env( castExpr->get_env() );
    869     castExpr->set_env( 0 );
    870     castExpr->set_arg( 0 );
    871     delete castExpr;
    872   }
    873   if( retval && retStmt->get_expr() ) {
    874     assert( !retStmt->get_expr()->get_results().empty() );
    875     if( retStmt->get_expr()->get_results().front()->get_isLvalue() ) {
     738                // change the application so it calls the adapter rather than the passed function
     739                ret = applyAdapter( appExpr, function, arg, scopeTyVars );
     740            } // if
     741            arg = appExpr->get_args().begin();
     742 
     743            TyVarMap exprTyVars;
     744            makeTyVarMap( function, exprTyVars );
     745 
     746            passTypeVars( appExpr, arg, exprTyVars );
     747            addInferredParams( appExpr, function, arg, exprTyVars );
     748
     749            arg = paramBegin;
     750 
     751            boxParams( appExpr, function, arg, exprTyVars );
     752
     753            passAdapters( appExpr, function, exprTyVars );
     754
     755            return ret;
     756        }
     757
     758        Expression *Pass1::mutate( UntypedExpr *expr ) {
     759            if ( !expr->get_results().empty() && isPolyType( expr->get_results().front(), env, scopeTyVars ) ) {
     760                if ( NameExpr *name = dynamic_cast< NameExpr *>( expr->get_function() ) ) {
     761                    if ( name->get_name() == "*?" ) {
     762                        Expression *ret = expr->get_args().front();
     763                        expr->get_args().clear();
     764                        delete expr;
     765                        return ret->acceptMutator( *this );
     766                    } // if
     767                } // if
     768            } // if
     769            return PolyMutator::mutate( expr );
     770        }
     771
     772        Expression *Pass1::mutate( AddressExpr *addrExpr ) {
     773            assert( !addrExpr->get_arg()->get_results().empty() );
     774            mutateExpression( addrExpr->get_arg() );
     775            if ( isPolyType( addrExpr->get_arg()->get_results().front(), env, scopeTyVars ) ) {
     776                Expression *ret = addrExpr->get_arg();
     777                delete ret->get_results().front();
     778                ret->get_results().front() = addrExpr->get_results().front()->clone();
     779                addrExpr->set_arg( 0 );
     780                delete addrExpr;
     781                return ret;
     782            } else {
     783                return addrExpr;
     784            } // if
     785        }
     786
     787        Statement *
     788        Pass1::mutate(ReturnStmt *retStmt) {
     789            // a cast expr on a polymorphic return value is either redundant or invalid
     790            while ( CastExpr *castExpr = dynamic_cast< CastExpr *>( retStmt->get_expr() ) ) {
     791                retStmt->set_expr( castExpr->get_arg() );
     792                retStmt->get_expr()->set_env( castExpr->get_env() );
     793                castExpr->set_env( 0 );
     794                castExpr->set_arg( 0 );
     795                delete castExpr;
     796            }
     797            if ( retval && retStmt->get_expr() ) {
     798                assert( !retStmt->get_expr()->get_results().empty() );
     799                if ( retStmt->get_expr()->get_results().front()->get_isLvalue() ) {
    876800///       retStmt->set_expr( mutateExpression( retStmt->get_expr() ) );
    877       TypeInstType *typeInst = dynamic_cast< TypeInstType* >( retval->get_type() );
    878       assert( typeInst );
    879       std::map< std::string, DeclarationWithType* >::const_iterator assignIter = assignOps.find( typeInst->get_name() );
    880       if( assignIter == assignOps.end() ) {
    881         throw SemanticError( "Attempt to return dtype or ftype object in ", retStmt->get_expr() );
    882       }
    883       ApplicationExpr *assignExpr = new ApplicationExpr( new VariableExpr( assignIter->second ) );
    884       Expression *retParm = new NameExpr( retval->get_name() );
    885       retParm->get_results().push_back( new PointerType( Type::Qualifiers(), retval->get_type()->clone() ) );
    886       assignExpr->get_args().push_back( retParm );
    887       assignExpr->get_args().push_back( retStmt->get_expr() );
    888       stmtsToAdd.push_back( new ExprStmt( noLabels, mutateExpression( assignExpr ) ) );
    889     } else {
    890       useRetval = true;
    891       stmtsToAdd.push_back( new ExprStmt( noLabels, mutateExpression( retStmt->get_expr() ) ) );
    892       useRetval = false;
    893     }
    894     retStmt->set_expr( 0 );
    895   } else {
    896     retStmt->set_expr( mutateExpression( retStmt->get_expr() ) );
    897   }
    898   return retStmt;
    899 }
    900 
    901 Type*
    902 Pass1::mutate( PointerType *pointerType )
    903 {
    904   TyVarMap oldtyVars = scopeTyVars;
    905   makeTyVarMap( pointerType, scopeTyVars );
    906  
    907   Type* ret = Mutator::mutate( pointerType );
    908  
    909   scopeTyVars = oldtyVars;
    910   return ret;
    911 }
    912 
    913 Type*
    914 Pass1::mutate( FunctionType *functionType )
    915 {
    916   TyVarMap oldtyVars = scopeTyVars;
    917   makeTyVarMap( functionType, scopeTyVars );
    918  
    919   Type* ret = Mutator::mutate( functionType );
    920  
    921   scopeTyVars = oldtyVars;
    922   return ret;
    923 }
    924 
    925 void
    926 Pass1::doEndScope()
    927 {
    928   adapters.clear();
    929 }
     801                    TypeInstType *typeInst = dynamic_cast< TypeInstType *>( retval->get_type() );
     802                    assert( typeInst );
     803                    std::map< std::string, DeclarationWithType *>::const_iterator assignIter = assignOps.find( typeInst->get_name() );
     804                    if ( assignIter == assignOps.end() ) {
     805                        throw SemanticError( "Attempt to return dtype or ftype object in ", retStmt->get_expr() );
     806                    } // if
     807                    ApplicationExpr *assignExpr = new ApplicationExpr( new VariableExpr( assignIter->second ) );
     808                    Expression *retParm = new NameExpr( retval->get_name() );
     809                    retParm->get_results().push_back( new PointerType( Type::Qualifiers(), retval->get_type()->clone() ) );
     810                    assignExpr->get_args().push_back( retParm );
     811                    assignExpr->get_args().push_back( retStmt->get_expr() );
     812                    stmtsToAdd.push_back( new ExprStmt( noLabels, mutateExpression( assignExpr ) ) );
     813                } else {
     814                    useRetval = true;
     815                    stmtsToAdd.push_back( new ExprStmt( noLabels, mutateExpression( retStmt->get_expr() ) ) );
     816                    useRetval = false;
     817                } // if
     818                retStmt->set_expr( 0 );
     819            } else {
     820                retStmt->set_expr( mutateExpression( retStmt->get_expr() ) );
     821            } // if
     822            return retStmt;
     823        }
     824
     825        Type *
     826        Pass1::mutate( PointerType *pointerType ) {
     827            TyVarMap oldtyVars = scopeTyVars;
     828            makeTyVarMap( pointerType, scopeTyVars );
     829 
     830            Type *ret = Mutator::mutate( pointerType );
     831 
     832            scopeTyVars = oldtyVars;
     833            return ret;
     834        }
     835
     836        Type *
     837        Pass1::mutate( FunctionType *functionType ) {
     838            TyVarMap oldtyVars = scopeTyVars;
     839            makeTyVarMap( functionType, scopeTyVars );
     840 
     841            Type *ret = Mutator::mutate( functionType );
     842 
     843            scopeTyVars = oldtyVars;
     844            return ret;
     845        }
     846
     847        void Pass1::doEndScope() {
     848            adapters.clear();
     849        }
    930850
    931851////////////////////////////////////////// Pass2 ////////////////////////////////////////////////////
    932852
    933 Pass2::Pass2()
    934 {
    935 }
    936 
    937 void
    938 Pass2::addAdapters( FunctionType *functionType )
    939 {
    940   std::list< DeclarationWithType* > &paramList = functionType->get_parameters();
    941   std::list< FunctionType* > functions;
    942   for( std::list< DeclarationWithType* >::iterator arg = paramList.begin(); arg != paramList.end(); ++arg ) {
    943     Type *orig = (*arg)->get_type();
    944     findAndReplaceFunction( orig, functions, scopeTyVars, needsAdapter );
    945     (*arg)->set_type( orig );
    946   }
    947   std::set< std::string > adaptersDone;
    948   for( std::list< FunctionType* >::iterator funType = functions.begin(); funType != functions.end(); ++funType ) {
    949     std::string mangleName = SymTab::Mangler::mangle( *funType );
    950     if( adaptersDone.find( mangleName ) == adaptersDone.end() ) {
    951       paramList.push_front( new ObjectDecl( "_adapter" + mangleName, Declaration::NoStorageClass, LinkageSpec::C, 0, new PointerType( Type::Qualifiers(), makeAdapterType( *funType, scopeTyVars ) ), 0 ) );
    952       adaptersDone.insert( adaptersDone.begin(), mangleName );
    953     }
    954   }
     853        Pass2::Pass2() {}
     854
     855        void Pass2::addAdapters( FunctionType *functionType ) {
     856            std::list< DeclarationWithType *> &paramList = functionType->get_parameters();
     857            std::list< FunctionType *> functions;
     858            for ( std::list< DeclarationWithType *>::iterator arg = paramList.begin(); arg != paramList.end(); ++arg ) {
     859                Type *orig = (*arg)->get_type();
     860                findAndReplaceFunction( orig, functions, scopeTyVars, needsAdapter );
     861                (*arg)->set_type( orig );
     862            }
     863            std::set< std::string > adaptersDone;
     864            for ( std::list< FunctionType *>::iterator funType = functions.begin(); funType != functions.end(); ++funType ) {
     865                std::string mangleName = SymTab::Mangler::mangle( *funType );
     866                if ( adaptersDone.find( mangleName ) == adaptersDone.end() ) {
     867                    paramList.push_front( new ObjectDecl( "_adapter" + mangleName, Declaration::NoStorageClass, LinkageSpec::C, 0, new PointerType( Type::Qualifiers(), makeAdapterType( *funType, scopeTyVars ) ), 0 ) );
     868                    adaptersDone.insert( adaptersDone.begin(), mangleName );
     869                }
     870            }
    955871///  deleteAll( functions );
    956 }
    957 
    958 template< typename DeclClass >
    959 DeclClass*
    960 Pass2::handleDecl( DeclClass *decl, Type *type )
    961 {
    962   DeclClass *ret = static_cast< DeclClass* >( Mutator::mutate( decl ) );
    963 
    964   return ret;
    965 }
    966 
    967 DeclarationWithType*
    968 Pass2::mutate( FunctionDecl *functionDecl )
    969 {
    970   return handleDecl( functionDecl, functionDecl->get_functionType() );
    971 }
    972 
    973 ObjectDecl*
    974 Pass2::mutate( ObjectDecl *objectDecl )
    975 {
    976   return handleDecl( objectDecl, objectDecl->get_type() );
    977 }
    978 
    979 TypeDecl*
    980 Pass2::mutate( TypeDecl *typeDecl )
    981 {
    982   scopeTyVars[ typeDecl->get_name() ] = typeDecl->get_kind();
    983   if( typeDecl->get_base() ) {
    984     return handleDecl( typeDecl, typeDecl->get_base() );
    985   } else {
    986     return Mutator::mutate( typeDecl );
    987   }
    988 }
    989 
    990 TypedefDecl*
    991 Pass2::mutate( TypedefDecl *typedefDecl )
    992 {
    993   return handleDecl( typedefDecl, typedefDecl->get_base() );
    994 }
    995 
    996 Type*
    997 Pass2::mutate( PointerType *pointerType )
    998 {
    999   TyVarMap oldtyVars = scopeTyVars;
    1000   makeTyVarMap( pointerType, scopeTyVars );
    1001  
    1002   Type* ret = Mutator::mutate( pointerType );
    1003  
    1004   scopeTyVars = oldtyVars;
    1005   return ret;
    1006 }
    1007 
    1008 Type *
    1009 Pass2::mutate( FunctionType *funcType )
    1010 {
    1011   TyVarMap oldtyVars = scopeTyVars;
    1012   makeTyVarMap( funcType, scopeTyVars );
    1013  
    1014   std::string typeName;
    1015   if( isPolyRet( funcType, typeName ) ) {
    1016     DeclarationWithType *ret = funcType->get_returnVals().front();
    1017     ret->set_type( new PointerType( Type::Qualifiers(), ret->get_type() ) );
    1018     funcType->get_parameters().push_front( ret );
    1019     funcType->get_returnVals().pop_front();
    1020   }
    1021  
    1022   std::list< DeclarationWithType* >::iterator last = funcType->get_parameters().begin();
    1023   std::list< DeclarationWithType* > inferredParams;
    1024   ObjectDecl *newObj = new ObjectDecl( "", Declaration::NoStorageClass, LinkageSpec::C, 0, new BasicType( Type::Qualifiers(), BasicType::LongUnsignedInt ), 0 );
     872        }
     873
     874        template< typename DeclClass >
     875        DeclClass *
     876        Pass2::handleDecl( DeclClass *decl, Type *type ) {
     877            DeclClass *ret = static_cast< DeclClass *>( Mutator::mutate( decl ) );
     878
     879            return ret;
     880        }
     881
     882        DeclarationWithType *
     883        Pass2::mutate( FunctionDecl *functionDecl ) {
     884            return handleDecl( functionDecl, functionDecl->get_functionType() );
     885        }
     886
     887        ObjectDecl *
     888        Pass2::mutate( ObjectDecl *objectDecl ) {
     889            return handleDecl( objectDecl, objectDecl->get_type() );
     890        }
     891
     892        TypeDecl *
     893        Pass2::mutate( TypeDecl *typeDecl ) {
     894            scopeTyVars[ typeDecl->get_name() ] = typeDecl->get_kind();
     895            if ( typeDecl->get_base() ) {
     896                return handleDecl( typeDecl, typeDecl->get_base() );
     897            } else {
     898                return Mutator::mutate( typeDecl );
     899            }
     900        }
     901
     902        TypedefDecl *
     903        Pass2::mutate( TypedefDecl *typedefDecl ) {
     904            return handleDecl( typedefDecl, typedefDecl->get_base() );
     905        }
     906
     907        Type *
     908        Pass2::mutate( PointerType *pointerType ) {
     909            TyVarMap oldtyVars = scopeTyVars;
     910            makeTyVarMap( pointerType, scopeTyVars );
     911 
     912            Type *ret = Mutator::mutate( pointerType );
     913 
     914            scopeTyVars = oldtyVars;
     915            return ret;
     916        }
     917
     918        Type *Pass2::mutate( FunctionType *funcType ) {
     919            TyVarMap oldtyVars = scopeTyVars;
     920            makeTyVarMap( funcType, scopeTyVars );
     921 
     922            std::string typeName;
     923            if ( isPolyRet( funcType, typeName ) ) {
     924                DeclarationWithType *ret = funcType->get_returnVals().front();
     925                ret->set_type( new PointerType( Type::Qualifiers(), ret->get_type() ) );
     926                funcType->get_parameters().push_front( ret );
     927                funcType->get_returnVals().pop_front();
     928            }
     929 
     930            std::list< DeclarationWithType *>::iterator last = funcType->get_parameters().begin();
     931            std::list< DeclarationWithType *> inferredParams;
     932            ObjectDecl *newObj = new ObjectDecl( "", Declaration::NoStorageClass, LinkageSpec::C, 0, new BasicType( Type::Qualifiers(), BasicType::LongUnsignedInt ), 0 );
    1025933///   ObjectDecl *newFunPtr = new ObjectDecl( "", Declaration::NoStorageClass, LinkageSpec::Cforall, 0, new PointerType( Type::Qualifiers(), new FunctionType( Type::Qualifiers(), true ) ), 0 );
    1026   for( std::list< TypeDecl* >::const_iterator tyParm = funcType->get_forall().begin(); tyParm != funcType->get_forall().end(); ++tyParm ) {
    1027     ObjectDecl *thisParm;
    1028     if( (*tyParm)->get_kind() == TypeDecl::Any ) {
    1029       thisParm = newObj->clone();
    1030       thisParm->set_name( (*tyParm)->get_name() );
    1031       last = funcType->get_parameters().insert( last, thisParm );
    1032       ++last;
    1033     }
    1034     for( std::list< DeclarationWithType* >::iterator assert = (*tyParm)->get_assertions().begin(); assert != (*tyParm)->get_assertions().end(); ++assert ) {
    1035 ///       *assert = (*assert)->acceptMutator( *this );
    1036       inferredParams.push_back( *assert );
    1037     }
    1038     (*tyParm)->get_assertions().clear();
    1039   }
    1040   delete newObj;
    1041   funcType->get_parameters().splice( last, inferredParams );
    1042   addAdapters( funcType );
    1043   mutateAll( funcType->get_returnVals(), *this );
    1044   mutateAll( funcType->get_parameters(), *this );
    1045  
    1046   scopeTyVars = oldtyVars;
    1047   return funcType;
    1048 }
     934            for ( std::list< TypeDecl *>::const_iterator tyParm = funcType->get_forall().begin(); tyParm != funcType->get_forall().end(); ++tyParm ) {
     935                ObjectDecl *thisParm;
     936                if ( (*tyParm)->get_kind() == TypeDecl::Any ) {
     937                    thisParm = newObj->clone();
     938                    thisParm->set_name( (*tyParm)->get_name() );
     939                    last = funcType->get_parameters().insert( last, thisParm );
     940                    ++last;
     941                }
     942                for ( std::list< DeclarationWithType *>::iterator assert = (*tyParm)->get_assertions().begin(); assert != (*tyParm)->get_assertions().end(); ++assert ) {
     943///      *assert = (*assert)->acceptMutator( *this );
     944                    inferredParams.push_back( *assert );
     945                }
     946                (*tyParm)->get_assertions().clear();
     947            }
     948            delete newObj;
     949            funcType->get_parameters().splice( last, inferredParams );
     950            addAdapters( funcType );
     951            mutateAll( funcType->get_returnVals(), *this );
     952            mutateAll( funcType->get_parameters(), *this );
     953 
     954            scopeTyVars = oldtyVars;
     955            return funcType;
     956        }
    1049957
    1050958////////////////////////////////////////// Pass3 ////////////////////////////////////////////////////
    1051959
    1052 template< typename DeclClass >
    1053 DeclClass*
    1054 Pass3::handleDecl( DeclClass *decl, Type *type )
    1055 {
    1056   TyVarMap oldtyVars = scopeTyVars;
    1057   makeTyVarMap( type, scopeTyVars );
    1058  
    1059   DeclClass *ret = static_cast< DeclClass* >( Mutator::mutate( decl ) );
    1060   ScrubTyVars::scrub( decl, scopeTyVars );
    1061 
    1062   scopeTyVars = oldtyVars;
    1063   return ret;
    1064 }
    1065 
    1066 ObjectDecl*
    1067 Pass3::mutate( ObjectDecl *objectDecl )
    1068 {
    1069   return handleDecl( objectDecl, objectDecl->get_type() );
    1070 }
    1071 
    1072 DeclarationWithType*
    1073 Pass3::mutate( FunctionDecl *functionDecl )
    1074 {
    1075   return handleDecl( functionDecl, functionDecl->get_functionType() );
    1076 }
    1077 
    1078 TypedefDecl*
    1079 Pass3::mutate( TypedefDecl *typedefDecl )
    1080 {
    1081   return handleDecl( typedefDecl, typedefDecl->get_base() );
    1082 }
    1083 
    1084 TypeDecl*
    1085 Pass3::mutate( TypeDecl *typeDecl )
    1086 {
     960        template< typename DeclClass >
     961        DeclClass *
     962        Pass3::handleDecl( DeclClass *decl, Type *type ) {
     963            TyVarMap oldtyVars = scopeTyVars;
     964            makeTyVarMap( type, scopeTyVars );
     965 
     966            DeclClass *ret = static_cast< DeclClass *>( Mutator::mutate( decl ) );
     967            ScrubTyVars::scrub( decl, scopeTyVars );
     968
     969            scopeTyVars = oldtyVars;
     970            return ret;
     971        }
     972
     973        ObjectDecl *
     974        Pass3::mutate( ObjectDecl *objectDecl ) {
     975            return handleDecl( objectDecl, objectDecl->get_type() );
     976        }
     977
     978        DeclarationWithType *
     979        Pass3::mutate( FunctionDecl *functionDecl ) {
     980            return handleDecl( functionDecl, functionDecl->get_functionType() );
     981        }
     982
     983        TypedefDecl *
     984        Pass3::mutate( TypedefDecl *typedefDecl ) {
     985            return handleDecl( typedefDecl, typedefDecl->get_base() );
     986        }
     987
     988        TypeDecl *
     989        Pass3::mutate( TypeDecl *typeDecl ) {
    1087990///   Initializer *init = 0;
    1088991///   std::list< Expression *> designators;
    1089992///   scopeTyVars[ typeDecl->get_name() ] = typeDecl->get_kind();
    1090 ///   if( typeDecl->get_base() ) {
     993///   if ( typeDecl->get_base() ) {
    1091994///     init = new SimpleInit( new SizeofExpr( handleDecl( typeDecl, typeDecl->get_base() ) ), designators );
    1092995///   }
    1093996///   return new ObjectDecl( typeDecl->get_name(), Declaration::Extern, LinkageSpec::C, 0, new BasicType( Type::Qualifiers(), BasicType::UnsignedInt ), init );
    1094997
    1095   scopeTyVars[ typeDecl->get_name() ] = typeDecl->get_kind();
    1096   return Mutator::mutate( typeDecl );
    1097 }
    1098 
    1099 Type*
    1100 Pass3::mutate( PointerType *pointerType )
    1101 {
    1102   TyVarMap oldtyVars = scopeTyVars;
    1103   makeTyVarMap( pointerType, scopeTyVars );
    1104  
    1105   Type* ret = Mutator::mutate( pointerType );
    1106  
    1107   scopeTyVars = oldtyVars;
    1108   return ret;
    1109 }
    1110 
    1111 Type*
    1112 Pass3::mutate( FunctionType *functionType )
    1113 {
    1114   TyVarMap oldtyVars = scopeTyVars;
    1115   makeTyVarMap( functionType, scopeTyVars );
    1116  
    1117   Type* ret = Mutator::mutate( functionType );
    1118  
    1119   scopeTyVars = oldtyVars;
    1120   return ret;
    1121 }
    1122 
    1123 Statement*
    1124 Pass3::mutate( DeclStmt *declStmt )
    1125 {
    1126   if( ObjectDecl *objectDecl = dynamic_cast< ObjectDecl* >( declStmt->get_decl() ) ) {
    1127     if( isPolyVal( objectDecl->get_type(), scopeTyVars ) ) {
    1128       TypeInstType *typeInst = dynamic_cast< TypeInstType* >( objectDecl->get_type() );
    1129       assert( typeInst );
    1130       UntypedExpr *alloc = new UntypedExpr( new NameExpr( "alloca" ) );
    1131       alloc->get_args().push_back( new NameExpr( typeInst->get_name() ) );
    1132       UntypedExpr *assign = new UntypedExpr( new NameExpr( "?=?" ) );
    1133       assign->get_args().push_back( new VariableExpr( objectDecl ) );
    1134       assign->get_args().push_back( alloc );
    1135       stmtsToAddAfter.push_back( new ExprStmt( noLabels, assign ) );
    1136     }
    1137   }
    1138   return Mutator::mutate( declStmt );
    1139 }
     998            scopeTyVars[ typeDecl->get_name() ] = typeDecl->get_kind();
     999            return Mutator::mutate( typeDecl );
     1000        }
     1001
     1002        Type *
     1003        Pass3::mutate( PointerType *pointerType ) {
     1004            TyVarMap oldtyVars = scopeTyVars;
     1005            makeTyVarMap( pointerType, scopeTyVars );
     1006 
     1007            Type *ret = Mutator::mutate( pointerType );
     1008 
     1009            scopeTyVars = oldtyVars;
     1010            return ret;
     1011        }
     1012
     1013        Type *
     1014        Pass3::mutate( FunctionType *functionType ) {
     1015            TyVarMap oldtyVars = scopeTyVars;
     1016            makeTyVarMap( functionType, scopeTyVars );
     1017 
     1018            Type *ret = Mutator::mutate( functionType );
     1019 
     1020            scopeTyVars = oldtyVars;
     1021            return ret;
     1022        }
     1023
     1024        Statement *Pass3::mutate( DeclStmt *declStmt ) {
     1025            if ( ObjectDecl *objectDecl = dynamic_cast< ObjectDecl *>( declStmt->get_decl() ) ) {
     1026                if ( isPolyVal( objectDecl->get_type(), scopeTyVars ) ) {
     1027                    TypeInstType *typeInst = dynamic_cast< TypeInstType *>( objectDecl->get_type() );
     1028                    assert( typeInst );
     1029                    UntypedExpr *alloc = new UntypedExpr( new NameExpr( "alloca" ) );
     1030                    alloc->get_args().push_back( new NameExpr( typeInst->get_name() ) );
     1031                    UntypedExpr *assign = new UntypedExpr( new NameExpr( "?=?" ) );
     1032                    assign->get_args().push_back( new VariableExpr( objectDecl ) );
     1033                    assign->get_args().push_back( alloc );
     1034                    stmtsToAddAfter.push_back( new ExprStmt( noLabels, assign ) );
     1035                }
     1036            }
     1037            return Mutator::mutate( declStmt );
     1038        }
    11401039   
    1141 } // anonymous namespace
     1040    } // anonymous namespace
    11421041
    11431042} // namespace GenPoly
Note: See TracChangeset for help on using the changeset viewer.