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