source: translator/GenPoly/Box.cc @ bdd516a

aaron-thesisarm-ehcleanup-dtorsctordeferred_resndemanglerenumforall-pointer-decaygc_noraiijacob/cs343-translationjenkins-sandboxmemorynew-astnew-ast-unique-exprnew-envno_listpersistent-indexerpthread-emulationqualifiedEnumresolv-newstringwith_gc
Last change on this file since bdd516a was bdd516a, checked in by Peter A. Buhr <pabuhr@…>, 8 years ago

fixed sizeof type variable, find lowest cost alternative for sizeof expression, removed unused classes, added compiler flag, remove temporary file for -CFA, formatting

  • Property mode set to 100644
File size: 43.1 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 <string>
10#include <iterator>
11#include <algorithm>
12#include <cassert>
13
14#include "Box.h"
15#include "PolyMutator.h"
16#include "FindFunction.h"
17#include "ScrubTyVars.h"
18
19#include "SynTree/Declaration.h"
20#include "SynTree/Type.h"
21#include "SynTree/Expression.h"
22#include "SynTree/Initializer.h"
23#include "SynTree/Statement.h"
24#include "SynTree/Mutator.h"
25#include "ResolvExpr/TypeEnvironment.h"
26#include "SymTab/Mangler.h"
27
28#include "SemanticError.h"
29#include "UniqueName.h"
30#include "utility.h"
31
32#include <ext/functional> // temporary
33
34namespace GenPoly {
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
114    }
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    }
124
125////////////////////////////////////////// Pass1 ////////////////////////////////////////////////////
126
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() ) ) {
132   
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;
194   
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
206   
207                scopeTyVars.clear();
208///     std::cerr << "clear\n";
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;
214///     std::cerr << "end FunctionDecl: ";
215///     for ( TyVarMap::iterator i = scopeTyVars.begin(); i != scopeTyVars.end(); ++i ) {
216///       std::cerr << i->first << " ";
217///     }
218///     std::cerr << "\n";
219                retval = oldRetval;
220                useRetval = oldUseRetval;
221                doEndScope();
222            } // if
223            return functionDecl;
224        }
225
226        TypeDecl *Pass1::mutate( TypeDecl *typeDecl ) {
227///     std::cerr << "add " << typeDecl->get_name() << "\n";
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++;
304///     stmtsToAdd.push_back( new ExprStmt( noLabels, appExpr ) );
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
352///   }
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 ) {
369///   std::cout << "function is ";
370///   function->print( std::cout );
371            for ( std::list< DeclarationWithType *>::const_iterator param = function->get_parameters().begin(); param != function->get_parameters().end(); ++param, ++arg ) {
372///     std::cout << "parameter is ";
373///     (*param)->print( std::cout );
374///     std::cout << std::endl << "argument is ";
375///     (*arg)->print( std::cout );
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 );
420///   std::cout << "arg type is ";
421///   arg->get_type()->print( std::cout );
422///   std::cout << "param type is ";
423///   param->get_type()->print( std::cout );
424///   std::cout << " tyVars are: ";
425///   printTyVarMap( std::cout, tyVars );
426            if ( isPolyVal( realParam->get_type(), tyVars ) ) {
427///     if ( dynamic_cast< PointerType *>( arg->get_type() ) ) {
428///       return new CastExpr( new VariableExpr( param ), arg->get_type()->clone() );
429///     } else {
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;
434///     }
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 ) {
703///     std::cerr << "mutate appExpr: ";
704///     for ( TyVarMap::iterator i = scopeTyVars.begin(); i != scopeTyVars.end(); ++i ) {
705///       std::cerr << i->first << " ";
706///     }
707///     std::cerr << "\n";
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 ) ) {
733///     std::cerr << "needs adapter: ";
734///     for ( TyVarMap::iterator i = scopeTyVars.begin(); i != scopeTyVars.end(); ++i ) {
735///       std::cerr << i->first << " ";
736///     }
737///     std::cerr << "\n";
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            addrExpr->set_arg( 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() ) {
800///       retStmt->set_expr( mutateExpression( retStmt->get_expr() ) );
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        }
850
851////////////////////////////////////////// Pass2 ////////////////////////////////////////////////////
852
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            }
871///  deleteAll( functions );
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 );
933///   ObjectDecl *newFunPtr = new ObjectDecl( "", Declaration::NoStorageClass, LinkageSpec::Cforall, 0, new PointerType( Type::Qualifiers(), new FunctionType( Type::Qualifiers(), true ) ), 0 );
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        }
957
958////////////////////////////////////////// Pass3 ////////////////////////////////////////////////////
959
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 ) {
990///   Initializer *init = 0;
991///   std::list< Expression *> designators;
992///   scopeTyVars[ typeDecl->get_name() ] = typeDecl->get_kind();
993///   if ( typeDecl->get_base() ) {
994///     init = new SimpleInit( new SizeofExpr( handleDecl( typeDecl, typeDecl->get_base() ) ), designators );
995///   }
996///   return new ObjectDecl( typeDecl->get_name(), Declaration::Extern, LinkageSpec::C, 0, new BasicType( Type::Qualifiers(), BasicType::UnsignedInt ), init );
997
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        }
1039   
1040    } // anonymous namespace
1041
1042} // namespace GenPoly
Note: See TracBrowser for help on using the repository browser.