- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
src/ResolvExpr/AlternativeFinder.cc
r8c84ebd r8e9cbb2 5 5 // file "LICENCE" distributed with Cforall. 6 6 // 7 // AlternativeFinder.cc -- 7 // AlternativeFinder.cc -- 8 8 // 9 9 // Author : Richard C. Bilson 10 10 // Created On : Sat May 16 23:52:08 2015 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Fri Jul 3 17:58:39 201513 // Update Count : 2 212 // Last Modified On : Mon Jul 4 17:02:51 2016 13 // Update Count : 29 14 14 // 15 15 … … 19 19 #include <functional> 20 20 #include <cassert> 21 #include <unordered_map> 22 #include <utility> 23 #include <vector> 21 24 22 25 #include "AlternativeFinder.h" … … 38 41 #include "Tuples/TupleAssignment.h" 39 42 #include "Tuples/NameMatcher.h" 40 #include "utility.h" 43 #include "Common/utility.h" 44 #include "InitTweak/InitTweak.h" 41 45 42 46 extern bool resolvep; 43 #define PRINT( text ) if ( resolvep ) { text } 47 #define PRINT( text ) if ( resolvep ) { text } 44 48 //#define DEBUG_COST 45 49 … … 107 111 if ( candidate->cost < mapPlace->second.candidate->cost ) { 108 112 PRINT( 109 std::c out<< "cost " << candidate->cost << " beats " << mapPlace->second.candidate->cost << std::endl;113 std::cerr << "cost " << candidate->cost << " beats " << mapPlace->second.candidate->cost << std::endl; 110 114 ) 111 115 selected[ mangleName ] = current; 112 116 } else if ( candidate->cost == mapPlace->second.candidate->cost ) { 113 117 PRINT( 114 std::c out<< "marking ambiguous" << std::endl;118 std::cerr << "marking ambiguous" << std::endl; 115 119 ) 116 120 mapPlace->second.isAmbiguous = true; … … 122 126 123 127 PRINT( 124 std::c out<< "there are " << selected.size() << " alternatives before elimination" << std::endl;128 std::cerr << "there are " << selected.size() << " alternatives before elimination" << std::endl; 125 129 ) 126 130 … … 182 186 begin++; 183 187 PRINT( 184 std::c out<< "findSubExprs" << std::endl;185 printAlts( finder.alternatives, std::c out);188 std::cerr << "findSubExprs" << std::endl; 189 printAlts( finder.alternatives, std::cerr ); 186 190 ) 187 191 *out++ = finder; … … 204 208 } 205 209 PRINT( 206 std::c out<< "alternatives before prune:" << std::endl;207 printAlts( alternatives, std::c out);210 std::cerr << "alternatives before prune:" << std::endl; 211 printAlts( alternatives, std::cerr ); 208 212 ) 209 213 AltList::iterator oldBegin = alternatives.begin(); … … 221 225 alternatives.erase( oldBegin, alternatives.end() ); 222 226 PRINT( 223 std::c out<< "there are " << alternatives.size() << " alternatives after elimination" << std::endl;227 std::cerr << "there are " << alternatives.size() << " alternatives after elimination" << std::endl; 224 228 ) 229 230 // Central location to handle gcc extension keyword for all expression types. 231 for ( Alternative &iter: alternatives ) { 232 iter.expr->set_extension( expr->get_extension() ); 233 } // for 225 234 } 226 235 … … 261 270 for ( std::list< Expression* >::iterator actualExpr = actuals.begin(); actualExpr != actuals.end(); ++actualExpr ) { 262 271 PRINT( 263 std::c out<< "actual expression:" << std::endl;264 (*actualExpr)->print( std::c out, 8 );265 std::c out<< "--- results are" << std::endl;266 printAll( (*actualExpr)->get_results(), std::c out, 8 );272 std::cerr << "actual expression:" << std::endl; 273 (*actualExpr)->print( std::cerr, 8 ); 274 std::cerr << "--- results are" << std::endl; 275 printAll( (*actualExpr)->get_results(), std::cerr, 8 ); 267 276 ) 268 277 std::list< DeclarationWithType* >::iterator startFormal = formal; … … 278 287 } 279 288 PRINT( 280 std::c out<< std::endl << "converting ";281 (*actual)->print( std::c out, 8 );282 std::c out<< std::endl << " to ";283 (*formal)->get_type()->print( std::c out, 8 );289 std::cerr << std::endl << "converting "; 290 (*actual)->print( std::cerr, 8 ); 291 std::cerr << std::endl << " to "; 292 (*formal)->get_type()->print( std::cerr, 8 ); 284 293 ) 285 294 Cost newCost = conversionCost( *actual, (*formal)->get_type(), indexer, alt.env ); 286 295 PRINT( 287 std::c out<< std::endl << "cost is" << newCost << std::endl;296 std::cerr << std::endl << "cost is" << newCost << std::endl; 288 297 ) 289 298 … … 323 332 for ( InferredParams::const_iterator assert = appExpr->get_inferParams().begin(); assert != appExpr->get_inferParams().end(); ++assert ) { 324 333 PRINT( 325 std::c out<< std::endl << "converting ";326 assert->second.actualType->print( std::c out, 8 );327 std::c out<< std::endl << " to ";328 assert->second.formalType->print( std::c out, 8 );334 std::cerr << std::endl << "converting "; 335 assert->second.actualType->print( std::cerr, 8 ); 336 std::cerr << std::endl << " to "; 337 assert->second.formalType->print( std::cerr, 8 ); 329 338 ) 330 339 Cost newCost = conversionCost( assert->second.actualType, assert->second.formalType, indexer, alt.env ); 331 340 PRINT( 332 std::c out<< std::endl << "cost of conversion is " << newCost << std::endl;341 std::cerr << std::endl << "cost of conversion is " << newCost << std::endl; 333 342 ) 334 343 if ( newCost == Cost::infinity ) { … … 407 416 } 408 417 409 static const int recursionLimit = 10; 418 // /// Map of declaration uniqueIds (intended to be the assertions in an AssertionSet) to their parents and the number of times they've been included 419 //typedef std::unordered_map< UniqueId, std::unordered_map< UniqueId, unsigned > > AssertionParentSet; 420 421 static const int recursionLimit = /*10*/ 4; ///< Limit to depth of recursion satisfaction 422 //static const unsigned recursionParentLimit = 1; ///< Limit to the number of times an assertion can recursively use itself 410 423 411 424 void addToIndexer( AssertionSet &assertSet, SymTab::Indexer &indexer ) { … … 416 429 } 417 430 } 418 431 419 432 template< typename ForwardIterator, typename OutputIterator > 420 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 ) { 433 void inferRecursive( ForwardIterator begin, ForwardIterator end, const Alternative &newAlt, OpenVarSet &openVars, const SymTab::Indexer &decls, const AssertionSet &newNeed, /*const AssertionParentSet &needParents,*/ 434 int level, const SymTab::Indexer &indexer, OutputIterator out ) { 421 435 if ( begin == end ) { 422 436 if ( newNeed.empty() ) { … … 431 445 printAssertionSet( newNeed, std::cerr, 8 ); 432 446 ) 433 inferRecursive( newNeed.begin(), newNeed.end(), newAlt, openVars, decls, newerNeed, level+1, indexer, out );447 inferRecursive( newNeed.begin(), newNeed.end(), newAlt, openVars, decls, newerNeed, /*needParents,*/ level+1, indexer, out ); 434 448 return; 435 449 } … … 438 452 ForwardIterator cur = begin++; 439 453 if ( ! cur->second ) { 440 inferRecursive( begin, end, newAlt, openVars, decls, newNeed, level, indexer, out );454 inferRecursive( begin, end, newAlt, openVars, decls, newNeed, /*needParents,*/ level, indexer, out ); 441 455 } 442 456 DeclarationWithType *curDecl = cur->first; … … 448 462 std::list< DeclarationWithType* > candidates; 449 463 decls.lookupId( curDecl->get_name(), candidates ); 450 /// if ( candidates.empty() ) { std::c out<< "no candidates!" << std::endl; }464 /// if ( candidates.empty() ) { std::cerr << "no candidates!" << std::endl; } 451 465 for ( std::list< DeclarationWithType* >::const_iterator candidate = candidates.begin(); candidate != candidates.end(); ++candidate ) { 452 466 PRINT( 453 std::c out<< "inferRecursive: candidate is ";454 (*candidate)->print( std::c out);455 std::c out<< std::endl;467 std::cerr << "inferRecursive: candidate is "; 468 (*candidate)->print( std::cerr ); 469 std::cerr << std::endl; 456 470 ) 471 457 472 AssertionSet newHave, newerNeed( newNeed ); 458 473 TypeEnvironment newEnv( newAlt.env ); … … 477 492 newerAlt.env = newEnv; 478 493 assert( (*candidate)->get_uniqueId() ); 479 Expression *varExpr = new VariableExpr( static_cast< DeclarationWithType* >( Declaration::declFromId( (*candidate)->get_uniqueId() ) ) ); 494 DeclarationWithType *candDecl = static_cast< DeclarationWithType* >( Declaration::declFromId( (*candidate)->get_uniqueId() ) ); 495 //AssertionParentSet newNeedParents( needParents ); 496 // skip repeatingly-self-recursive assertion satisfaction 497 // DOESN'T WORK: grandchild nodes conflict with their cousins 498 //if ( newNeedParents[ curDecl->get_uniqueId() ][ candDecl->get_uniqueId() ]++ > recursionParentLimit ) continue; 499 Expression *varExpr = new VariableExpr( candDecl ); 480 500 deleteAll( varExpr->get_results() ); 481 501 varExpr->get_results().clear(); 482 502 varExpr->get_results().push_front( adjType->clone() ); 483 503 PRINT( 484 std::c out<< "satisfying assertion " << curDecl->get_uniqueId() << " ";485 curDecl->print( std::c out);486 std::c out<< " with declaration " << (*candidate)->get_uniqueId() << " ";487 (*candidate)->print( std::c out);488 std::c out<< std::endl;504 std::cerr << "satisfying assertion " << curDecl->get_uniqueId() << " "; 505 curDecl->print( std::cerr ); 506 std::cerr << " with declaration " << (*candidate)->get_uniqueId() << " "; 507 (*candidate)->print( std::cerr ); 508 std::cerr << std::endl; 489 509 ) 490 510 ApplicationExpr *appExpr = static_cast< ApplicationExpr* >( newerAlt.expr ); 491 511 // XXX: this is a memory leak, but adjType can't be deleted because it might contain assertions 492 512 appExpr->get_inferParams()[ curDecl->get_uniqueId() ] = ParamEntry( (*candidate)->get_uniqueId(), adjType->clone(), curDecl->get_type()->clone(), varExpr ); 493 inferRecursive( begin, end, newerAlt, newOpenVars, newDecls, newerNeed, level, indexer, out );513 inferRecursive( begin, end, newerAlt, newOpenVars, newDecls, newerNeed, /*newNeedParents,*/ level, indexer, out ); 494 514 } else { 495 515 delete adjType; … … 501 521 void AlternativeFinder::inferParameters( const AssertionSet &need, AssertionSet &have, const Alternative &newAlt, OpenVarSet &openVars, OutputIterator out ) { 502 522 // PRINT( 503 // std::c out<< "inferParameters: assertions needed are" << std::endl;504 // printAll( need, std::c out, 8 );523 // std::cerr << "inferParameters: assertions needed are" << std::endl; 524 // printAll( need, std::cerr, 8 ); 505 525 // ) 506 526 SymTab::Indexer decls( indexer ); 507 527 PRINT( 508 std::c out<< "============= original indexer" << std::endl;509 indexer.print( std::c out);510 std::c out<< "============= new indexer" << std::endl;511 decls.print( std::c out);528 std::cerr << "============= original indexer" << std::endl; 529 indexer.print( std::cerr ); 530 std::cerr << "============= new indexer" << std::endl; 531 decls.print( std::cerr ); 512 532 ) 513 533 addToIndexer( have, decls ); 514 534 AssertionSet newNeed; 515 inferRecursive( need.begin(), need.end(), newAlt, openVars, decls, newNeed, 0, indexer, out ); 535 //AssertionParentSet needParents; 536 inferRecursive( need.begin(), need.end(), newAlt, openVars, decls, newNeed, /*needParents,*/ 0, indexer, out ); 516 537 // PRINT( 517 // std::c out<< "declaration 14 is ";538 // std::cerr << "declaration 14 is "; 518 539 // Declaration::declFromId 519 540 // *out++ = newAlt; … … 532 553 makeExprList( actualAlt, appExpr->get_args() ); 533 554 PRINT( 534 std::c out<< "need assertions:" << std::endl;535 printAssertionSet( resultNeed, std::c out, 8 );555 std::cerr << "need assertions:" << std::endl; 556 printAssertionSet( resultNeed, std::cerr, 8 ); 536 557 ) 537 558 inferParameters( resultNeed, resultHave, newAlt, openVars, out ); … … 543 564 AlternativeFinder funcOpFinder( indexer, env ); 544 565 545 AlternativeFinder funcFinder( indexer, env ); { 546 NameExpr *fname = 0;; 547 if ( ( fname = dynamic_cast<NameExpr *>( untypedExpr->get_function())) 548 && ( fname->get_name() == std::string("&&")) ) { 566 AlternativeFinder funcFinder( indexer, env ); 567 568 { 569 std::string fname = InitTweak::getFunctionName( untypedExpr ); 570 if ( fname == "&&" ) { 549 571 VoidType v = Type::Qualifiers(); // resolve to type void * 550 572 PointerType pt( Type::Qualifiers(), v.clone() ); … … 570 592 571 593 AltList candidates; 594 SemanticError errors; 572 595 573 596 for ( AltList::const_iterator func = funcFinder.alternatives.begin(); func != funcFinder.alternatives.end(); ++func ) { 574 PRINT( 575 std::cout << "working on alternative: " << std::endl; 576 func->print( std::cout, 8 ); 577 ) 578 // check if the type is pointer to function 579 PointerType *pointer; 580 if ( func->expr->get_results().size() == 1 && ( pointer = dynamic_cast< PointerType* >( func->expr->get_results().front() ) ) ) { 581 if ( FunctionType *function = dynamic_cast< FunctionType* >( pointer->get_base() ) ) { 582 for ( std::list< AltList >::iterator actualAlt = possibilities.begin(); actualAlt != possibilities.end(); ++actualAlt ) { 583 // XXX 584 //Designators::check_alternative( function, *actualAlt ); 585 makeFunctionAlternatives( *func, function, *actualAlt, std::back_inserter( candidates ) ); 586 } 587 } else if ( TypeInstType *typeInst = dynamic_cast< TypeInstType* >( pointer->get_base() ) ) { 588 EqvClass eqvClass; 589 if ( func->env.lookup( typeInst->get_name(), eqvClass ) && eqvClass.type ) { 590 if ( FunctionType *function = dynamic_cast< FunctionType* >( eqvClass.type ) ) { 591 for ( std::list< AltList >::iterator actualAlt = possibilities.begin(); actualAlt != possibilities.end(); ++actualAlt ) { 592 makeFunctionAlternatives( *func, function, *actualAlt, std::back_inserter( candidates ) ); 593 } // for 597 try { 598 PRINT( 599 std::cerr << "working on alternative: " << std::endl; 600 func->print( std::cerr, 8 ); 601 ) 602 // check if the type is pointer to function 603 PointerType *pointer; 604 if ( func->expr->get_results().size() == 1 && ( pointer = dynamic_cast< PointerType* >( func->expr->get_results().front() ) ) ) { 605 if ( FunctionType *function = dynamic_cast< FunctionType* >( pointer->get_base() ) ) { 606 for ( std::list< AltList >::iterator actualAlt = possibilities.begin(); actualAlt != possibilities.end(); ++actualAlt ) { 607 // XXX 608 //Designators::check_alternative( function, *actualAlt ); 609 makeFunctionAlternatives( *func, function, *actualAlt, std::back_inserter( candidates ) ); 610 } 611 } else if ( TypeInstType *typeInst = dynamic_cast< TypeInstType* >( pointer->get_base() ) ) { 612 EqvClass eqvClass; 613 if ( func->env.lookup( typeInst->get_name(), eqvClass ) && eqvClass.type ) { 614 if ( FunctionType *function = dynamic_cast< FunctionType* >( eqvClass.type ) ) { 615 for ( std::list< AltList >::iterator actualAlt = possibilities.begin(); actualAlt != possibilities.end(); ++actualAlt ) { 616 makeFunctionAlternatives( *func, function, *actualAlt, std::back_inserter( candidates ) ); 617 } // for 618 } // if 594 619 } // if 595 620 } // if 621 } else { 622 // seek a function operator that's compatible 623 if ( ! doneInit ) { 624 doneInit = true; 625 NameExpr *opExpr = new NameExpr( "?()" ); 626 try { 627 funcOpFinder.findWithAdjustment( opExpr ); 628 } catch( SemanticError &e ) { 629 // it's ok if there aren't any defined function ops 630 } 631 PRINT( 632 std::cerr << "known function ops:" << std::endl; 633 printAlts( funcOpFinder.alternatives, std::cerr, 8 ); 634 ) 635 } 636 637 for ( AltList::const_iterator funcOp = funcOpFinder.alternatives.begin(); funcOp != funcOpFinder.alternatives.end(); ++funcOp ) { 638 // check if the type is pointer to function 639 PointerType *pointer; 640 if ( funcOp->expr->get_results().size() == 1 641 && ( pointer = dynamic_cast< PointerType* >( funcOp->expr->get_results().front() ) ) ) { 642 if ( FunctionType *function = dynamic_cast< FunctionType* >( pointer->get_base() ) ) { 643 for ( std::list< AltList >::iterator actualAlt = possibilities.begin(); actualAlt != possibilities.end(); ++actualAlt ) { 644 AltList currentAlt; 645 currentAlt.push_back( *func ); 646 currentAlt.insert( currentAlt.end(), actualAlt->begin(), actualAlt->end() ); 647 makeFunctionAlternatives( *funcOp, function, currentAlt, std::back_inserter( candidates ) ); 648 } // for 649 } // if 650 } // if 651 } // for 596 652 } // if 597 } else { 598 // seek a function operator that's compatible 599 if ( ! doneInit ) { 600 doneInit = true; 601 NameExpr *opExpr = new NameExpr( "?()" ); 602 try { 603 funcOpFinder.findWithAdjustment( opExpr ); 604 } catch( SemanticError &e ) { 605 // it's ok if there aren't any defined function ops 606 } 607 PRINT( 608 std::cout << "known function ops:" << std::endl; 609 printAlts( funcOpFinder.alternatives, std::cout, 8 ); 610 ) 611 } 612 613 for ( AltList::const_iterator funcOp = funcOpFinder.alternatives.begin(); funcOp != funcOpFinder.alternatives.end(); ++funcOp ) { 614 // check if the type is pointer to function 615 PointerType *pointer; 616 if ( funcOp->expr->get_results().size() == 1 617 && ( pointer = dynamic_cast< PointerType* >( funcOp->expr->get_results().front() ) ) ) { 618 if ( FunctionType *function = dynamic_cast< FunctionType* >( pointer->get_base() ) ) { 619 for ( std::list< AltList >::iterator actualAlt = possibilities.begin(); actualAlt != possibilities.end(); ++actualAlt ) { 620 AltList currentAlt; 621 currentAlt.push_back( *func ); 622 currentAlt.insert( currentAlt.end(), actualAlt->begin(), actualAlt->end() ); 623 makeFunctionAlternatives( *funcOp, function, currentAlt, std::back_inserter( candidates ) ); 624 } // for 625 } // if 626 } // if 627 } // for 628 } // if 629 } // for 653 } catch ( SemanticError &e ) { 654 errors.append( e ); 655 } 656 } // for 657 658 // Implement SFINAE; resolution errors are only errors if there aren't any non-erroneous resolutions 659 if ( candidates.empty() && ! errors.isEmpty() ) { throw errors; } 630 660 631 661 for ( AltList::iterator withFunc = candidates.begin(); withFunc != candidates.end(); ++withFunc ) { … … 639 669 FunctionType *function = dynamic_cast< FunctionType* >( pointer->get_base() ); 640 670 assert( function ); 641 std::c out<< "Case +++++++++++++" << std::endl;642 std::c out<< "formals are:" << std::endl;643 printAll( function->get_parameters(), std::c out, 8 );644 std::c out<< "actuals are:" << std::endl;645 printAll( appExpr->get_args(), std::c out, 8 );646 std::c out<< "bindings are:" << std::endl;647 withFunc->env.print( std::c out, 8 );648 std::c out<< "cost of conversion is:" << cvtCost << std::endl;671 std::cerr << "Case +++++++++++++" << std::endl; 672 std::cerr << "formals are:" << std::endl; 673 printAll( function->get_parameters(), std::cerr, 8 ); 674 std::cerr << "actuals are:" << std::endl; 675 printAll( appExpr->get_args(), std::cerr, 8 ); 676 std::cerr << "bindings are:" << std::endl; 677 withFunc->env.print( std::cerr, 8 ); 678 std::cerr << "cost of conversion is:" << cvtCost << std::endl; 649 679 ) 650 680 if ( cvtCost != Cost::infinity ) { … … 698 728 std::list< Type* >::iterator candidate_end = (*i).expr->get_results().begin(); 699 729 std::advance( candidate_end, castExpr->get_results().size() ); 730 // unification run for side-effects 731 unifyList( castExpr->get_results().begin(), castExpr->get_results().end(), 732 (*i).expr->get_results().begin(), candidate_end, 733 i->env, needAssertions, haveAssertions, openVars, indexer ); 700 734 Cost thisCost = castCostList( (*i).expr->get_results().begin(), candidate_end, 701 castExpr->get_results().begin(), castExpr->get_results().end(), indexer, i->env ); 735 castExpr->get_results().begin(), castExpr->get_results().end(), 736 indexer, i->env ); 702 737 if ( thisCost != Cost::infinity ) { 703 738 // count one safe conversion for each value that is thrown away … … 787 822 } 788 823 824 void AlternativeFinder::visit( AlignofExpr *alignofExpr ) { 825 if ( alignofExpr->get_isType() ) { 826 alternatives.push_back( Alternative( alignofExpr->clone(), env, Cost::zero ) ); 827 } else { 828 // find all alternatives for the argument to sizeof 829 AlternativeFinder finder( indexer, env ); 830 finder.find( alignofExpr->get_expr() ); 831 // find the lowest cost alternative among the alternatives, otherwise ambiguous 832 AltList winners; 833 findMinCost( finder.alternatives.begin(), finder.alternatives.end(), back_inserter( winners ) ); 834 if ( winners.size() != 1 ) { 835 throw SemanticError( "Ambiguous expression in alignof operand: ", alignofExpr->get_expr() ); 836 } // if 837 // return the lowest cost alternative for the argument 838 Alternative &choice = winners.front(); 839 alternatives.push_back( Alternative( new AlignofExpr( choice.expr->clone() ), choice.env, Cost::zero ) ); 840 } // if 841 } 842 843 template< typename StructOrUnionType > 844 void AlternativeFinder::addOffsetof( StructOrUnionType *aggInst, const std::string &name ) { 845 std::list< Declaration* > members; 846 aggInst->lookup( name, members ); 847 for ( std::list< Declaration* >::const_iterator i = members.begin(); i != members.end(); ++i ) { 848 if ( DeclarationWithType *dwt = dynamic_cast< DeclarationWithType* >( *i ) ) { 849 alternatives.push_back( Alternative( new OffsetofExpr( aggInst->clone(), dwt->clone() ), env, Cost::zero ) ); 850 renameTypes( alternatives.back().expr ); 851 } else { 852 assert( false ); 853 } 854 } 855 } 856 857 void AlternativeFinder::visit( UntypedOffsetofExpr *offsetofExpr ) { 858 AlternativeFinder funcFinder( indexer, env ); 859 if ( StructInstType *structInst = dynamic_cast< StructInstType* >( offsetofExpr->get_type() ) ) { 860 addOffsetof( structInst, offsetofExpr->get_member() ); 861 } else if ( UnionInstType *unionInst = dynamic_cast< UnionInstType* >( offsetofExpr->get_type() ) ) { 862 addOffsetof( unionInst, offsetofExpr->get_member() ); 863 } 864 } 865 866 void AlternativeFinder::visit( OffsetofExpr *offsetofExpr ) { 867 alternatives.push_back( Alternative( offsetofExpr->clone(), env, Cost::zero ) ); 868 } 869 870 void AlternativeFinder::visit( OffsetPackExpr *offsetPackExpr ) { 871 alternatives.push_back( Alternative( offsetPackExpr->clone(), env, Cost::zero ) ); 872 } 873 789 874 void AlternativeFinder::resolveAttr( DeclarationWithType *funcDecl, FunctionType *function, Type *argType, const TypeEnvironment &env ) { 790 875 // assume no polymorphism … … 792 877 assert( function->get_parameters().size() == 1 ); 793 878 PRINT( 794 std::c out<< "resolvAttr: funcDecl is ";795 funcDecl->print( std::c out);796 std::c out<< " argType is ";797 argType->print( std::c out);798 std::c out<< std::endl;879 std::cerr << "resolvAttr: funcDecl is "; 880 funcDecl->print( std::cerr ); 881 std::cerr << " argType is "; 882 argType->print( std::cerr ); 883 std::cerr << std::endl; 799 884 ) 800 885 if ( typesCompatibleIgnoreQualifiers( argType, function->get_parameters().front()->get_type(), indexer, env ) ) { … … 917 1002 } // for 918 1003 } 1004 1005 void AlternativeFinder::visit( ImplicitCopyCtorExpr * impCpCtorExpr ) { 1006 alternatives.push_back( Alternative( impCpCtorExpr->clone(), env, Cost::zero ) ); 1007 } 919 1008 } // namespace ResolvExpr 920 1009
Note:
See TracChangeset
for help on using the changeset viewer.