- File:
-
- 1 edited
-
src/ResolvExpr/AlternativeFinder.cc (modified) (55 diffs)
Legend:
- Unmodified
- Added
- Removed
-
src/ResolvExpr/AlternativeFinder.cc
r8e18b8e ra8706fc 21 21 #include <list> // for _List_iterator, list, _List_const_... 22 22 #include <map> // for _Rb_tree_iterator, map, _Rb_tree_c... 23 #include <memory> // for allocator_traits<>::value_type 23 #include <memory> // for allocator_traits<>::value_type, unique_ptr 24 24 #include <utility> // for pair 25 25 #include <vector> // for vector … … 35 35 #include "ResolveTypeof.h" // for resolveTypeof 36 36 #include "Resolver.h" // for resolveStmtExpr 37 #include "Common/GC.h" // for new_static_root38 37 #include "SymTab/Indexer.h" // for Indexer 39 38 #include "SymTab/Mangler.h" // for Mangler … … 102 101 void addAnonConversions( const Alternative & alt ); 103 102 /// Adds alternatives for member expressions, given the aggregate, conversion cost for that aggregate, and name of the member 104 template< typename StructOrUnionType > void addAggMembers( StructOrUnionType *aggInst, Expression *expr, const Cost &newCost, const TypeEnvironment & env, const std::string & name);103 template< typename StructOrUnionType > void addAggMembers( StructOrUnionType *aggInst, Expression *expr, const Cost &newCost, const TypeEnvironment & env, Expression * member ); 105 104 /// Adds alternatives for member expressions where the left side has tuple type 106 105 void addTupleMembers( TupleType * tupleType, Expression *expr, const Cost &newCost, const TypeEnvironment & env, Expression * member ); … … 166 165 candidate->env.apply( newType ); 167 166 mangleName = SymTab::Mangler::mangle( newType ); 167 delete newType; 168 168 } 169 169 std::map< std::string, PruneStruct >::iterator mapPlace = selected.find( mangleName ); … … 297 297 // adds anonymous member interpretations whenever an aggregate value type is seen. 298 298 // 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 299 Expression* aggrExpr = alt.expr->clone();299 std::unique_ptr<Expression> aggrExpr( alt.expr->clone() ); 300 300 alt.env.apply( aggrExpr->get_result() ); 301 301 Type * aggrType = aggrExpr->get_result(); 302 302 if ( dynamic_cast< ReferenceType * >( aggrType ) ) { 303 303 aggrType = aggrType->stripReferences(); 304 aggrExpr = new CastExpr{ aggrExpr, aggrType->clone() };304 aggrExpr.reset( new CastExpr( aggrExpr.release(), aggrType->clone() ) ); 305 305 } 306 306 307 307 if ( StructInstType *structInst = dynamic_cast< StructInstType* >( aggrExpr->get_result() ) ) { 308 addAggMembers( structInst, aggrExpr, alt.cost+Cost::safe, alt.env, "" ); 308 NameExpr nameExpr( "" ); 309 addAggMembers( structInst, aggrExpr.get(), alt.cost+Cost::safe, alt.env, &nameExpr ); 309 310 } else if ( UnionInstType *unionInst = dynamic_cast< UnionInstType* >( aggrExpr->get_result() ) ) { 310 addAggMembers( unionInst, aggrExpr, alt.cost+Cost::safe, alt.env, "" ); 311 NameExpr nameExpr( "" ); 312 addAggMembers( unionInst, aggrExpr.get(), alt.cost+Cost::safe, alt.env, &nameExpr ); 311 313 } // if 312 314 } 313 315 314 316 template< typename StructOrUnionType > 315 void AlternativeFinder::Finder::addAggMembers( StructOrUnionType *aggInst, Expression *expr, const Cost &newCost, const TypeEnvironment & env, const std::string & name ) { 317 void AlternativeFinder::Finder::addAggMembers( StructOrUnionType *aggInst, Expression *expr, const Cost &newCost, const TypeEnvironment & env, Expression * member ) { 318 // by this point, member must be a name expr 319 NameExpr * nameExpr = dynamic_cast< NameExpr * >( member ); 320 if ( ! nameExpr ) return; 321 const std::string & name = nameExpr->get_name(); 316 322 std::list< Declaration* > members; 317 323 aggInst->lookup( name, members ); … … 338 344 if ( ss >> val && ! (ss >> tmp) ) { 339 345 if ( val >= 0 && (unsigned int)val < tupleType->size() ) { 340 alternatives.push_back( Alternative( new TupleIndexExpr( expr , val ), env, newCost ) );346 alternatives.push_back( Alternative( new TupleIndexExpr( expr->clone(), val ), env, newCost ) ); 341 347 } // if 342 348 } // if … … 347 353 int val; 348 354 ss >> val; 349 alternatives.push_back( Alternative( new TupleIndexExpr( expr , val ), env, newCost ) );355 alternatives.push_back( Alternative( new TupleIndexExpr( expr->clone(), val ), env, newCost ) ); 350 356 } 351 357 } // if … … 353 359 354 360 void AlternativeFinder::Finder::postvisit( ApplicationExpr *applicationExpr ) { 355 alternatives.push_back( Alternative( applicationExpr , env, Cost::zero ) );361 alternatives.push_back( Alternative( applicationExpr->clone(), env, Cost::zero ) ); 356 362 } 357 363 … … 462 468 } 463 469 470 // /// Map of declaration uniqueIds (intended to be the assertions in an AssertionSet) to their parents and the number of times they've been included 471 //typedef std::unordered_map< UniqueId, std::unordered_map< UniqueId, unsigned > > AssertionParentSet; 472 464 473 static const int recursionLimit = /*10*/ 4; ///< Limit to depth of recursion satisfaction 474 //static const unsigned recursionParentLimit = 1; ///< Limit to the number of times an assertion can recursively use itself 465 475 466 476 void addToIndexer( AssertionSet &assertSet, SymTab::Indexer &indexer ) { … … 473 483 474 484 template< typename ForwardIterator, typename OutputIterator > 475 void inferRecursive( ForwardIterator begin, ForwardIterator end, const Alternative &newAlt, OpenVarSet &openVars, const SymTab::Indexer &decls, const AssertionSet &newNeed, int level, const SymTab::Indexer &indexer, OutputIterator out ) { 485 void inferRecursive( ForwardIterator begin, ForwardIterator end, const Alternative &newAlt, OpenVarSet &openVars, const SymTab::Indexer &decls, const AssertionSet &newNeed, /*const AssertionParentSet &needParents,*/ 486 int level, const SymTab::Indexer &indexer, OutputIterator out ) { 476 487 if ( begin == end ) { 477 488 if ( newNeed.empty() ) { … … 491 502 printAssertionSet( newNeed, std::cerr, 8 ); 492 503 ) 493 inferRecursive( newNeed.begin(), newNeed.end(), newAlt, openVars, decls, newerNeed, level+1, indexer, out );504 inferRecursive( newNeed.begin(), newNeed.end(), newAlt, openVars, decls, newerNeed, /*needParents,*/ level+1, indexer, out ); 494 505 return; 495 506 } … … 498 509 ForwardIterator cur = begin++; 499 510 if ( ! cur->second.isUsed ) { 500 inferRecursive( begin, end, newAlt, openVars, decls, newNeed, level, indexer, out );511 inferRecursive( begin, end, newAlt, openVars, decls, newNeed, /*needParents,*/ level, indexer, out ); 501 512 return; // xxx - should this continue? previously this wasn't here, and it looks like it should be 502 513 } … … 551 562 } 552 563 564 //AssertionParentSet newNeedParents( needParents ); 565 // skip repeatingly-self-recursive assertion satisfaction 566 // DOESN'T WORK: grandchild nodes conflict with their cousins 567 //if ( newNeedParents[ curDecl->get_uniqueId() ][ candDecl->get_uniqueId() ]++ > recursionParentLimit ) continue; 568 553 569 Expression *varExpr = data.combine( newerAlt.cvtCost ); 570 delete varExpr->get_result(); 554 571 varExpr->set_result( adjType->clone() ); 555 572 PRINT( … … 565 582 inferParameters = (*inferParameters)[ id ].inferParams.get(); 566 583 } 567 568 (*inferParameters)[ curDecl->get_uniqueId() ] = ParamEntry( candidate->get_uniqueId(), adjType, curDecl->get_type(), varExpr ); 569 inferRecursive( begin, end, newerAlt, newOpenVars, newDecls, newerNeed, level, indexer, out ); 584 // XXX: this is a memory leak, but adjType can't be deleted because it might contain assertions 585 (*inferParameters)[ curDecl->get_uniqueId() ] = ParamEntry( candidate->get_uniqueId(), adjType->clone(), curDecl->get_type()->clone(), varExpr ); 586 inferRecursive( begin, end, newerAlt, newOpenVars, newDecls, newerNeed, /*newNeedParents,*/ level, indexer, out ); 587 } else { 588 delete adjType; 570 589 } 571 590 } … … 587 606 addToIndexer( have, decls ); 588 607 AssertionSet newNeed; 608 //AssertionParentSet needParents; 589 609 PRINT( 590 610 std::cerr << "env is: " << std::endl; … … 593 613 ) 594 614 595 inferRecursive( need.begin(), need.end(), newAlt, openVars, decls, newNeed, 0, indexer, out );615 inferRecursive( need.begin(), need.end(), newAlt, openVars, decls, newNeed, /*needParents,*/ 0, indexer, out ); 596 616 // PRINT( 597 617 // std::cerr << "declaration 14 is "; … … 614 634 struct ArgPack { 615 635 std::size_t parent; ///< Index of parent pack 616 Expression* expr;///< The argument stored here636 std::unique_ptr<Expression> expr; ///< The argument stored here 617 637 Cost cost; ///< The cost of this argument 618 638 TypeEnvironment env; ///< Environment for this pack … … 626 646 627 647 ArgPack() 628 : parent(0), expr( nullptr), cost(Cost::zero), env(), need(), have(), openVars(),629 nextArg(0),tupleStart(0), nextExpl(0), explAlt(0) {}648 : parent(0), expr(), cost(Cost::zero), env(), need(), have(), openVars(), nextArg(0), 649 tupleStart(0), nextExpl(0), explAlt(0) {} 630 650 631 651 ArgPack(const TypeEnvironment& env, const AssertionSet& need, const AssertionSet& have, 632 652 const OpenVarSet& openVars) 633 : parent(0), expr( nullptr), cost(Cost::zero), env(env), need(need), have(have),653 : parent(0), expr(), cost(Cost::zero), env(env), need(need), have(have), 634 654 openVars(openVars), nextArg(0), tupleStart(0), nextExpl(0), explAlt(0) {} 635 655 … … 638 658 unsigned tupleStart = 0, Cost cost = Cost::zero, unsigned nextExpl = 0, 639 659 unsigned explAlt = 0 ) 640 : parent(parent), expr(expr ), cost(cost), env(move(env)), need(move(need)),660 : parent(parent), expr(expr->clone()), cost(cost), env(move(env)), need(move(need)), 641 661 have(move(have)), openVars(move(openVars)), nextArg(nextArg), tupleStart(tupleStart), 642 662 nextExpl(nextExpl), explAlt(explAlt) {} … … 644 664 ArgPack(const ArgPack& o, TypeEnvironment&& env, AssertionSet&& need, AssertionSet&& have, 645 665 OpenVarSet&& openVars, unsigned nextArg, Cost added ) 646 : parent(o.parent), expr(o.expr ), cost(o.cost + added), env(move(env)),647 need(move(need)), have(move(have)), openVars(move(openVars)), nextArg(nextArg),648 tupleStart(o.tupleStart), nextExpl(0), explAlt(0) {}666 : parent(o.parent), expr(o.expr ? o.expr->clone() : nullptr), cost(o.cost + added), 667 env(move(env)), need(move(need)), have(move(have)), openVars(move(openVars)), 668 nextArg(nextArg), tupleStart(o.tupleStart), nextExpl(0), explAlt(0) {} 649 669 650 670 /// true iff this pack is in the middle of an exploded argument … … 661 681 std::list<Expression*> exprs; 662 682 const ArgPack* pack = this; 663 if ( expr ) { exprs.push_front( expr ); }683 if ( expr ) { exprs.push_front( expr.release() ); } 664 684 while ( pack->tupleStart == 0 ) { 665 685 pack = &packs[pack->parent]; 666 exprs.push_front( pack->expr );686 exprs.push_front( pack->expr->clone() ); 667 687 cost += pack->cost; 668 688 } 669 689 // reset pack to appropriate tuple 670 expr = new TupleExpr{ exprs };690 expr.reset( new TupleExpr( exprs ) ); 671 691 tupleStart = pack->tupleStart - 1; 672 692 parent = pack->parent; … … 721 741 722 742 results.emplace_back( 723 i, expl.exprs[results[i].nextExpl] , copy(results[i].env),743 i, expl.exprs[results[i].nextExpl].get(), copy(results[i].env), 724 744 copy(results[i].need), copy(results[i].have), 725 745 copy(results[i].openVars), nextArg, nTuples, Cost::zero, nextExpl, … … 742 762 newResult.parent = i; 743 763 std::list<Expression*> emptyList; 744 newResult.expr = new TupleExpr{ emptyList };764 newResult.expr.reset( new TupleExpr( emptyList ) ); 745 765 argType = newResult.expr->get_result(); 746 766 } else { … … 749 769 newResult.cost = results[i].cost; 750 770 newResult.tupleStart = results[i].tupleStart; 751 newResult.expr = results[i].expr;771 newResult.expr.reset( results[i].expr->clone() ); 752 772 argType = newResult.expr->get_result(); 753 773 … … 799 819 // add new result 800 820 results.emplace_back( 801 i, expl.exprs.front() , move(env), copy(results[i].need),821 i, expl.exprs.front().get(), move(env), copy(results[i].need), 802 822 copy(results[i].have), move(openVars), nextArg + 1, 803 823 nTuples, expl.cost, expl.exprs.size() == 1 ? 0 : 1, j ); … … 825 845 if ( results[i].hasExpl() ) { 826 846 const ExplodedActual& expl = results[i].getExpl( args ); 827 Expression* expr = expl.exprs[results[i].nextExpl] ;847 Expression* expr = expl.exprs[results[i].nextExpl].get(); 828 848 829 849 TypeEnvironment env = results[i].env; … … 896 916 897 917 // consider only first exploded actual 898 Expression* expr = expl.exprs.front() ;918 Expression* expr = expl.exprs.front().get(); 899 919 Type* actualType = expr->result->clone(); 900 920 … … 924 944 925 945 template<typename OutputIterator> 926 void AlternativeFinder::Finder::validateFunctionAlternative( const Alternative &func, 927 ArgPack& result,const std::vector<ArgPack>& results, OutputIterator out ) {928 ApplicationExpr *appExpr = new ApplicationExpr( func.expr );946 void AlternativeFinder::Finder::validateFunctionAlternative( const Alternative &func, ArgPack& result, 947 const std::vector<ArgPack>& results, OutputIterator out ) { 948 ApplicationExpr *appExpr = new ApplicationExpr( func.expr->clone() ); 929 949 // sum cost and accumulate actuals 930 950 std::list<Expression*>& args = appExpr->args; … … 932 952 const ArgPack* pack = &result; 933 953 while ( pack->expr ) { 934 args.push_front( pack->expr );954 args.push_front( pack->expr->clone() ); 935 955 cost += pack->cost; 936 956 pack = &results[pack->parent]; … … 999 1019 1000 1020 results.emplace_back( 1001 i, expl.exprs[results[i].nextExpl] , copy(results[i].env),1021 i, expl.exprs[results[i].nextExpl].get(), copy(results[i].env), 1002 1022 copy(results[i].need), copy(results[i].have), 1003 1023 copy(results[i].openVars), nextArg, 0, Cost::zero, nextExpl, … … 1035 1055 // add new result 1036 1056 results.emplace_back( 1037 i, expl.exprs.front() , move(env), copy(results[i].need),1057 i, expl.exprs.front().get(), move(env), copy(results[i].need), 1038 1058 copy(results[i].have), move(openVars), nextArg + 1, 0, 1039 1059 expl.cost, expl.exprs.size() == 1 ? 0 : 1, j ); … … 1069 1089 1070 1090 // find function operators 1071 static auto *opExpr = new_static_root<NameExpr>( "?()" );1091 static NameExpr *opExpr = new NameExpr( "?()" ); 1072 1092 AlternativeFinder funcOpFinder( indexer, env ); 1073 1093 // it's ok if there aren't any defined function ops 1074 funcOpFinder.maybeFind( opExpr );1094 funcOpFinder.maybeFind( opExpr); 1075 1095 PRINT( 1076 1096 std::cerr << "known function ops:" << std::endl; … … 1101 1121 ) 1102 1122 // check if the type is pointer to function 1103 if ( PointerType *pointer = dynamic_cast< PointerType* >( func->expr-> get_result()->stripReferences() ) ) {1104 if ( FunctionType *function = dynamic_cast< FunctionType* >( pointer-> get_base()) ) {1123 if ( PointerType *pointer = dynamic_cast< PointerType* >( func->expr->result->stripReferences() ) ) { 1124 if ( FunctionType *function = dynamic_cast< FunctionType* >( pointer->base ) ) { 1105 1125 Alternative newFunc( *func ); 1106 1126 referenceToRvalueConversion( newFunc.expr, newFunc.cost ); … … 1108 1128 std::back_inserter( candidates ) ); 1109 1129 } 1110 } else if ( TypeInstType *typeInst = dynamic_cast< TypeInstType* >( func->expr->get_result()->stripReferences() ) ) { // handle ftype (e.g. *? on function pointer) 1111 if ( const EqvClass *eqvClass = func->env.lookup( typeInst->get_name() ) ) { 1112 if ( FunctionType *function = dynamic_cast< FunctionType* >( eqvClass->type ) ) { 1130 } else if ( TypeInstType *typeInst = dynamic_cast< TypeInstType* >( func->expr->result->stripReferences() ) ) { // handle ftype (e.g. *? on function pointer) 1131 EqvClass eqvClass; 1132 if ( func->env.lookup( typeInst->name, eqvClass ) && eqvClass.type ) { 1133 if ( FunctionType *function = dynamic_cast< FunctionType* >( eqvClass.type ) ) { 1113 1134 Alternative newFunc( *func ); 1114 1135 referenceToRvalueConversion( newFunc.expr, newFunc.cost ); … … 1138 1159 // check if type is a pointer to function 1139 1160 if ( PointerType* pointer = dynamic_cast<PointerType*>( 1140 funcOp->expr-> get_result()->stripReferences() ) ) {1161 funcOp->expr->result->stripReferences() ) ) { 1141 1162 if ( FunctionType* function = 1142 dynamic_cast<FunctionType*>( pointer-> get_base()) ) {1163 dynamic_cast<FunctionType*>( pointer->base ) ) { 1143 1164 Alternative newFunc( *funcOp ); 1144 1165 referenceToRvalueConversion( newFunc.expr, newFunc.cost ); … … 1162 1183 PRINT( 1163 1184 ApplicationExpr *appExpr = strict_dynamic_cast< ApplicationExpr* >( withFunc.expr ); 1164 PointerType *pointer = strict_dynamic_cast< PointerType* >( appExpr-> get_function()->get_result());1165 FunctionType *function = strict_dynamic_cast< FunctionType* >( pointer-> get_base());1166 std::cerr << "Case +++++++++++++ " << appExpr-> get_function()<< std::endl;1185 PointerType *pointer = strict_dynamic_cast< PointerType* >( appExpr->function->result ); 1186 FunctionType *function = strict_dynamic_cast< FunctionType* >( pointer->base ); 1187 std::cerr << "Case +++++++++++++ " << appExpr->function << std::endl; 1167 1188 std::cerr << "formals are:" << std::endl; 1168 printAll( function-> get_parameters(), std::cerr, 8 );1189 printAll( function->parameters, std::cerr, 8 ); 1169 1190 std::cerr << "actuals are:" << std::endl; 1170 printAll( appExpr-> get_args(), std::cerr, 8 );1191 printAll( appExpr->args, std::cerr, 8 ); 1171 1192 std::cerr << "bindings are:" << std::endl; 1172 1193 withFunc.env.print( std::cerr, 8 ); … … 1209 1230 bool isLvalue( Expression *expr ) { 1210 1231 // xxx - recurse into tuples? 1211 return expr->result && ( expr-> get_result()->get_lvalue() || dynamic_cast< ReferenceType * >( expr->get_result()) );1232 return expr->result && ( expr->result->get_lvalue() || dynamic_cast< ReferenceType * >( expr->result ) ); 1212 1233 } 1213 1234 … … 1218 1239 if ( isLvalue( alt.expr ) ) { 1219 1240 alternatives.push_back( 1220 Alternative{ new AddressExpr( alt.expr ), alt.env, alt.cost } );1241 Alternative{ new AddressExpr( alt.expr->clone() ), alt.env, alt.cost } ); 1221 1242 } // if 1222 1243 } // for … … 1224 1245 1225 1246 void AlternativeFinder::Finder::postvisit( LabelAddressExpr * expr ) { 1226 alternatives.push_back( Alternative{ expr , env, Cost::zero } );1247 alternatives.push_back( Alternative{ expr->clone(), env, Cost::zero } ); 1227 1248 } 1228 1249 … … 1244 1265 componentExprs.push_back( restructureCast( idx, toType->getComponent( i ), isGenerated ) ); 1245 1266 } 1267 delete argExpr; 1246 1268 assert( componentExprs.size() > 0 ); 1247 1269 // produce the tuple of casts … … 1319 1341 for ( Alternative & alt : finder.alternatives ) { 1320 1342 alternatives.push_back( Alternative( 1321 new VirtualCastExpr( alt.expr , castExpr->get_result()->clone() ),1343 new VirtualCastExpr( alt.expr->clone(), castExpr->get_result()->clone() ), 1322 1344 alt.env, alt.cost ) ); 1323 }1324 }1325 1326 namespace {1327 /// Gets name from untyped member expression (member must be NameExpr)1328 const std::string& get_member_name( UntypedMemberExpr *memberExpr ) {1329 NameExpr * nameExpr = dynamic_cast< NameExpr * >( memberExpr->get_member() );1330 assert( nameExpr );1331 return nameExpr->get_name();1332 1345 } 1333 1346 } … … 1341 1354 Expression * aggrExpr = agg->expr->clone(); 1342 1355 referenceToRvalueConversion( aggrExpr, cost ); 1356 std::unique_ptr<Expression> guard( aggrExpr ); 1343 1357 1344 1358 // find member of the given type 1345 1359 if ( StructInstType *structInst = dynamic_cast< StructInstType* >( aggrExpr->get_result() ) ) { 1346 addAggMembers( structInst, aggrExpr, cost, agg->env, get_member_name(memberExpr) );1360 addAggMembers( structInst, aggrExpr, cost, agg->env, memberExpr->get_member() ); 1347 1361 } else if ( UnionInstType *unionInst = dynamic_cast< UnionInstType* >( aggrExpr->get_result() ) ) { 1348 addAggMembers( unionInst, aggrExpr, cost, agg->env, get_member_name(memberExpr) );1362 addAggMembers( unionInst, aggrExpr, cost, agg->env, memberExpr->get_member() ); 1349 1363 } else if ( TupleType * tupleType = dynamic_cast< TupleType * >( aggrExpr->get_result() ) ) { 1350 1364 addTupleMembers( tupleType, aggrExpr, cost, agg->env, memberExpr->get_member() ); … … 1354 1368 1355 1369 void AlternativeFinder::Finder::postvisit( MemberExpr *memberExpr ) { 1356 alternatives.push_back( Alternative( memberExpr , env, Cost::zero ) );1370 alternatives.push_back( Alternative( memberExpr->clone(), env, Cost::zero ) ); 1357 1371 } 1358 1372 … … 1385 1399 1386 1400 void AlternativeFinder::Finder::postvisit( ConstantExpr *constantExpr ) { 1387 alternatives.push_back( Alternative( constantExpr , env, Cost::zero ) );1401 alternatives.push_back( Alternative( constantExpr->clone(), env, Cost::zero ) ); 1388 1402 } 1389 1403 … … 1405 1419 Alternative &choice = winners.front(); 1406 1420 referenceToRvalueConversion( choice.expr, choice.cost ); 1407 alternatives.push_back( Alternative( new SizeofExpr( choice.expr ), choice.env, Cost::zero ) );1421 alternatives.push_back( Alternative( new SizeofExpr( choice.expr->clone() ), choice.env, Cost::zero ) ); 1408 1422 } // if 1409 1423 } … … 1426 1440 Alternative &choice = winners.front(); 1427 1441 referenceToRvalueConversion( choice.expr, choice.cost ); 1428 alternatives.push_back( Alternative( new AlignofExpr( choice.expr ), choice.env, Cost::zero ) );1442 alternatives.push_back( Alternative( new AlignofExpr( choice.expr->clone() ), choice.env, Cost::zero ) ); 1429 1443 } // if 1430 1444 } … … 1455 1469 1456 1470 void AlternativeFinder::Finder::postvisit( OffsetofExpr *offsetofExpr ) { 1457 alternatives.push_back( Alternative( offsetofExpr , env, Cost::zero ) );1471 alternatives.push_back( Alternative( offsetofExpr->clone(), env, Cost::zero ) ); 1458 1472 } 1459 1473 1460 1474 void AlternativeFinder::Finder::postvisit( OffsetPackExpr *offsetPackExpr ) { 1461 alternatives.push_back( Alternative( offsetPackExpr , env, Cost::zero ) );1475 alternatives.push_back( Alternative( offsetPackExpr->clone(), env, Cost::zero ) ); 1462 1476 } 1463 1477 … … 1537 1551 compositeEnv.simpleCombine( second.env ); 1538 1552 1539 LogicalExpr *newExpr = new LogicalExpr( first.expr , second.expr, logicalExpr->get_isAnd() );1553 LogicalExpr *newExpr = new LogicalExpr( first.expr->clone(), second.expr->clone(), logicalExpr->get_isAnd() ); 1540 1554 alternatives.push_back( Alternative( newExpr, compositeEnv, first.cost + second.cost ) ); 1541 1555 } … … 1570 1584 Type* commonType = nullptr; 1571 1585 if ( unify( second.expr->result, third.expr->result, newAlt.env, needAssertions, haveAssertions, openVars, indexer, commonType ) ) { 1572 ConditionalExpr *newExpr = new ConditionalExpr( first.expr , second.expr, third.expr);1586 ConditionalExpr *newExpr = new ConditionalExpr( first.expr->clone(), second.expr->clone(), third.expr->clone() ); 1573 1587 newExpr->result = commonType ? commonType : second.expr->result->clone(); 1574 1588 // convert both options to the conditional result type … … 1589 1603 secondFinder.findWithAdjustment( commaExpr->get_arg2() ); 1590 1604 for ( const Alternative & alt : secondFinder.alternatives ) { 1591 alternatives.push_back( Alternative( new CommaExpr( newFirstArg , alt.expr), alt.env, alt.cost ) );1605 alternatives.push_back( Alternative( new CommaExpr( newFirstArg->clone(), alt.expr->clone() ), alt.env, alt.cost ) ); 1592 1606 } // for 1607 delete newFirstArg; 1593 1608 } 1594 1609 … … 1611 1626 Type* commonType = nullptr; 1612 1627 if ( unify( first.expr->result, second.expr->result, newAlt.env, needAssertions, haveAssertions, openVars, indexer, commonType ) ) { 1613 RangeExpr * newExpr = new RangeExpr( first.expr , second.expr);1628 RangeExpr * newExpr = new RangeExpr( first.expr->clone(), second.expr->clone() ); 1614 1629 newExpr->result = commonType ? commonType : first.expr->result->clone(); 1615 1630 newAlt.expr = newExpr; … … 1639 1654 1640 1655 void AlternativeFinder::Finder::postvisit( TupleExpr *tupleExpr ) { 1641 alternatives.push_back( Alternative( tupleExpr , env, Cost::zero ) );1656 alternatives.push_back( Alternative( tupleExpr->clone(), env, Cost::zero ) ); 1642 1657 } 1643 1658 1644 1659 void AlternativeFinder::Finder::postvisit( ImplicitCopyCtorExpr * impCpCtorExpr ) { 1645 alternatives.push_back( Alternative( impCpCtorExpr , env, Cost::zero ) );1660 alternatives.push_back( Alternative( impCpCtorExpr->clone(), env, Cost::zero ) ); 1646 1661 } 1647 1662 … … 1652 1667 finder.findWithoutPrune( ctorExpr->get_callExpr() ); 1653 1668 for ( Alternative & alt : finder.alternatives ) { 1654 alternatives.push_back( Alternative( new ConstructorExpr( alt.expr ), alt.env, alt.cost ) );1669 alternatives.push_back( Alternative( new ConstructorExpr( alt.expr->clone() ), alt.env, alt.cost ) ); 1655 1670 } 1656 1671 } 1657 1672 1658 1673 void AlternativeFinder::Finder::postvisit( TupleIndexExpr *tupleExpr ) { 1659 alternatives.push_back( Alternative( tupleExpr , env, Cost::zero ) );1674 alternatives.push_back( Alternative( tupleExpr->clone(), env, Cost::zero ) ); 1660 1675 } 1661 1676 1662 1677 void AlternativeFinder::Finder::postvisit( TupleAssignExpr *tupleAssignExpr ) { 1663 alternatives.push_back( Alternative( tupleAssignExpr , env, Cost::zero ) );1678 alternatives.push_back( Alternative( tupleAssignExpr->clone(), env, Cost::zero ) ); 1664 1679 } 1665 1680 … … 1669 1684 for ( Alternative & alt : finder.alternatives ) { 1670 1685 // ensure that the id is passed on to the UniqueExpr alternative so that the expressions are "linked" 1671 UniqueExpr * newUnqExpr = new UniqueExpr( alt.expr , unqExpr->get_id() );1686 UniqueExpr * newUnqExpr = new UniqueExpr( alt.expr->clone(), unqExpr->get_id() ); 1672 1687 alternatives.push_back( Alternative( newUnqExpr, alt.env, alt.cost ) ); 1673 1688 } … … 1720 1735 // count one safe conversion for each value that is thrown away 1721 1736 thisCost.incSafe( discardedValues ); 1722 Alternative newAlt( new InitExpr( restructureCast( alt.expr , toType, true ), initAlt.designation), newEnv, alt.cost, thisCost );1737 Alternative newAlt( new InitExpr( restructureCast( alt.expr->clone(), toType, true ), initAlt.designation->clone() ), newEnv, alt.cost, thisCost ); 1723 1738 inferParameters( needAssertions, haveAssertions, newAlt, openVars, back_inserter( candidates ) ); 1724 1739 }
Note:
See TracChangeset
for help on using the changeset viewer.