- File:
-
- 1 edited
-
src/ResolvExpr/AlternativeFinder.cc (modified) (62 diffs)
Legend:
- Unmodified
- Added
- Removed
-
src/ResolvExpr/AlternativeFinder.cc
rd286cf68 r982f95d 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 , unique_ptr23 #include <memory> // for allocator_traits<>::value_type 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_root 37 38 #include "SymTab/Indexer.h" // for Indexer 38 39 #include "SymTab/Mangler.h" // for Mangler … … 97 98 void postvisit( InitExpr * initExpr ); 98 99 void postvisit( DeletedExpr * delExpr ); 99 void postvisit( GenericExpr * genExpr );100 100 101 101 /// Adds alternatives for anonymous members … … 166 166 candidate->env.apply( newType ); 167 167 mangleName = SymTab::Mangler::mangle( newType ); 168 delete newType;169 168 } 170 169 std::map< std::string, PruneStruct >::iterator mapPlace = selected.find( mangleName ); … … 176 175 selected[ mangleName ] = current; 177 176 } else if ( candidate->cost == mapPlace->second.candidate->cost ) { 178 // if one of the candidates contains a deleted identifier, can pick the other, since 179 // deleted expressions should not be ambiguous if there is another option that is at least as good 180 if ( findDeletedExpr( candidate->expr ) ) { 181 // do nothing 182 PRINT( std::cerr << "candidate is deleted" << std::endl; ) 183 } else if ( findDeletedExpr( mapPlace->second.candidate->expr ) ) { 184 PRINT( std::cerr << "current is deleted" << std::endl; ) 185 selected[ mangleName ] = current; 186 } else { 187 PRINT( 188 std::cerr << "marking ambiguous" << std::endl; 189 ) 190 mapPlace->second.isAmbiguous = true; 191 } 177 PRINT( 178 std::cerr << "marking ambiguous" << std::endl; 179 ) 180 mapPlace->second.isAmbiguous = true; 192 181 } else { 193 182 PRINT( … … 244 233 } 245 234 246 void AlternativeFinder::find( Expression *expr, bool adjust, bool prune, bool failFast) {235 void AlternativeFinder::find( Expression *expr, ResolvMode mode ) { 247 236 PassVisitor<Finder> finder( *this ); 248 237 expr->accept( finder ); 249 if ( failFast && alternatives.empty() ) {238 if ( mode.failFast && alternatives.empty() ) { 250 239 PRINT( 251 240 std::cerr << "No reasonable alternatives for expression " << expr << std::endl; … … 253 242 SemanticError( expr, "No reasonable alternatives for expression " ); 254 243 } 255 if ( prune ) {244 if ( mode.prune ) { 256 245 auto oldsize = alternatives.size(); 257 246 PRINT( … … 261 250 AltList pruned; 262 251 pruneAlternatives( alternatives.begin(), alternatives.end(), back_inserter( pruned ) ); 263 if ( failFast && pruned.empty() ) {252 if ( mode.failFast && pruned.empty() ) { 264 253 std::ostringstream stream; 265 254 AltList winners; … … 280 269 } 281 270 // adjust types after pruning so that types substituted by pruneAlternatives are correctly adjusted 282 for ( AltList::iterator i = alternatives.begin(); i != alternatives.end(); ++i) {283 if ( adjust) {284 adjustExprType( i ->expr->get_result(), i->env, indexer );271 if ( mode.adjust ) { 272 for ( Alternative& i : alternatives ) { 273 adjustExprType( i.expr->result, i.env, indexer ); 285 274 } 286 275 } … … 294 283 295 284 void AlternativeFinder::findWithAdjustment( Expression *expr ) { 296 find( expr, true);285 find( expr, ResolvMode::withAdjustment() ); 297 286 } 298 287 299 288 void AlternativeFinder::findWithoutPrune( Expression * expr ) { 300 find( expr, true, false);289 find( expr, ResolvMode::withoutPrune() ); 301 290 } 302 291 303 292 void AlternativeFinder::maybeFind( Expression * expr ) { 304 find( expr, true, true, false);293 find( expr, ResolvMode::withoutFailFast() ); 305 294 } 306 295 … … 308 297 // adds anonymous member interpretations whenever an aggregate value type is seen. 309 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 310 std::unique_ptr<Expression> aggrExpr( alt.expr->clone());311 alt.env.apply( aggrExpr-> result);312 Type * aggrType = aggrExpr-> result;299 Expression* aggrExpr = alt.expr->clone(); 300 alt.env.apply( aggrExpr->get_result() ); 301 Type * aggrType = aggrExpr->get_result(); 313 302 if ( dynamic_cast< ReferenceType * >( aggrType ) ) { 314 303 aggrType = aggrType->stripReferences(); 315 aggrExpr .reset( new CastExpr( aggrExpr.release(), aggrType->clone() ) );316 } 317 318 if ( StructInstType *structInst = dynamic_cast< StructInstType* >( aggrExpr-> result) ) {319 addAggMembers( structInst, aggrExpr .get(), alt.cost+Cost::safe, alt.env, "" );320 } else if ( UnionInstType *unionInst = dynamic_cast< UnionInstType* >( aggrExpr-> result) ) {321 addAggMembers( unionInst, aggrExpr .get(), alt.cost+Cost::safe, alt.env, "" );304 aggrExpr = new CastExpr{ aggrExpr, aggrType->clone() }; 305 } 306 307 if ( StructInstType *structInst = dynamic_cast< StructInstType* >( aggrExpr->get_result() ) ) { 308 addAggMembers( structInst, aggrExpr, alt.cost+Cost::safe, alt.env, "" ); 309 } else if ( UnionInstType *unionInst = dynamic_cast< UnionInstType* >( aggrExpr->get_result() ) ) { 310 addAggMembers( unionInst, aggrExpr, alt.cost+Cost::safe, alt.env, "" ); 322 311 } // if 323 312 } … … 328 317 aggInst->lookup( name, members ); 329 318 330 for ( Declaration * decl : members ) { 331 if ( DeclarationWithType *dwt = dynamic_cast< DeclarationWithType* >( decl ) ) { 332 // addAnonAlternatives uses vector::push_back, which invalidates references to existing elements, so 333 // can't construct in place and use vector::back 334 Alternative newAlt( new MemberExpr( dwt, expr->clone() ), env, newCost ); 335 renameTypes( newAlt.expr ); 336 addAnonConversions( newAlt ); // add anonymous member interpretations whenever an aggregate value type is seen as a member expression. 337 alternatives.push_back( std::move(newAlt) ); 319 for ( std::list< Declaration* >::const_iterator i = members.begin(); i != members.end(); ++i ) { 320 if ( DeclarationWithType *dwt = dynamic_cast< DeclarationWithType* >( *i ) ) { 321 alternatives.push_back( Alternative( new MemberExpr( dwt, expr->clone() ), env, newCost ) ); 322 renameTypes( alternatives.back().expr ); 323 addAnonConversions( alternatives.back() ); // add anonymous member interpretations whenever an aggregate value type is seen as a member expression. 338 324 } else { 339 325 assert( false ); … … 345 331 if ( ConstantExpr * constantExpr = dynamic_cast< ConstantExpr * >( member ) ) { 346 332 // get the value of the constant expression as an int, must be between 0 and the length of the tuple type to have meaning 347 auto val = constantExpr->intValue(); 333 // xxx - this should be improved by memoizing the value of constant exprs 334 // during parsing and reusing that information here. 335 std::stringstream ss( constantExpr->get_constant()->get_value() ); 336 int val = 0; 348 337 std::string tmp; 349 if ( val >= 0 && (unsigned long long)val < tupleType->size() ) { 350 alternatives.push_back( Alternative( new TupleIndexExpr( expr->clone(), val ), env, newCost ) ); 338 if ( ss >> val && ! (ss >> tmp) ) { 339 if ( val >= 0 && (unsigned int)val < tupleType->size() ) { 340 alternatives.push_back( Alternative( new TupleIndexExpr( expr, val ), env, newCost ) ); 341 } // if 351 342 } // if 343 } else if ( NameExpr * nameExpr = dynamic_cast< NameExpr * >( member ) ) { 344 // xxx - temporary hack until 0/1 are int constants 345 if ( nameExpr->get_name() == "0" || nameExpr->get_name() == "1" ) { 346 std::stringstream ss( nameExpr->get_name() ); 347 int val; 348 ss >> val; 349 alternatives.push_back( Alternative( new TupleIndexExpr( expr, val ), env, newCost ) ); 350 } 352 351 } // if 353 352 } 354 353 355 354 void AlternativeFinder::Finder::postvisit( ApplicationExpr *applicationExpr ) { 356 alternatives.push_back( Alternative( applicationExpr ->clone(), env, Cost::zero ) );355 alternatives.push_back( Alternative( applicationExpr, env, Cost::zero ) ); 357 356 } 358 357 … … 436 435 return Cost::infinity; 437 436 } 438 }439 if ( DefaultArgExpr * def = dynamic_cast< DefaultArgExpr * >( *actualExpr ) ) {440 // default arguments should be free - don't include conversion cost.441 // Unwrap them here because they are not relevant to the rest of the system.442 *actualExpr = def->expr;443 ++formal;444 continue;445 437 } 446 438 Type * formalType = (*formal)->get_type(); … … 560 552 561 553 Expression *varExpr = data.combine( newerAlt.cvtCost ); 562 delete varExpr->get_result();563 554 varExpr->set_result( adjType->clone() ); 564 555 PRINT( … … 574 565 inferParameters = (*inferParameters)[ id ].inferParams.get(); 575 566 } 576 // XXX: this is a memory leak, but adjType can't be deleted because it might contain assertions577 (*inferParameters)[ curDecl->get_uniqueId() ] = ParamEntry( candidate->get_uniqueId(), adjType ->clone(), curDecl->get_type()->clone(), varExpr );567 568 (*inferParameters)[ curDecl->get_uniqueId() ] = ParamEntry( candidate->get_uniqueId(), adjType, curDecl->get_type(), varExpr ); 578 569 inferRecursive( begin, end, newerAlt, newOpenVars, newDecls, newerNeed, level, indexer, out ); 579 } else {580 delete adjType;581 570 } 582 571 } … … 615 604 ConstantExpr* getDefaultValue( Initializer* init ) { 616 605 if ( SingleInit* si = dynamic_cast<SingleInit*>( init ) ) { 617 if ( CastExpr* ce = dynamic_cast<CastExpr*>( si->value ) ) { 618 return dynamic_cast<ConstantExpr*>( ce->arg ); 619 } else { 620 return dynamic_cast<ConstantExpr*>( si->value ); 606 if ( CastExpr* ce = dynamic_cast<CastExpr*>( si->get_value() ) ) { 607 return dynamic_cast<ConstantExpr*>( ce->get_arg() ); 621 608 } 622 609 } … … 627 614 struct ArgPack { 628 615 std::size_t parent; ///< Index of parent pack 629 std::unique_ptr<Expression> expr;///< The argument stored here616 Expression* expr; ///< The argument stored here 630 617 Cost cost; ///< The cost of this argument 631 618 TypeEnvironment env; ///< Environment for this pack … … 639 626 640 627 ArgPack() 641 : parent(0), expr( ), cost(Cost::zero), env(), need(), have(), openVars(), nextArg(0),642 tupleStart(0), nextExpl(0), explAlt(0) {}628 : parent(0), expr(nullptr), cost(Cost::zero), env(), need(), have(), openVars(), 629 nextArg(0), tupleStart(0), nextExpl(0), explAlt(0) {} 643 630 644 631 ArgPack(const TypeEnvironment& env, const AssertionSet& need, const AssertionSet& have, 645 632 const OpenVarSet& openVars) 646 : parent(0), expr( ), cost(Cost::zero), env(env), need(need), have(have),633 : parent(0), expr(nullptr), cost(Cost::zero), env(env), need(need), have(have), 647 634 openVars(openVars), nextArg(0), tupleStart(0), nextExpl(0), explAlt(0) {} 648 635 … … 651 638 unsigned tupleStart = 0, Cost cost = Cost::zero, unsigned nextExpl = 0, 652 639 unsigned explAlt = 0 ) 653 : parent(parent), expr(expr ->clone()), cost(cost), env(move(env)), need(move(need)),640 : parent(parent), expr(expr), cost(cost), env(move(env)), need(move(need)), 654 641 have(move(have)), openVars(move(openVars)), nextArg(nextArg), tupleStart(tupleStart), 655 642 nextExpl(nextExpl), explAlt(explAlt) {} … … 657 644 ArgPack(const ArgPack& o, TypeEnvironment&& env, AssertionSet&& need, AssertionSet&& have, 658 645 OpenVarSet&& openVars, unsigned nextArg, Cost added ) 659 : parent(o.parent), expr(o.expr ? o.expr->clone() : nullptr), cost(o.cost + added),660 env(move(env)), need(move(need)), have(move(have)), openVars(move(openVars)),661 nextArg(nextArg),tupleStart(o.tupleStart), nextExpl(0), explAlt(0) {}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) {} 662 649 663 650 /// true iff this pack is in the middle of an exploded argument … … 674 661 std::list<Expression*> exprs; 675 662 const ArgPack* pack = this; 676 if ( expr ) { exprs.push_front( expr .release()); }663 if ( expr ) { exprs.push_front( expr ); } 677 664 while ( pack->tupleStart == 0 ) { 678 665 pack = &packs[pack->parent]; 679 exprs.push_front( pack->expr ->clone());666 exprs.push_front( pack->expr ); 680 667 cost += pack->cost; 681 668 } 682 669 // reset pack to appropriate tuple 683 expr .reset( new TupleExpr( exprs ) );670 expr = new TupleExpr{ exprs }; 684 671 tupleStart = pack->tupleStart - 1; 685 672 parent = pack->parent; … … 734 721 735 722 results.emplace_back( 736 i, expl.exprs[results[i].nextExpl] .get(), copy(results[i].env),723 i, expl.exprs[results[i].nextExpl], copy(results[i].env), 737 724 copy(results[i].need), copy(results[i].have), 738 725 copy(results[i].openVars), nextArg, nTuples, Cost::zero, nextExpl, … … 755 742 newResult.parent = i; 756 743 std::list<Expression*> emptyList; 757 newResult.expr .reset( new TupleExpr( emptyList ) );744 newResult.expr = new TupleExpr{ emptyList }; 758 745 argType = newResult.expr->get_result(); 759 746 } else { … … 762 749 newResult.cost = results[i].cost; 763 750 newResult.tupleStart = results[i].tupleStart; 764 newResult.expr .reset( results[i].expr->clone() );751 newResult.expr = results[i].expr; 765 752 argType = newResult.expr->get_result(); 766 753 … … 812 799 // add new result 813 800 results.emplace_back( 814 i, expl.exprs.front() .get(), move(env), copy(results[i].need),801 i, expl.exprs.front(), move(env), copy(results[i].need), 815 802 copy(results[i].have), move(openVars), nextArg + 1, 816 803 nTuples, expl.cost, expl.exprs.size() == 1 ? 0 : 1, j ); … … 838 825 if ( results[i].hasExpl() ) { 839 826 const ExplodedActual& expl = results[i].getExpl( args ); 840 Expression* expr = expl.exprs[results[i].nextExpl] .get();827 Expression* expr = expl.exprs[results[i].nextExpl]; 841 828 842 829 TypeEnvironment env = results[i].env; … … 879 866 indexer ) ) { 880 867 results.emplace_back( 881 i, new DefaultArgExpr( cnstExpr ), move(env), move(need), move(have),868 i, cnstExpr, move(env), move(need), move(have), 882 869 move(openVars), nextArg, nTuples ); 883 870 } … … 909 896 910 897 // consider only first exploded actual 911 Expression* expr = expl.exprs.front() .get();898 Expression* expr = expl.exprs.front(); 912 899 Type* actualType = expr->result->clone(); 913 900 … … 937 924 938 925 template<typename OutputIterator> 939 void AlternativeFinder::Finder::validateFunctionAlternative( const Alternative &func, ArgPack& result,940 const std::vector<ArgPack>& results, OutputIterator out ) {941 ApplicationExpr *appExpr = new ApplicationExpr( func.expr ->clone());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 ); 942 929 // sum cost and accumulate actuals 943 930 std::list<Expression*>& args = appExpr->args; … … 945 932 const ArgPack* pack = &result; 946 933 while ( pack->expr ) { 947 args.push_front( pack->expr ->clone());934 args.push_front( pack->expr ); 948 935 cost += pack->cost; 949 936 pack = &results[pack->parent]; … … 1012 999 1013 1000 results.emplace_back( 1014 i, expl.exprs[results[i].nextExpl] .get(), copy(results[i].env),1001 i, expl.exprs[results[i].nextExpl], copy(results[i].env), 1015 1002 copy(results[i].need), copy(results[i].have), 1016 1003 copy(results[i].openVars), nextArg, 0, Cost::zero, nextExpl, … … 1048 1035 // add new result 1049 1036 results.emplace_back( 1050 i, expl.exprs.front() .get(), move(env), copy(results[i].need),1037 i, expl.exprs.front(), move(env), copy(results[i].need), 1051 1038 copy(results[i].have), move(openVars), nextArg + 1, 0, 1052 1039 expl.cost, expl.exprs.size() == 1 ? 0 : 1, j ); … … 1071 1058 funcFinder.findWithAdjustment( untypedExpr->function ); 1072 1059 // if there are no function alternatives, then proceeding is a waste of time. 1073 // xxx - findWithAdjustment throws, so this check and others like it shouldn't be necessary.1074 1060 if ( funcFinder.alternatives.empty() ) return; 1075 1061 … … 1083 1069 1084 1070 // find function operators 1085 static NameExpr *opExpr = new NameExpr( "?()" );1071 static auto *opExpr = new_static_root<NameExpr>( "?()" ); 1086 1072 AlternativeFinder funcOpFinder( indexer, env ); 1087 1073 // it's ok if there aren't any defined function ops … … 1099 1085 argExpansions.emplace_back(); 1100 1086 auto& argE = argExpansions.back(); 1101 //argE.reserve( arg.alternatives.size() );1087 argE.reserve( arg.alternatives.size() ); 1102 1088 1103 1089 for ( const Alternative& actual : arg ) { … … 1115 1101 ) 1116 1102 // check if the type is pointer to function 1117 if ( PointerType *pointer = dynamic_cast< PointerType* >( func->expr-> result->stripReferences() ) ) {1118 if ( FunctionType *function = dynamic_cast< FunctionType* >( pointer-> base) ) {1103 if ( PointerType *pointer = dynamic_cast< PointerType* >( func->expr->get_result()->stripReferences() ) ) { 1104 if ( FunctionType *function = dynamic_cast< FunctionType* >( pointer->get_base() ) ) { 1119 1105 Alternative newFunc( *func ); 1120 1106 referenceToRvalueConversion( newFunc.expr, newFunc.cost ); … … 1122 1108 std::back_inserter( candidates ) ); 1123 1109 } 1124 } else if ( TypeInstType *typeInst = dynamic_cast< TypeInstType* >( func->expr-> result->stripReferences() ) ) { // handle ftype (e.g. *? on function pointer)1125 if ( const EqvClass *eqvClass = func->env.lookup( typeInst->name) ) {1126 if ( FunctionType *function = dynamic_cast< FunctionType* >( eqvClass ->type ) ) {1110 } else if ( TypeInstType *typeInst = dynamic_cast< TypeInstType* >( func->expr->get_result()->stripReferences() ) ) { // handle ftype (e.g. *? on function pointer) 1111 if ( ClassRef eqvClass = func->env.lookup( typeInst->get_name() ) ) { 1112 if ( FunctionType *function = dynamic_cast< FunctionType* >( eqvClass.get_bound().type ) ) { 1127 1113 Alternative newFunc( *func ); 1128 1114 referenceToRvalueConversion( newFunc.expr, newFunc.cost ); … … 1152 1138 // check if type is a pointer to function 1153 1139 if ( PointerType* pointer = dynamic_cast<PointerType*>( 1154 funcOp->expr-> result->stripReferences() ) ) {1140 funcOp->expr->get_result()->stripReferences() ) ) { 1155 1141 if ( FunctionType* function = 1156 dynamic_cast<FunctionType*>( pointer-> base) ) {1142 dynamic_cast<FunctionType*>( pointer->get_base() ) ) { 1157 1143 Alternative newFunc( *funcOp ); 1158 1144 referenceToRvalueConversion( newFunc.expr, newFunc.cost ); … … 1176 1162 PRINT( 1177 1163 ApplicationExpr *appExpr = strict_dynamic_cast< ApplicationExpr* >( withFunc.expr ); 1178 PointerType *pointer = strict_dynamic_cast< PointerType* >( appExpr-> function->result);1179 FunctionType *function = strict_dynamic_cast< FunctionType* >( pointer-> base);1180 std::cerr << "Case +++++++++++++ " << appExpr-> function<< std::endl;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; 1181 1167 std::cerr << "formals are:" << std::endl; 1182 printAll( function-> parameters, std::cerr, 8 );1168 printAll( function->get_parameters(), std::cerr, 8 ); 1183 1169 std::cerr << "actuals are:" << std::endl; 1184 printAll( appExpr-> args, std::cerr, 8 );1170 printAll( appExpr->get_args(), std::cerr, 8 ); 1185 1171 std::cerr << "bindings are:" << std::endl; 1186 1172 withFunc.env.print( std::cerr, 8 ); … … 1223 1209 bool isLvalue( Expression *expr ) { 1224 1210 // xxx - recurse into tuples? 1225 return expr->result && ( expr-> result->get_lvalue() || dynamic_cast< ReferenceType * >( expr->result) );1211 return expr->result && ( expr->get_result()->get_lvalue() || dynamic_cast< ReferenceType * >( expr->get_result() ) ); 1226 1212 } 1227 1213 … … 1232 1218 if ( isLvalue( alt.expr ) ) { 1233 1219 alternatives.push_back( 1234 Alternative{ new AddressExpr( alt.expr ->clone()), alt.env, alt.cost } );1220 Alternative{ new AddressExpr( alt.expr ), alt.env, alt.cost } ); 1235 1221 } // if 1236 1222 } // for … … 1238 1224 1239 1225 void AlternativeFinder::Finder::postvisit( LabelAddressExpr * expr ) { 1240 alternatives.push_back( Alternative{ expr ->clone(), env, Cost::zero } );1226 alternatives.push_back( Alternative{ expr, env, Cost::zero } ); 1241 1227 } 1242 1228 … … 1258 1244 componentExprs.push_back( restructureCast( idx, toType->getComponent( i ), isGenerated ) ); 1259 1245 } 1260 delete argExpr;1261 1246 assert( componentExprs.size() > 0 ); 1262 1247 // produce the tuple of casts … … 1334 1319 for ( Alternative & alt : finder.alternatives ) { 1335 1320 alternatives.push_back( Alternative( 1336 new VirtualCastExpr( alt.expr ->clone(), castExpr->get_result()->clone() ),1321 new VirtualCastExpr( alt.expr, castExpr->get_result()->clone() ), 1337 1322 alt.env, alt.cost ) ); 1338 1323 } … … 1356 1341 Expression * aggrExpr = agg->expr->clone(); 1357 1342 referenceToRvalueConversion( aggrExpr, cost ); 1358 std::unique_ptr<Expression> guard( aggrExpr );1359 1343 1360 1344 // find member of the given type … … 1370 1354 1371 1355 void AlternativeFinder::Finder::postvisit( MemberExpr *memberExpr ) { 1372 alternatives.push_back( Alternative( memberExpr ->clone(), env, Cost::zero ) );1356 alternatives.push_back( Alternative( memberExpr, env, Cost::zero ) ); 1373 1357 } 1374 1358 … … 1380 1364 Cost cost = Cost::zero; 1381 1365 Expression * newExpr = data.combine( cost ); 1382 1383 // addAnonAlternatives uses vector::push_back, which invalidates references to existing elements, so 1384 // can't construct in place and use vector::back 1385 Alternative newAlt( newExpr, env, Cost::zero, cost ); 1366 alternatives.push_back( Alternative( newExpr, env, Cost::zero, cost ) ); 1386 1367 PRINT( 1387 1368 std::cerr << "decl is "; … … 1392 1373 std::cerr << std::endl; 1393 1374 ) 1394 renameTypes( newAlt.expr ); 1395 addAnonConversions( newAlt ); // add anonymous member interpretations whenever an aggregate value type is seen as a name expression. 1396 alternatives.push_back( std::move(newAlt) ); 1375 renameTypes( alternatives.back().expr ); 1376 addAnonConversions( alternatives.back() ); // add anonymous member interpretations whenever an aggregate value type is seen as a name expression. 1397 1377 } // for 1398 1378 } … … 1405 1385 1406 1386 void AlternativeFinder::Finder::postvisit( ConstantExpr *constantExpr ) { 1407 alternatives.push_back( Alternative( constantExpr ->clone(), env, Cost::zero ) );1387 alternatives.push_back( Alternative( constantExpr, env, Cost::zero ) ); 1408 1388 } 1409 1389 … … 1425 1405 Alternative &choice = winners.front(); 1426 1406 referenceToRvalueConversion( choice.expr, choice.cost ); 1427 alternatives.push_back( Alternative( new SizeofExpr( choice.expr ->clone()), choice.env, Cost::zero ) );1407 alternatives.push_back( Alternative( new SizeofExpr( choice.expr ), choice.env, Cost::zero ) ); 1428 1408 } // if 1429 1409 } … … 1446 1426 Alternative &choice = winners.front(); 1447 1427 referenceToRvalueConversion( choice.expr, choice.cost ); 1448 alternatives.push_back( Alternative( new AlignofExpr( choice.expr ->clone()), choice.env, Cost::zero ) );1428 alternatives.push_back( Alternative( new AlignofExpr( choice.expr ), choice.env, Cost::zero ) ); 1449 1429 } // if 1450 1430 } … … 1475 1455 1476 1456 void AlternativeFinder::Finder::postvisit( OffsetofExpr *offsetofExpr ) { 1477 alternatives.push_back( Alternative( offsetofExpr ->clone(), env, Cost::zero ) );1457 alternatives.push_back( Alternative( offsetofExpr, env, Cost::zero ) ); 1478 1458 } 1479 1459 1480 1460 void AlternativeFinder::Finder::postvisit( OffsetPackExpr *offsetPackExpr ) { 1481 alternatives.push_back( Alternative( offsetPackExpr ->clone(), env, Cost::zero ) );1461 alternatives.push_back( Alternative( offsetPackExpr, env, Cost::zero ) ); 1482 1462 } 1483 1463 … … 1557 1537 compositeEnv.simpleCombine( second.env ); 1558 1538 1559 LogicalExpr *newExpr = new LogicalExpr( first.expr ->clone(), second.expr->clone(), logicalExpr->get_isAnd() );1539 LogicalExpr *newExpr = new LogicalExpr( first.expr, second.expr, logicalExpr->get_isAnd() ); 1560 1540 alternatives.push_back( Alternative( newExpr, compositeEnv, first.cost + second.cost ) ); 1561 1541 } … … 1590 1570 Type* commonType = nullptr; 1591 1571 if ( unify( second.expr->result, third.expr->result, newAlt.env, needAssertions, haveAssertions, openVars, indexer, commonType ) ) { 1592 ConditionalExpr *newExpr = new ConditionalExpr( first.expr ->clone(), second.expr->clone(), third.expr->clone());1572 ConditionalExpr *newExpr = new ConditionalExpr( first.expr, second.expr, third.expr ); 1593 1573 newExpr->result = commonType ? commonType : second.expr->result->clone(); 1594 1574 // convert both options to the conditional result type … … 1609 1589 secondFinder.findWithAdjustment( commaExpr->get_arg2() ); 1610 1590 for ( const Alternative & alt : secondFinder.alternatives ) { 1611 alternatives.push_back( Alternative( new CommaExpr( newFirstArg ->clone(), alt.expr->clone()), alt.env, alt.cost ) );1591 alternatives.push_back( Alternative( new CommaExpr( newFirstArg, alt.expr ), alt.env, alt.cost ) ); 1612 1592 } // for 1613 delete newFirstArg;1614 1593 } 1615 1594 … … 1632 1611 Type* commonType = nullptr; 1633 1612 if ( unify( first.expr->result, second.expr->result, newAlt.env, needAssertions, haveAssertions, openVars, indexer, commonType ) ) { 1634 RangeExpr * newExpr = new RangeExpr( first.expr ->clone(), second.expr->clone());1613 RangeExpr * newExpr = new RangeExpr( first.expr, second.expr ); 1635 1614 newExpr->result = commonType ? commonType : first.expr->result->clone(); 1636 1615 newAlt.expr = newExpr; … … 1660 1639 1661 1640 void AlternativeFinder::Finder::postvisit( TupleExpr *tupleExpr ) { 1662 alternatives.push_back( Alternative( tupleExpr ->clone(), env, Cost::zero ) );1641 alternatives.push_back( Alternative( tupleExpr, env, Cost::zero ) ); 1663 1642 } 1664 1643 1665 1644 void AlternativeFinder::Finder::postvisit( ImplicitCopyCtorExpr * impCpCtorExpr ) { 1666 alternatives.push_back( Alternative( impCpCtorExpr ->clone(), env, Cost::zero ) );1645 alternatives.push_back( Alternative( impCpCtorExpr, env, Cost::zero ) ); 1667 1646 } 1668 1647 … … 1673 1652 finder.findWithoutPrune( ctorExpr->get_callExpr() ); 1674 1653 for ( Alternative & alt : finder.alternatives ) { 1675 alternatives.push_back( Alternative( new ConstructorExpr( alt.expr ->clone()), alt.env, alt.cost ) );1654 alternatives.push_back( Alternative( new ConstructorExpr( alt.expr ), alt.env, alt.cost ) ); 1676 1655 } 1677 1656 } 1678 1657 1679 1658 void AlternativeFinder::Finder::postvisit( TupleIndexExpr *tupleExpr ) { 1680 alternatives.push_back( Alternative( tupleExpr ->clone(), env, Cost::zero ) );1659 alternatives.push_back( Alternative( tupleExpr, env, Cost::zero ) ); 1681 1660 } 1682 1661 1683 1662 void AlternativeFinder::Finder::postvisit( TupleAssignExpr *tupleAssignExpr ) { 1684 alternatives.push_back( Alternative( tupleAssignExpr ->clone(), env, Cost::zero ) );1663 alternatives.push_back( Alternative( tupleAssignExpr, env, Cost::zero ) ); 1685 1664 } 1686 1665 … … 1690 1669 for ( Alternative & alt : finder.alternatives ) { 1691 1670 // ensure that the id is passed on to the UniqueExpr alternative so that the expressions are "linked" 1692 UniqueExpr * newUnqExpr = new UniqueExpr( alt.expr ->clone(), unqExpr->get_id() );1671 UniqueExpr * newUnqExpr = new UniqueExpr( alt.expr, unqExpr->get_id() ); 1693 1672 alternatives.push_back( Alternative( newUnqExpr, alt.env, alt.cost ) ); 1694 1673 } … … 1741 1720 // count one safe conversion for each value that is thrown away 1742 1721 thisCost.incSafe( discardedValues ); 1743 Alternative newAlt( new InitExpr( restructureCast( alt.expr ->clone(), toType, true ), initAlt.designation->clone()), newEnv, alt.cost, thisCost );1722 Alternative newAlt( new InitExpr( restructureCast( alt.expr, toType, true ), initAlt.designation ), newEnv, alt.cost, thisCost ); 1744 1723 inferParameters( needAssertions, haveAssertions, newAlt, openVars, back_inserter( candidates ) ); 1745 1724 } … … 1762 1741 assertf( false, "AlternativeFinder should never see a DeletedExpr." ); 1763 1742 } 1764 1765 void AlternativeFinder::Finder::postvisit( GenericExpr * ) {1766 assertf( false, "_Generic is not yet supported." );1767 }1768 1743 } // namespace ResolvExpr 1769 1744
Note:
See TracChangeset
for help on using the changeset viewer.