source: translator/GenPoly/Box.cc @ 51b7345

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 51b7345 was 51b7345, checked in by Peter A. Buhr <pabuhr@…>, 10 years ago

initial commit

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