source: translator/GenPoly/Box.cc @ 0dd3a2f

ADTaaron-thesisarm-ehast-experimentalcleanup-dtorsctordeferred_resndemanglerenumforall-pointer-decaygc_noraiijacob/cs343-translationjenkins-sandboxmemorynew-astnew-ast-unique-exprnew-envno_listpersistent-indexerpthread-emulationqualifiedEnumresolv-newstringwith_gc
Last change on this file since 0dd3a2f was a32b204, checked in by Peter A. Buhr <pabuhr@…>, 9 years ago

licencing: second groups of files

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