Changeset 91b8a17


Ignore:
Timestamp:
Feb 24, 2016, 5:08:21 PM (8 years ago)
Author:
Aaron Moss <a3moss@…>
Branches:
ADT, aaron-thesis, arm-eh, ast-experimental, cleanup-dtors, ctor, deferred_resn, demangler, enum, forall-pointer-decay, gc_noraii, jacob/cs343-translation, jenkins-sandbox, master, memory, new-ast, new-ast-unique-expr, new-env, no_list, persistent-indexer, pthread-emulation, qualifiedEnum, resolv-new, string, with_gc
Children:
44b7088, 8bb59af
Parents:
b502055
Message:

Implement SFINAE for function resolution

File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/ResolvExpr/AlternativeFinder.cc

    rb502055 r91b8a17  
    572572
    573573                AltList candidates;
     574                SemanticError errors;
    574575
    575576                for ( AltList::const_iterator func = funcFinder.alternatives.begin(); func != funcFinder.alternatives.end(); ++func ) {
    576                         PRINT(
    577                                 std::cerr << "working on alternative: " << std::endl;
    578                                 func->print( std::cerr, 8 );
    579                         )
    580                         // check if the type is pointer to function
    581                         PointerType *pointer;
    582                         if ( func->expr->get_results().size() == 1 && ( pointer = dynamic_cast< PointerType* >( func->expr->get_results().front() ) ) ) {
    583                                 if ( FunctionType *function = dynamic_cast< FunctionType* >( pointer->get_base() ) ) {
    584                                         for ( std::list< AltList >::iterator actualAlt = possibilities.begin(); actualAlt != possibilities.end(); ++actualAlt ) {
    585                                                 // XXX
    586                                                 //Designators::check_alternative( function, *actualAlt );
    587                                                 makeFunctionAlternatives( *func, function, *actualAlt, std::back_inserter( candidates ) );
    588                                         }
    589                                 } else if ( TypeInstType *typeInst = dynamic_cast< TypeInstType* >( pointer->get_base() ) ) {
    590                                         EqvClass eqvClass;
    591                                         if ( func->env.lookup( typeInst->get_name(), eqvClass ) && eqvClass.type ) {
    592                                                 if ( FunctionType *function = dynamic_cast< FunctionType* >( eqvClass.type ) ) {
    593                                                         for ( std::list< AltList >::iterator actualAlt = possibilities.begin(); actualAlt != possibilities.end(); ++actualAlt ) {
    594                                                                 makeFunctionAlternatives( *func, function, *actualAlt, std::back_inserter( candidates ) );
    595                                                         } // for
     577                        try {
     578                                PRINT(
     579                                        std::cerr << "working on alternative: " << std::endl;
     580                                        func->print( std::cerr, 8 );
     581                                )
     582                                // check if the type is pointer to function
     583                                PointerType *pointer;
     584                                if ( func->expr->get_results().size() == 1 && ( pointer = dynamic_cast< PointerType* >( func->expr->get_results().front() ) ) ) {
     585                                        if ( FunctionType *function = dynamic_cast< FunctionType* >( pointer->get_base() ) ) {
     586                                                for ( std::list< AltList >::iterator actualAlt = possibilities.begin(); actualAlt != possibilities.end(); ++actualAlt ) {
     587                                                        // XXX
     588                                                        //Designators::check_alternative( function, *actualAlt );
     589                                                        makeFunctionAlternatives( *func, function, *actualAlt, std::back_inserter( candidates ) );
     590                                                }
     591                                        } else if ( TypeInstType *typeInst = dynamic_cast< TypeInstType* >( pointer->get_base() ) ) {
     592                                                EqvClass eqvClass;
     593                                                if ( func->env.lookup( typeInst->get_name(), eqvClass ) && eqvClass.type ) {
     594                                                        if ( FunctionType *function = dynamic_cast< FunctionType* >( eqvClass.type ) ) {
     595                                                                for ( std::list< AltList >::iterator actualAlt = possibilities.begin(); actualAlt != possibilities.end(); ++actualAlt ) {
     596                                                                        makeFunctionAlternatives( *func, function, *actualAlt, std::back_inserter( candidates ) );
     597                                                                } // for
     598                                                        } // if
    596599                                                } // if
    597600                                        } // if
     601                                } else {
     602                                        // seek a function operator that's compatible
     603                                        if ( ! doneInit ) {
     604                                                doneInit = true;
     605                                                NameExpr *opExpr = new NameExpr( "?()" );
     606                                                try {
     607                                                        funcOpFinder.findWithAdjustment( opExpr );
     608                                                } catch( SemanticError &e ) {
     609                                                        // it's ok if there aren't any defined function ops
     610                                                }
     611                                                PRINT(
     612                                                        std::cerr << "known function ops:" << std::endl;
     613                                                        printAlts( funcOpFinder.alternatives, std::cerr, 8 );
     614                                                )
     615                                        }
     616
     617                                        for ( AltList::const_iterator funcOp = funcOpFinder.alternatives.begin(); funcOp != funcOpFinder.alternatives.end(); ++funcOp ) {
     618                                                // check if the type is pointer to function
     619                                                PointerType *pointer;
     620                                                if ( funcOp->expr->get_results().size() == 1
     621                                                        && ( pointer = dynamic_cast< PointerType* >( funcOp->expr->get_results().front() ) ) ) {
     622                                                        if ( FunctionType *function = dynamic_cast< FunctionType* >( pointer->get_base() ) ) {
     623                                                                for ( std::list< AltList >::iterator actualAlt = possibilities.begin(); actualAlt != possibilities.end(); ++actualAlt ) {
     624                                                                        AltList currentAlt;
     625                                                                        currentAlt.push_back( *func );
     626                                                                        currentAlt.insert( currentAlt.end(), actualAlt->begin(), actualAlt->end() );
     627                                                                        makeFunctionAlternatives( *funcOp, function, currentAlt, std::back_inserter( candidates ) );
     628                                                                } // for
     629                                                        } // if
     630                                                } // if
     631                                        } // for
    598632                                } // if
    599                         } else {
    600                                 // seek a function operator that's compatible
    601                                 if ( ! doneInit ) {
    602                                         doneInit = true;
    603                                         NameExpr *opExpr = new NameExpr( "?()" );
    604                                         try {
    605                                                 funcOpFinder.findWithAdjustment( opExpr );
    606                                         } catch( SemanticError &e ) {
    607                                                 // it's ok if there aren't any defined function ops
    608                                         }
    609                                         PRINT(
    610                                                 std::cerr << "known function ops:" << std::endl;
    611                                                 printAlts( funcOpFinder.alternatives, std::cerr, 8 );
    612                                         )
    613                                 }
    614 
    615                                 for ( AltList::const_iterator funcOp = funcOpFinder.alternatives.begin(); funcOp != funcOpFinder.alternatives.end(); ++funcOp ) {
    616                                         // check if the type is pointer to function
    617                                         PointerType *pointer;
    618                                         if ( funcOp->expr->get_results().size() == 1
    619                                                  && ( pointer = dynamic_cast< PointerType* >( funcOp->expr->get_results().front() ) ) ) {
    620                                                 if ( FunctionType *function = dynamic_cast< FunctionType* >( pointer->get_base() ) ) {
    621                                                         for ( std::list< AltList >::iterator actualAlt = possibilities.begin(); actualAlt != possibilities.end(); ++actualAlt ) {
    622                                                                 AltList currentAlt;
    623                                                                 currentAlt.push_back( *func );
    624                                                                 currentAlt.insert( currentAlt.end(), actualAlt->begin(), actualAlt->end() );
    625                                                                 makeFunctionAlternatives( *funcOp, function, currentAlt, std::back_inserter( candidates ) );
    626                                                         } // for
    627                                                 } // if
    628                                         } // if
    629                                 } // for
    630                         } // if
    631                 } // for
     633                        } catch ( SemanticError &e ) {
     634                                errors.append( e );
     635                        }
     636                } // for
     637
     638                // Implement SFINAE; resolution errors are only errors if there aren't any non-erroneous resolutions
     639                if ( candidates.empty() && ! errors.isEmpty() ) { throw errors; }
    632640
    633641                for ( AltList::iterator withFunc = candidates.begin(); withFunc != candidates.end(); ++withFunc ) {
Note: See TracChangeset for help on using the changeset viewer.