Changes in src/GenPoly/Box.cc [271a5d3:474a170]
- File:
-
- 1 edited
-
src/GenPoly/Box.cc (modified) (16 diffs)
Legend:
- Unmodified
- Added
- Removed
-
src/GenPoly/Box.cc
r271a5d3 r474a170 37 37 #include "InitTweak/InitTweak.h" // for getFunctionName, isAssignment 38 38 #include "Lvalue.h" // for generalizedLvalue 39 #include "ResolvExpr/TypeEnvironment.h" // for EqvClass40 39 #include "ResolvExpr/typeops.h" // for typesCompatible 41 40 #include "ScopedSet.h" // for ScopedSet, ScopedSet<>::iter... … … 95 94 private: 96 95 /// Pass the extra type parameters from polymorphic generic arguments or return types into a function application 97 void passArgTypeVars( ApplicationExpr *appExpr, Type *parmType, Type *argBaseType, std::list< Expression *>::iterator &arg, const TyVarMap &exprTyVars, std::set< std::string > &seenTypes ); 96 /// Will insert 0, 2 or 3 more arguments. 97 std::list< Expression *>::iterator passArgTypeVars( ApplicationExpr *appExpr, Type *parmType, Type *argBaseType, std::list< Expression *>::iterator arg, const TyVarMap &exprTyVars, std::set< std::string > &seenTypes ); 98 98 /// passes extra type parameters into a polymorphic function application 99 99 /// Returns an iterator to the first argument after the added … … 488 488 makeTyVarMap( functionType, scopeTyVars ); 489 489 490 std::list< DeclarationWithType *> ¶mList = functionType->parameters;491 490 std::list< FunctionType const *> functions; 492 491 for ( TypeDecl * const tyVar : functionType->forall ) { … … 495 494 } // for 496 495 } // for 497 for ( DeclarationWithType * const arg : paramList) {496 for ( DeclarationWithType * const arg : functionType->parameters ) { 498 497 findFunction( arg->get_type(), functions, scopeTyVars, needsAdapter ); 499 498 } // for … … 532 531 } 533 532 534 void Pass1::passArgTypeVars( ApplicationExpr *appExpr, Type *parmType, Type *argBaseType, std::list< Expression *>::iterator &arg, const TyVarMap &exprTyVars, std::set< std::string > &seenTypes ) {533 std::list< Expression *>::iterator Pass1::passArgTypeVars( ApplicationExpr *appExpr, Type *parmType, Type *argBaseType, std::list< Expression *>::iterator arg, const TyVarMap &exprTyVars, std::set< std::string > &seenTypes ) { 535 534 Type *polyType = isPolyType( parmType, exprTyVars ); 536 535 if ( polyType && ! dynamic_cast< TypeInstType* >( polyType ) ) { 537 536 std::string typeName = mangleType( polyType ); 538 if ( seenTypes.count( typeName ) ) return ;537 if ( seenTypes.count( typeName ) ) return arg; 539 538 540 539 arg = appExpr->get_args().insert( arg, new SizeofExpr( argBaseType->clone() ) ); … … 556 555 seenTypes.insert( typeName ); 557 556 } 557 return arg; 558 558 } 559 559 … … 562 562 std::list< Expression *>::iterator arg = appExpr->args.begin(); 563 563 // pass size/align for type variables 564 // NOTE: This is iterating over a map. This means the sorting 565 // order of the keys changes behaviour, as the iteration order 566 // is visible outside the loop. - The order matches the orignal 567 // order because the vars have been renamed with numbers that, 568 // even when converted to strings, sort in the original order. 569 // (At least, that is the best explination I have.) 564 570 for ( std::pair<std::string, TypeDecl::Data> const & tyParam : exprTyVars ) { 565 ResolvExpr::EqvClass eqvClass; 566 if ( tyParam.second.isComplete ) { 567 Type *concrete = env->lookup( tyParam.first ); 568 // If there is an unbound type variable, it should have detected already. 569 assertf( concrete, "Unbound type variable: %s in: %s", 570 toCString( tyParam.first ), toCString( *env ) ); 571 572 arg = appExpr->get_args().insert( arg, new SizeofExpr( concrete->clone() ) ); 573 arg++; 574 arg = appExpr->get_args().insert( arg, new AlignofExpr( concrete->clone() ) ); 575 arg++; 576 } // if 571 if ( !tyParam.second.isComplete ) continue; 572 Type *concrete = env->lookup( tyParam.first ); 573 // If there is an unbound type variable, it should have detected already. 574 assertf( concrete, "Unbound type variable: %s in: %s", 575 toCString( tyParam.first ), toCString( *env ) ); 576 577 arg = appExpr->get_args().insert( arg, new SizeofExpr( concrete->clone() ) ); 578 arg++; 579 arg = appExpr->get_args().insert( arg, new AlignofExpr( concrete->clone() ) ); 580 arg++; 577 581 } // for 578 582 … … 582 586 assert( funcType ); 583 587 584 // These iterators don't advance in unison.585 std::list< DeclarationWithType* >::const_iterator fnParm = funcType->get_parameters().begin();586 std::list< Expression* >::const_iterator fnArg = arg;587 std::set< std::string > seenTypes; ///< names for generic types we've seen588 // Iterator over the original function arguments. 589 std::list< Expression* >::const_iterator fnArg; 590 // Names for generic types we've seen. 591 std::set< std::string > seenTypes; 588 592 589 593 // a polymorphic return type may need to be added to the argument list 590 594 if ( polyRetType ) { 591 595 Type *concRetType = replaceWithConcrete( polyRetType, env ); 592 passArgTypeVars( appExpr, polyRetType, concRetType, arg, exprTyVars, seenTypes ); 593 ++fnArg; // skip the return parameter in the argument list 596 arg = passArgTypeVars( appExpr, polyRetType, concRetType, arg, exprTyVars, seenTypes ); 597 // Skip the return parameter in the argument list. 598 fnArg = arg + 1; 599 } else { 600 fnArg = arg; 594 601 } 595 602 596 603 // add type information args for presently unseen types in parameter list 604 std::list< DeclarationWithType* >::const_iterator fnParm = funcType->get_parameters().begin(); 597 605 for ( ; fnParm != funcType->get_parameters().end() && fnArg != appExpr->get_args().end(); ++fnParm, ++fnArg ) { 598 if ( ! (*fnArg)->get_result() ) continue;599 606 Type * argType = (*fnArg)->get_result(); 600 passArgTypeVars( appExpr, (*fnParm)->get_type(), argType, arg, exprTyVars, seenTypes ); 607 if ( ! argType ) continue; 608 arg = passArgTypeVars( appExpr, (*fnParm)->get_type(), argType, arg, exprTyVars, seenTypes ); 601 609 } 602 610 return arg; … … 680 688 Expression *Pass1::applyAdapter( ApplicationExpr *appExpr, FunctionType *function ) { 681 689 Expression *ret = appExpr; 682 // if ( ! function->get_returnVals().empty() && isPolyType( function->get_returnVals().front()->get_type(), tyVars ) ) {683 690 if ( isDynRet( function, scopeTyVars ) ) { 684 691 ret = addRetParam( appExpr, function->returnVals.front()->get_type() ); … … 772 779 773 780 void Pass1::addInferredParams( ApplicationExpr *appExpr, std::list< Expression *>::iterator arg, FunctionType *functionType, const TyVarMap &tyVars ) { 774 std::list< Expression *>::iterator cur = arg;775 781 for ( TypeDecl * const tyVar : functionType->forall ) { 776 782 for ( DeclarationWithType * const assert : tyVar->assertions ) { … … 779 785 Expression *newExpr = inferParam->second.expr->clone(); 780 786 boxParam( newExpr, assert->get_type(), tyVars ); 781 appExpr->get_args().insert( cur, newExpr ); 787 arg = appExpr->get_args().insert( arg, newExpr ); 788 ++arg; 782 789 } // for 783 790 } // for … … 922 929 // only attempt to create an adapter or pass one as a parameter if we haven't already done so for this 923 930 // pre-substitution parameter function type. 924 if ( adaptersDone.find( mangleName ) == adaptersDone.end() ) {925 adaptersDone.insert( adaptersDone.begin(), mangleName );931 // The second part of the insert result is "is the value new". 932 if ( adaptersDone.insert( mangleName ).second ) { 926 933 927 934 // apply substitution to type variables to figure out what the adapter's type should look like … … 1106 1113 1107 1114 Expression *ret = appExpr; 1115 // Save iterator to the first original parameter (works with lists). 1108 1116 std::list< Expression *>::iterator paramBegin = appExpr->get_args().begin(); 1109 1117 … … 1172 1180 1173 1181 void Pass1::premutate( AddressExpr * ) { visit_children = false; } 1182 1174 1183 Expression * Pass1::postmutate( AddressExpr * addrExpr ) { 1175 1184 assert( addrExpr->arg->result && ! addrExpr->arg->result->isVoid() ); … … 1232 1241 1233 1242 void Pass2::addAdapters( FunctionType *functionType ) { 1234 std::list< DeclarationWithType *> ¶mList = functionType->parameters;1235 1243 std::list< FunctionType const *> functions; 1236 1244 for ( DeclarationWithType * const arg : functionType->parameters ) { … … 1245 1253 std::string adapterName = makeAdapterName( mangleName ); 1246 1254 // adapter may not be used in body, pass along with unused attribute. 1247 paramList.push_front( new ObjectDecl( adapterName, Type::StorageClasses(), LinkageSpec::C, 0, new PointerType( Type::Qualifiers(), makeAdapterType( funType, scopeTyVars ) ), 0, { new Attribute( "unused" ) } ) ); 1255 functionType->parameters.push_front( 1256 new ObjectDecl( adapterName, Type::StorageClasses(), LinkageSpec::C, 0, new PointerType( Type::Qualifiers(), makeAdapterType( funType, scopeTyVars ) ), 0, { new Attribute( "unused" ) } ) ); 1248 1257 adaptersDone.insert( adaptersDone.begin(), mangleName ); 1249 1258 } 1250 1259 } 1251 // deleteAll( functions );1252 1260 } 1253 1261
Note:
See TracChangeset
for help on using the changeset viewer.