- File:
-
- 1 edited
-
src/ResolvExpr/AlternativeFinder.cc (modified) (16 diffs)
Legend:
- Unmodified
- Added
- Removed
-
src/ResolvExpr/AlternativeFinder.cc
r25fcb84 r00ac42e 102 102 void addAnonConversions( const Alternative & alt ); 103 103 /// 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, Expression * member);104 template< typename StructOrUnionType > void addAggMembers( StructOrUnionType *aggInst, Expression *expr, const Cost &newCost, const TypeEnvironment & env, const std::string & name ); 105 105 /// Adds alternatives for member expressions where the left side has tuple type 106 106 void addTupleMembers( TupleType * tupleType, Expression *expr, const Cost &newCost, const TypeEnvironment & env, Expression * member ); … … 307 307 308 308 if ( StructInstType *structInst = dynamic_cast< StructInstType* >( aggrExpr->result ) ) { 309 NameExpr nameExpr( "" ); 310 addAggMembers( structInst, aggrExpr.get(), alt.cost+Cost::safe, alt.env, &nameExpr ); 309 addAggMembers( structInst, aggrExpr.get(), alt.cost+Cost::safe, alt.env, "" ); 311 310 } else if ( UnionInstType *unionInst = dynamic_cast< UnionInstType* >( aggrExpr->result ) ) { 312 NameExpr nameExpr( "" ); 313 addAggMembers( unionInst, aggrExpr.get(), alt.cost+Cost::safe, alt.env, &nameExpr ); 311 addAggMembers( unionInst, aggrExpr.get(), alt.cost+Cost::safe, alt.env, "" ); 314 312 } // if 315 313 } 316 314 317 315 template< typename StructOrUnionType > 318 void AlternativeFinder::Finder::addAggMembers( StructOrUnionType *aggInst, Expression *expr, const Cost &newCost, const TypeEnvironment & env, Expression * member ) { 319 // by this point, member must be a name expr 320 NameExpr * nameExpr = dynamic_cast< NameExpr * >( member ); 321 if ( ! nameExpr ) return; 322 const std::string & name = nameExpr->name; 316 void AlternativeFinder::Finder::addAggMembers( StructOrUnionType *aggInst, Expression *expr, const Cost &newCost, const TypeEnvironment & env, const std::string & name ) { 323 317 std::list< Declaration* > members; 324 318 aggInst->lookup( name, members ); 325 319 326 for ( std::list< Declaration* >::const_iterator i = members.begin(); i != members.end(); ++i ) { 327 if ( DeclarationWithType *dwt = dynamic_cast< DeclarationWithType* >( *i ) ) { 328 alternatives.push_back( Alternative( new MemberExpr( dwt, expr->clone() ), env, newCost ) ); 329 renameTypes( alternatives.back().expr ); 330 addAnonConversions( alternatives.back() ); // add anonymous member interpretations whenever an aggregate value type is seen as a member expression. 320 for ( Declaration * decl : members ) { 321 if ( DeclarationWithType *dwt = dynamic_cast< DeclarationWithType* >( decl ) ) { 322 // addAnonAlternatives uses vector::push_back, which invalidates references to existing elements, so 323 // can't construct in place and use vector::back 324 Alternative newAlt( new MemberExpr( dwt, expr->clone() ), env, newCost ); 325 renameTypes( newAlt.expr ); 326 addAnonConversions( newAlt ); // add anonymous member interpretations whenever an aggregate value type is seen as a member expression. 327 alternatives.push_back( std::move(newAlt) ); 331 328 } else { 332 329 assert( false ); … … 469 466 } 470 467 471 // /// Map of declaration uniqueIds (intended to be the assertions in an AssertionSet) to their parents and the number of times they've been included472 //typedef std::unordered_map< UniqueId, std::unordered_map< UniqueId, unsigned > > AssertionParentSet;473 474 468 static const int recursionLimit = /*10*/ 4; ///< Limit to depth of recursion satisfaction 475 //static const unsigned recursionParentLimit = 1; ///< Limit to the number of times an assertion can recursively use itself476 469 477 470 void addToIndexer( AssertionSet &assertSet, SymTab::Indexer &indexer ) { … … 484 477 485 478 template< typename ForwardIterator, typename OutputIterator > 486 void inferRecursive( ForwardIterator begin, ForwardIterator end, const Alternative &newAlt, OpenVarSet &openVars, const SymTab::Indexer &decls, const AssertionSet &newNeed, /*const AssertionParentSet &needParents,*/ 487 int level, const SymTab::Indexer &indexer, OutputIterator out ) { 479 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 ) { 488 480 if ( begin == end ) { 489 481 if ( newNeed.empty() ) { … … 503 495 printAssertionSet( newNeed, std::cerr, 8 ); 504 496 ) 505 inferRecursive( newNeed.begin(), newNeed.end(), newAlt, openVars, decls, newerNeed, /*needParents,*/level+1, indexer, out );497 inferRecursive( newNeed.begin(), newNeed.end(), newAlt, openVars, decls, newerNeed, level+1, indexer, out ); 506 498 return; 507 499 } … … 510 502 ForwardIterator cur = begin++; 511 503 if ( ! cur->second.isUsed ) { 512 inferRecursive( begin, end, newAlt, openVars, decls, newNeed, /*needParents,*/level, indexer, out );504 inferRecursive( begin, end, newAlt, openVars, decls, newNeed, level, indexer, out ); 513 505 return; // xxx - should this continue? previously this wasn't here, and it looks like it should be 514 506 } … … 563 555 } 564 556 565 //AssertionParentSet newNeedParents( needParents );566 // skip repeatingly-self-recursive assertion satisfaction567 // DOESN'T WORK: grandchild nodes conflict with their cousins568 //if ( newNeedParents[ curDecl->get_uniqueId() ][ candDecl->get_uniqueId() ]++ > recursionParentLimit ) continue;569 570 557 Expression *varExpr = data.combine( newerAlt.cvtCost ); 571 558 delete varExpr->get_result(); … … 585 572 // XXX: this is a memory leak, but adjType can't be deleted because it might contain assertions 586 573 (*inferParameters)[ curDecl->get_uniqueId() ] = ParamEntry( candidate->get_uniqueId(), adjType->clone(), curDecl->get_type()->clone(), varExpr ); 587 inferRecursive( begin, end, newerAlt, newOpenVars, newDecls, newerNeed, /*newNeedParents,*/level, indexer, out );574 inferRecursive( begin, end, newerAlt, newOpenVars, newDecls, newerNeed, level, indexer, out ); 588 575 } else { 589 576 delete adjType; … … 607 594 addToIndexer( have, decls ); 608 595 AssertionSet newNeed; 609 //AssertionParentSet needParents;610 596 PRINT( 611 597 std::cerr << "env is: " << std::endl; … … 614 600 ) 615 601 616 inferRecursive( need.begin(), need.end(), newAlt, openVars, decls, newNeed, /*needParents,*/0, indexer, out );602 inferRecursive( need.begin(), need.end(), newAlt, openVars, decls, newNeed, 0, indexer, out ); 617 603 // PRINT( 618 604 // std::cerr << "declaration 14 is "; … … 1093 1079 AlternativeFinder funcOpFinder( indexer, env ); 1094 1080 // it's ok if there aren't any defined function ops 1095 funcOpFinder.maybeFind( opExpr );1081 funcOpFinder.maybeFind( opExpr ); 1096 1082 PRINT( 1097 1083 std::cerr << "known function ops:" << std::endl; … … 1130 1116 } 1131 1117 } else if ( TypeInstType *typeInst = dynamic_cast< TypeInstType* >( func->expr->result->stripReferences() ) ) { // handle ftype (e.g. *? on function pointer) 1132 EqvClass eqvClass; 1133 if ( func->env.lookup( typeInst->name, eqvClass ) && eqvClass.type ) { 1134 if ( FunctionType *function = dynamic_cast< FunctionType* >( eqvClass.type ) ) { 1118 if ( const EqvClass *eqvClass = func->env.lookup( typeInst->name ) ) { 1119 if ( FunctionType *function = dynamic_cast< FunctionType* >( eqvClass->type ) ) { 1135 1120 Alternative newFunc( *func ); 1136 1121 referenceToRvalueConversion( newFunc.expr, newFunc.cost ); … … 1347 1332 } 1348 1333 1334 namespace { 1335 /// Gets name from untyped member expression (member must be NameExpr) 1336 const std::string& get_member_name( UntypedMemberExpr *memberExpr ) { 1337 NameExpr * nameExpr = dynamic_cast< NameExpr * >( memberExpr->get_member() ); 1338 assert( nameExpr ); 1339 return nameExpr->get_name(); 1340 } 1341 } 1342 1349 1343 void AlternativeFinder::Finder::postvisit( UntypedMemberExpr *memberExpr ) { 1350 1344 AlternativeFinder funcFinder( indexer, env ); … … 1359 1353 // find member of the given type 1360 1354 if ( StructInstType *structInst = dynamic_cast< StructInstType* >( aggrExpr->get_result() ) ) { 1361 addAggMembers( structInst, aggrExpr, cost, agg->env, memberExpr->get_member() );1355 addAggMembers( structInst, aggrExpr, cost, agg->env, get_member_name(memberExpr) ); 1362 1356 } else if ( UnionInstType *unionInst = dynamic_cast< UnionInstType* >( aggrExpr->get_result() ) ) { 1363 addAggMembers( unionInst, aggrExpr, cost, agg->env, memberExpr->get_member() );1357 addAggMembers( unionInst, aggrExpr, cost, agg->env, get_member_name(memberExpr) ); 1364 1358 } else if ( TupleType * tupleType = dynamic_cast< TupleType * >( aggrExpr->get_result() ) ) { 1365 1359 addTupleMembers( tupleType, aggrExpr, cost, agg->env, memberExpr->get_member() ); … … 1379 1373 Cost cost = Cost::zero; 1380 1374 Expression * newExpr = data.combine( cost ); 1381 alternatives.push_back( Alternative( newExpr, env, Cost::zero, cost ) ); 1375 1376 // addAnonAlternatives uses vector::push_back, which invalidates references to existing elements, so 1377 // can't construct in place and use vector::back 1378 Alternative newAlt( newExpr, env, Cost::zero, cost ); 1382 1379 PRINT( 1383 1380 std::cerr << "decl is "; … … 1388 1385 std::cerr << std::endl; 1389 1386 ) 1390 renameTypes( alternatives.back().expr ); 1391 addAnonConversions( alternatives.back() ); // add anonymous member interpretations whenever an aggregate value type is seen as a name expression. 1387 renameTypes( newAlt.expr ); 1388 addAnonConversions( newAlt ); // add anonymous member interpretations whenever an aggregate value type is seen as a name expression. 1389 alternatives.push_back( std::move(newAlt) ); 1392 1390 } // for 1393 1391 }
Note:
See TracChangeset
for help on using the changeset viewer.