source: src/GenPoly/Box.cc@ cdec5af

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 cdec5af was cdec5af, checked in by Aaron Moss <a3moss@…>, 10 years ago

Added LayoutStructDecls to box pass

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