source: translator/GenPoly/Box.cc@ c8ffe20b

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

initial commit

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