- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
src/ResolvExpr/AlternativeFinder.cc
r8e9cbb2 r8c84ebd 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 : Mon Jul 4 17:02:51 201613 // Update Count : 2 912 // Last Modified On : Fri Jul 3 17:58:39 2015 13 // Update Count : 22 14 14 // 15 15 … … 19 19 #include <functional> 20 20 #include <cassert> 21 #include <unordered_map>22 #include <utility>23 #include <vector>24 21 25 22 #include "AlternativeFinder.h" … … 41 38 #include "Tuples/TupleAssignment.h" 42 39 #include "Tuples/NameMatcher.h" 43 #include "Common/utility.h" 44 #include "InitTweak/InitTweak.h" 40 #include "utility.h" 45 41 46 42 extern bool resolvep; 47 #define PRINT( text ) if ( resolvep ) { text } 43 #define PRINT( text ) if ( resolvep ) { text } 48 44 //#define DEBUG_COST 49 45 … … 111 107 if ( candidate->cost < mapPlace->second.candidate->cost ) { 112 108 PRINT( 113 std::c err<< "cost " << candidate->cost << " beats " << mapPlace->second.candidate->cost << std::endl;109 std::cout << "cost " << candidate->cost << " beats " << mapPlace->second.candidate->cost << std::endl; 114 110 ) 115 111 selected[ mangleName ] = current; 116 112 } else if ( candidate->cost == mapPlace->second.candidate->cost ) { 117 113 PRINT( 118 std::c err<< "marking ambiguous" << std::endl;114 std::cout << "marking ambiguous" << std::endl; 119 115 ) 120 116 mapPlace->second.isAmbiguous = true; … … 126 122 127 123 PRINT( 128 std::c err<< "there are " << selected.size() << " alternatives before elimination" << std::endl;124 std::cout << "there are " << selected.size() << " alternatives before elimination" << std::endl; 129 125 ) 130 126 … … 186 182 begin++; 187 183 PRINT( 188 std::c err<< "findSubExprs" << std::endl;189 printAlts( finder.alternatives, std::c err);184 std::cout << "findSubExprs" << std::endl; 185 printAlts( finder.alternatives, std::cout ); 190 186 ) 191 187 *out++ = finder; … … 208 204 } 209 205 PRINT( 210 std::c err<< "alternatives before prune:" << std::endl;211 printAlts( alternatives, std::c err);206 std::cout << "alternatives before prune:" << std::endl; 207 printAlts( alternatives, std::cout ); 212 208 ) 213 209 AltList::iterator oldBegin = alternatives.begin(); … … 225 221 alternatives.erase( oldBegin, alternatives.end() ); 226 222 PRINT( 227 std::c err<< "there are " << alternatives.size() << " alternatives after elimination" << std::endl;223 std::cout << "there are " << alternatives.size() << " alternatives after elimination" << std::endl; 228 224 ) 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 } // for234 225 } 235 226 … … 270 261 for ( std::list< Expression* >::iterator actualExpr = actuals.begin(); actualExpr != actuals.end(); ++actualExpr ) { 271 262 PRINT( 272 std::c err<< "actual expression:" << std::endl;273 (*actualExpr)->print( std::c err, 8 );274 std::c err<< "--- results are" << std::endl;275 printAll( (*actualExpr)->get_results(), std::c err, 8 );263 std::cout << "actual expression:" << std::endl; 264 (*actualExpr)->print( std::cout, 8 ); 265 std::cout << "--- results are" << std::endl; 266 printAll( (*actualExpr)->get_results(), std::cout, 8 ); 276 267 ) 277 268 std::list< DeclarationWithType* >::iterator startFormal = formal; … … 287 278 } 288 279 PRINT( 289 std::c err<< std::endl << "converting ";290 (*actual)->print( std::c err, 8 );291 std::c err<< std::endl << " to ";292 (*formal)->get_type()->print( std::c err, 8 );280 std::cout << std::endl << "converting "; 281 (*actual)->print( std::cout, 8 ); 282 std::cout << std::endl << " to "; 283 (*formal)->get_type()->print( std::cout, 8 ); 293 284 ) 294 285 Cost newCost = conversionCost( *actual, (*formal)->get_type(), indexer, alt.env ); 295 286 PRINT( 296 std::c err<< std::endl << "cost is" << newCost << std::endl;287 std::cout << std::endl << "cost is" << newCost << std::endl; 297 288 ) 298 289 … … 332 323 for ( InferredParams::const_iterator assert = appExpr->get_inferParams().begin(); assert != appExpr->get_inferParams().end(); ++assert ) { 333 324 PRINT( 334 std::c err<< std::endl << "converting ";335 assert->second.actualType->print( std::c err, 8 );336 std::c err<< std::endl << " to ";337 assert->second.formalType->print( std::c err, 8 );325 std::cout << std::endl << "converting "; 326 assert->second.actualType->print( std::cout, 8 ); 327 std::cout << std::endl << " to "; 328 assert->second.formalType->print( std::cout, 8 ); 338 329 ) 339 330 Cost newCost = conversionCost( assert->second.actualType, assert->second.formalType, indexer, alt.env ); 340 331 PRINT( 341 std::c err<< std::endl << "cost of conversion is " << newCost << std::endl;332 std::cout << std::endl << "cost of conversion is " << newCost << std::endl; 342 333 ) 343 334 if ( newCost == Cost::infinity ) { … … 416 407 } 417 408 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 409 static const int recursionLimit = 10; 423 410 424 411 void addToIndexer( AssertionSet &assertSet, SymTab::Indexer &indexer ) { … … 429 416 } 430 417 } 431 418 432 419 template< typename ForwardIterator, typename OutputIterator > 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 ) { 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 ) { 435 421 if ( begin == end ) { 436 422 if ( newNeed.empty() ) { … … 445 431 printAssertionSet( newNeed, std::cerr, 8 ); 446 432 ) 447 inferRecursive( newNeed.begin(), newNeed.end(), newAlt, openVars, decls, newerNeed, /*needParents,*/level+1, indexer, out );433 inferRecursive( newNeed.begin(), newNeed.end(), newAlt, openVars, decls, newerNeed, level+1, indexer, out ); 448 434 return; 449 435 } … … 452 438 ForwardIterator cur = begin++; 453 439 if ( ! cur->second ) { 454 inferRecursive( begin, end, newAlt, openVars, decls, newNeed, /*needParents,*/level, indexer, out );440 inferRecursive( begin, end, newAlt, openVars, decls, newNeed, level, indexer, out ); 455 441 } 456 442 DeclarationWithType *curDecl = cur->first; … … 462 448 std::list< DeclarationWithType* > candidates; 463 449 decls.lookupId( curDecl->get_name(), candidates ); 464 /// if ( candidates.empty() ) { std::c err<< "no candidates!" << std::endl; }450 /// if ( candidates.empty() ) { std::cout << "no candidates!" << std::endl; } 465 451 for ( std::list< DeclarationWithType* >::const_iterator candidate = candidates.begin(); candidate != candidates.end(); ++candidate ) { 466 452 PRINT( 467 std::c err<< "inferRecursive: candidate is ";468 (*candidate)->print( std::c err);469 std::c err<< std::endl;453 std::cout << "inferRecursive: candidate is "; 454 (*candidate)->print( std::cout ); 455 std::cout << std::endl; 470 456 ) 471 472 457 AssertionSet newHave, newerNeed( newNeed ); 473 458 TypeEnvironment newEnv( newAlt.env ); … … 492 477 newerAlt.env = newEnv; 493 478 assert( (*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 ); 479 Expression *varExpr = new VariableExpr( static_cast< DeclarationWithType* >( Declaration::declFromId( (*candidate)->get_uniqueId() ) ) ); 500 480 deleteAll( varExpr->get_results() ); 501 481 varExpr->get_results().clear(); 502 482 varExpr->get_results().push_front( adjType->clone() ); 503 483 PRINT( 504 std::c err<< "satisfying assertion " << curDecl->get_uniqueId() << " ";505 curDecl->print( std::c err);506 std::c err<< " with declaration " << (*candidate)->get_uniqueId() << " ";507 (*candidate)->print( std::c err);508 std::c err<< std::endl;484 std::cout << "satisfying assertion " << curDecl->get_uniqueId() << " "; 485 curDecl->print( std::cout ); 486 std::cout << " with declaration " << (*candidate)->get_uniqueId() << " "; 487 (*candidate)->print( std::cout ); 488 std::cout << std::endl; 509 489 ) 510 490 ApplicationExpr *appExpr = static_cast< ApplicationExpr* >( newerAlt.expr ); 511 491 // XXX: this is a memory leak, but adjType can't be deleted because it might contain assertions 512 492 appExpr->get_inferParams()[ curDecl->get_uniqueId() ] = ParamEntry( (*candidate)->get_uniqueId(), adjType->clone(), curDecl->get_type()->clone(), varExpr ); 513 inferRecursive( begin, end, newerAlt, newOpenVars, newDecls, newerNeed, /*newNeedParents,*/level, indexer, out );493 inferRecursive( begin, end, newerAlt, newOpenVars, newDecls, newerNeed, level, indexer, out ); 514 494 } else { 515 495 delete adjType; … … 521 501 void AlternativeFinder::inferParameters( const AssertionSet &need, AssertionSet &have, const Alternative &newAlt, OpenVarSet &openVars, OutputIterator out ) { 522 502 // PRINT( 523 // std::c err<< "inferParameters: assertions needed are" << std::endl;524 // printAll( need, std::c err, 8 );503 // std::cout << "inferParameters: assertions needed are" << std::endl; 504 // printAll( need, std::cout, 8 ); 525 505 // ) 526 506 SymTab::Indexer decls( indexer ); 527 507 PRINT( 528 std::c err<< "============= original indexer" << std::endl;529 indexer.print( std::c err);530 std::c err<< "============= new indexer" << std::endl;531 decls.print( std::c err);508 std::cout << "============= original indexer" << std::endl; 509 indexer.print( std::cout ); 510 std::cout << "============= new indexer" << std::endl; 511 decls.print( std::cout ); 532 512 ) 533 513 addToIndexer( have, decls ); 534 514 AssertionSet newNeed; 535 //AssertionParentSet needParents; 536 inferRecursive( need.begin(), need.end(), newAlt, openVars, decls, newNeed, /*needParents,*/ 0, indexer, out ); 515 inferRecursive( need.begin(), need.end(), newAlt, openVars, decls, newNeed, 0, indexer, out ); 537 516 // PRINT( 538 // std::c err<< "declaration 14 is ";517 // std::cout << "declaration 14 is "; 539 518 // Declaration::declFromId 540 519 // *out++ = newAlt; … … 553 532 makeExprList( actualAlt, appExpr->get_args() ); 554 533 PRINT( 555 std::c err<< "need assertions:" << std::endl;556 printAssertionSet( resultNeed, std::c err, 8 );534 std::cout << "need assertions:" << std::endl; 535 printAssertionSet( resultNeed, std::cout, 8 ); 557 536 ) 558 537 inferParameters( resultNeed, resultHave, newAlt, openVars, out ); … … 564 543 AlternativeFinder funcOpFinder( indexer, env ); 565 544 566 AlternativeFinder funcFinder( indexer, env ); 567 568 { 569 std::string fname = InitTweak::getFunctionName( untypedExpr ); 570 if ( fname == "&&" ) { 545 AlternativeFinder funcFinder( indexer, env ); { 546 NameExpr *fname = 0;; 547 if ( ( fname = dynamic_cast<NameExpr *>( untypedExpr->get_function())) 548 && ( fname->get_name() == std::string("&&")) ) { 571 549 VoidType v = Type::Qualifiers(); // resolve to type void * 572 550 PointerType pt( Type::Qualifiers(), v.clone() ); … … 592 570 593 571 AltList candidates; 594 SemanticError errors;595 572 596 573 for ( AltList::const_iterator func = funcFinder.alternatives.begin(); func != funcFinder.alternatives.end(); ++func ) { 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 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 619 594 } // if 620 595 } // 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 ) 596 } // 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 635 606 } 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 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 650 625 } // if 651 } // for 652 } // if 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; } 626 } // if 627 } // for 628 } // if 629 } // for 660 630 661 631 for ( AltList::iterator withFunc = candidates.begin(); withFunc != candidates.end(); ++withFunc ) { … … 669 639 FunctionType *function = dynamic_cast< FunctionType* >( pointer->get_base() ); 670 640 assert( function ); 671 std::c err<< "Case +++++++++++++" << std::endl;672 std::c err<< "formals are:" << std::endl;673 printAll( function->get_parameters(), std::c err, 8 );674 std::c err<< "actuals are:" << std::endl;675 printAll( appExpr->get_args(), std::c err, 8 );676 std::c err<< "bindings are:" << std::endl;677 withFunc->env.print( std::c err, 8 );678 std::c err<< "cost of conversion is:" << cvtCost << std::endl;641 std::cout << "Case +++++++++++++" << std::endl; 642 std::cout << "formals are:" << std::endl; 643 printAll( function->get_parameters(), std::cout, 8 ); 644 std::cout << "actuals are:" << std::endl; 645 printAll( appExpr->get_args(), std::cout, 8 ); 646 std::cout << "bindings are:" << std::endl; 647 withFunc->env.print( std::cout, 8 ); 648 std::cout << "cost of conversion is:" << cvtCost << std::endl; 679 649 ) 680 650 if ( cvtCost != Cost::infinity ) { … … 728 698 std::list< Type* >::iterator candidate_end = (*i).expr->get_results().begin(); 729 699 std::advance( candidate_end, castExpr->get_results().size() ); 730 // unification run for side-effects731 unifyList( castExpr->get_results().begin(), castExpr->get_results().end(),732 (*i).expr->get_results().begin(), candidate_end,733 i->env, needAssertions, haveAssertions, openVars, indexer );734 700 Cost thisCost = castCostList( (*i).expr->get_results().begin(), candidate_end, 735 castExpr->get_results().begin(), castExpr->get_results().end(), 736 indexer, i->env ); 701 castExpr->get_results().begin(), castExpr->get_results().end(), indexer, i->env ); 737 702 if ( thisCost != Cost::infinity ) { 738 703 // count one safe conversion for each value that is thrown away … … 822 787 } 823 788 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 sizeof829 AlternativeFinder finder( indexer, env );830 finder.find( alignofExpr->get_expr() );831 // find the lowest cost alternative among the alternatives, otherwise ambiguous832 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 } // if837 // return the lowest cost alternative for the argument838 Alternative &choice = winners.front();839 alternatives.push_back( Alternative( new AlignofExpr( choice.expr->clone() ), choice.env, Cost::zero ) );840 } // if841 }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 874 789 void AlternativeFinder::resolveAttr( DeclarationWithType *funcDecl, FunctionType *function, Type *argType, const TypeEnvironment &env ) { 875 790 // assume no polymorphism … … 877 792 assert( function->get_parameters().size() == 1 ); 878 793 PRINT( 879 std::c err<< "resolvAttr: funcDecl is ";880 funcDecl->print( std::c err);881 std::c err<< " argType is ";882 argType->print( std::c err);883 std::c err<< std::endl;794 std::cout << "resolvAttr: funcDecl is "; 795 funcDecl->print( std::cout ); 796 std::cout << " argType is "; 797 argType->print( std::cout ); 798 std::cout << std::endl; 884 799 ) 885 800 if ( typesCompatibleIgnoreQualifiers( argType, function->get_parameters().front()->get_type(), indexer, env ) ) { … … 1002 917 } // for 1003 918 } 1004 1005 void AlternativeFinder::visit( ImplicitCopyCtorExpr * impCpCtorExpr ) {1006 alternatives.push_back( Alternative( impCpCtorExpr->clone(), env, Cost::zero ) );1007 }1008 919 } // namespace ResolvExpr 1009 920
Note:
See TracChangeset
for help on using the changeset viewer.