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