- File:
-
- 1 edited
-
src/ResolvExpr/AlternativeFinder.cc (modified) (33 diffs)
Legend:
- Unmodified
- Added
- Removed
-
src/ResolvExpr/AlternativeFinder.cc
rddf8a29 r322b97e 14 14 // 15 15 16 #include <algorithm> // for copy 17 #include <cassert> // for safe_dynamic_cast, assert, assertf 18 #include <iostream> // for operator<<, cerr, ostream, endl 19 #include <iterator> // for back_insert_iterator, back_inserter 20 #include <list> // for _List_iterator, list, _List_const_... 21 #include <map> // for _Rb_tree_iterator, map, _Rb_tree_c... 22 #include <memory> // for allocator_traits<>::value_type 23 #include <utility> // for pair 24 25 #include "Alternative.h" // for AltList, Alternative 16 #include <list> 17 #include <iterator> 18 #include <algorithm> 19 #include <functional> 20 #include <cassert> 21 #include <unordered_map> 22 #include <utility> 23 #include <vector> 24 26 25 #include "AlternativeFinder.h" 27 #include "Common/SemanticError.h" // for SemanticError 28 #include "Common/utility.h" // for deleteAll, printAll, CodeLocation 29 #include "Cost.h" // for Cost, Cost::zero, operator<<, Cost... 30 #include "InitTweak/InitTweak.h" // for getFunctionName 31 #include "RenameVars.h" // for RenameVars, global_renamer 32 #include "ResolveTypeof.h" // for resolveTypeof 33 #include "Resolver.h" // for resolveStmtExpr 34 #include "SymTab/Indexer.h" // for Indexer 35 #include "SymTab/Mangler.h" // for Mangler 36 #include "SymTab/Validate.h" // for validateType 37 #include "SynTree/Constant.h" // for Constant 38 #include "SynTree/Declaration.h" // for DeclarationWithType, TypeDecl, Dec... 39 #include "SynTree/Expression.h" // for Expression, CastExpr, NameExpr 40 #include "SynTree/Initializer.h" // for SingleInit, operator<<, Designation 41 #include "SynTree/SynTree.h" // for UniqueId 42 #include "SynTree/Type.h" // for Type, FunctionType, PointerType 43 #include "Tuples/Explode.h" // for explode 44 #include "Tuples/Tuples.h" // for isTtype, handleTupleAssignment 45 #include "Unify.h" // for unify 46 #include "typeops.h" // for adjustExprType, polyCost, castCost 26 #include "Alternative.h" 27 #include "Cost.h" 28 #include "typeops.h" 29 #include "Unify.h" 30 #include "RenameVars.h" 31 #include "SynTree/Type.h" 32 #include "SynTree/Declaration.h" 33 #include "SynTree/Expression.h" 34 #include "SynTree/Initializer.h" 35 #include "SynTree/Visitor.h" 36 #include "SymTab/Indexer.h" 37 #include "SymTab/Mangler.h" 38 #include "SynTree/TypeSubstitution.h" 39 #include "SymTab/Validate.h" 40 #include "Tuples/Tuples.h" 41 #include "Tuples/Explode.h" 42 #include "Common/utility.h" 43 #include "InitTweak/InitTweak.h" 44 #include "InitTweak/GenInit.h" 45 #include "ResolveTypeof.h" 46 #include "Resolver.h" 47 47 48 48 extern bool resolvep; … … 67 67 68 68 Cost sumCost( const AltList &in ) { 69 Cost total = Cost::zero;69 Cost total; 70 70 for ( AltList::const_iterator i = in.begin(); i != in.end(); ++i ) { 71 71 total += i->cost; … … 144 144 expr->get_result()->accept( global_renamer ); 145 145 } 146 147 void referenceToRvalueConversion( Expression *& expr ) { 148 if ( dynamic_cast< ReferenceType * >( expr->get_result() ) ) { 149 // cast away reference from expr 150 expr = new CastExpr( expr, expr->get_result()->stripReferences()->clone() ); 151 } 152 } 153 } // namespace 146 } 154 147 155 148 template< typename InputIterator, typename OutputIterator > … … 193 186 if ( alternatives.begin() == oldBegin ) { 194 187 std::ostringstream stream; 188 stream << "Can't choose between " << alternatives.size() << " alternatives for expression "; 189 expr->print( stream ); 190 stream << "Alternatives are:"; 195 191 AltList winners; 196 192 findMinCost( alternatives.begin(), alternatives.end(), back_inserter( winners ) ); 197 stream << "Can't choose between " << winners.size() << " alternatives for expression ";198 expr->print( stream );199 stream << "Alternatives are:";200 193 printAlts( winners, stream, 8 ); 201 194 throw SemanticError( stream.str() ); … … 220 213 void AlternativeFinder::addAnonConversions( const Alternative & alt ) { 221 214 // adds anonymous member interpretations whenever an aggregate value type is seen. 222 // it's okay for the aggregate expression to have reference type -- cast it to the base type to treat the aggregate as the referenced value 223 std::unique_ptr<Expression> aggrExpr( alt.expr->clone() ); 224 alt.env.apply( aggrExpr->get_result() ); 225 Type * aggrType = aggrExpr->get_result(); 226 if ( dynamic_cast< ReferenceType * >( aggrType ) ) { 227 aggrType = aggrType->stripReferences(); 228 aggrExpr.reset( new CastExpr( aggrExpr.release(), aggrType->clone() ) ); 229 } 230 231 if ( StructInstType *structInst = dynamic_cast< StructInstType* >( aggrExpr->get_result() ) ) { 215 Expression * expr = alt.expr->clone(); 216 std::unique_ptr< Expression > manager( expr ); // RAII for expr 217 alt.env.apply( expr->get_result() ); 218 if ( StructInstType *structInst = dynamic_cast< StructInstType* >( expr->get_result() ) ) { 232 219 NameExpr nameExpr( "" ); 233 addAggMembers( structInst, aggrExpr.get(), alt.cost+Cost::safe, alt.env, &nameExpr );234 } else if ( UnionInstType *unionInst = dynamic_cast< UnionInstType* >( aggrExpr->get_result() ) ) {220 addAggMembers( structInst, expr, alt.cost+Cost( 0, 0, 1 ), alt.env, &nameExpr ); 221 } else if ( UnionInstType *unionInst = dynamic_cast< UnionInstType* >( expr->get_result() ) ) { 235 222 NameExpr nameExpr( "" ); 236 addAggMembers( unionInst, aggrExpr.get(), alt.cost+Cost::safe, alt.env, &nameExpr );223 addAggMembers( unionInst, expr, alt.cost+Cost( 0, 0, 1 ), alt.env, &nameExpr ); 237 224 } // if 238 225 } … … 241 228 void AlternativeFinder::addAggMembers( StructOrUnionType *aggInst, Expression *expr, const Cost &newCost, const TypeEnvironment & env, Expression * member ) { 242 229 // by this point, member must be a name expr 243 NameExpr * nameExpr = dynamic_cast< NameExpr * >( member ); 244 if ( ! nameExpr ) return; 230 NameExpr * nameExpr = safe_dynamic_cast< NameExpr * >( member ); 245 231 const std::string & name = nameExpr->get_name(); 246 232 std::list< Declaration* > members; … … 264 250 // during parsing and reusing that information here. 265 251 std::stringstream ss( constantExpr->get_constant()->get_value() ); 266 int val = 0;252 int val; 267 253 std::string tmp; 268 254 if ( ss >> val && ! (ss >> tmp) ) { … … 286 272 } 287 273 288 Cost computeConversionCost( Type * actualType, Type * formalType, const SymTab::Indexer &indexer, const TypeEnvironment & env ) { 289 PRINT( 290 std::cerr << std::endl << "converting "; 291 actualType->print( std::cerr, 8 ); 292 std::cerr << std::endl << " to "; 293 formalType->print( std::cerr, 8 ); 294 std::cerr << std::endl << "environment is: "; 295 env.print( std::cerr, 8 ); 296 std::cerr << std::endl; 297 ) 298 Cost convCost = conversionCost( actualType, formalType, indexer, env ); 299 PRINT( 300 std::cerr << std::endl << "cost is" << convCost << std::endl; 301 ) 302 if ( convCost == Cost::infinity ) { 303 return convCost; 304 } 305 convCost.incPoly( polyCost( formalType, env, indexer ) + polyCost( actualType, env, indexer ) ); 306 return convCost; 307 } 308 309 Cost computeExpressionConversionCost( Expression *& actualExpr, Type * formalType, const SymTab::Indexer &indexer, const TypeEnvironment & env ) { 310 Cost convCost = computeConversionCost( actualExpr->result, formalType, indexer, env ); 311 // if ( convCost != Cost::zero ) { 312 313 // xxx - temporary -- ignore poly cost, since this causes some polymorphic functions to be cast, which causes the specialize 314 // pass to try to specialize them, which currently does not work. Once that is fixed, remove the next 3 lines and uncomment the 315 // previous line. 316 Cost tmpCost = convCost; 317 tmpCost.incPoly( -tmpCost.get_polyCost() ); 318 if ( tmpCost != Cost::zero ) { 319 Type *newType = formalType->clone(); 320 env.apply( newType ); 321 actualExpr = new CastExpr( actualExpr, newType ); 322 // xxx - SHOULD be able to resolve this cast, but at the moment pointers are not castable to zero_t, but are implicitly convertible. This is clearly 323 // inconsistent, once this is fixed it should be possible to resolve the cast. 324 // xxx - this isn't working, it appears because type1 (the formal type) is seen as widenable, but it shouldn't be, because this makes the conversion from DT* to DT* since commontype(zero_t, DT*) is DT*, rather than just nothing. 325 326 // AlternativeFinder finder( indexer, env ); 327 // finder.findWithAdjustment( actualExpr ); 328 // assertf( finder.get_alternatives().size() > 0, "Somehow castable expression failed to find alternatives." ); 329 // assertf( finder.get_alternatives().size() == 1, "Somehow got multiple alternatives for known cast expression." ); 330 // Alternative & alt = finder.get_alternatives().front(); 331 // delete actualExpr; 332 // actualExpr = alt.expr->clone(); 333 } 334 return convCost; 335 } 336 337 Cost computeApplicationConversionCost( Alternative &alt, const SymTab::Indexer &indexer ) { 274 Cost computeConversionCost( Alternative &alt, const SymTab::Indexer &indexer ) { 338 275 ApplicationExpr *appExpr = safe_dynamic_cast< ApplicationExpr* >( alt.expr ); 339 276 PointerType *pointer = safe_dynamic_cast< PointerType* >( appExpr->get_function()->get_result() ); 340 277 FunctionType *function = safe_dynamic_cast< FunctionType* >( pointer->get_base() ); 341 278 342 Cost convCost = Cost::zero;279 Cost convCost( 0, 0, 0 ); 343 280 std::list< DeclarationWithType* >& formals = function->get_parameters(); 344 281 std::list< DeclarationWithType* >::iterator formal = formals.begin(); … … 353 290 actualType->print( std::cerr, 8 ); 354 291 ) 292 Cost actualCost; 355 293 if ( formal == formals.end() ) { 356 294 if ( function->get_isVarArgs() ) { 357 convCost.incUnsafe(); 358 // convert reference-typed expressions to value-typed expressions 359 referenceToRvalueConversion( *actualExpr ); 295 convCost += Cost( 1, 0, 0 ); 360 296 continue; 361 297 } else { … … 369 305 std::cerr << std::endl << " to "; 370 306 formalType->print( std::cerr, 8 ); 371 std::cerr << std::endl << "environment is: "; 372 alt.env.print( std::cerr, 8 ); 373 std::cerr << std::endl; 374 ) 375 convCost += computeExpressionConversionCost( *actualExpr, formalType, indexer, alt.env ); 307 ) 308 Cost newCost = conversionCost( actualType, formalType, indexer, alt.env ); 309 PRINT( 310 std::cerr << std::endl << "cost is" << newCost << std::endl; 311 ) 312 313 if ( newCost == Cost::infinity ) { 314 return newCost; 315 } 316 convCost += newCost; 317 actualCost += newCost; 318 if ( actualCost != Cost( 0, 0, 0 ) ) { 319 Type *newType = formalType->clone(); 320 alt.env.apply( newType ); 321 *actualExpr = new CastExpr( *actualExpr, newType ); 322 } 323 convCost += Cost( 0, polyCost( formalType, alt.env, indexer ) + polyCost( actualType, alt.env, indexer ), 0 ); 376 324 ++formal; // can't be in for-loop update because of the continue 377 325 } … … 381 329 382 330 for ( InferredParams::const_iterator assert = appExpr->get_inferParams().begin(); assert != appExpr->get_inferParams().end(); ++assert ) { 383 convCost += computeConversionCost( assert->second.actualType, assert->second.formalType, indexer, alt.env ); 331 PRINT( 332 std::cerr << std::endl << "converting "; 333 assert->second.actualType->print( std::cerr, 8 ); 334 std::cerr << std::endl << " to "; 335 assert->second.formalType->print( std::cerr, 8 ); 336 ) 337 Cost newCost = conversionCost( assert->second.actualType, assert->second.formalType, indexer, alt.env ); 338 PRINT( 339 std::cerr << std::endl << "cost of conversion is " << newCost << std::endl; 340 ) 341 if ( newCost == Cost::infinity ) { 342 return newCost; 343 } 344 convCost += newCost; 345 convCost += Cost( 0, polyCost( assert->second.formalType, alt.env, indexer ) + polyCost( assert->second.actualType, alt.env, indexer ), 0 ); 384 346 } 385 347 … … 438 400 Expression * actual = actualIt->expr; 439 401 Type * actualType = actual->get_result(); 440 441 402 PRINT( 442 403 std::cerr << "formal type is "; … … 447 408 ) 448 409 if ( ! unify( formalType, actualType, resultEnv, resultNeed, resultHave, openVars, indexer ) ) { 449 // std::cerr << "unify failed" << std::endl;450 410 return false; 451 411 } … … 492 452 // match flattened actuals with formal parameters - actuals will be grouped to match 493 453 // with formals as appropriate 494 Cost cost = Cost::zero;454 Cost cost; 495 455 std::list< Expression * > newExprs; 496 456 ObjectDecl * obj = safe_dynamic_cast< ObjectDecl * >( formal ); … … 653 613 AssertionSet newNeed; 654 614 //AssertionParentSet needParents; 655 PRINT(656 std::cerr << "env is: " << std::endl;657 newAlt.env.print( std::cerr, 0 );658 std::cerr << std::endl;659 )660 661 615 inferRecursive( need.begin(), need.end(), newAlt, openVars, decls, newNeed, /*needParents,*/ 0, indexer, out ); 662 616 // PRINT( … … 689 643 makeExprList( instantiatedActuals, appExpr->get_args() ); 690 644 PRINT( 691 std::cerr << "instantiate function success: " << appExpr << std::endl;692 645 std::cerr << "need assertions:" << std::endl; 693 646 printAssertionSet( resultNeed, std::cerr, 8 ); … … 710 663 UntypedExpr *vexpr = untypedExpr->clone(); 711 664 vexpr->set_result( pt.clone() ); 712 alternatives.push_back( Alternative( vexpr, env, Cost ::zero) );665 alternatives.push_back( Alternative( vexpr, env, Cost()) ); 713 666 return; 714 667 } … … 728 681 AltList candidates; 729 682 SemanticError errors; 730 for ( AltList:: iterator func = funcFinder.alternatives.begin(); func != funcFinder.alternatives.end(); ++func ) {683 for ( AltList::const_iterator func = funcFinder.alternatives.begin(); func != funcFinder.alternatives.end(); ++func ) { 731 684 try { 732 685 PRINT( … … 735 688 ) 736 689 // check if the type is pointer to function 737 if ( PointerType *pointer = dynamic_cast< PointerType* >( func->expr->get_result()->stripReferences() ) ) { 690 PointerType *pointer; 691 if ( ( pointer = dynamic_cast< PointerType* >( func->expr->get_result() ) ) ) { 738 692 if ( FunctionType *function = dynamic_cast< FunctionType* >( pointer->get_base() ) ) { 739 referenceToRvalueConversion( func->expr );740 693 for ( std::list< AltList >::iterator actualAlt = possibilities.begin(); actualAlt != possibilities.end(); ++actualAlt ) { 741 694 // XXX … … 743 696 makeFunctionAlternatives( *func, function, *actualAlt, std::back_inserter( candidates ) ); 744 697 } 745 } 746 } else if ( TypeInstType *typeInst = dynamic_cast< TypeInstType* >( func->expr->get_result()->stripReferences() ) ) { // handle ftype (e.g. *? on function pointer) 747 referenceToRvalueConversion( func->expr ); 748 EqvClass eqvClass; 749 if ( func->env.lookup( typeInst->get_name(), eqvClass ) && eqvClass.type ) { 750 if ( FunctionType *function = dynamic_cast< FunctionType* >( eqvClass.type ) ) { 751 for ( std::list< AltList >::iterator actualAlt = possibilities.begin(); actualAlt != possibilities.end(); ++actualAlt ) { 752 makeFunctionAlternatives( *func, function, *actualAlt, std::back_inserter( candidates ) ); 753 } // for 698 } else if ( TypeInstType *typeInst = dynamic_cast< TypeInstType* >( pointer->get_base() ) ) { 699 EqvClass eqvClass; 700 if ( func->env.lookup( typeInst->get_name(), eqvClass ) && eqvClass.type ) { 701 if ( FunctionType *function = dynamic_cast< FunctionType* >( eqvClass.type ) ) { 702 for ( std::list< AltList >::iterator actualAlt = possibilities.begin(); actualAlt != possibilities.end(); ++actualAlt ) { 703 makeFunctionAlternatives( *func, function, *actualAlt, std::back_inserter( candidates ) ); 704 } // for 705 } // if 754 706 } // if 755 707 } // if … … 770 722 } 771 723 772 for ( AltList:: iterator funcOp = funcOpFinder.alternatives.begin(); funcOp != funcOpFinder.alternatives.end(); ++funcOp ) {724 for ( AltList::const_iterator funcOp = funcOpFinder.alternatives.begin(); funcOp != funcOpFinder.alternatives.end(); ++funcOp ) { 773 725 // check if the type is pointer to function 774 if ( PointerType *pointer = dynamic_cast< PointerType* >( funcOp->expr->get_result()->stripReferences() ) ) { 726 PointerType *pointer; 727 if ( ( pointer = dynamic_cast< PointerType* >( funcOp->expr->get_result() ) ) ) { 775 728 if ( FunctionType *function = dynamic_cast< FunctionType* >( pointer->get_base() ) ) { 776 referenceToRvalueConversion( funcOp->expr );777 729 for ( std::list< AltList >::iterator actualAlt = possibilities.begin(); actualAlt != possibilities.end(); ++actualAlt ) { 778 730 AltList currentAlt; … … 795 747 // compute conversionsion costs 796 748 for ( AltList::iterator withFunc = candidates.begin(); withFunc != candidates.end(); ++withFunc ) { 797 Cost cvtCost = compute ApplicationConversionCost( *withFunc, indexer );749 Cost cvtCost = computeConversionCost( *withFunc, indexer ); 798 750 799 751 PRINT( … … 801 753 PointerType *pointer = safe_dynamic_cast< PointerType* >( appExpr->get_function()->get_result() ); 802 754 FunctionType *function = safe_dynamic_cast< FunctionType* >( pointer->get_base() ); 803 std::cerr << "Case +++++++++++++ " << appExpr->get_function()<< std::endl;755 std::cerr << "Case +++++++++++++" << std::endl; 804 756 std::cerr << "formals are:" << std::endl; 805 757 printAll( function->get_parameters(), std::cerr, 8 ); … … 844 796 bool isLvalue( Expression *expr ) { 845 797 // xxx - recurse into tuples? 846 return expr->has_result() && ( expr->get_result()->get_lvalue() || dynamic_cast< ReferenceType * >( expr->get_result() ));798 return expr->has_result() && expr->get_result()->get_lvalue(); 847 799 } 848 800 … … 858 810 859 811 Expression * restructureCast( Expression * argExpr, Type * toType ) { 860 if ( argExpr->get_result()->size() > 1 && ! toType->isVoid() && ! dynamic_cast<ReferenceType *>( toType ) ) { 861 // Argument expression is a tuple and the target type is not void and not a reference type. 862 // Cast each member of the tuple to its corresponding target type, producing the tuple of those 863 // cast expressions. If there are more components of the tuple than components in the target type, 864 // then excess components do not come out in the result expression (but UniqueExprs ensure that 865 // side effects will still be done). 866 if ( Tuples::maybeImpureIgnoreUnique( argExpr ) ) { 812 if ( argExpr->get_result()->size() > 1 && ! toType->isVoid() ) { 813 // Argument expression is a tuple and the target type is not void. Cast each member of the tuple 814 // to its corresponding target type, producing the tuple of those cast expressions. If there are 815 // more components of the tuple than components in the target type, then excess components do not 816 // come out in the result expression (but UniqueExprs ensure that side effects will still be done). 817 if ( Tuples::maybeImpure( argExpr ) && ! dynamic_cast< UniqueExpr * >( argExpr ) ) { 867 818 // expressions which may contain side effects require a single unique instance of the expression. 868 819 argExpr = new UniqueExpr( argExpr ); … … 904 855 // that are cast directly. The candidate is invalid if it has fewer results than there are types to cast 905 856 // to. 906 int discardedValues = i->expr->get_result()->size() - castExpr->get_result()->size();857 int discardedValues = (*i).expr->get_result()->size() - castExpr->get_result()->size(); 907 858 if ( discardedValues < 0 ) continue; 908 859 // xxx - may need to go into tuple types and extract relevant types and use unifyList. Note that currently, this does not 909 860 // allow casting a tuple to an atomic type (e.g. (int)([1, 2, 3])) 910 861 // unification run for side-effects 911 unify( castExpr->get_result(), i->expr->get_result(), i->env, needAssertions, haveAssertions, openVars, indexer );912 Cost thisCost = castCost( i->expr->get_result(), castExpr->get_result(), indexer, i->env );862 unify( castExpr->get_result(), (*i).expr->get_result(), i->env, needAssertions, haveAssertions, openVars, indexer ); 863 Cost thisCost = castCost( (*i).expr->get_result(), castExpr->get_result(), indexer, i->env ); 913 864 if ( thisCost != Cost::infinity ) { 914 865 // count one safe conversion for each value that is thrown away 915 thisCost.incSafe( discardedValues ); 916 Alternative newAlt( restructureCast( i->expr->clone(), toType ), i->env, i->cost, thisCost ); 917 // xxx - this doesn't work at the moment, since inferParameters requires an ApplicationExpr as the alternative. 918 // Once this works, it should be possible to infer parameters on a cast expression and specialize any function. 919 920 // inferParameters( needAssertions, haveAssertions, newAlt, openVars, back_inserter( candidates ) ); 921 candidates.emplace_back( std::move( newAlt ) ); 866 thisCost += Cost( 0, 0, discardedValues ); 867 868 candidates.push_back( Alternative( restructureCast( i->expr->clone(), toType ), i->env, i->cost, thisCost ) ); 922 869 } // if 923 870 } // for … … 948 895 funcFinder.findWithAdjustment( memberExpr->get_aggregate() ); 949 896 for ( AltList::const_iterator agg = funcFinder.alternatives.begin(); agg != funcFinder.alternatives.end(); ++agg ) { 950 // it's okay for the aggregate expression to have reference type -- cast it to the base type to treat the aggregate as the referenced value 951 std::unique_ptr<Expression> aggrExpr( agg->expr->clone() ); 952 Type * aggrType = aggrExpr->get_result(); 953 if ( dynamic_cast< ReferenceType * >( aggrType ) ) { 954 aggrType = aggrType->stripReferences(); 955 aggrExpr.reset( new CastExpr( aggrExpr.release(), aggrType->clone() ) ); 956 } 957 // find member of the given type 958 if ( StructInstType *structInst = dynamic_cast< StructInstType* >( aggrExpr->get_result() ) ) { 959 addAggMembers( structInst, aggrExpr.get(), agg->cost, agg->env, memberExpr->get_member() ); 960 } else if ( UnionInstType *unionInst = dynamic_cast< UnionInstType* >( aggrExpr->get_result() ) ) { 961 addAggMembers( unionInst, aggrExpr.get(), agg->cost, agg->env, memberExpr->get_member() ); 962 } else if ( TupleType * tupleType = dynamic_cast< TupleType * >( aggrExpr->get_result() ) ) { 963 addTupleMembers( tupleType, aggrExpr.get(), agg->cost, agg->env, memberExpr->get_member() ); 897 if ( StructInstType *structInst = dynamic_cast< StructInstType* >( agg->expr->get_result() ) ) { 898 addAggMembers( structInst, agg->expr, agg->cost, agg->env, memberExpr->get_member() ); 899 } else if ( UnionInstType *unionInst = dynamic_cast< UnionInstType* >( agg->expr->get_result() ) ) { 900 addAggMembers( unionInst, agg->expr, agg->cost, agg->env, memberExpr->get_member() ); 901 } else if ( TupleType * tupleType = dynamic_cast< TupleType * >( agg->expr->get_result() ) ) { 902 addTupleMembers( tupleType, agg->expr, agg->cost, agg->env, memberExpr->get_member() ); 964 903 } // if 965 904 } // for … … 976 915 for ( std::list< DeclarationWithType* >::iterator i = declList.begin(); i != declList.end(); ++i ) { 977 916 VariableExpr newExpr( *i, nameExpr->get_argName() ); 978 alternatives.push_back( Alternative( newExpr.clone(), env, Cost ::zero) );917 alternatives.push_back( Alternative( newExpr.clone(), env, Cost() ) ); 979 918 PRINT( 980 919 std::cerr << "decl is "; … … 1016 955 // return the lowest cost alternative for the argument 1017 956 Alternative &choice = winners.front(); 1018 referenceToRvalueConversion( choice.expr );1019 957 alternatives.push_back( Alternative( new SizeofExpr( choice.expr->clone() ), choice.env, Cost::zero ) ); 1020 958 } // if … … 1037 975 // return the lowest cost alternative for the argument 1038 976 Alternative &choice = winners.front(); 1039 referenceToRvalueConversion( choice.expr );1040 977 alternatives.push_back( Alternative( new AlignofExpr( choice.expr->clone() ), choice.env, Cost::zero ) ); 1041 978 } // if … … 1122 1059 for ( std::list< DeclarationWithType* >::iterator i = attrList.begin(); i != attrList.end(); ++i ) { 1123 1060 VariableExpr newExpr( *i ); 1124 alternatives.push_back( Alternative( newExpr.clone(), env, Cost ::zero) );1061 alternatives.push_back( Alternative( newExpr.clone(), env, Cost() ) ); 1125 1062 renameTypes( alternatives.back().expr ); 1126 1063 } // for … … 1162 1099 ConditionalExpr *newExpr = new ConditionalExpr( first->expr->clone(), second->expr->clone(), third->expr->clone() ); 1163 1100 newExpr->set_result( commonType ? commonType : second->expr->get_result()->clone() ); 1164 // convert both options to the conditional result type1165 newAlt.cost += computeExpressionConversionCost( newExpr->arg2, newExpr->result, indexer, newAlt.env );1166 newAlt.cost += computeExpressionConversionCost( newExpr->arg3, newExpr->result, indexer, newAlt.env );1167 1101 newAlt.expr = newExpr; 1168 1102 inferParameters( needAssertions, haveAssertions, newAlt, openVars, back_inserter( alternatives ) ); … … 1298 1232 if ( thisCost != Cost::infinity ) { 1299 1233 // count one safe conversion for each value that is thrown away 1300 thisCost .incSafe(discardedValues );1234 thisCost += Cost( 0, 0, discardedValues ); 1301 1235 candidates.push_back( Alternative( new InitExpr( restructureCast( alt.expr->clone(), toType ), initAlt.designation->clone() ), newEnv, alt.cost, thisCost ) ); 1302 1236 }
Note:
See TracChangeset
for help on using the changeset viewer.