Changeset a5a71d0 for src/GenPoly
- Timestamp:
- Apr 6, 2016, 5:11:32 PM (9 years ago)
- Branches:
- ADT, aaron-thesis, arm-eh, ast-experimental, cleanup-dtors, ctor, deferred_resn, demangler, enum, forall-pointer-decay, gc_noraii, jacob/cs343-translation, jenkins-sandbox, master, memory, new-ast, new-ast-unique-expr, new-env, no_list, persistent-indexer, pthread-emulation, qualifiedEnum, resolv-new, with_gc
- Children:
- eab39cd
- Parents:
- 39786813 (diff), 3aba311 (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the(diff)
links above to see all the changes relative to each parent. - Location:
- src/GenPoly
- Files:
-
- 2 deleted
- 4 edited
Legend:
- Unmodified
- Added
- Removed
-
src/GenPoly/Box.cc
r39786813 ra5a71d0 14 14 // 15 15 16 #include <algorithm> 17 #include <iterator> 18 #include <list> 19 #include <map> 16 20 #include <set> 17 21 #include <stack> 18 22 #include <string> 19 #include < iterator>20 #include < algorithm>23 #include <utility> 24 #include <vector> 21 25 #include <cassert> 22 26 23 27 #include "Box.h" 24 #include " InstantiateGeneric.h"28 #include "DeclMutator.h" 25 29 #include "PolyMutator.h" 26 30 #include "FindFunction.h" 31 #include "ScopedMap.h" 27 32 #include "ScrubTyVars.h" 28 33 … … 30 35 31 36 #include "SynTree/Constant.h" 32 #include "SynTree/ Type.h"37 #include "SynTree/Declaration.h" 33 38 #include "SynTree/Expression.h" 34 39 #include "SynTree/Initializer.h" 40 #include "SynTree/Mutator.h" 35 41 #include "SynTree/Statement.h" 36 #include "SynTree/Mutator.h" 42 #include "SynTree/Type.h" 43 #include "SynTree/TypeSubstitution.h" 37 44 38 45 #include "ResolvExpr/TypeEnvironment.h" … … 40 47 #include "ResolvExpr/typeops.h" 41 48 49 #include "SymTab/Indexer.h" 42 50 #include "SymTab/Mangler.h" 43 51 … … 54 62 FunctionType *makeAdapterType( FunctionType *adaptee, const TyVarMap &tyVars ); 55 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* > ¶ms, 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 56 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 57 182 class Pass1 : public PolyMutator { … … 100 225 ObjectDecl *makeTemporary( Type *type ); 101 226 102 typedef std::map< std::string, DeclarationWithType *> AdapterMap;103 227 std::map< std::string, DeclarationWithType *> assignOps; 104 228 ResolvExpr::TypeMap< DeclarationWithType > scopedAssignOps; 105 std::stack< AdapterMap> adapters;229 ScopedMap< std::string, DeclarationWithType* > adapters; 106 230 DeclarationWithType *retval; 107 231 bool useRetval; … … 124 248 125 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 ); } 126 278 }; 127 279 … … 159 311 } // anonymous namespace 160 312 161 void printAllNotBuiltin( const std::list< Declaration *>& translationUnit, std::ostream &os ) {162 for ( std::list< Declaration *>::const_iterator i = translationUnit.begin(); i != translationUnit.end(); ++i ) {163 if ( ! LinkageSpec::isBuiltin( (*i)->get_linkage() ) ) {164 (*i)->print( os );165 os << std::endl;166 } // if167 } // for168 }169 170 313 /// version of mutateAll with special handling for translation unit so you can check the end of the prelude when debugging 171 314 template< typename MutatorType > … … 195 338 196 339 void box( std::list< Declaration *>& translationUnit ) { 340 LayoutFunctionBuilder layoutBuilder; 197 341 Pass1 pass1; 198 342 Pass2 pass2; 343 GenericInstantiator instantiator; 199 344 MemberExprFixer memberFixer; 200 345 Pass3 pass3; 346 347 layoutBuilder.mutateDeclarationList( translationUnit ); 201 348 mutateTranslationUnit/*All*/( translationUnit, pass1 ); 202 349 mutateTranslationUnit/*All*/( translationUnit, pass2 ); 203 instantiateGeneric( translationUnit ); 350 // instantiateGeneric( translationUnit ); 351 instantiator.mutateDeclarationList( translationUnit ); 204 352 mutateTranslationUnit/*All*/( translationUnit, memberFixer ); 205 353 mutateTranslationUnit/*All*/( translationUnit, pass3 ); 206 354 } 207 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( ¶mType ), DeclarationNode::NoStorageClass, LinkageSpec::Cforall, 0, sizeAlignType.clone(), 0 ) ); 387 layoutFnType->get_parameters().push_back( new ObjectDecl( alignofName( ¶mType ), 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 208 554 ////////////////////////////////////////// Pass1 //////////////////////////////////////////////////// 209 555 … … 245 591 } 246 592 247 Pass1::Pass1() : useRetval( false ), tempNamer( "_temp" ) { 248 adapters.push(AdapterMap()); 249 } 593 Pass1::Pass1() : useRetval( false ), tempNamer( "_temp" ) {} 250 594 251 595 /// Returns T if the given declaration is (*?=?)(T *, T) for some TypeInstType T (return not checked, but maybe should be), NULL otherwise … … 350 694 } // for 351 695 352 AdapterMap & adapters = Pass1::adapters.top();353 696 for ( std::list< FunctionType *>::iterator funType = functions.begin(); funType != functions.end(); ++funType ) { 354 697 std::string mangleName = mangleAdapterName( *funType, scopeTyVars ); … … 773 1116 mangleName += makePolyMonoSuffix( originalFunction, exprTyVars ); 774 1117 775 AdapterMap & adapters = Pass1::adapters.top();776 Adapter Map::iterator adapter = adapters.find( mangleName );1118 typedef ScopedMap< std::string, DeclarationWithType* >::iterator AdapterIter; 1119 AdapterIter adapter = adapters.find( mangleName ); 777 1120 if ( adapter == adapters.end() ) { 778 1121 // adapter has not been created yet in the current scope, so define it 779 1122 FunctionDecl *newAdapter = makeAdapter( *funType, realFunction, mangleName, exprTyVars ); 780 adapter = adapters.insert( adapters.begin(), std::pair< std::string, DeclarationWithType *>( mangleName, newAdapter ) ); 1123 std::pair< AdapterIter, bool > answer = adapters.insert( std::pair< std::string, DeclarationWithType *>( mangleName, newAdapter ) ); 1124 adapter = answer.first; 781 1125 stmtsToAdd.push_back( new DeclStmt( noLabels, newAdapter ) ); 782 1126 } // if … … 1157 1501 1158 1502 void Pass1::doBeginScope() { 1159 // push a copy of the current map 1160 adapters.push(adapters.top()); 1503 adapters.beginScope(); 1161 1504 scopedAssignOps.beginScope(); 1162 1505 } 1163 1506 1164 1507 void Pass1::doEndScope() { 1165 adapters. pop();1508 adapters.endScope(); 1166 1509 scopedAssignOps.endScope(); 1167 1510 } … … 1310 1653 } 1311 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 1312 1844 ////////////////////////////////////////// MemberExprFixer //////////////////////////////////////////////////// 1313 1845 -
src/GenPoly/DeclMutator.cc
r39786813 ra5a71d0 24 24 } 25 25 26 DeclMutator::DeclMutator() : Mutator(), declsToAdd(1) {}26 DeclMutator::DeclMutator() : Mutator(), declsToAdd(1), declsToAddAfter(1) {} 27 27 28 28 DeclMutator::~DeclMutator() {} 29 29 30 30 void DeclMutator::mutateDeclarationList( std::list< Declaration* > &decls ) { 31 for ( std::list< Declaration* >::iterator decl = decls.begin(); decl != decls.end(); ++decl ) { 31 for ( std::list< Declaration* >::iterator decl = decls.begin(); ; ++decl ) { 32 // splice in new declarations after previous decl 33 decls.splice( decl, declsToAddAfter.back() ); 34 35 if ( decl == decls.end() ) break; 36 32 37 // run mutator on declaration 33 38 *decl = maybeMutate( *decl, *this ); … … 39 44 40 45 void DeclMutator::doBeginScope() { 41 // add new decl list for inside of scope46 // add new decl lists for inside of scope 42 47 declsToAdd.resize( declsToAdd.size()+1 ); 48 declsToAddAfter.resize( declsToAddAfter.size()+1 ); 43 49 } 44 50 … … 49 55 newBack->splice( newBack->end(), *back ); 50 56 declsToAdd.pop_back(); 57 58 back = declsToAddAfter.rbegin(); 59 newBack = back + 1; 60 newBack->splice( newBack->end(), *back ); 61 declsToAddAfter.pop_back(); 51 62 } 52 63 … … 61 72 stmt = maybeMutate( stmt, *this ); 62 73 // return if no declarations to add 63 if ( declsToAdd.back().empty() ) return stmt; 74 if ( declsToAdd.back().empty() && declsToAddAfter.back().empty() ) { 75 doEndScope(); 76 return stmt; 77 } 64 78 65 79 // otherwise add declarations to new compound statement … … 71 85 declsToAdd.back().clear(); 72 86 87 // add mutated statement 88 compound->get_kids().push_back( stmt ); 89 90 // add declarations after to new compound statement 91 for ( std::list< Declaration* >::iterator decl = declsToAddAfter.back().begin(); decl != declsToAddAfter.back().end(); ++decl ) { 92 DeclStmt *declStmt = new DeclStmt( noLabels, *decl ); 93 compound->get_kids().push_back( declStmt ); 94 } 95 declsToAddAfter.back().clear(); 96 73 97 doEndScope(); 74 75 // add mutated statement and return76 compound->get_kids().push_back( stmt );77 98 return compound; 78 99 } … … 80 101 void DeclMutator::mutateStatementList( std::list< Statement* > &stmts ) { 81 102 doBeginScope(); 103 82 104 83 for ( std::list< Statement* >::iterator stmt = stmts.begin(); stmt != stmts.end(); ++stmt ) { 105 for ( std::list< Statement* >::iterator stmt = stmts.begin(); ; ++stmt ) { 106 // add any new declarations after the previous statement 107 for ( std::list< Declaration* >::iterator decl = declsToAddAfter.back().begin(); decl != declsToAddAfter.back().end(); ++decl ) { 108 DeclStmt *declStmt = new DeclStmt( noLabels, *decl ); 109 stmts.insert( stmt, declStmt ); 110 } 111 declsToAddAfter.back().clear(); 112 113 if ( stmt == stmts.end() ) break; 114 84 115 // run mutator on statement 85 116 *stmt = maybeMutate( *stmt, *this ); … … 92 123 declsToAdd.back().clear(); 93 124 } 94 125 95 126 doEndScope(); 96 127 } … … 98 129 void DeclMutator::addDeclaration( Declaration *decl ) { 99 130 declsToAdd.back().push_back( decl ); 131 } 132 133 void DeclMutator::addDeclarationAfter( Declaration *decl ) { 134 declsToAddAfter.back().push_back( decl ); 100 135 } 101 136 -
src/GenPoly/DeclMutator.h
r39786813 ra5a71d0 55 55 /// Add a declaration to the list to be added before the current position 56 56 void addDeclaration( Declaration* decl ); 57 /// Add a declaration to the list to be added after the current position 58 void addDeclarationAfter( Declaration* decl ); 57 59 private: 58 60 /// A stack of declarations to add before the current declaration or statement 59 61 std::vector< std::list< Declaration* > > declsToAdd; 62 /// A stack of declarations to add after the current declaration or statement 63 std::vector< std::list< Declaration* > > declsToAddAfter; 60 64 }; 61 65 } // namespace -
src/GenPoly/module.mk
r39786813 ra5a71d0 23 23 GenPoly/CopyParams.cc \ 24 24 GenPoly/FindFunction.cc \ 25 GenPoly/InstantiateGeneric.cc \26 25 GenPoly/DeclMutator.cc
Note: See TracChangeset
for help on using the changeset viewer.