source: src/GenPoly/Box.cc@ 5189888

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

allow nested routines to use type variables in containing scope, fix missing adapters, generalized iostream write

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