source: src/GenPoly/Box.cc@ 9cb8e88d

ADT aaron-thesis arm-eh ast-experimental cleanup-dtors ctor deferred_resn demangler enum forall-pointer-decay gc_noraii jacob/cs343-translation jenkins-sandbox memory new-ast new-ast-unique-expr new-env no_list persistent-indexer pthread-emulation qualifiedEnum resolv-new with_gc
Last change on this file since 9cb8e88d was f2b2029, checked in by Rob Schluntz <rschlunt@…>, 10 years ago

documentation in Box.cc

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