source: src/GenPoly/Box.cc@ db4ecc5

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 with_gc
Last change on this file since db4ecc5 was a5a71d0, checked in by Rob Schluntz <rschlunt@…>, 10 years ago

Merge branch 'fix-memory-error' into ctor

Conflicts:

src/CodeGen/CodeGenerator.cc
src/Makefile.in
src/Parser/DeclarationNode.cc
src/Parser/ParseNode.h
src/Parser/TypeData.cc
src/Parser/parser.cc
src/Parser/parser.yy
src/ResolvExpr/Resolver.cc
src/SymTab/Validate.cc
src/SynTree/Declaration.h
src/SynTree/Mutator.cc
src/SynTree/Mutator.h
src/SynTree/SynTree.h
src/SynTree/Visitor.cc
src/SynTree/Visitor.h
src/libcfa/prelude.cf

  • Property mode set to 100644
File size: 94.0 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 : Tue Feb 09 14:39:52 2016
13// Update Count : 295
14//
15
16#include <algorithm>
17#include <iterator>
18#include <list>
19#include <map>
20#include <set>
21#include <stack>
22#include <string>
23#include <utility>
24#include <vector>
25#include <cassert>
26
27#include "Box.h"
28#include "DeclMutator.h"
29#include "PolyMutator.h"
30#include "FindFunction.h"
31#include "ScopedMap.h"
32#include "ScrubTyVars.h"
33
34#include "Parser/ParseNode.h"
35
36#include "SynTree/Constant.h"
37#include "SynTree/Declaration.h"
38#include "SynTree/Expression.h"
39#include "SynTree/Initializer.h"
40#include "SynTree/Mutator.h"
41#include "SynTree/Statement.h"
42#include "SynTree/Type.h"
43#include "SynTree/TypeSubstitution.h"
44
45#include "ResolvExpr/TypeEnvironment.h"
46#include "ResolvExpr/TypeMap.h"
47#include "ResolvExpr/typeops.h"
48
49#include "SymTab/Indexer.h"
50#include "SymTab/Mangler.h"
51
52#include "Common/SemanticError.h"
53#include "Common/UniqueName.h"
54#include "Common/utility.h"
55
56#include <ext/functional> // temporary
57
58namespace GenPoly {
59 namespace {
60 const std::list<Label> noLabels;
61
62 FunctionType *makeAdapterType( FunctionType *adaptee, const TyVarMap &tyVars );
63
64 /// Key for a unique concrete type; generic base type paired with type parameter list
65 struct ConcreteType {
66 ConcreteType() : base(NULL), params() {}
67
68 ConcreteType(AggregateDecl *_base, const std::list< Type* >& _params) : base(_base), params() { cloneAll(_params, params); }
69
70 ConcreteType(const ConcreteType& that) : base(that.base), params() { cloneAll(that.params, params); }
71
72 /// Extracts types from a list of TypeExpr*
73 ConcreteType(AggregateDecl *_base, const std::list< TypeExpr* >& _params) : base(_base), params() {
74 for ( std::list< TypeExpr* >::const_iterator param = _params.begin(); param != _params.end(); ++param ) {
75 params.push_back( (*param)->get_type()->clone() );
76 }
77 }
78
79 ConcreteType& operator= (const ConcreteType& that) {
80 deleteAll( params );
81 params.clear();
82
83 base = that.base;
84 cloneAll( that.params, params );
85
86 return *this;
87 }
88
89 ~ConcreteType() { deleteAll( params ); }
90
91 bool operator== (const ConcreteType& that) const {
92 if ( base != that.base ) return false;
93
94 SymTab::Indexer dummy;
95 if ( params.size() != that.params.size() ) return false;
96 for ( std::list< Type* >::const_iterator it = params.begin(), jt = that.params.begin(); it != params.end(); ++it, ++jt ) {
97 if ( ! ResolvExpr::typesCompatible( *it, *jt, dummy ) ) return false;
98 }
99 return true;
100 }
101
102 AggregateDecl *base; ///< Base generic type
103 std::list< Type* > params; ///< Instantiation parameters
104 };
105
106 /// Maps a concrete type to the some value, accounting for scope
107 template< typename Value >
108 class InstantiationMap {
109 /// Information about a specific instantiation of a generic type
110 struct Instantiation {
111 ConcreteType key; ///< Instantiation parameters for this type
112 Value *value; ///< Value for this instantiation
113
114 Instantiation() : key(), value(0) {}
115 Instantiation(const ConcreteType &_key, Value *_value) : key(_key), value(_value) {}
116 };
117 /// Map of generic types to instantiations of them
118 typedef std::map< AggregateDecl*, std::vector< Instantiation > > Scope;
119
120 std::vector< Scope > scopes; ///< list of scopes, from outermost to innermost
121
122 public:
123 /// Starts a new scope
124 void beginScope() {
125 Scope scope;
126 scopes.push_back(scope);
127 }
128
129 /// Ends a scope
130 void endScope() {
131 scopes.pop_back();
132 }
133
134 /// Default constructor initializes with one scope
135 InstantiationMap() { beginScope(); }
136
137// private:
138 /// Gets the value for the concrete instantiation of this type, assuming it has already been instantiated in the current scope.
139 /// Returns NULL on none such.
140 Value *lookup( AggregateDecl *generic, const std::list< TypeExpr* >& params ) {
141 ConcreteType key(generic, params);
142 // scan scopes from innermost out
143 for ( typename std::vector< Scope >::const_reverse_iterator scope = scopes.rbegin(); scope != scopes.rend(); ++scope ) {
144 // skip scope if no instantiations of this generic type
145 typename Scope::const_iterator insts = scope->find( generic );
146 if ( insts == scope->end() ) continue;
147 // look through instantiations for matches to concrete type
148 for ( typename std::vector< Instantiation >::const_iterator inst = insts->second.begin(); inst != insts->second.end(); ++inst ) {
149 if ( inst->key == key ) return inst->value;
150 }
151 }
152 // no matching instantiation found
153 return 0;
154 }
155 public:
156// StructDecl* lookup( StructInstType *inst, const std::list< TypeExpr* > &typeSubs ) { return (StructDecl*)lookup( inst->get_baseStruct(), typeSubs ); }
157// UnionDecl* lookup( UnionInstType *inst, const std::list< TypeExpr* > &typeSubs ) { return (UnionDecl*)lookup( inst->get_baseUnion(), typeSubs ); }
158
159// private:
160 /// Adds a value for a concrete type to the current scope
161 void insert( AggregateDecl *generic, const std::list< TypeExpr* > &params, Value *value ) {
162 ConcreteType key(generic, params);
163 scopes.back()[generic].push_back( Instantiation( key, value ) );
164 }
165// public:
166// void insert( StructInstType *inst, const std::list< TypeExpr* > &typeSubs, StructDecl *decl ) { insert( inst->get_baseStruct(), typeSubs, decl ); }
167// void insert( UnionInstType *inst, const std::list< TypeExpr* > &typeSubs, UnionDecl *decl ) { insert( inst->get_baseUnion(), typeSubs, decl ); }
168 };
169
170 /// Adds layout-generation functions to polymorphic types
171 class LayoutFunctionBuilder : public DeclMutator {
172 unsigned int functionNesting; // current level of nested functions
173 public:
174 LayoutFunctionBuilder() : functionNesting( 0 ) {}
175
176 virtual DeclarationWithType *mutate( FunctionDecl *functionDecl );
177 virtual Declaration *mutate( StructDecl *structDecl );
178 virtual Declaration *mutate( UnionDecl *unionDecl );
179 };
180
181 /// 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
182 class Pass1 : public PolyMutator {
183 public:
184 Pass1();
185 virtual Expression *mutate( ApplicationExpr *appExpr );
186 virtual Expression *mutate( AddressExpr *addrExpr );
187 virtual Expression *mutate( UntypedExpr *expr );
188 virtual DeclarationWithType* mutate( FunctionDecl *functionDecl );
189 virtual TypeDecl *mutate( TypeDecl *typeDecl );
190 virtual Expression *mutate( CommaExpr *commaExpr );
191 virtual Expression *mutate( ConditionalExpr *condExpr );
192 virtual Statement * mutate( ReturnStmt *returnStmt );
193 virtual Type *mutate( PointerType *pointerType );
194 virtual Type * mutate( FunctionType *functionType );
195
196 virtual void doBeginScope();
197 virtual void doEndScope();
198 private:
199 /// Makes a new temporary array holding the offsets of the fields of `type`, and returns a new variable expression referencing it
200 Expression *makeOffsetArray( StructInstType *type );
201 /// Pass the extra type parameters from polymorphic generic arguments or return types into a function application
202 void passArgTypeVars( ApplicationExpr *appExpr, Type *parmType, Type *argBaseType, std::list< Expression *>::iterator &arg, const TyVarMap &exprTyVars, std::set< std::string > &seenTypes );
203 /// passes extra type parameters into a polymorphic function application
204 void passTypeVars( ApplicationExpr *appExpr, ReferenceToType *polyRetType, std::list< Expression *>::iterator &arg, const TyVarMap &exprTyVars );
205 /// wraps a function application with a new temporary for the out-parameter return value
206 Expression *addRetParam( ApplicationExpr *appExpr, FunctionType *function, Type *retType, std::list< Expression *>::iterator &arg );
207 /// Replaces all the type parameters of a generic type with their concrete equivalents under the current environment
208 void replaceParametersWithConcrete( ApplicationExpr *appExpr, std::list< Expression* >& params );
209 /// Replaces a polymorphic type with its concrete equivalant under the current environment (returns itself if concrete).
210 /// If `doClone` is set to false, will not clone interior types
211 Type *replaceWithConcrete( ApplicationExpr *appExpr, Type *type, bool doClone = true );
212 /// wraps a function application returning a polymorphic type with a new temporary for the out-parameter return value
213 Expression *addPolyRetParam( ApplicationExpr *appExpr, FunctionType *function, ReferenceToType *polyType, std::list< Expression *>::iterator &arg );
214 Expression *applyAdapter( ApplicationExpr *appExpr, FunctionType *function, std::list< Expression *>::iterator &arg, const TyVarMap &exprTyVars );
215 void boxParam( Type *formal, Expression *&arg, const TyVarMap &exprTyVars );
216 void boxParams( ApplicationExpr *appExpr, FunctionType *function, std::list< Expression *>::iterator &arg, const TyVarMap &exprTyVars );
217 void addInferredParams( ApplicationExpr *appExpr, FunctionType *functionType, std::list< Expression *>::iterator &arg, const TyVarMap &tyVars );
218 /// Stores assignment operators from assertion list in local map of assignment operations
219 void findAssignOps( const std::list< TypeDecl *> &forall );
220 void passAdapters( ApplicationExpr *appExpr, FunctionType *functionType, const TyVarMap &exprTyVars );
221 FunctionDecl *makeAdapter( FunctionType *adaptee, FunctionType *realType, const std::string &mangleName, const TyVarMap &tyVars );
222 /// Replaces intrinsic operator functions with their arithmetic desugaring
223 Expression *handleIntrinsics( ApplicationExpr *appExpr );
224 /// Inserts a new temporary variable into the current scope with an auto-generated name
225 ObjectDecl *makeTemporary( Type *type );
226
227 std::map< std::string, DeclarationWithType *> assignOps;
228 ResolvExpr::TypeMap< DeclarationWithType > scopedAssignOps;
229 ScopedMap< std::string, DeclarationWithType* > adapters;
230 DeclarationWithType *retval;
231 bool useRetval;
232 UniqueName tempNamer;
233 };
234
235 /// Moves polymorphic returns in function types to pointer-type parameters, adds type size and assertion parameters to parameter lists as well
236 class Pass2 : public PolyMutator {
237 public:
238 template< typename DeclClass >
239 DeclClass *handleDecl( DeclClass *decl, Type *type );
240 virtual DeclarationWithType *mutate( FunctionDecl *functionDecl );
241 virtual ObjectDecl *mutate( ObjectDecl *objectDecl );
242 virtual TypeDecl *mutate( TypeDecl *typeDecl );
243 virtual TypedefDecl *mutate( TypedefDecl *typedefDecl );
244 virtual Type *mutate( PointerType *pointerType );
245 virtual Type *mutate( FunctionType *funcType );
246 private:
247 void addAdapters( FunctionType *functionType );
248
249 std::map< UniqueId, std::string > adapterName;
250 };
251
252 /// Mutator pass that replaces concrete instantiations of generic types with actual struct declarations, scoped appropriately
253 class GenericInstantiator : public DeclMutator {
254 /// Map of (generic type, parameter list) pairs to concrete type instantiations
255 InstantiationMap< AggregateDecl > instantiations;
256 /// Namer for concrete types
257 UniqueName typeNamer;
258
259 public:
260 GenericInstantiator() : DeclMutator(), instantiations(), typeNamer("_conc_") {}
261
262 virtual Type* mutate( StructInstType *inst );
263 virtual Type* mutate( UnionInstType *inst );
264
265 // virtual Expression* mutate( MemberExpr *memberExpr );
266
267 virtual void doBeginScope();
268 virtual void doEndScope();
269 private:
270 /// Wrap instantiation lookup for structs
271 StructDecl* lookup( StructInstType *inst, const std::list< TypeExpr* > &typeSubs ) { return (StructDecl*)instantiations.lookup( inst->get_baseStruct(), typeSubs ); }
272 /// Wrap instantiation lookup for unions
273 UnionDecl* lookup( UnionInstType *inst, const std::list< TypeExpr* > &typeSubs ) { return (UnionDecl*)instantiations.lookup( inst->get_baseUnion(), typeSubs ); }
274 /// Wrap instantiation insertion for structs
275 void insert( StructInstType *inst, const std::list< TypeExpr* > &typeSubs, StructDecl *decl ) { instantiations.insert( inst->get_baseStruct(), typeSubs, decl ); }
276 /// Wrap instantiation insertion for unions
277 void insert( UnionInstType *inst, const std::list< TypeExpr* > &typeSubs, UnionDecl *decl ) { instantiations.insert( inst->get_baseUnion(), typeSubs, decl ); }
278 };
279
280 /// Replaces member expressions for polymorphic types with calculated add-field-offset-and-dereference;
281 /// also fixes offsetof expressions.
282 class MemberExprFixer : public PolyMutator {
283 public:
284 template< typename DeclClass >
285 DeclClass *handleDecl( DeclClass *decl, Type *type );
286 virtual DeclarationWithType *mutate( FunctionDecl *functionDecl );
287 virtual ObjectDecl *mutate( ObjectDecl *objectDecl );
288 virtual TypedefDecl *mutate( TypedefDecl *objectDecl );
289 virtual TypeDecl *mutate( TypeDecl *objectDecl );
290 virtual Statement *mutate( DeclStmt *declStmt );
291 virtual Type *mutate( PointerType *pointerType );
292 virtual Type *mutate( FunctionType *funcType );
293 virtual Expression *mutate( MemberExpr *memberExpr );
294 virtual Expression *mutate( OffsetofExpr *offsetofExpr );
295 };
296
297 /// 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
298 class Pass3 : public PolyMutator {
299 public:
300 template< typename DeclClass >
301 DeclClass *handleDecl( DeclClass *decl, Type *type );
302 virtual DeclarationWithType *mutate( FunctionDecl *functionDecl );
303 virtual ObjectDecl *mutate( ObjectDecl *objectDecl );
304 virtual TypedefDecl *mutate( TypedefDecl *objectDecl );
305 virtual TypeDecl *mutate( TypeDecl *objectDecl );
306 virtual Type *mutate( PointerType *pointerType );
307 virtual Type *mutate( FunctionType *funcType );
308 private:
309 };
310
311 } // anonymous namespace
312
313 /// version of mutateAll with special handling for translation unit so you can check the end of the prelude when debugging
314 template< typename MutatorType >
315 inline void mutateTranslationUnit( std::list< Declaration* > &translationUnit, MutatorType &mutator ) {
316 bool seenIntrinsic = false;
317 SemanticError errors;
318 for ( typename std::list< Declaration* >::iterator i = translationUnit.begin(); i != translationUnit.end(); ++i ) {
319 try {
320 if ( *i ) {
321 if ( (*i)->get_linkage() == LinkageSpec::Intrinsic ) {
322 seenIntrinsic = true;
323 } else if ( seenIntrinsic ) {
324 seenIntrinsic = false; // break on this line when debugging for end of prelude
325 }
326
327 *i = dynamic_cast< Declaration* >( (*i)->acceptMutator( mutator ) );
328 assert( *i );
329 } // if
330 } catch( SemanticError &e ) {
331 errors.append( e );
332 } // try
333 } // for
334 if ( ! errors.isEmpty() ) {
335 throw errors;
336 } // if
337 }
338
339 void box( std::list< Declaration *>& translationUnit ) {
340 LayoutFunctionBuilder layoutBuilder;
341 Pass1 pass1;
342 Pass2 pass2;
343 GenericInstantiator instantiator;
344 MemberExprFixer memberFixer;
345 Pass3 pass3;
346
347 layoutBuilder.mutateDeclarationList( translationUnit );
348 mutateTranslationUnit/*All*/( translationUnit, pass1 );
349 mutateTranslationUnit/*All*/( translationUnit, pass2 );
350// instantiateGeneric( translationUnit );
351 instantiator.mutateDeclarationList( translationUnit );
352 mutateTranslationUnit/*All*/( translationUnit, memberFixer );
353 mutateTranslationUnit/*All*/( translationUnit, pass3 );
354 }
355
356 ////////////////////////////////// LayoutFunctionBuilder ////////////////////////////////////////////
357
358 DeclarationWithType *LayoutFunctionBuilder::mutate( FunctionDecl *functionDecl ) {
359 functionDecl->set_functionType( maybeMutate( functionDecl->get_functionType(), *this ) );
360 mutateAll( functionDecl->get_oldDecls(), *this );
361 ++functionNesting;
362 functionDecl->set_statements( maybeMutate( functionDecl->get_statements(), *this ) );
363 --functionNesting;
364 return functionDecl;
365 }
366
367 /// Get a list of type declarations that will affect a layout function
368 std::list< TypeDecl* > takeOtypeOnly( std::list< TypeDecl* > &decls ) {
369 std::list< TypeDecl * > otypeDecls;
370
371 for ( std::list< TypeDecl* >::const_iterator decl = decls.begin(); decl != decls.end(); ++decl ) {
372 if ( (*decl)->get_kind() == TypeDecl::Any ) {
373 otypeDecls.push_back( *decl );
374 }
375 }
376
377 return otypeDecls;
378 }
379
380 /// Adds parameters for otype layout to a function type
381 void addOtypeParams( FunctionType *layoutFnType, std::list< TypeDecl* > &otypeParams ) {
382 BasicType sizeAlignType( Type::Qualifiers(), BasicType::LongUnsignedInt );
383
384 for ( std::list< TypeDecl* >::const_iterator param = otypeParams.begin(); param != otypeParams.end(); ++param ) {
385 TypeInstType paramType( Type::Qualifiers(), (*param)->get_name(), *param );
386 layoutFnType->get_parameters().push_back( new ObjectDecl( sizeofName( &paramType ), DeclarationNode::NoStorageClass, LinkageSpec::Cforall, 0, sizeAlignType.clone(), 0 ) );
387 layoutFnType->get_parameters().push_back( new ObjectDecl( alignofName( &paramType ), DeclarationNode::NoStorageClass, LinkageSpec::Cforall, 0, sizeAlignType.clone(), 0 ) );
388 }
389 }
390
391 /// Builds a layout function declaration
392 FunctionDecl *buildLayoutFunctionDecl( const std::string &typeName, unsigned int functionNesting, FunctionType *layoutFnType ) {
393 // Routines at global scope marked "static" to prevent multiple definitions is separate translation units
394 // because each unit generates copies of the default routines for each aggregate.
395 FunctionDecl *layoutDecl = new FunctionDecl(
396 "__layoutof_" + typeName, functionNesting > 0 ? DeclarationNode::NoStorageClass : DeclarationNode::Static, LinkageSpec::AutoGen, layoutFnType, new CompoundStmt( noLabels ), true, false );
397 layoutDecl->fixUniqueId();
398 return layoutDecl;
399 }
400
401 /// Makes a unary operation
402 Expression *makeOp( const std::string &name, Expression *arg ) {
403 UntypedExpr *expr = new UntypedExpr( new NameExpr( name ) );
404 expr->get_args().push_back( arg );
405 return expr;
406 }
407
408 /// Makes a binary operation
409 Expression *makeOp( const std::string &name, Expression *lhs, Expression *rhs ) {
410 UntypedExpr *expr = new UntypedExpr( new NameExpr( name ) );
411 expr->get_args().push_back( lhs );
412 expr->get_args().push_back( rhs );
413 return expr;
414 }
415
416 /// Returns the dereference of a local pointer variable
417 Expression *derefVar( ObjectDecl *var ) {
418 return makeOp( "*?", new VariableExpr( var ) );
419 }
420
421 /// makes an if-statement with a single-expression if-block and no then block
422 Statement *makeCond( Expression *cond, Expression *ifPart ) {
423 return new IfStmt( noLabels, cond, new ExprStmt( noLabels, ifPart ), 0 );
424 }
425
426 /// makes a statement that assigns rhs to lhs if lhs < rhs
427 Statement *makeAssignMax( Expression *lhs, Expression *rhs ) {
428 return makeCond( makeOp( "?<?", lhs, rhs ), makeOp( "?=?", lhs->clone(), rhs->clone() ) );
429 }
430
431 /// makes a statement that aligns lhs to rhs (rhs should be an integer power of two)
432 Statement *makeAlignTo( Expression *lhs, Expression *rhs ) {
433 // check that the lhs is zeroed out to the level of rhs
434 Expression *ifCond = makeOp( "?&?", lhs, makeOp( "?-?", rhs, new ConstantExpr( Constant( new BasicType( Type::Qualifiers(), BasicType::LongUnsignedInt ), "1" ) ) ) );
435 // if not aligned, increment to alignment
436 Expression *ifExpr = makeOp( "?+=?", lhs->clone(), makeOp( "?-?", rhs->clone(), ifCond->clone() ) );
437 return makeCond( ifCond, ifExpr );
438 }
439
440 /// adds an expression to a compound statement
441 void addExpr( CompoundStmt *stmts, Expression *expr ) {
442 stmts->get_kids().push_back( new ExprStmt( noLabels, expr ) );
443 }
444
445 /// adds a statement to a compound statement
446 void addStmt( CompoundStmt *stmts, Statement *stmt ) {
447 stmts->get_kids().push_back( stmt );
448 }
449
450 Declaration *LayoutFunctionBuilder::mutate( StructDecl *structDecl ) {
451 // do not generate layout function for "empty" tag structs
452 if ( structDecl->get_members().empty() ) return structDecl;
453
454 // get parameters that can change layout, exiting early if none
455 std::list< TypeDecl* > otypeParams = takeOtypeOnly( structDecl->get_parameters() );
456 if ( otypeParams.empty() ) return structDecl;
457
458 // build layout function signature
459 FunctionType *layoutFnType = new FunctionType( Type::Qualifiers(), false );
460 BasicType *sizeAlignType = new BasicType( Type::Qualifiers(), BasicType::LongUnsignedInt );
461 PointerType *sizeAlignOutType = new PointerType( Type::Qualifiers(), sizeAlignType );
462
463 ObjectDecl *sizeParam = new ObjectDecl( "__sizeof_" + structDecl->get_name(), DeclarationNode::NoStorageClass, LinkageSpec::Cforall, 0, sizeAlignOutType, 0 );
464 layoutFnType->get_parameters().push_back( sizeParam );
465 ObjectDecl *alignParam = new ObjectDecl( "__alignof_" + structDecl->get_name(), DeclarationNode::NoStorageClass, LinkageSpec::Cforall, 0, sizeAlignOutType->clone(), 0 );
466 layoutFnType->get_parameters().push_back( alignParam );
467 ObjectDecl *offsetParam = new ObjectDecl( "__offsetof_" + structDecl->get_name(), DeclarationNode::NoStorageClass, LinkageSpec::Cforall, 0, sizeAlignOutType->clone(), 0 );
468 layoutFnType->get_parameters().push_back( offsetParam );
469 addOtypeParams( layoutFnType, otypeParams );
470
471 // build function decl
472 FunctionDecl *layoutDecl = buildLayoutFunctionDecl( structDecl->get_name(), functionNesting, layoutFnType );
473
474 // calculate struct layout in function body
475
476 // initialize size and alignment to 0 and 1 (will have at least one member to re-edit size
477 addExpr( layoutDecl->get_statements(), makeOp( "?=?", derefVar( sizeParam ), new ConstantExpr( Constant( sizeAlignType->clone(), "0" ) ) ) );
478 addExpr( layoutDecl->get_statements(), makeOp( "?=?", derefVar( alignParam ), new ConstantExpr( Constant( sizeAlignType->clone(), "1" ) ) ) );
479 unsigned long n_members = 0;
480 bool firstMember = true;
481 for ( std::list< Declaration* >::const_iterator member = structDecl->get_members().begin(); member != structDecl->get_members().end(); ++member ) {
482 DeclarationWithType *dwt = dynamic_cast< DeclarationWithType * >( *member );
483 assert( dwt );
484 Type *memberType = dwt->get_type();
485
486 if ( firstMember ) {
487 firstMember = false;
488 } else {
489 // make sure all members after the first (automatically aligned at 0) are properly padded for alignment
490 addStmt( layoutDecl->get_statements(), makeAlignTo( derefVar( sizeParam ), new AlignofExpr( memberType->clone() ) ) );
491 }
492
493 // place current size in the current offset index
494 addExpr( layoutDecl->get_statements(), makeOp( "?=?", makeOp( "?[?]", new VariableExpr( offsetParam ), new ConstantExpr( Constant::from( n_members ) ) ),
495 derefVar( sizeParam ) ) );
496 ++n_members;
497
498 // add member size to current size
499 addExpr( layoutDecl->get_statements(), makeOp( "?+=?", derefVar( sizeParam ), new SizeofExpr( memberType->clone() ) ) );
500
501 // take max of member alignment and global alignment
502 addStmt( layoutDecl->get_statements(), makeAssignMax( derefVar( alignParam ), new AlignofExpr( memberType->clone() ) ) );
503 }
504 // make sure the type is end-padded to a multiple of its alignment
505 addStmt( layoutDecl->get_statements(), makeAlignTo( derefVar( sizeParam ), derefVar( alignParam ) ) );
506
507 addDeclarationAfter( layoutDecl );
508 return structDecl;
509 }
510
511 Declaration *LayoutFunctionBuilder::mutate( UnionDecl *unionDecl ) {
512 // do not generate layout function for "empty" tag unions
513 if ( unionDecl->get_members().empty() ) return unionDecl;
514
515 // get parameters that can change layout, exiting early if none
516 std::list< TypeDecl* > otypeParams = takeOtypeOnly( unionDecl->get_parameters() );
517 if ( otypeParams.empty() ) return unionDecl;
518
519 // build layout function signature
520 FunctionType *layoutFnType = new FunctionType( Type::Qualifiers(), false );
521 BasicType *sizeAlignType = new BasicType( Type::Qualifiers(), BasicType::LongUnsignedInt );
522 PointerType *sizeAlignOutType = new PointerType( Type::Qualifiers(), sizeAlignType );
523
524 ObjectDecl *sizeParam = new ObjectDecl( "__sizeof_" + unionDecl->get_name(), DeclarationNode::NoStorageClass, LinkageSpec::Cforall, 0, sizeAlignOutType, 0 );
525 layoutFnType->get_parameters().push_back( sizeParam );
526 ObjectDecl *alignParam = new ObjectDecl( "__alignof_" + unionDecl->get_name(), DeclarationNode::NoStorageClass, LinkageSpec::Cforall, 0, sizeAlignOutType->clone(), 0 );
527 layoutFnType->get_parameters().push_back( alignParam );
528 addOtypeParams( layoutFnType, otypeParams );
529
530 // build function decl
531 FunctionDecl *layoutDecl = buildLayoutFunctionDecl( unionDecl->get_name(), functionNesting, layoutFnType );
532
533 // calculate union layout in function body
534 addExpr( layoutDecl->get_statements(), makeOp( "?=?", derefVar( sizeParam ), new ConstantExpr( Constant( sizeAlignType->clone(), "1" ) ) ) );
535 addExpr( layoutDecl->get_statements(), makeOp( "?=?", derefVar( alignParam ), new ConstantExpr( Constant( sizeAlignType->clone(), "1" ) ) ) );
536 for ( std::list< Declaration* >::const_iterator member = unionDecl->get_members().begin(); member != unionDecl->get_members().end(); ++member ) {
537 DeclarationWithType *dwt = dynamic_cast< DeclarationWithType * >( *member );
538 assert( dwt );
539 Type *memberType = dwt->get_type();
540
541 // take max member size and global size
542 addStmt( layoutDecl->get_statements(), makeAssignMax( derefVar( sizeParam ), new SizeofExpr( memberType->clone() ) ) );
543
544 // take max of member alignment and global alignment
545 addStmt( layoutDecl->get_statements(), makeAssignMax( derefVar( alignParam ), new AlignofExpr( memberType->clone() ) ) );
546 }
547 // make sure the type is end-padded to a multiple of its alignment
548 addStmt( layoutDecl->get_statements(), makeAlignTo( derefVar( sizeParam ), derefVar( alignParam ) ) );
549
550 addDeclarationAfter( layoutDecl );
551 return unionDecl;
552 }
553
554 ////////////////////////////////////////// Pass1 ////////////////////////////////////////////////////
555
556 namespace {
557 std::string makePolyMonoSuffix( FunctionType * function, const TyVarMap &tyVars ) {
558 std::stringstream name;
559
560 // NOTE: this function previously used isPolyObj, which failed to produce
561 // the correct thing in some situations. It's not clear to me why this wasn't working.
562
563 // if the return type or a parameter type involved polymorphic types, then the adapter will need
564 // to take those polymorphic types as pointers. Therefore, there can be two different functions
565 // with the same mangled name, so we need to further mangle the names.
566 for ( std::list< DeclarationWithType *>::iterator retval = function->get_returnVals().begin(); retval != function->get_returnVals().end(); ++retval ) {
567 if ( isPolyType( (*retval)->get_type(), tyVars ) ) {
568 name << "P";
569 } else {
570 name << "M";
571 }
572 }
573 name << "_";
574 std::list< DeclarationWithType *> &paramList = function->get_parameters();
575 for ( std::list< DeclarationWithType *>::iterator arg = paramList.begin(); arg != paramList.end(); ++arg ) {
576 if ( isPolyType( (*arg)->get_type(), tyVars ) ) {
577 name << "P";
578 } else {
579 name << "M";
580 }
581 } // for
582 return name.str();
583 }
584
585 std::string mangleAdapterName( FunctionType * function, const TyVarMap &tyVars ) {
586 return SymTab::Mangler::mangle( function ) + makePolyMonoSuffix( function, tyVars );
587 }
588
589 std::string makeAdapterName( const std::string &mangleName ) {
590 return "_adapter" + mangleName;
591 }
592
593 Pass1::Pass1() : useRetval( false ), tempNamer( "_temp" ) {}
594
595 /// Returns T if the given declaration is (*?=?)(T *, T) for some TypeInstType T (return not checked, but maybe should be), NULL otherwise
596 TypeInstType *isTypeInstAssignment( DeclarationWithType *decl ) {
597 if ( decl->get_name() == "?=?" ) {
598 if ( FunctionType *funType = getFunctionType( decl->get_type() ) ) {
599 if ( funType->get_parameters().size() == 2 ) {
600 if ( PointerType *pointer = dynamic_cast< PointerType *>( funType->get_parameters().front()->get_type() ) ) {
601 if ( TypeInstType *refType = dynamic_cast< TypeInstType *>( pointer->get_base() ) ) {
602 if ( TypeInstType *refType2 = dynamic_cast< TypeInstType *>( funType->get_parameters().back()->get_type() ) ) {
603 if ( refType->get_name() == refType2->get_name() ) {
604 return refType;
605 } // if
606 } // if
607 } // if
608 } // if
609 } // if
610 } // if
611 } // if
612 return 0;
613 }
614
615 /// returns T if the given declaration is: (*?=?)(T *, T) for some type T (return not checked, but maybe should be), NULL otherwise
616 /// Only picks assignments where neither parameter is cv-qualified
617 Type *isAssignment( DeclarationWithType *decl ) {
618 if ( decl->get_name() == "?=?" ) {
619 if ( FunctionType *funType = getFunctionType( decl->get_type() ) ) {
620 if ( funType->get_parameters().size() == 2 ) {
621 Type::Qualifiers defaultQualifiers;
622 Type *paramType1 = funType->get_parameters().front()->get_type();
623 if ( paramType1->get_qualifiers() != defaultQualifiers ) return 0;
624 Type *paramType2 = funType->get_parameters().back()->get_type();
625 if ( paramType2->get_qualifiers() != defaultQualifiers ) return 0;
626
627 if ( PointerType *pointerType = dynamic_cast< PointerType* >( paramType1 ) ) {
628 Type *baseType1 = pointerType->get_base();
629 if ( baseType1->get_qualifiers() != defaultQualifiers ) return 0;
630 SymTab::Indexer dummy;
631 if ( ResolvExpr::typesCompatible( baseType1, paramType2, dummy ) ) {
632 return baseType1;
633 } // if
634 } // if
635 } // if
636 } // if
637 } // if
638 return 0;
639 }
640
641 void Pass1::findAssignOps( const std::list< TypeDecl *> &forall ) {
642 // what if a nested function uses an assignment operator?
643 // assignOps.clear();
644 for ( std::list< TypeDecl *>::const_iterator i = forall.begin(); i != forall.end(); ++i ) {
645 for ( std::list< DeclarationWithType *>::const_iterator assert = (*i)->get_assertions().begin(); assert != (*i)->get_assertions().end(); ++assert ) {
646 std::string typeName;
647 if ( TypeInstType *typeInst = isTypeInstAssignment( *assert ) ) {
648 assignOps[ typeInst->get_name() ] = *assert;
649 } // if
650 } // for
651 } // for
652 }
653
654 DeclarationWithType *Pass1::mutate( FunctionDecl *functionDecl ) {
655 // if this is a polymorphic assignment function, put it in the map for this scope
656 if ( Type *assignedType = isAssignment( functionDecl ) ) {
657 if ( ! dynamic_cast< TypeInstType* >( assignedType ) ) {
658 scopedAssignOps.insert( assignedType, functionDecl );
659 }
660 }
661
662 if ( functionDecl->get_statements() ) { // empty routine body ?
663 doBeginScope();
664 TyVarMap oldtyVars = scopeTyVars;
665 std::map< std::string, DeclarationWithType *> oldassignOps = assignOps;
666 DeclarationWithType *oldRetval = retval;
667 bool oldUseRetval = useRetval;
668
669 // process polymorphic return value
670 retval = 0;
671 if ( isPolyRet( functionDecl->get_functionType() ) && functionDecl->get_linkage() == LinkageSpec::Cforall ) {
672 retval = functionDecl->get_functionType()->get_returnVals().front();
673
674 // give names to unnamed return values
675 if ( retval->get_name() == "" ) {
676 retval->set_name( "_retparm" );
677 retval->set_linkage( LinkageSpec::C );
678 } // if
679 } // if
680
681 FunctionType *functionType = functionDecl->get_functionType();
682 makeTyVarMap( functionDecl->get_functionType(), scopeTyVars );
683 findAssignOps( functionDecl->get_functionType()->get_forall() );
684
685 std::list< DeclarationWithType *> &paramList = functionType->get_parameters();
686 std::list< FunctionType *> functions;
687 for ( std::list< TypeDecl *>::iterator tyVar = functionType->get_forall().begin(); tyVar != functionType->get_forall().end(); ++tyVar ) {
688 for ( std::list< DeclarationWithType *>::iterator assert = (*tyVar)->get_assertions().begin(); assert != (*tyVar)->get_assertions().end(); ++assert ) {
689 findFunction( (*assert)->get_type(), functions, scopeTyVars, needsAdapter );
690 } // for
691 } // for
692 for ( std::list< DeclarationWithType *>::iterator arg = paramList.begin(); arg != paramList.end(); ++arg ) {
693 findFunction( (*arg)->get_type(), functions, scopeTyVars, needsAdapter );
694 } // for
695
696 for ( std::list< FunctionType *>::iterator funType = functions.begin(); funType != functions.end(); ++funType ) {
697 std::string mangleName = mangleAdapterName( *funType, scopeTyVars );
698 if ( adapters.find( mangleName ) == adapters.end() ) {
699 std::string adapterName = makeAdapterName( mangleName );
700 adapters.insert( std::pair< std::string, DeclarationWithType *>( mangleName, new ObjectDecl( adapterName, DeclarationNode::NoStorageClass, LinkageSpec::C, 0, new PointerType( Type::Qualifiers(), makeAdapterType( *funType, scopeTyVars ) ), 0 ) ) );
701 } // if
702 } // for
703
704 functionDecl->set_statements( functionDecl->get_statements()->acceptMutator( *this ) );
705
706 scopeTyVars = oldtyVars;
707 assignOps = oldassignOps;
708 // std::cerr << "end FunctionDecl: ";
709 // for ( TyVarMap::iterator i = scopeTyVars.begin(); i != scopeTyVars.end(); ++i ) {
710 // std::cerr << i->first << " ";
711 // }
712 // std::cerr << "\n";
713 retval = oldRetval;
714 useRetval = oldUseRetval;
715 doEndScope();
716 } // if
717 return functionDecl;
718 }
719
720 TypeDecl *Pass1::mutate( TypeDecl *typeDecl ) {
721 scopeTyVars[ typeDecl->get_name() ] = typeDecl->get_kind();
722 return Mutator::mutate( typeDecl );
723 }
724
725 Expression *Pass1::mutate( CommaExpr *commaExpr ) {
726 bool oldUseRetval = useRetval;
727 useRetval = false;
728 commaExpr->set_arg1( maybeMutate( commaExpr->get_arg1(), *this ) );
729 useRetval = oldUseRetval;
730 commaExpr->set_arg2( maybeMutate( commaExpr->get_arg2(), *this ) );
731 return commaExpr;
732 }
733
734 Expression *Pass1::mutate( ConditionalExpr *condExpr ) {
735 bool oldUseRetval = useRetval;
736 useRetval = false;
737 condExpr->set_arg1( maybeMutate( condExpr->get_arg1(), *this ) );
738 useRetval = oldUseRetval;
739 condExpr->set_arg2( maybeMutate( condExpr->get_arg2(), *this ) );
740 condExpr->set_arg3( maybeMutate( condExpr->get_arg3(), *this ) );
741 return condExpr;
742
743 }
744
745 Expression *Pass1::makeOffsetArray( StructInstType *ty ) {
746 std::list<Expression*> noDesignators;
747 std::list< Declaration* > &baseMembers = ty->get_baseStruct()->get_members();
748
749 // make a new temporary array
750 Type *offsetType = new BasicType( Type::Qualifiers(), BasicType::LongUnsignedInt );
751 std::stringstream lenGen;
752 lenGen << baseMembers.size();
753 ConstantExpr *lenExpr = new ConstantExpr( Constant( offsetType->clone(), lenGen.str() ) );
754 ObjectDecl *arrayTemp = makeTemporary( new ArrayType( Type::Qualifiers(), offsetType, lenExpr, false, false ) );
755
756 // build initializer list for temporary
757 std::list< Initializer* > inits;
758 for ( std::list< Declaration* >::const_iterator member = baseMembers.begin(); member != baseMembers.end(); ++member ) {
759 DeclarationWithType *memberDecl;
760 if ( DeclarationWithType *origMember = dynamic_cast< DeclarationWithType* >( *member ) ) {
761 memberDecl = origMember->clone();
762 } else {
763 memberDecl = new ObjectDecl( (*member)->get_name(), DeclarationNode::NoStorageClass, LinkageSpec::Cforall, 0, offsetType->clone(), 0 );
764 }
765 inits.push_back( new SingleInit( new OffsetofExpr( ty->clone(), memberDecl ), noDesignators ) );
766 }
767 arrayTemp->set_init( new ListInit( inits, noDesignators ) );
768
769 // return variable pointing to temporary
770 return new VariableExpr( arrayTemp );
771 }
772
773 void Pass1::passArgTypeVars( ApplicationExpr *appExpr, Type *parmType, Type *argBaseType, std::list< Expression *>::iterator &arg, const TyVarMap &exprTyVars, std::set< std::string > &seenTypes ) {
774 Type *polyBase = hasPolyBase( parmType, exprTyVars );
775 if ( polyBase && ! dynamic_cast< TypeInstType* >( polyBase ) ) {
776 std::string sizeName = sizeofName( polyBase );
777 if ( seenTypes.count( sizeName ) ) return;
778
779 arg = appExpr->get_args().insert( arg, new SizeofExpr( argBaseType->clone() ) );
780 arg++;
781 arg = appExpr->get_args().insert( arg, new AlignofExpr( argBaseType->clone() ) );
782 arg++;
783 if ( dynamic_cast< StructInstType* >( polyBase ) ) {
784 if ( StructInstType *argBaseStructType = dynamic_cast< StructInstType* >( argBaseType ) ) {
785 arg = appExpr->get_args().insert( arg, makeOffsetArray( argBaseStructType ) );
786 arg++;
787 } else {
788 throw SemanticError( "Cannot pass non-struct type for generic struct" );
789 }
790 }
791
792 seenTypes.insert( sizeName );
793 }
794 }
795
796 void Pass1::passTypeVars( ApplicationExpr *appExpr, ReferenceToType *polyRetType, std::list< Expression *>::iterator &arg, const TyVarMap &exprTyVars ) {
797 // pass size/align for type variables
798 for ( TyVarMap::const_iterator tyParm = exprTyVars.begin(); tyParm != exprTyVars.end(); ++tyParm ) {
799 ResolvExpr::EqvClass eqvClass;
800 assert( env );
801 if ( tyParm->second == TypeDecl::Any ) {
802 Type *concrete = env->lookup( tyParm->first );
803 if ( concrete ) {
804 arg = appExpr->get_args().insert( arg, new SizeofExpr( concrete->clone() ) );
805 arg++;
806 arg = appExpr->get_args().insert( arg, new AlignofExpr( concrete->clone() ) );
807 arg++;
808 } else {
809 throw SemanticError( "unbound type variable in application ", appExpr );
810 } // if
811 } // if
812 } // for
813
814 // add size/align for generic types to parameter list
815 if ( appExpr->get_function()->get_results().empty() ) return;
816 FunctionType *funcType = getFunctionType( appExpr->get_function()->get_results().front() );
817 assert( funcType );
818
819 std::list< DeclarationWithType* >::const_iterator fnParm = funcType->get_parameters().begin();
820 std::list< Expression* >::const_iterator fnArg = arg;
821 std::set< std::string > seenTypes; //< names for generic types we've seen
822
823 // a polymorphic return type may need to be added to the argument list
824 if ( polyRetType ) {
825 Type *concRetType = replaceWithConcrete( appExpr, polyRetType );
826 passArgTypeVars( appExpr, polyRetType, concRetType, arg, exprTyVars, seenTypes );
827 }
828
829 // add type information args for presently unseen types in parameter list
830 for ( ; fnParm != funcType->get_parameters().end() && fnArg != appExpr->get_args().end(); ++fnParm, ++fnArg ) {
831 VariableExpr *fnArgBase = getBaseVar( *fnArg );
832 if ( ! fnArgBase || fnArgBase->get_results().empty() ) continue;
833 passArgTypeVars( appExpr, (*fnParm)->get_type(), fnArgBase->get_results().front(), arg, exprTyVars, seenTypes );
834 }
835 }
836
837 ObjectDecl *Pass1::makeTemporary( Type *type ) {
838 ObjectDecl *newObj = new ObjectDecl( tempNamer.newName(), DeclarationNode::NoStorageClass, LinkageSpec::C, 0, type, 0 );
839 stmtsToAdd.push_back( new DeclStmt( noLabels, newObj ) );
840 return newObj;
841 }
842
843 Expression *Pass1::addRetParam( ApplicationExpr *appExpr, FunctionType *function, Type *retType, std::list< Expression *>::iterator &arg ) {
844 // ***** Code Removal ***** After introducing a temporary variable for all return expressions, the following code appears superfluous.
845 // if ( useRetval ) {
846 // assert( retval );
847 // arg = appExpr->get_args().insert( arg, new VariableExpr( retval ) );
848 // arg++;
849 // } else {
850
851 // Create temporary to hold return value of polymorphic function and produce that temporary as a result
852 // using a comma expression. Possibly change comma expression into statement expression "{}" for multiple
853 // return values.
854 ObjectDecl *newObj = makeTemporary( retType->clone() );
855 Expression *paramExpr = new VariableExpr( newObj );
856
857 // If the type of the temporary is not polymorphic, box temporary by taking its address;
858 // otherwise the temporary is already boxed and can be used directly.
859 if ( ! isPolyType( newObj->get_type(), scopeTyVars, env ) ) {
860 paramExpr = new AddressExpr( paramExpr );
861 } // if
862 arg = appExpr->get_args().insert( arg, paramExpr ); // add argument to function call
863 arg++;
864 // Build a comma expression to call the function and emulate a normal return.
865 CommaExpr *commaExpr = new CommaExpr( appExpr, new VariableExpr( newObj ) );
866 commaExpr->set_env( appExpr->get_env() );
867 appExpr->set_env( 0 );
868 return commaExpr;
869 // } // if
870 // return appExpr;
871 }
872
873 void Pass1::replaceParametersWithConcrete( ApplicationExpr *appExpr, std::list< Expression* >& params ) {
874 for ( std::list< Expression* >::iterator param = params.begin(); param != params.end(); ++param ) {
875 TypeExpr *paramType = dynamic_cast< TypeExpr* >( *param );
876 assert(paramType && "Aggregate parameters should be type expressions");
877 paramType->set_type( replaceWithConcrete( appExpr, paramType->get_type(), false ) );
878 }
879 }
880
881 Type *Pass1::replaceWithConcrete( ApplicationExpr *appExpr, Type *type, bool doClone ) {
882 if ( TypeInstType *typeInst = dynamic_cast< TypeInstType * >( type ) ) {
883 Type *concrete = env->lookup( typeInst->get_name() );
884 if ( concrete == 0 ) {
885 throw SemanticError( "Unbound type variable " + typeInst->get_name() + " in ", appExpr );
886 } // if
887 return concrete;
888 } else if ( StructInstType *structType = dynamic_cast< StructInstType* >( type ) ) {
889 if ( doClone ) {
890 structType = structType->clone();
891 }
892 replaceParametersWithConcrete( appExpr, structType->get_parameters() );
893 return structType;
894 } else if ( UnionInstType *unionType = dynamic_cast< UnionInstType* >( type ) ) {
895 if ( doClone ) {
896 unionType = unionType->clone();
897 }
898 replaceParametersWithConcrete( appExpr, unionType->get_parameters() );
899 return unionType;
900 }
901 return type;
902 }
903
904 Expression *Pass1::addPolyRetParam( ApplicationExpr *appExpr, FunctionType *function, ReferenceToType *polyType, std::list< Expression *>::iterator &arg ) {
905 assert( env );
906 Type *concrete = replaceWithConcrete( appExpr, polyType );
907 // add out-parameter for return value
908 return addRetParam( appExpr, function, concrete, arg );
909 }
910
911 Expression *Pass1::applyAdapter( ApplicationExpr *appExpr, FunctionType *function, std::list< Expression *>::iterator &arg, const TyVarMap &tyVars ) {
912 Expression *ret = appExpr;
913 if ( ! function->get_returnVals().empty() && isPolyType( function->get_returnVals().front()->get_type(), tyVars ) ) {
914 ret = addRetParam( appExpr, function, function->get_returnVals().front()->get_type(), arg );
915 } // if
916 std::string mangleName = mangleAdapterName( function, tyVars );
917 std::string adapterName = makeAdapterName( mangleName );
918
919 // cast adaptee to void (*)(), since it may have any type inside a polymorphic function
920 Type * adapteeType = new PointerType( Type::Qualifiers(), new FunctionType( Type::Qualifiers(), true ) );
921 appExpr->get_args().push_front( new CastExpr( appExpr->get_function(), adapteeType ) );
922 appExpr->set_function( new NameExpr( adapterName ) );
923
924 return ret;
925 }
926
927 void Pass1::boxParam( Type *param, Expression *&arg, const TyVarMap &exprTyVars ) {
928 assert( ! arg->get_results().empty() );
929 if ( isPolyType( param, exprTyVars ) ) {
930 if ( isPolyType( arg->get_results().front() ) ) {
931 // if the argument's type is polymorphic, we don't need to box again!
932 return;
933 } else if ( arg->get_results().front()->get_isLvalue() ) {
934 // VariableExpr and MemberExpr are lvalues
935 arg = new AddressExpr( arg );
936 } else {
937 // use type computed in unification to declare boxed variables
938 Type * newType = param->clone();
939 if ( env ) env->apply( newType );
940 ObjectDecl *newObj = new ObjectDecl( tempNamer.newName(), DeclarationNode::NoStorageClass, LinkageSpec::C, 0, newType, 0 );
941 newObj->get_type()->get_qualifiers() = Type::Qualifiers(); // TODO: is this right???
942 stmtsToAdd.push_back( new DeclStmt( noLabels, newObj ) );
943 UntypedExpr *assign = new UntypedExpr( new NameExpr( "?=?" ) );
944 assign->get_args().push_back( new VariableExpr( newObj ) );
945 assign->get_args().push_back( arg );
946 stmtsToAdd.push_back( new ExprStmt( noLabels, assign ) );
947 arg = new AddressExpr( new VariableExpr( newObj ) );
948 } // if
949 } // if
950 }
951
952 /// cast parameters to polymorphic functions so that types are replaced with
953 /// void * if they are type parameters in the formal type.
954 /// this gets rid of warnings from gcc.
955 void addCast( Expression *&actual, Type *formal, const TyVarMap &tyVars ) {
956 Type * newType = formal->clone();
957 if ( getFunctionType( newType ) ) {
958 newType = ScrubTyVars::scrub( newType, tyVars );
959 actual = new CastExpr( actual, newType );
960 } // if
961 }
962
963 void Pass1::boxParams( ApplicationExpr *appExpr, FunctionType *function, std::list< Expression *>::iterator &arg, const TyVarMap &exprTyVars ) {
964 for ( std::list< DeclarationWithType *>::const_iterator param = function->get_parameters().begin(); param != function->get_parameters().end(); ++param, ++arg ) {
965 assert( arg != appExpr->get_args().end() );
966 addCast( *arg, (*param)->get_type(), exprTyVars );
967 boxParam( (*param)->get_type(), *arg, exprTyVars );
968 } // for
969 }
970
971 void Pass1::addInferredParams( ApplicationExpr *appExpr, FunctionType *functionType, std::list< Expression *>::iterator &arg, const TyVarMap &tyVars ) {
972 std::list< Expression *>::iterator cur = arg;
973 for ( std::list< TypeDecl *>::iterator tyVar = functionType->get_forall().begin(); tyVar != functionType->get_forall().end(); ++tyVar ) {
974 for ( std::list< DeclarationWithType *>::iterator assert = (*tyVar)->get_assertions().begin(); assert != (*tyVar)->get_assertions().end(); ++assert ) {
975 InferredParams::const_iterator inferParam = appExpr->get_inferParams().find( (*assert)->get_uniqueId() );
976 assert( inferParam != appExpr->get_inferParams().end() && "NOTE: Explicit casts of polymorphic functions to compatible monomorphic functions are currently unsupported" );
977 Expression *newExpr = inferParam->second.expr->clone();
978 addCast( newExpr, (*assert)->get_type(), tyVars );
979 boxParam( (*assert)->get_type(), newExpr, tyVars );
980 appExpr->get_args().insert( cur, newExpr );
981 } // for
982 } // for
983 }
984
985 void makeRetParm( FunctionType *funcType ) {
986 DeclarationWithType *retParm = funcType->get_returnVals().front();
987
988 // make a new parameter that is a pointer to the type of the old return value
989 retParm->set_type( new PointerType( Type::Qualifiers(), retParm->get_type() ) );
990 funcType->get_parameters().push_front( retParm );
991
992 // we don't need the return value any more
993 funcType->get_returnVals().clear();
994 }
995
996 FunctionType *makeAdapterType( FunctionType *adaptee, const TyVarMap &tyVars ) {
997 // actually make the adapter type
998 FunctionType *adapter = adaptee->clone();
999 if ( ! adapter->get_returnVals().empty() && isPolyType( adapter->get_returnVals().front()->get_type(), tyVars ) ) {
1000 makeRetParm( adapter );
1001 } // if
1002 adapter->get_parameters().push_front( new ObjectDecl( "", DeclarationNode::NoStorageClass, LinkageSpec::C, 0, new PointerType( Type::Qualifiers(), new FunctionType( Type::Qualifiers(), true ) ), 0 ) );
1003 return adapter;
1004 }
1005
1006 Expression *makeAdapterArg( DeclarationWithType *param, DeclarationWithType *arg, DeclarationWithType *realParam, const TyVarMap &tyVars ) {
1007 assert( param );
1008 assert( arg );
1009 if ( isPolyType( realParam->get_type(), tyVars ) ) {
1010 if ( ! isPolyType( arg->get_type() ) ) {
1011 UntypedExpr *deref = new UntypedExpr( new NameExpr( "*?" ) );
1012 deref->get_args().push_back( new CastExpr( new VariableExpr( param ), new PointerType( Type::Qualifiers(), arg->get_type()->clone() ) ) );
1013 deref->get_results().push_back( arg->get_type()->clone() );
1014 return deref;
1015 } // if
1016 } // if
1017 return new VariableExpr( param );
1018 }
1019
1020 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 ) {
1021 UniqueName paramNamer( "_p" );
1022 for ( ; param != paramEnd; ++param, ++arg, ++realParam ) {
1023 if ( (*param)->get_name() == "" ) {
1024 (*param)->set_name( paramNamer.newName() );
1025 (*param)->set_linkage( LinkageSpec::C );
1026 } // if
1027 adapteeApp->get_args().push_back( makeAdapterArg( *param, *arg, *realParam, tyVars ) );
1028 } // for
1029 }
1030
1031
1032
1033 FunctionDecl *Pass1::makeAdapter( FunctionType *adaptee, FunctionType *realType, const std::string &mangleName, const TyVarMap &tyVars ) {
1034 FunctionType *adapterType = makeAdapterType( adaptee, tyVars );
1035 adapterType = ScrubTyVars::scrub( adapterType, tyVars );
1036 DeclarationWithType *adapteeDecl = adapterType->get_parameters().front();
1037 adapteeDecl->set_name( "_adaptee" );
1038 ApplicationExpr *adapteeApp = new ApplicationExpr( new CastExpr( new VariableExpr( adapteeDecl ), new PointerType( Type::Qualifiers(), realType ) ) );
1039 Statement *bodyStmt;
1040
1041 std::list< TypeDecl *>::iterator tyArg = realType->get_forall().begin();
1042 std::list< TypeDecl *>::iterator tyParam = adapterType->get_forall().begin();
1043 std::list< TypeDecl *>::iterator realTyParam = adaptee->get_forall().begin();
1044 for ( ; tyParam != adapterType->get_forall().end(); ++tyArg, ++tyParam, ++realTyParam ) {
1045 assert( tyArg != realType->get_forall().end() );
1046 std::list< DeclarationWithType *>::iterator assertArg = (*tyArg)->get_assertions().begin();
1047 std::list< DeclarationWithType *>::iterator assertParam = (*tyParam)->get_assertions().begin();
1048 std::list< DeclarationWithType *>::iterator realAssertParam = (*realTyParam)->get_assertions().begin();
1049 for ( ; assertParam != (*tyParam)->get_assertions().end(); ++assertArg, ++assertParam, ++realAssertParam ) {
1050 assert( assertArg != (*tyArg)->get_assertions().end() );
1051 adapteeApp->get_args().push_back( makeAdapterArg( *assertParam, *assertArg, *realAssertParam, tyVars ) );
1052 } // for
1053 } // for
1054
1055 std::list< DeclarationWithType *>::iterator arg = realType->get_parameters().begin();
1056 std::list< DeclarationWithType *>::iterator param = adapterType->get_parameters().begin();
1057 std::list< DeclarationWithType *>::iterator realParam = adaptee->get_parameters().begin();
1058 param++; // skip adaptee parameter
1059 if ( realType->get_returnVals().empty() ) {
1060 addAdapterParams( adapteeApp, arg, param, adapterType->get_parameters().end(), realParam, tyVars );
1061 bodyStmt = new ExprStmt( noLabels, adapteeApp );
1062 } else if ( isPolyType( adaptee->get_returnVals().front()->get_type(), tyVars ) ) {
1063 if ( (*param)->get_name() == "" ) {
1064 (*param)->set_name( "_ret" );
1065 (*param)->set_linkage( LinkageSpec::C );
1066 } // if
1067 UntypedExpr *assign = new UntypedExpr( new NameExpr( "?=?" ) );
1068 UntypedExpr *deref = new UntypedExpr( new NameExpr( "*?" ) );
1069 deref->get_args().push_back( new CastExpr( new VariableExpr( *param++ ), new PointerType( Type::Qualifiers(), realType->get_returnVals().front()->get_type()->clone() ) ) );
1070 assign->get_args().push_back( deref );
1071 addAdapterParams( adapteeApp, arg, param, adapterType->get_parameters().end(), realParam, tyVars );
1072 assign->get_args().push_back( adapteeApp );
1073 bodyStmt = new ExprStmt( noLabels, assign );
1074 } else {
1075 // adapter for a function that returns a monomorphic value
1076 addAdapterParams( adapteeApp, arg, param, adapterType->get_parameters().end(), realParam, tyVars );
1077 bodyStmt = new ReturnStmt( noLabels, adapteeApp );
1078 } // if
1079 CompoundStmt *adapterBody = new CompoundStmt( noLabels );
1080 adapterBody->get_kids().push_back( bodyStmt );
1081 std::string adapterName = makeAdapterName( mangleName );
1082 return new FunctionDecl( adapterName, DeclarationNode::NoStorageClass, LinkageSpec::C, adapterType, adapterBody, false, false );
1083 }
1084
1085 void Pass1::passAdapters( ApplicationExpr * appExpr, FunctionType * functionType, const TyVarMap & exprTyVars ) {
1086 // collect a list of function types passed as parameters or implicit parameters (assertions)
1087 std::list< DeclarationWithType *> &paramList = functionType->get_parameters();
1088 std::list< FunctionType *> functions;
1089 for ( std::list< TypeDecl *>::iterator tyVar = functionType->get_forall().begin(); tyVar != functionType->get_forall().end(); ++tyVar ) {
1090 for ( std::list< DeclarationWithType *>::iterator assert = (*tyVar)->get_assertions().begin(); assert != (*tyVar)->get_assertions().end(); ++assert ) {
1091 findFunction( (*assert)->get_type(), functions, exprTyVars, needsAdapter );
1092 } // for
1093 } // for
1094 for ( std::list< DeclarationWithType *>::iterator arg = paramList.begin(); arg != paramList.end(); ++arg ) {
1095 findFunction( (*arg)->get_type(), functions, exprTyVars, needsAdapter );
1096 } // for
1097
1098 // parameter function types for which an appropriate adapter has been generated. we cannot use the types
1099 // after applying substitutions, since two different parameter types may be unified to the same type
1100 std::set< std::string > adaptersDone;
1101
1102 for ( std::list< FunctionType *>::iterator funType = functions.begin(); funType != functions.end(); ++funType ) {
1103 FunctionType *originalFunction = (*funType)->clone();
1104 FunctionType *realFunction = (*funType)->clone();
1105 std::string mangleName = SymTab::Mangler::mangle( realFunction );
1106
1107 // only attempt to create an adapter or pass one as a parameter if we haven't already done so for this
1108 // pre-substitution parameter function type.
1109 if ( adaptersDone.find( mangleName ) == adaptersDone.end() ) {
1110 adaptersDone.insert( adaptersDone.begin(), mangleName );
1111
1112 // apply substitution to type variables to figure out what the adapter's type should look like
1113 assert( env );
1114 env->apply( realFunction );
1115 mangleName = SymTab::Mangler::mangle( realFunction );
1116 mangleName += makePolyMonoSuffix( originalFunction, exprTyVars );
1117
1118 typedef ScopedMap< std::string, DeclarationWithType* >::iterator AdapterIter;
1119 AdapterIter adapter = adapters.find( mangleName );
1120 if ( adapter == adapters.end() ) {
1121 // adapter has not been created yet in the current scope, so define it
1122 FunctionDecl *newAdapter = makeAdapter( *funType, realFunction, mangleName, exprTyVars );
1123 std::pair< AdapterIter, bool > answer = adapters.insert( std::pair< std::string, DeclarationWithType *>( mangleName, newAdapter ) );
1124 adapter = answer.first;
1125 stmtsToAdd.push_back( new DeclStmt( noLabels, newAdapter ) );
1126 } // if
1127 assert( adapter != adapters.end() );
1128
1129 // add the appropriate adapter as a parameter
1130 appExpr->get_args().push_front( new VariableExpr( adapter->second ) );
1131 } // if
1132 } // for
1133 } // passAdapters
1134
1135 Expression *makeIncrDecrExpr( ApplicationExpr *appExpr, Type *polyType, bool isIncr ) {
1136 NameExpr *opExpr;
1137 if ( isIncr ) {
1138 opExpr = new NameExpr( "?+=?" );
1139 } else {
1140 opExpr = new NameExpr( "?-=?" );
1141 } // if
1142 UntypedExpr *addAssign = new UntypedExpr( opExpr );
1143 if ( AddressExpr *address = dynamic_cast< AddressExpr *>( appExpr->get_args().front() ) ) {
1144 addAssign->get_args().push_back( address->get_arg() );
1145 } else {
1146 addAssign->get_args().push_back( appExpr->get_args().front() );
1147 } // if
1148 addAssign->get_args().push_back( new NameExpr( sizeofName( polyType ) ) );
1149 addAssign->get_results().front() = appExpr->get_results().front()->clone();
1150 if ( appExpr->get_env() ) {
1151 addAssign->set_env( appExpr->get_env() );
1152 appExpr->set_env( 0 );
1153 } // if
1154 appExpr->get_args().clear();
1155 delete appExpr;
1156 return addAssign;
1157 }
1158
1159 Expression *Pass1::handleIntrinsics( ApplicationExpr *appExpr ) {
1160 if ( VariableExpr *varExpr = dynamic_cast< VariableExpr *>( appExpr->get_function() ) ) {
1161 if ( varExpr->get_var()->get_linkage() == LinkageSpec::Intrinsic ) {
1162 if ( varExpr->get_var()->get_name() == "?[?]" ) {
1163 assert( ! appExpr->get_results().empty() );
1164 assert( appExpr->get_args().size() == 2 );
1165 Type *baseType1 = isPolyPtr( appExpr->get_args().front()->get_results().front(), scopeTyVars, env );
1166 Type *baseType2 = isPolyPtr( appExpr->get_args().back()->get_results().front(), scopeTyVars, env );
1167 assert( ! baseType1 || ! baseType2 ); // the arguments cannot both be polymorphic pointers
1168 UntypedExpr *ret = 0;
1169 if ( baseType1 || baseType2 ) { // one of the arguments is a polymorphic pointer
1170 ret = new UntypedExpr( new NameExpr( "?+?" ) );
1171 } // if
1172 if ( baseType1 ) {
1173 UntypedExpr *multiply = new UntypedExpr( new NameExpr( "?*?" ) );
1174 multiply->get_args().push_back( appExpr->get_args().back() );
1175 multiply->get_args().push_back( new NameExpr( sizeofName( baseType1 ) ) );
1176 ret->get_args().push_back( appExpr->get_args().front() );
1177 ret->get_args().push_back( multiply );
1178 } else if ( baseType2 ) {
1179 UntypedExpr *multiply = new UntypedExpr( new NameExpr( "?*?" ) );
1180 multiply->get_args().push_back( appExpr->get_args().front() );
1181 multiply->get_args().push_back( new NameExpr( sizeofName( baseType2 ) ) );
1182 ret->get_args().push_back( multiply );
1183 ret->get_args().push_back( appExpr->get_args().back() );
1184 } // if
1185 if ( baseType1 || baseType2 ) {
1186 ret->get_results().push_front( appExpr->get_results().front()->clone() );
1187 if ( appExpr->get_env() ) {
1188 ret->set_env( appExpr->get_env() );
1189 appExpr->set_env( 0 );
1190 } // if
1191 appExpr->get_args().clear();
1192 delete appExpr;
1193 return ret;
1194 } // if
1195 } else if ( varExpr->get_var()->get_name() == "*?" ) {
1196 assert( ! appExpr->get_results().empty() );
1197 assert( ! appExpr->get_args().empty() );
1198 if ( isPolyType( appExpr->get_results().front(), scopeTyVars, env ) ) {
1199 Expression *ret = appExpr->get_args().front();
1200 delete ret->get_results().front();
1201 ret->get_results().front() = appExpr->get_results().front()->clone();
1202 if ( appExpr->get_env() ) {
1203 ret->set_env( appExpr->get_env() );
1204 appExpr->set_env( 0 );
1205 } // if
1206 appExpr->get_args().clear();
1207 delete appExpr;
1208 return ret;
1209 } // if
1210 } else if ( varExpr->get_var()->get_name() == "?++" || varExpr->get_var()->get_name() == "?--" ) {
1211 assert( ! appExpr->get_results().empty() );
1212 assert( appExpr->get_args().size() == 1 );
1213 if ( Type *baseType = isPolyPtr( appExpr->get_results().front(), scopeTyVars, env ) ) {
1214 Type *tempType = appExpr->get_results().front()->clone();
1215 if ( env ) {
1216 env->apply( tempType );
1217 } // if
1218 ObjectDecl *newObj = makeTemporary( tempType );
1219 VariableExpr *tempExpr = new VariableExpr( newObj );
1220 UntypedExpr *assignExpr = new UntypedExpr( new NameExpr( "?=?" ) );
1221 assignExpr->get_args().push_back( tempExpr->clone() );
1222 if ( AddressExpr *address = dynamic_cast< AddressExpr *>( appExpr->get_args().front() ) ) {
1223 assignExpr->get_args().push_back( address->get_arg()->clone() );
1224 } else {
1225 assignExpr->get_args().push_back( appExpr->get_args().front()->clone() );
1226 } // if
1227 CommaExpr *firstComma = new CommaExpr( assignExpr, makeIncrDecrExpr( appExpr, baseType, varExpr->get_var()->get_name() == "?++" ) );
1228 return new CommaExpr( firstComma, tempExpr );
1229 } // if
1230 } else if ( varExpr->get_var()->get_name() == "++?" || varExpr->get_var()->get_name() == "--?" ) {
1231 assert( ! appExpr->get_results().empty() );
1232 assert( appExpr->get_args().size() == 1 );
1233 if ( Type *baseType = isPolyPtr( appExpr->get_results().front(), scopeTyVars, env ) ) {
1234 return makeIncrDecrExpr( appExpr, baseType, varExpr->get_var()->get_name() == "++?" );
1235 } // if
1236 } else if ( varExpr->get_var()->get_name() == "?+?" || varExpr->get_var()->get_name() == "?-?" ) {
1237 assert( ! appExpr->get_results().empty() );
1238 assert( appExpr->get_args().size() == 2 );
1239 Type *baseType1 = isPolyPtr( appExpr->get_args().front()->get_results().front(), scopeTyVars, env );
1240 Type *baseType2 = isPolyPtr( appExpr->get_args().back()->get_results().front(), scopeTyVars, env );
1241 if ( baseType1 && baseType2 ) {
1242 UntypedExpr *divide = new UntypedExpr( new NameExpr( "?/?" ) );
1243 divide->get_args().push_back( appExpr );
1244 divide->get_args().push_back( new NameExpr( sizeofName( baseType1 ) ) );
1245 divide->get_results().push_front( appExpr->get_results().front()->clone() );
1246 if ( appExpr->get_env() ) {
1247 divide->set_env( appExpr->get_env() );
1248 appExpr->set_env( 0 );
1249 } // if
1250 return divide;
1251 } else if ( baseType1 ) {
1252 UntypedExpr *multiply = new UntypedExpr( new NameExpr( "?*?" ) );
1253 multiply->get_args().push_back( appExpr->get_args().back() );
1254 multiply->get_args().push_back( new NameExpr( sizeofName( baseType1 ) ) );
1255 appExpr->get_args().back() = multiply;
1256 } else if ( baseType2 ) {
1257 UntypedExpr *multiply = new UntypedExpr( new NameExpr( "?*?" ) );
1258 multiply->get_args().push_back( appExpr->get_args().front() );
1259 multiply->get_args().push_back( new NameExpr( sizeofName( baseType2 ) ) );
1260 appExpr->get_args().front() = multiply;
1261 } // if
1262 } else if ( varExpr->get_var()->get_name() == "?+=?" || varExpr->get_var()->get_name() == "?-=?" ) {
1263 assert( ! appExpr->get_results().empty() );
1264 assert( appExpr->get_args().size() == 2 );
1265 Type *baseType = isPolyPtr( appExpr->get_results().front(), scopeTyVars, env );
1266 if ( baseType ) {
1267 UntypedExpr *multiply = new UntypedExpr( new NameExpr( "?*?" ) );
1268 multiply->get_args().push_back( appExpr->get_args().back() );
1269 multiply->get_args().push_back( new NameExpr( sizeofName( baseType ) ) );
1270 appExpr->get_args().back() = multiply;
1271 } // if
1272 } // if
1273 return appExpr;
1274 } // if
1275 } // if
1276 return 0;
1277 }
1278
1279 Expression *Pass1::mutate( ApplicationExpr *appExpr ) {
1280 // std::cerr << "mutate appExpr: ";
1281 // for ( TyVarMap::iterator i = scopeTyVars.begin(); i != scopeTyVars.end(); ++i ) {
1282 // std::cerr << i->first << " ";
1283 // }
1284 // std::cerr << "\n";
1285 bool oldUseRetval = useRetval;
1286 useRetval = false;
1287 appExpr->get_function()->acceptMutator( *this );
1288 mutateAll( appExpr->get_args(), *this );
1289 useRetval = oldUseRetval;
1290
1291 assert( ! appExpr->get_function()->get_results().empty() );
1292 PointerType *pointer = dynamic_cast< PointerType *>( appExpr->get_function()->get_results().front() );
1293 assert( pointer );
1294 FunctionType *function = dynamic_cast< FunctionType *>( pointer->get_base() );
1295 assert( function );
1296
1297 if ( Expression *newExpr = handleIntrinsics( appExpr ) ) {
1298 return newExpr;
1299 } // if
1300
1301 Expression *ret = appExpr;
1302
1303 std::list< Expression *>::iterator arg = appExpr->get_args().begin();
1304 std::list< Expression *>::iterator paramBegin = appExpr->get_args().begin();
1305
1306 TyVarMap exprTyVars;
1307 makeTyVarMap( function, exprTyVars );
1308 ReferenceToType *polyRetType = isPolyRet( function );
1309
1310 if ( polyRetType ) {
1311 ret = addPolyRetParam( appExpr, function, polyRetType, arg );
1312 } else if ( needsAdapter( function, scopeTyVars ) ) {
1313 // std::cerr << "needs adapter: ";
1314 // for ( TyVarMap::iterator i = scopeTyVars.begin(); i != scopeTyVars.end(); ++i ) {
1315 // std::cerr << i->first << " ";
1316 // }
1317 // std::cerr << "\n";
1318 // change the application so it calls the adapter rather than the passed function
1319 ret = applyAdapter( appExpr, function, arg, scopeTyVars );
1320 } // if
1321 arg = appExpr->get_args().begin();
1322
1323 passTypeVars( appExpr, polyRetType, arg, exprTyVars );
1324 addInferredParams( appExpr, function, arg, exprTyVars );
1325
1326 arg = paramBegin;
1327
1328 boxParams( appExpr, function, arg, exprTyVars );
1329
1330 passAdapters( appExpr, function, exprTyVars );
1331
1332 return ret;
1333 }
1334
1335 Expression *Pass1::mutate( UntypedExpr *expr ) {
1336 if ( ! expr->get_results().empty() && isPolyType( expr->get_results().front(), scopeTyVars, env ) ) {
1337 if ( NameExpr *name = dynamic_cast< NameExpr *>( expr->get_function() ) ) {
1338 if ( name->get_name() == "*?" ) {
1339 Expression *ret = expr->get_args().front();
1340 expr->get_args().clear();
1341 delete expr;
1342 return ret->acceptMutator( *this );
1343 } // if
1344 } // if
1345 } // if
1346 return PolyMutator::mutate( expr );
1347 }
1348
1349 Expression *Pass1::mutate( AddressExpr *addrExpr ) {
1350 assert( ! addrExpr->get_arg()->get_results().empty() );
1351
1352 bool needs = false;
1353 if ( UntypedExpr *expr = dynamic_cast< UntypedExpr *>( addrExpr->get_arg() ) ) {
1354 if ( ! expr->get_results().empty() && isPolyType( expr->get_results().front(), scopeTyVars, env ) ) {
1355 if ( NameExpr *name = dynamic_cast< NameExpr *>( expr->get_function() ) ) {
1356 if ( name->get_name() == "*?" ) {
1357 if ( ApplicationExpr * appExpr = dynamic_cast< ApplicationExpr * >( expr->get_args().front() ) ) {
1358 assert( ! appExpr->get_function()->get_results().empty() );
1359 PointerType *pointer = dynamic_cast< PointerType *>( appExpr->get_function()->get_results().front() );
1360 assert( pointer );
1361 FunctionType *function = dynamic_cast< FunctionType *>( pointer->get_base() );
1362 assert( function );
1363 needs = needsAdapter( function, scopeTyVars );
1364 } // if
1365 } // if
1366 } // if
1367 } // if
1368 } // if
1369 addrExpr->set_arg( mutateExpression( addrExpr->get_arg() ) );
1370 if ( isPolyType( addrExpr->get_arg()->get_results().front(), scopeTyVars, env ) || needs ) {
1371 Expression *ret = addrExpr->get_arg();
1372 delete ret->get_results().front();
1373 ret->get_results().front() = addrExpr->get_results().front()->clone();
1374 addrExpr->set_arg( 0 );
1375 delete addrExpr;
1376 return ret;
1377 } else {
1378 return addrExpr;
1379 } // if
1380 }
1381
1382 /// Wraps a function declaration in a new pointer-to-function variable expression
1383 VariableExpr *wrapFunctionDecl( DeclarationWithType *functionDecl ) {
1384 // line below cloned from FixFunction.cc
1385 ObjectDecl *functionObj = new ObjectDecl( functionDecl->get_name(), functionDecl->get_storageClass(), functionDecl->get_linkage(), 0,
1386 new PointerType( Type::Qualifiers(), functionDecl->get_type()->clone() ), 0 );
1387 functionObj->set_mangleName( functionDecl->get_mangleName() );
1388 return new VariableExpr( functionObj );
1389 }
1390
1391 Statement * Pass1::mutate( ReturnStmt *returnStmt ) {
1392 if ( retval && returnStmt->get_expr() ) {
1393 assert( ! returnStmt->get_expr()->get_results().empty() );
1394 // ***** Code Removal ***** After introducing a temporary variable for all return expressions, the following code appears superfluous.
1395 // if ( returnStmt->get_expr()->get_results().front()->get_isLvalue() ) {
1396 // by this point, a cast expr on a polymorphic return value is redundant
1397 while ( CastExpr *castExpr = dynamic_cast< CastExpr *>( returnStmt->get_expr() ) ) {
1398 returnStmt->set_expr( castExpr->get_arg() );
1399 returnStmt->get_expr()->set_env( castExpr->get_env() );
1400 castExpr->set_env( 0 );
1401 castExpr->set_arg( 0 );
1402 delete castExpr;
1403 } //while
1404
1405 // find assignment operator for (polymorphic) return type
1406 ApplicationExpr *assignExpr = 0;
1407 if ( TypeInstType *typeInst = dynamic_cast< TypeInstType *>( retval->get_type() ) ) {
1408 // find assignment operator for type variable
1409 std::map< std::string, DeclarationWithType *>::const_iterator assignIter = assignOps.find( typeInst->get_name() );
1410 if ( assignIter == assignOps.end() ) {
1411 throw SemanticError( "Attempt to return dtype or ftype object in ", returnStmt->get_expr() );
1412 } // if
1413 assignExpr = new ApplicationExpr( new VariableExpr( assignIter->second ) );
1414 } else if ( ReferenceToType *refType = dynamic_cast< ReferenceToType *>( retval->get_type() ) ) {
1415 // find assignment operator for generic type
1416 DeclarationWithType *functionDecl = scopedAssignOps.find( refType );
1417 if ( ! functionDecl ) {
1418 throw SemanticError( "Attempt to return dtype or ftype generic object in ", returnStmt->get_expr() );
1419 }
1420
1421 // wrap it up in an application expression
1422 assignExpr = new ApplicationExpr( wrapFunctionDecl( functionDecl ) );
1423 assignExpr->set_env( env->clone() );
1424
1425 // find each of its needed secondary assignment operators
1426 std::list< Expression* > &tyParams = refType->get_parameters();
1427 std::list< TypeDecl* > &forallParams = functionDecl->get_type()->get_forall();
1428 std::list< Expression* >::const_iterator tyIt = tyParams.begin();
1429 std::list< TypeDecl* >::const_iterator forallIt = forallParams.begin();
1430 for ( ; tyIt != tyParams.end() && forallIt != forallParams.end(); ++tyIt, ++forallIt ) {
1431 if ( (*forallIt)->get_kind() != TypeDecl::Any ) continue; // skip types with no assign op (ftype/dtype)
1432
1433 std::list< DeclarationWithType* > &asserts = (*forallIt)->get_assertions();
1434 assert( ! asserts.empty() && "Type param needs assignment operator assertion" );
1435 DeclarationWithType *actualDecl = asserts.front();
1436 TypeInstType *actualType = isTypeInstAssignment( actualDecl );
1437 assert( actualType && "First assertion of type with assertions should be assignment operator" );
1438 TypeExpr *formalTypeExpr = dynamic_cast< TypeExpr* >( *tyIt );
1439 assert( formalTypeExpr && "type parameters must be type expressions" );
1440 Type *formalType = formalTypeExpr->get_type();
1441 assignExpr->get_env()->add( actualType->get_name(), formalType );
1442
1443 DeclarationWithType *assertAssign = 0;
1444 if ( TypeInstType *formalTypeInstType = dynamic_cast< TypeInstType* >( formalType ) ) {
1445 std::map< std::string, DeclarationWithType *>::const_iterator assertAssignIt = assignOps.find( formalTypeInstType->get_name() );
1446 if ( assertAssignIt == assignOps.end() ) {
1447 throw SemanticError( "No assignment operation found for ", formalTypeInstType );
1448 }
1449 assertAssign = assertAssignIt->second;
1450 } else {
1451 assertAssign = scopedAssignOps.find( formalType );
1452 if ( ! assertAssign ) {
1453 throw SemanticError( "No assignment operation found for ", formalType );
1454 }
1455 }
1456
1457
1458 assignExpr->get_inferParams()[ actualDecl->get_uniqueId() ]
1459 = ParamEntry( assertAssign->get_uniqueId(), assertAssign->get_type()->clone(), actualDecl->get_type()->clone(), wrapFunctionDecl( assertAssign ) );
1460 }
1461 }
1462 assert( assignExpr );
1463
1464 // replace return statement with appropriate assignment to out parameter
1465 Expression *retParm = new NameExpr( retval->get_name() );
1466 retParm->get_results().push_back( new PointerType( Type::Qualifiers(), retval->get_type()->clone() ) );
1467 assignExpr->get_args().push_back( retParm );
1468 assignExpr->get_args().push_back( returnStmt->get_expr() );
1469 stmtsToAdd.push_back( new ExprStmt( noLabels, mutateExpression( assignExpr ) ) );
1470 // } else {
1471 // useRetval = true;
1472 // stmtsToAdd.push_back( new ExprStmt( noLabels, mutateExpression( returnStmt->get_expr() ) ) );
1473 // useRetval = false;
1474 // } // if
1475 returnStmt->set_expr( 0 );
1476 } else {
1477 returnStmt->set_expr( mutateExpression( returnStmt->get_expr() ) );
1478 } // if
1479 return returnStmt;
1480 }
1481
1482 Type * Pass1::mutate( PointerType *pointerType ) {
1483 TyVarMap oldtyVars = scopeTyVars;
1484 makeTyVarMap( pointerType, scopeTyVars );
1485
1486 Type *ret = Mutator::mutate( pointerType );
1487
1488 scopeTyVars = oldtyVars;
1489 return ret;
1490 }
1491
1492 Type * Pass1::mutate( FunctionType *functionType ) {
1493 TyVarMap oldtyVars = scopeTyVars;
1494 makeTyVarMap( functionType, scopeTyVars );
1495
1496 Type *ret = Mutator::mutate( functionType );
1497
1498 scopeTyVars = oldtyVars;
1499 return ret;
1500 }
1501
1502 void Pass1::doBeginScope() {
1503 adapters.beginScope();
1504 scopedAssignOps.beginScope();
1505 }
1506
1507 void Pass1::doEndScope() {
1508 adapters.endScope();
1509 scopedAssignOps.endScope();
1510 }
1511
1512////////////////////////////////////////// Pass2 ////////////////////////////////////////////////////
1513
1514 void Pass2::addAdapters( FunctionType *functionType ) {
1515 std::list< DeclarationWithType *> &paramList = functionType->get_parameters();
1516 std::list< FunctionType *> functions;
1517 for ( std::list< DeclarationWithType *>::iterator arg = paramList.begin(); arg != paramList.end(); ++arg ) {
1518 Type *orig = (*arg)->get_type();
1519 findAndReplaceFunction( orig, functions, scopeTyVars, needsAdapter );
1520 (*arg)->set_type( orig );
1521 }
1522 std::set< std::string > adaptersDone;
1523 for ( std::list< FunctionType *>::iterator funType = functions.begin(); funType != functions.end(); ++funType ) {
1524 std::string mangleName = mangleAdapterName( *funType, scopeTyVars );
1525 if ( adaptersDone.find( mangleName ) == adaptersDone.end() ) {
1526 std::string adapterName = makeAdapterName( mangleName );
1527 paramList.push_front( new ObjectDecl( adapterName, DeclarationNode::NoStorageClass, LinkageSpec::C, 0, new PointerType( Type::Qualifiers(), makeAdapterType( *funType, scopeTyVars ) ), 0 ) );
1528 adaptersDone.insert( adaptersDone.begin(), mangleName );
1529 }
1530 }
1531// deleteAll( functions );
1532 }
1533
1534 template< typename DeclClass >
1535 DeclClass * Pass2::handleDecl( DeclClass *decl, Type *type ) {
1536 DeclClass *ret = static_cast< DeclClass *>( Mutator::mutate( decl ) );
1537
1538 return ret;
1539 }
1540
1541 DeclarationWithType * Pass2::mutate( FunctionDecl *functionDecl ) {
1542 return handleDecl( functionDecl, functionDecl->get_functionType() );
1543 }
1544
1545 ObjectDecl * Pass2::mutate( ObjectDecl *objectDecl ) {
1546 return handleDecl( objectDecl, objectDecl->get_type() );
1547 }
1548
1549 TypeDecl * Pass2::mutate( TypeDecl *typeDecl ) {
1550 scopeTyVars[ typeDecl->get_name() ] = typeDecl->get_kind();
1551 if ( typeDecl->get_base() ) {
1552 return handleDecl( typeDecl, typeDecl->get_base() );
1553 } else {
1554 return Mutator::mutate( typeDecl );
1555 }
1556 }
1557
1558 TypedefDecl * Pass2::mutate( TypedefDecl *typedefDecl ) {
1559 return handleDecl( typedefDecl, typedefDecl->get_base() );
1560 }
1561
1562 Type * Pass2::mutate( PointerType *pointerType ) {
1563 TyVarMap oldtyVars = scopeTyVars;
1564 makeTyVarMap( pointerType, scopeTyVars );
1565
1566 Type *ret = Mutator::mutate( pointerType );
1567
1568 scopeTyVars = oldtyVars;
1569 return ret;
1570 }
1571
1572 Type *Pass2::mutate( FunctionType *funcType ) {
1573 TyVarMap oldtyVars = scopeTyVars;
1574 makeTyVarMap( funcType, scopeTyVars );
1575
1576 // move polymorphic return type to parameter list
1577 if ( isPolyRet( funcType ) ) {
1578 DeclarationWithType *ret = funcType->get_returnVals().front();
1579 ret->set_type( new PointerType( Type::Qualifiers(), ret->get_type() ) );
1580 funcType->get_parameters().push_front( ret );
1581 funcType->get_returnVals().pop_front();
1582 }
1583
1584 // add size/align and assertions for type parameters to parameter list
1585 std::list< DeclarationWithType *>::iterator last = funcType->get_parameters().begin();
1586 std::list< DeclarationWithType *> inferredParams;
1587 ObjectDecl newObj( "", DeclarationNode::NoStorageClass, LinkageSpec::C, 0, new BasicType( Type::Qualifiers(), BasicType::LongUnsignedInt ), 0 );
1588 ObjectDecl newPtr( "", DeclarationNode::NoStorageClass, LinkageSpec::C, 0,
1589 new PointerType( Type::Qualifiers(), new BasicType( Type::Qualifiers(), BasicType::LongUnsignedInt ) ), 0 );
1590// ObjectDecl *newFunPtr = new ObjectDecl( "", DeclarationNode::NoStorageClass, LinkageSpec::Cforall, 0, new PointerType( Type::Qualifiers(), new FunctionType( Type::Qualifiers(), true ) ), 0 );
1591 for ( std::list< TypeDecl *>::const_iterator tyParm = funcType->get_forall().begin(); tyParm != funcType->get_forall().end(); ++tyParm ) {
1592 ObjectDecl *sizeParm, *alignParm;
1593 // add all size and alignment parameters to parameter list
1594 if ( (*tyParm)->get_kind() == TypeDecl::Any ) {
1595 TypeInstType parmType( Type::Qualifiers(), (*tyParm)->get_name(), *tyParm );
1596
1597 sizeParm = newObj.clone();
1598 sizeParm->set_name( sizeofName( &parmType ) );
1599 last = funcType->get_parameters().insert( last, sizeParm );
1600 ++last;
1601
1602 alignParm = newObj.clone();
1603 alignParm->set_name( alignofName( &parmType ) );
1604 last = funcType->get_parameters().insert( last, alignParm );
1605 ++last;
1606 }
1607 // move all assertions into parameter list
1608 for ( std::list< DeclarationWithType *>::iterator assert = (*tyParm)->get_assertions().begin(); assert != (*tyParm)->get_assertions().end(); ++assert ) {
1609// *assert = (*assert)->acceptMutator( *this );
1610 inferredParams.push_back( *assert );
1611 }
1612 (*tyParm)->get_assertions().clear();
1613 }
1614
1615 // add size/align for generic parameter types to parameter list
1616 std::set< std::string > seenTypes; // sizeofName for generic types we've seen
1617 for ( std::list< DeclarationWithType* >::const_iterator fnParm = last; fnParm != funcType->get_parameters().end(); ++fnParm ) {
1618 Type *polyBase = hasPolyBase( (*fnParm)->get_type(), scopeTyVars );
1619 if ( polyBase && ! dynamic_cast< TypeInstType* >( polyBase ) ) {
1620 std::string sizeName = sizeofName( polyBase );
1621 if ( seenTypes.count( sizeName ) ) continue;
1622
1623 ObjectDecl *sizeParm, *alignParm, *offsetParm;
1624 sizeParm = newObj.clone();
1625 sizeParm->set_name( sizeName );
1626 last = funcType->get_parameters().insert( last, sizeParm );
1627 ++last;
1628
1629 alignParm = newObj.clone();
1630 alignParm->set_name( alignofName( polyBase ) );
1631 last = funcType->get_parameters().insert( last, alignParm );
1632 ++last;
1633
1634 if ( dynamic_cast< StructInstType* >( polyBase ) ) {
1635 offsetParm = newPtr.clone();
1636 offsetParm->set_name( offsetofName( polyBase ) );
1637 last = funcType->get_parameters().insert( last, offsetParm );
1638 ++last;
1639 }
1640
1641 seenTypes.insert( sizeName );
1642 }
1643 }
1644
1645 // splice assertion parameters into parameter list
1646 funcType->get_parameters().splice( last, inferredParams );
1647 addAdapters( funcType );
1648 mutateAll( funcType->get_returnVals(), *this );
1649 mutateAll( funcType->get_parameters(), *this );
1650
1651 scopeTyVars = oldtyVars;
1652 return funcType;
1653 }
1654
1655//////////////////////////////////////// GenericInstantiator //////////////////////////////////////////////////
1656
1657 /// Makes substitutions of params into baseParams; returns true if all parameters substituted for a concrete type
1658 bool makeSubstitutions( const std::list< TypeDecl* >& baseParams, const std::list< Expression* >& params, std::list< TypeExpr* >& out ) {
1659 bool allConcrete = true; // will finish the substitution list even if they're not all concrete
1660
1661 // substitute concrete types for given parameters, and incomplete types for placeholders
1662 std::list< TypeDecl* >::const_iterator baseParam = baseParams.begin();
1663 std::list< Expression* >::const_iterator param = params.begin();
1664 for ( ; baseParam != baseParams.end() && param != params.end(); ++baseParam, ++param ) {
1665 // switch ( (*baseParam)->get_kind() ) {
1666 // case TypeDecl::Any: { // any type is a valid substitution here; complete types can be used to instantiate generics
1667 TypeExpr *paramType = dynamic_cast< TypeExpr* >( *param );
1668 assert(paramType && "Aggregate parameters should be type expressions");
1669 out.push_back( paramType->clone() );
1670 // check that the substituted type isn't a type variable itself
1671 if ( dynamic_cast< TypeInstType* >( paramType->get_type() ) ) {
1672 allConcrete = false;
1673 }
1674 // break;
1675 // }
1676 // case TypeDecl::Dtype: // dtype can be consistently replaced with void [only pointers, which become void*]
1677 // out.push_back( new TypeExpr( new VoidType( Type::Qualifiers() ) ) );
1678 // break;
1679 // case TypeDecl::Ftype: // pointer-to-ftype can be consistently replaced with void (*)(void) [similar to dtype]
1680 // out.push_back( new TypeExpr( new FunctionType( Type::Qualifiers(), false ) ) );
1681 // break;
1682 // }
1683 }
1684
1685 // if any parameters left over, not done
1686 if ( baseParam != baseParams.end() ) return false;
1687 // // if not enough parameters given, substitute remaining incomplete types for placeholders
1688 // for ( ; baseParam != baseParams.end(); ++baseParam ) {
1689 // switch ( (*baseParam)->get_kind() ) {
1690 // case TypeDecl::Any: // no more substitutions here, fail early
1691 // return false;
1692 // case TypeDecl::Dtype: // dtype can be consistently replaced with void [only pointers, which become void*]
1693 // out.push_back( new TypeExpr( new VoidType( Type::Qualifiers() ) ) );
1694 // break;
1695 // case TypeDecl::Ftype: // pointer-to-ftype can be consistently replaced with void (*)(void) [similar to dtype]
1696 // out.push_back( new TypeExpr( new FunctionType( Type::Qualifiers(), false ) ) );
1697 // break;
1698 // }
1699 // }
1700
1701 return allConcrete;
1702 }
1703
1704 /// Substitutes types of members of in according to baseParams => typeSubs, appending the result to out
1705 void substituteMembers( const std::list< Declaration* >& in, const std::list< TypeDecl* >& baseParams, const std::list< TypeExpr* >& typeSubs,
1706 std::list< Declaration* >& out ) {
1707 // substitute types into new members
1708 TypeSubstitution subs( baseParams.begin(), baseParams.end(), typeSubs.begin() );
1709 for ( std::list< Declaration* >::const_iterator member = in.begin(); member != in.end(); ++member ) {
1710 Declaration *newMember = (*member)->clone();
1711 subs.apply(newMember);
1712 out.push_back( newMember );
1713 }
1714 }
1715
1716 Type* GenericInstantiator::mutate( StructInstType *inst ) {
1717 // mutate subtypes
1718 Type *mutated = Mutator::mutate( inst );
1719 inst = dynamic_cast< StructInstType* >( mutated );
1720 if ( ! inst ) return mutated;
1721
1722 // exit early if no need for further mutation
1723 if ( inst->get_parameters().empty() ) return inst;
1724 assert( inst->get_baseParameters() && "Base struct has parameters" );
1725
1726 // check if type can be concretely instantiated; put substitutions into typeSubs
1727 std::list< TypeExpr* > typeSubs;
1728 if ( ! makeSubstitutions( *inst->get_baseParameters(), inst->get_parameters(), typeSubs ) ) {
1729 deleteAll( typeSubs );
1730 return inst;
1731 }
1732
1733 // make concrete instantiation of generic type
1734 StructDecl *concDecl = lookup( inst, typeSubs );
1735 if ( ! concDecl ) {
1736 // set concDecl to new type, insert type declaration into statements to add
1737 concDecl = new StructDecl( typeNamer.newName( inst->get_name() ) );
1738 substituteMembers( inst->get_baseStruct()->get_members(), *inst->get_baseParameters(), typeSubs, concDecl->get_members() );
1739 DeclMutator::addDeclaration( concDecl );
1740 insert( inst, typeSubs, concDecl );
1741 }
1742 StructInstType *newInst = new StructInstType( inst->get_qualifiers(), concDecl->get_name() );
1743 newInst->set_baseStruct( concDecl );
1744
1745 deleteAll( typeSubs );
1746 delete inst;
1747 return newInst;
1748 }
1749
1750 Type* GenericInstantiator::mutate( UnionInstType *inst ) {
1751 // mutate subtypes
1752 Type *mutated = Mutator::mutate( inst );
1753 inst = dynamic_cast< UnionInstType* >( mutated );
1754 if ( ! inst ) return mutated;
1755
1756 // exit early if no need for further mutation
1757 if ( inst->get_parameters().empty() ) return inst;
1758 assert( inst->get_baseParameters() && "Base union has parameters" );
1759
1760 // check if type can be concretely instantiated; put substitutions into typeSubs
1761 std::list< TypeExpr* > typeSubs;
1762 if ( ! makeSubstitutions( *inst->get_baseParameters(), inst->get_parameters(), typeSubs ) ) {
1763 deleteAll( typeSubs );
1764 return inst;
1765 }
1766
1767 // make concrete instantiation of generic type
1768 UnionDecl *concDecl = lookup( inst, typeSubs );
1769 if ( ! concDecl ) {
1770 // set concDecl to new type, insert type declaration into statements to add
1771 concDecl = new UnionDecl( typeNamer.newName( inst->get_name() ) );
1772 substituteMembers( inst->get_baseUnion()->get_members(), *inst->get_baseParameters(), typeSubs, concDecl->get_members() );
1773 DeclMutator::addDeclaration( concDecl );
1774 insert( inst, typeSubs, concDecl );
1775 }
1776 UnionInstType *newInst = new UnionInstType( inst->get_qualifiers(), concDecl->get_name() );
1777 newInst->set_baseUnion( concDecl );
1778
1779 deleteAll( typeSubs );
1780 delete inst;
1781 return newInst;
1782 }
1783
1784 // /// Gets the base struct or union declaration for a member expression; NULL if not applicable
1785 // AggregateDecl* getMemberBaseDecl( MemberExpr *memberExpr ) {
1786 // // get variable for member aggregate
1787 // VariableExpr *varExpr = dynamic_cast< VariableExpr* >( memberExpr->get_aggregate() );
1788 // if ( ! varExpr ) return NULL;
1789 //
1790 // // get object for variable
1791 // ObjectDecl *objectDecl = dynamic_cast< ObjectDecl* >( varExpr->get_var() );
1792 // if ( ! objectDecl ) return NULL;
1793 //
1794 // // get base declaration from object type
1795 // Type *objectType = objectDecl->get_type();
1796 // StructInstType *structType = dynamic_cast< StructInstType* >( objectType );
1797 // if ( structType ) return structType->get_baseStruct();
1798 // UnionInstType *unionType = dynamic_cast< UnionInstType* >( objectType );
1799 // if ( unionType ) return unionType->get_baseUnion();
1800 //
1801 // return NULL;
1802 // }
1803 //
1804 // /// Finds the declaration with the given name, returning decls.end() if none such
1805 // std::list< Declaration* >::const_iterator findDeclNamed( const std::list< Declaration* > &decls, const std::string &name ) {
1806 // for( std::list< Declaration* >::const_iterator decl = decls.begin(); decl != decls.end(); ++decl ) {
1807 // if ( (*decl)->get_name() == name ) return decl;
1808 // }
1809 // return decls.end();
1810 // }
1811 //
1812 // Expression* Instantiate::mutate( MemberExpr *memberExpr ) {
1813 // // mutate, exiting early if no longer MemberExpr
1814 // Expression *expr = Mutator::mutate( memberExpr );
1815 // memberExpr = dynamic_cast< MemberExpr* >( expr );
1816 // if ( ! memberExpr ) return expr;
1817 //
1818 // // get declaration of member and base declaration of member, exiting early if not found
1819 // AggregateDecl *memberBase = getMemberBaseDecl( memberExpr );
1820 // if ( ! memberBase ) return memberExpr;
1821 // DeclarationWithType *memberDecl = memberExpr->get_member();
1822 // std::list< Declaration* >::const_iterator baseIt = findDeclNamed( memberBase->get_members(), memberDecl->get_name() );
1823 // if ( baseIt == memberBase->get_members().end() ) return memberExpr;
1824 // DeclarationWithType *baseDecl = dynamic_cast< DeclarationWithType* >( *baseIt );
1825 // if ( ! baseDecl ) return memberExpr;
1826 //
1827 // // check if stated type of the member is not the type of the member's declaration; if so, need a cast
1828 // // this *SHOULD* be safe, I don't think anything but the void-replacements I put in for dtypes would make it past the typechecker
1829 // SymTab::Indexer dummy;
1830 // if ( ResolvExpr::typesCompatible( memberDecl->get_type(), baseDecl->get_type(), dummy ) ) return memberExpr;
1831 // else return new CastExpr( memberExpr, memberDecl->get_type() );
1832 // }
1833
1834 void GenericInstantiator::doBeginScope() {
1835 DeclMutator::doBeginScope();
1836 instantiations.beginScope();
1837 }
1838
1839 void GenericInstantiator::doEndScope() {
1840 DeclMutator::doEndScope();
1841 instantiations.endScope();
1842 }
1843
1844////////////////////////////////////////// MemberExprFixer ////////////////////////////////////////////////////
1845
1846 template< typename DeclClass >
1847 DeclClass * MemberExprFixer::handleDecl( DeclClass *decl, Type *type ) {
1848 TyVarMap oldtyVars = scopeTyVars;
1849 makeTyVarMap( type, scopeTyVars );
1850
1851 DeclClass *ret = static_cast< DeclClass *>( Mutator::mutate( decl ) );
1852
1853 scopeTyVars = oldtyVars;
1854 return ret;
1855 }
1856
1857 ObjectDecl * MemberExprFixer::mutate( ObjectDecl *objectDecl ) {
1858 return handleDecl( objectDecl, objectDecl->get_type() );
1859 }
1860
1861 DeclarationWithType * MemberExprFixer::mutate( FunctionDecl *functionDecl ) {
1862 return handleDecl( functionDecl, functionDecl->get_functionType() );
1863 }
1864
1865 TypedefDecl * MemberExprFixer::mutate( TypedefDecl *typedefDecl ) {
1866 return handleDecl( typedefDecl, typedefDecl->get_base() );
1867 }
1868
1869 TypeDecl * MemberExprFixer::mutate( TypeDecl *typeDecl ) {
1870 scopeTyVars[ typeDecl->get_name() ] = typeDecl->get_kind();
1871 return Mutator::mutate( typeDecl );
1872 }
1873
1874 Type * MemberExprFixer::mutate( PointerType *pointerType ) {
1875 TyVarMap oldtyVars = scopeTyVars;
1876 makeTyVarMap( pointerType, scopeTyVars );
1877
1878 Type *ret = Mutator::mutate( pointerType );
1879
1880 scopeTyVars = oldtyVars;
1881 return ret;
1882 }
1883
1884 Type * MemberExprFixer::mutate( FunctionType *functionType ) {
1885 TyVarMap oldtyVars = scopeTyVars;
1886 makeTyVarMap( functionType, scopeTyVars );
1887
1888 Type *ret = Mutator::mutate( functionType );
1889
1890 scopeTyVars = oldtyVars;
1891 return ret;
1892 }
1893
1894 Statement *MemberExprFixer::mutate( DeclStmt *declStmt ) {
1895 if ( ObjectDecl *objectDecl = dynamic_cast< ObjectDecl *>( declStmt->get_decl() ) ) {
1896 if ( isPolyType( objectDecl->get_type(), scopeTyVars ) ) {
1897 // change initialization of a polymorphic value object
1898 // to allocate storage with alloca
1899 Type *declType = objectDecl->get_type();
1900 UntypedExpr *alloc = new UntypedExpr( new NameExpr( "__builtin_alloca" ) );
1901 alloc->get_args().push_back( new NameExpr( sizeofName( declType ) ) );
1902
1903 delete objectDecl->get_init();
1904
1905 std::list<Expression*> designators;
1906 objectDecl->set_init( new SingleInit( alloc, designators, false ) ); // not constructed
1907 }
1908 }
1909 return Mutator::mutate( declStmt );
1910 }
1911
1912 /// Finds the member in the base list that matches the given declaration; returns its index, or -1 if not present
1913 long findMember( DeclarationWithType *memberDecl, std::list< Declaration* > &baseDecls ) {
1914 long i = 0;
1915 for(std::list< Declaration* >::const_iterator decl = baseDecls.begin(); decl != baseDecls.end(); ++decl, ++i ) {
1916 if ( memberDecl->get_name() != (*decl)->get_name() ) continue;
1917
1918 if ( DeclarationWithType *declWithType = dynamic_cast< DeclarationWithType* >( *decl ) ) {
1919 if ( memberDecl->get_mangleName().empty() || declWithType->get_mangleName().empty()
1920 || memberDecl->get_mangleName() == declWithType->get_mangleName() ) return i;
1921 else continue;
1922 } else return i;
1923 }
1924 return -1;
1925 }
1926
1927 /// Returns an index expression into the offset array for a type
1928 Expression *makeOffsetIndex( Type *objectType, long i ) {
1929 std::stringstream offset_namer;
1930 offset_namer << i;
1931 ConstantExpr *fieldIndex = new ConstantExpr( Constant( new BasicType( Type::Qualifiers(), BasicType::LongUnsignedInt ), offset_namer.str() ) );
1932 UntypedExpr *fieldOffset = new UntypedExpr( new NameExpr( "?[?]" ) );
1933 fieldOffset->get_args().push_back( new NameExpr( offsetofName( objectType ) ) );
1934 fieldOffset->get_args().push_back( fieldIndex );
1935 return fieldOffset;
1936 }
1937
1938 /// Returns an expression dereferenced n times
1939 Expression *makeDerefdVar( Expression *derefdVar, long n ) {
1940 for ( int i = 1; i < n; ++i ) {
1941 UntypedExpr *derefExpr = new UntypedExpr( new NameExpr( "*?" ) );
1942 derefExpr->get_args().push_back( derefdVar );
1943 derefdVar = derefExpr;
1944 }
1945 return derefdVar;
1946 }
1947
1948 Expression *MemberExprFixer::mutate( MemberExpr *memberExpr ) {
1949 // mutate, exiting early if no longer MemberExpr
1950 Expression *expr = Mutator::mutate( memberExpr );
1951 memberExpr = dynamic_cast< MemberExpr* >( expr );
1952 if ( ! memberExpr ) return expr;
1953
1954 // get declaration for base struct, exiting early if not found
1955 int varDepth;
1956 VariableExpr *varExpr = getBaseVar( memberExpr->get_aggregate(), &varDepth );
1957 if ( ! varExpr ) return memberExpr;
1958 ObjectDecl *objectDecl = dynamic_cast< ObjectDecl* >( varExpr->get_var() );
1959 if ( ! objectDecl ) return memberExpr;
1960
1961 // only mutate member expressions for polymorphic types
1962 int tyDepth;
1963 Type *objectType = hasPolyBase( objectDecl->get_type(), scopeTyVars, &tyDepth );
1964 if ( ! objectType ) return memberExpr;
1965
1966 Expression *newMemberExpr = 0;
1967 if ( StructInstType *structType = dynamic_cast< StructInstType* >( objectType ) ) {
1968 // look up offset index
1969 long i = findMember( memberExpr->get_member(), structType->get_baseStruct()->get_members() );
1970 if ( i == -1 ) return memberExpr;
1971
1972 // replace member expression with pointer to base plus offset
1973 UntypedExpr *fieldLoc = new UntypedExpr( new NameExpr( "?+?" ) );
1974 fieldLoc->get_args().push_back( makeDerefdVar( varExpr->clone(), varDepth ) );
1975 fieldLoc->get_args().push_back( makeOffsetIndex( objectType, i ) );
1976 newMemberExpr = fieldLoc;
1977 } else if ( dynamic_cast< UnionInstType* >( objectType ) ) {
1978 // union members are all at offset zero, so build appropriately-dereferenced variable
1979 newMemberExpr = makeDerefdVar( varExpr->clone(), varDepth );
1980 } else return memberExpr;
1981 assert( newMemberExpr );
1982
1983 Type *memberType = memberExpr->get_member()->get_type();
1984 if ( ! isPolyType( memberType, scopeTyVars ) ) {
1985 // Not all members of a polymorphic type are themselves of polymorphic type; in this case the member expression should be wrapped and dereferenced to form an lvalue
1986 CastExpr *ptrCastExpr = new CastExpr( newMemberExpr, new PointerType( Type::Qualifiers(), memberType->clone() ) );
1987 UntypedExpr *derefExpr = new UntypedExpr( new NameExpr( "*?" ) );
1988 derefExpr->get_args().push_back( ptrCastExpr );
1989 newMemberExpr = derefExpr;
1990 }
1991
1992 delete memberExpr;
1993 return newMemberExpr;
1994 }
1995
1996 Expression *MemberExprFixer::mutate( OffsetofExpr *offsetofExpr ) {
1997 // mutate, exiting early if no longer OffsetofExpr
1998 Expression *expr = Mutator::mutate( offsetofExpr );
1999 offsetofExpr = dynamic_cast< OffsetofExpr* >( expr );
2000 if ( ! offsetofExpr ) return expr;
2001
2002 // only mutate expressions for polymorphic structs/unions
2003 Type *ty = isPolyType( offsetofExpr->get_type(), scopeTyVars );
2004 if ( ! ty ) return offsetofExpr;
2005
2006 if ( StructInstType *structType = dynamic_cast< StructInstType* >( ty ) ) {
2007 // replace offsetof expression by index into offset array
2008 long i = findMember( offsetofExpr->get_member(), structType->get_baseStruct()->get_members() );
2009 if ( i == -1 ) return offsetofExpr;
2010
2011 Expression *offsetInd = makeOffsetIndex( ty, i );
2012 delete offsetofExpr;
2013 return offsetInd;
2014 } else if ( dynamic_cast< UnionInstType* >( ty ) ) {
2015 // all union members are at offset zero
2016 delete offsetofExpr;
2017 return new ConstantExpr( Constant( new BasicType( Type::Qualifiers(), BasicType::LongUnsignedInt ), std::string("0") ) );
2018 } else return offsetofExpr;
2019 }
2020
2021////////////////////////////////////////// Pass3 ////////////////////////////////////////////////////
2022
2023 template< typename DeclClass >
2024 DeclClass * Pass3::handleDecl( DeclClass *decl, Type *type ) {
2025 TyVarMap oldtyVars = scopeTyVars;
2026 makeTyVarMap( type, scopeTyVars );
2027
2028 DeclClass *ret = static_cast< DeclClass *>( Mutator::mutate( decl ) );
2029 ScrubTyVars::scrub( decl, scopeTyVars );
2030
2031 scopeTyVars = oldtyVars;
2032 return ret;
2033 }
2034
2035 ObjectDecl * Pass3::mutate( ObjectDecl *objectDecl ) {
2036 return handleDecl( objectDecl, objectDecl->get_type() );
2037 }
2038
2039 DeclarationWithType * Pass3::mutate( FunctionDecl *functionDecl ) {
2040 return handleDecl( functionDecl, functionDecl->get_functionType() );
2041 }
2042
2043 TypedefDecl * Pass3::mutate( TypedefDecl *typedefDecl ) {
2044 return handleDecl( typedefDecl, typedefDecl->get_base() );
2045 }
2046
2047 TypeDecl * Pass3::mutate( TypeDecl *typeDecl ) {
2048// Initializer *init = 0;
2049// std::list< Expression *> designators;
2050// scopeTyVars[ typeDecl->get_name() ] = typeDecl->get_kind();
2051// if ( typeDecl->get_base() ) {
2052// init = new SimpleInit( new SizeofExpr( handleDecl( typeDecl, typeDecl->get_base() ) ), designators );
2053// }
2054// return new ObjectDecl( typeDecl->get_name(), Declaration::Extern, LinkageSpec::C, 0, new BasicType( Type::Qualifiers(), BasicType::UnsignedInt ), init );
2055
2056 scopeTyVars[ typeDecl->get_name() ] = typeDecl->get_kind();
2057 return Mutator::mutate( typeDecl );
2058 }
2059
2060 Type * Pass3::mutate( PointerType *pointerType ) {
2061 TyVarMap oldtyVars = scopeTyVars;
2062 makeTyVarMap( pointerType, scopeTyVars );
2063
2064 Type *ret = Mutator::mutate( pointerType );
2065
2066 scopeTyVars = oldtyVars;
2067 return ret;
2068 }
2069
2070 Type * Pass3::mutate( FunctionType *functionType ) {
2071 TyVarMap oldtyVars = scopeTyVars;
2072 makeTyVarMap( functionType, scopeTyVars );
2073
2074 Type *ret = Mutator::mutate( functionType );
2075
2076 scopeTyVars = oldtyVars;
2077 return ret;
2078 }
2079 } // anonymous namespace
2080} // namespace GenPoly
2081
2082// Local Variables: //
2083// tab-width: 4 //
2084// mode: c++ //
2085// compile-command: "make install" //
2086// End: //
Note: See TracBrowser for help on using the repository browser.