source: translator/GenPoly/Box.cc@ 51587aa

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 51587aa was 51587aa, checked in by Peter A. Buhr <pabuhr@…>, 11 years ago

licencing: fourth groups of files

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