source: src/GenPoly/Box.cc@ cf16f94

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 string with_gc
Last change on this file since cf16f94 was cf16f94, checked in by Peter A. Buhr <pabuhr@…>, 10 years ago

create temporary return variable for return expressions, remove unnecessary code after temporary-return-variable change, fix missing lvalue qualifiers, change stream operator to |

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