Changeset aeb75b1 for src/ResolvExpr


Ignore:
Timestamp:
Oct 2, 2017, 3:02:21 PM (7 years ago)
Author:
Aaron Moss <a3moss@…>
Branches:
ADT, aaron-thesis, arm-eh, ast-experimental, cleanup-dtors, deferred_resn, demangler, enum, forall-pointer-decay, jacob/cs343-translation, jenkins-sandbox, master, new-ast, new-ast-unique-expr, new-env, no_list, persistent-indexer, pthread-emulation, qualifiedEnum, resolv-new, with_gc
Children:
e472d54
Parents:
9bae71f
Message:

First draft of iterative bottom-up resolver [BROKEN]

Location:
src/ResolvExpr
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • src/ResolvExpr/AlternativeFinder.cc

    r9bae71f raeb75b1  
    2222#include <memory>                  // for allocator_traits<>::value_type
    2323#include <utility>                 // for pair
     24#include <vector>                  // for vector
    2425
    2526#include "Alternative.h"           // for AltList, Alternative
     
    396397///     needAssertions.insert( needAssertions.end(), (*tyvar)->get_assertions().begin(), (*tyvar)->get_assertions().end() );
    397398                }
    398         }
    399 
    400         /// instantiate a single argument by matching actuals from [actualIt, actualEnd) against formalType,
    401         /// producing expression(s) in out and their total cost in cost.
    402         template< typename AltIterator, typename OutputIterator >
    403         bool instantiateArgument( Type * formalType, Initializer * defaultValue, AltIterator & actualIt, AltIterator actualEnd, OpenVarSet & openVars, TypeEnvironment & resultEnv, AssertionSet & resultNeed, AssertionSet & resultHave, const SymTab::Indexer & indexer, Cost & cost, OutputIterator out ) {
    404                 if ( TupleType * tupleType = dynamic_cast< TupleType * >( formalType ) ) {
    405                         // formalType is a TupleType - group actuals into a TupleExpr whose type unifies with the TupleType
    406                         std::list< Expression * > exprs;
    407                         for ( Type * type : *tupleType ) {
    408                                 if ( ! instantiateArgument( type, defaultValue, actualIt, actualEnd, openVars, resultEnv, resultNeed, resultHave, indexer, cost, back_inserter( exprs ) ) ) {
    409                                         deleteAll( exprs );
    410                                         return false;
    411                                 }
    412                         }
    413                         *out++ = new TupleExpr( exprs );
    414                 } else if ( TypeInstType * ttype = Tuples::isTtype( formalType ) ) {
    415                         // xxx - mixing default arguments with variadic??
    416                         std::list< Expression * > exprs;
    417                         for ( ; actualIt != actualEnd; ++actualIt ) {
    418                                 exprs.push_back( actualIt->expr->clone() );
    419                                 cost += actualIt->cost;
    420                         }
    421                         Expression * arg = nullptr;
    422                         if ( exprs.size() == 1 && Tuples::isTtype( exprs.front()->get_result() ) ) {
    423                                 // the case where a ttype value is passed directly is special, e.g. for argument forwarding purposes
    424                                 // xxx - what if passing multiple arguments, last of which is ttype?
    425                                 // xxx - what would happen if unify was changed so that unifying tuple types flattened both before unifying lists? then pass in TupleType(ttype) below.
    426                                 arg = exprs.front();
    427                         } else {
    428                                 arg = new TupleExpr( exprs );
    429                         }
    430                         assert( arg && arg->get_result() );
    431                         if ( ! unify( ttype, arg->get_result(), resultEnv, resultNeed, resultHave, openVars, indexer ) ) {
    432                                 return false;
    433                         }
    434                         *out++ = arg;
    435                 } else if ( actualIt != actualEnd ) {
    436                         // both actualType and formalType are atomic (non-tuple) types - if they unify
    437                         // then accept actual as an argument, otherwise return false (fail to instantiate argument)
    438                         Expression * actual = actualIt->expr;
    439                         Type * actualType = actual->get_result();
    440 
    441                         PRINT(
    442                                 std::cerr << "formal type is ";
    443                                 formalType->print( std::cerr );
    444                                 std::cerr << std::endl << "actual type is ";
    445                                 actualType->print( std::cerr );
    446                                 std::cerr << std::endl;
    447                         )
    448                         if ( ! unify( formalType, actualType, resultEnv, resultNeed, resultHave, openVars, indexer ) ) {
    449                                 // std::cerr << "unify failed" << std::endl;
    450                                 return false;
    451                         }
    452                         // move the expression from the alternative to the output iterator
    453                         *out++ = actual;
    454                         actualIt->expr = nullptr;
    455                         cost += actualIt->cost;
    456                         ++actualIt;
    457                 } else {
    458                         // End of actuals - Handle default values
    459                         if ( SingleInit *si = dynamic_cast<SingleInit *>( defaultValue )) {
    460                                 if ( CastExpr * castExpr = dynamic_cast< CastExpr * >( si->get_value() ) ) {
    461                                         // so far, only constant expressions are accepted as default values
    462                                         if ( ConstantExpr *cnstexpr = dynamic_cast<ConstantExpr *>( castExpr->get_arg() ) ) {
    463                                                 if ( Constant *cnst = dynamic_cast<Constant *>( cnstexpr->get_constant() ) ) {
    464                                                         if ( unify( formalType, cnst->get_type(), resultEnv, resultNeed, resultHave, openVars, indexer ) ) {
    465                                                                 *out++ = cnstexpr->clone();
    466                                                                 return true;
    467                                                         } // if
    468                                                 } // if
    469                                         } // if
    470                                 }
    471                         } // if
    472                         return false;
    473                 } // if
    474                 return true;
    475         }
    476 
    477         bool AlternativeFinder::instantiateFunction( std::list< DeclarationWithType* >& formals, const AltList &actuals, bool isVarArgs, OpenVarSet& openVars, TypeEnvironment &resultEnv, AssertionSet &resultNeed, AssertionSet &resultHave, AltList & out ) {
    478                 simpleCombineEnvironments( actuals.begin(), actuals.end(), resultEnv );
    479                 // make sure we don't widen any existing bindings
    480                 for ( TypeEnvironment::iterator i = resultEnv.begin(); i != resultEnv.end(); ++i ) {
    481                         i->allowWidening = false;
    482                 }
    483                 resultEnv.extractOpenVars( openVars );
    484 
    485                 // flatten actuals so that each actual has an atomic (non-tuple) type
    486                 AltList exploded;
    487                 Tuples::explode( actuals, indexer, back_inserter( exploded ) );
    488 
    489                 AltList::iterator actualExpr = exploded.begin();
    490                 AltList::iterator actualEnd = exploded.end();
    491                 for ( DeclarationWithType * formal : formals ) {
    492                         // match flattened actuals with formal parameters - actuals will be grouped to match
    493                         // with formals as appropriate
    494                         Cost cost = Cost::zero;
    495                         std::list< Expression * > newExprs;
    496                         ObjectDecl * obj = strict_dynamic_cast< ObjectDecl * >( formal );
    497                         if ( ! instantiateArgument( obj->get_type(), obj->get_init(), actualExpr, actualEnd, openVars, resultEnv, resultNeed, resultHave, indexer, cost, back_inserter( newExprs ) ) ) {
    498                                 deleteAll( newExprs );
    499                                 return false;
    500                         }
    501                         // success - produce argument as a new alternative
    502                         assert( newExprs.size() == 1 );
    503                         out.push_back( Alternative( newExprs.front(), resultEnv, cost ) );
    504                 }
    505                 if ( actualExpr != actualEnd ) {
    506                         // there are still actuals remaining, but we've run out of formal parameters to match against
    507                         // this is okay only if the function is variadic
    508                         if ( ! isVarArgs ) {
    509                                 return false;
    510                         }
    511                         out.splice( out.end(), exploded, actualExpr, actualEnd );
    512                 }
    513                 return true;
    514399        }
    515400
     
    667552        }
    668553
    669         template< typename OutputIterator >
    670         void AlternativeFinder::makeFunctionAlternatives( const Alternative &func, FunctionType *funcType, const AltList &actualAlt, OutputIterator out ) {
    671                 OpenVarSet openVars;
    672                 AssertionSet resultNeed, resultHave;
    673                 TypeEnvironment resultEnv;
    674                 makeUnifiableVars( funcType, openVars, resultNeed );
    675                 resultEnv.add( funcType->get_forall() ); // add all type variables as open variables now so that those not used in the parameter list are still considered open
    676                 AltList instantiatedActuals; // filled by instantiate function
     554        /// Gets a default value from an initializer, nullptr if not present
     555        ConstantExpr* getDefaultValue( Initializer* init ) {
     556                if ( SingleInit* si = dynamic_cast<SingleInit*>( init ) ) {
     557                        if ( CastExpr* ce = dynamic_cast<CastExpr*>( si->get_value() ) ) {
     558                                return dynamic_cast<ConstantExpr*>( ce->get_arg() );
     559                        }
     560                }
     561                return nullptr;
     562        }
     563
     564        /// State to iteratively build a match of parameter expressions to arguments
     565        struct ArgPack {
     566                AltList actuals;      ///< Arguments included in this pack
     567                TypeEnvironment env;  ///< Environment for this pack
     568                AssertionSet need;    ///< Assertions outstanding for this pack
     569                AssertionSet have;    ///< Assertions found for this pack
     570                OpenVarSet openVars;  ///< Open variables for this pack
     571                unsigned nextArg;     ///< Index of next argument in arguments list
     572               
     573                /// Number of elements included in current tuple element (nested appropriately)
     574                std::vector<unsigned> tupleEls;
     575
     576                ArgPack(const TypeEnvironment& env, const AssertionSet& need, const AssertionSet& have,
     577                                const OpenVarSet& openVars)
     578                        : actuals(), env(env), need(need), have(have), openVars(openVars), nextArg(0),
     579                          tupleEls() {}
     580               
     581                ArgPack(const ArgPack& old, Expression* actual, const Cost& cost = Cost::zero)
     582                        : actuals(old.actuals), env(old.env), need(old.need), have(old.have),
     583                          openVars(old.openVars), nextArg(old.nextArg + 1), tupleEls(old.tupleEls) {
     584                        actuals.emplace_back( actual, this->env, cost );
     585                }
     586               
     587                ArgPack(const ArgPack& old, Expression* actual, TypeEnvironment&& env, AssertionSet&& need,
     588                                AssertionSet&& have, const Cost& cost = Cost::zero)
     589                        : actuals(old.actuals), env(std::move(env)), need(std::move(need)),
     590                          have(std::move(have)), openVars(old.openVars), nextArg(old.nextArg + 1),
     591                          tupleEls(old.tupleEls) {
     592                        // add new actual
     593                        actuals.emplace_back( actual, this->env, cost );
     594                        // count tuple elements, if applicable
     595                        if ( ! tupleEls.empty() ) ++tupleEls.back();
     596                }
     597
     598                /// Starts a new tuple expression
     599                void beginTuple() {
     600                        if ( ! tupleEls.empty() ) ++tupleEls.back();
     601                        tupleEls.push_back(0);
     602                }
     603
     604                /// Ends a tuple expression, consolidating the appropriate actuals
     605                void endTuple() {
     606                        // set up new Tuple alternative
     607                        std::list<Expression*> exprs;
     608                        Cost cost = Cost::zero;
     609
     610                        // transfer elements into alternative
     611                        for (unsigned i = 0; i < tupleEls.back(); ++i) {
     612                                exprs.push_front( actuals.back().expr );
     613                                cost += actuals.back().cost;
     614                                actuals.pop_back();
     615                        }
     616                        tupleEls.pop_back();
     617
     618                        // build new alternative
     619                        actuals.emplace_back( new TupleExpr( exprs ), this->env, cost );
     620                }
     621        };
     622
     623        /// Iterates a result, exploding actuals as needed.
     624        /// add is a function that takes the same parameters as this (with the exception of add)
     625        template<typename F>
     626        void addExplodedActual( ArgPack& result, Expression* expr, Cost cost,
     627                        std::vector<ArgPack>& nextResults, F add ) {
     628                Type* res = expr->get_result()->stripReferences();
     629                if ( TupleType* tupleType = dynamic_cast<TupleType*>( res ) ) {
     630                        if ( TupleExpr* tupleExpr = dynamic_cast<TupleExpr*>( expr ) ) {
     631                                // recursively explode tuple
     632                                for ( Expression* sexpr : tupleExpr->get_exprs() ) {
     633                                        addExplodedActual( result, sexpr, cost, nextResults, add );
     634                                        cost = Cost::zero; // reset cost so not duplicated
     635                                }
     636                        } else {
     637                                // tuple type, but not tuple expr - recursively index into components.
     638                                // if expr type is reference, convert to value type
     639                                Expression* arg = expr->clone();
     640                                if ( Tuples::maybeImpureIgnoreUnique( arg ) ) {
     641                                        // expressions which may contain side effects require a single unique instance of the expression.
     642                                        arg = new UniqueExpr( arg );
     643                                }
     644                                // cast reference to value type to facilitate further explosion
     645                                if ( dynamic_cast<ReferenceType*>( arg->get_result() ) ) {
     646                                        arg = new CastExpr( arg, tupleType->clone() );
     647                                }
     648                                // explode tuple by index
     649                                for ( unsigned i = 0; i < tupleType->size(); ++i ) {
     650                                        TupleIndexExpr* idx = new TupleIndexExpr( arg->clone(), i );
     651                                        addExplodedActual( result, idx, cost, nextResults, add );
     652                                        cost = Cost::zero; // reset cost so not duplicated
     653                                        delete idx;
     654                                }
     655                                delete arg;
     656                        }
     657                } else {
     658                        // add non-tuple results directly
     659                        add( result, expr->clone(), cost, nextResults );
     660                }
     661        }
     662
     663        /// Instantiates an argument to match a formal, returns false if no results left
     664        bool instantiateArgument( Type* formalType, Initializer* initializer,
     665                        const std::vector< AlternativeFinder >& args,
     666                        std::vector<ArgPack>& results, std::vector<ArgPack>& nextResults,
     667                        const SymTab::Indexer& indexer ) {
     668                if ( TupleType* tupleType = dynamic_cast<TupleType*>( formalType ) ) {
     669                        // formalType is a TupleType - group actuals into a TupleExpr
     670                        for ( ArgPack& result : results ) { result.beginTuple(); }
     671                        for ( Type* type : *tupleType ) {
     672                                // xxx - dropping initializer changes behaviour from previous, but seems correct
     673                                if ( ! instantiateArgument( type, nullptr, args, results, nextResults, indexer ) )
     674                                        return false;
     675                        }
     676                        for ( ArgPack& result : results ) { result.endTuple(); }
     677                        return true;
     678                } else if ( TypeInstType* ttype = Tuples::isTtype( formalType ) ) {
     679                        // formalType is a ttype, consumes all remaining arguments
     680                        // xxx - mixing default arguments with variadic??
     681                        std::vector<ArgPack> finalResults{};  /// list of completed tuples
     682                        // start tuples
     683                        for ( ArgPack& result : results ) { result.beginTuple(); }
     684                        // iterate until all results completed
     685                        while ( ! results.empty() ) {
     686                                // add another argument to results
     687                                for ( ArgPack& result : results ) {
     688                                        // finish result when out of arguments
     689                                        if ( result.nextArg >= args.size() ) {
     690                                                Type* argType = result.actuals.back().expr->get_result();
     691                                                if ( result.tupleEls.back() == 1 && Tuples::isTtype( argType ) ) {
     692                                                        // the case where a ttype value is passed directly is special, e.g. for
     693                                                        // argument forwarding purposes
     694                                                        // xxx - what if passing multiple arguments, last of which is ttype?
     695                                                        // xxx - what would happen if unify was changed so that unifying tuple
     696                                                        // types flattened both before unifying lists? then pass in TupleType
     697                                                        // (ttype) below.
     698                                                        result.tupleEls.pop_back();
     699                                                } else {
     700                                                        // collapse leftover arguments into tuple
     701                                                        result.endTuple();
     702                                                        argType = result.actuals.back().expr->get_result();
     703                                                }
     704                                                // check unification for ttype before adding to final
     705                                                if ( unify( ttype, argType, result.env, result.need, result.have,
     706                                                                result.openVars, indexer ) ) {
     707                                                        finalResults.emplace_back( std::move(result) );
     708                                                }
     709                                                continue;
     710                                        }
     711
     712                                        // add each possible next argument
     713                                        for ( const Alternative& actual : args[result.nextArg] ) {
     714                                                addExplodedActual( result, actual.expr, actual.cost, nextResults,
     715                                                        []( ArgPack& result, Expression* expr, Cost cost,
     716                                                                        std::vector<ArgPack>& nextResults ) {
     717                                                                nextResults.emplace_back( result, expr, cost );
     718                                                        } );
     719                                        }
     720                                }
     721
     722                                // reset for next round
     723                                results.swap( nextResults );
     724                                nextResults.clear();
     725                        }
     726                        results.swap( finalResults );
     727                        return ! results.empty();
     728                }
     729               
     730                // iterate each current subresult
     731                for ( ArgPack& result : results ) {
     732                        if ( result.nextArg >= args.size() ) {
     733                                // If run out of actuals, handle default values
     734                                if ( ConstantExpr* cnstExpr = getDefaultValue( initializer ) ) {
     735                                        if ( Constant* cnst = dynamic_cast<Constant*>( cnstExpr->get_constant() ) ) {
     736                                                TypeEnvironment resultEnv = result.env;
     737                                                AssertionSet resultNeed = result.need, resultHave = result.have;
     738                                                if ( unify( formalType, cnst->get_type(),
     739                                                                resultEnv, resultNeed, resultHave, result.openVars,
     740                                                                indexer ) ) {
     741                                                        nextResults.emplace_back( result, cnstExpr->clone(),
     742                                                                std::move(resultEnv), std::move(resultNeed),
     743                                                                std::move(resultHave) );
     744                                                }
     745                                        }
     746                                }
     747                                continue;
     748                        }
     749
     750                        // Check each possible next argument
     751                        for ( const Alternative& actual : args[result.nextArg] ) {
     752                                addExplodedActual( result, actual.expr, actual.cost, nextResults,
     753                                        [formalType,&indexer]( ArgPack& result, Expression* expr, Cost cost,
     754                                                        std::vector<ArgPack>& nextResults ) {
     755                                                // attempt to unify actual with parameter
     756                                                TypeEnvironment resultEnv = result.env;
     757                                                AssertionSet resultNeed = result.need, resultHave = result.have;
     758                                                Type* actualType = expr->get_result();
     759
     760                                                PRINT(
     761                                                        std::cerr << "formal type is ";
     762                                                        formalType->print( std::cerr );
     763                                                        std::cerr << std::endl << "actual type is ";
     764                                                        actualType->print( std::cerr );
     765                                                        std::cerr << std::endl;
     766                                                )
     767
     768                                                if ( unify( formalType, actualType, resultEnv, resultNeed, resultHave,
     769                                                                result.openVars, indexer ) ) {
     770                                                        nextResults.emplace_back( result, expr->clone(),
     771                                                                std::move(resultEnv), std::move(resultNeed), std::move(resultHave),
     772                                                                cost );
     773                                                }
     774                                        } );
     775                        }
     776                }
     777
     778                // reset for next parameter
     779                results.swap( nextResults );
     780                nextResults.clear();
     781               
     782                return ! results.empty();
     783        }
     784
     785        template<typename OutputIterator>
     786        void AlternativeFinder::makeFunctionAlternatives( const Alternative& func,
     787                        FunctionType* funcType, const std::vector< AlternativeFinder >& args,
     788                        OutputIterator out ) {
     789                OpenVarSet funcOpenVars;
     790                AssertionSet funcNeed, funcHave;
     791                TypeEnvironment funcEnv;
     792                makeUnifiableVars( funcType, funcOpenVars, funcNeed );
     793                // add all type variables as open variables now so that those not used in the parameter
     794                // list are still considered open.
     795                funcEnv.add( funcType->get_forall() );
     796
    677797                if ( targetType && ! targetType->isVoid() && ! funcType->get_returnVals().empty() ) {
    678798                        // attempt to narrow based on expected target type
    679                         Type * returnType = funcType->get_returnVals().front()->get_type();
    680                         if ( ! unify( returnType, targetType, resultEnv, resultNeed, resultHave, openVars, indexer ) ) {
    681                                 // unification failed, don't pursue this alternative
     799                        Type* returnType = funcType->get_returnVals().front()->get_type();
     800                        if ( ! unify( returnType, targetType, funcEnv, funcNeed, funcHave, funcOpenVars,
     801                                        indexer ) ) {
     802                                // unification failed, don't pursue this function alternative
    682803                                return;
    683804                        }
    684805                }
    685806
    686                 if ( instantiateFunction( funcType->get_parameters(), actualAlt, funcType->get_isVarArgs(), openVars, resultEnv, resultNeed, resultHave, instantiatedActuals ) ) {
     807                // iteratively build matches, one parameter at a time
     808                std::vector<ArgPack> results{ ArgPack{ funcEnv, funcNeed, funcHave, funcOpenVars } };
     809                std::vector<ArgPack> nextResults{};
     810                for ( DeclarationWithType* formal : funcType->get_parameters() ) {
     811                        ObjectDecl* obj = strict_dynamic_cast< ObjectDecl* >( formal );
     812                        if ( ! instantiateArgument(
     813                                        obj->get_type(), obj->get_init(), args, results, nextResults, indexer ) )
     814                                return;
     815                }
     816
     817                // filter out results that don't use all the arguments, and aren't variadic
     818                std::vector<ArgPack> finalResults{};
     819                if ( funcType->get_isVarArgs() ) {
     820                        while ( ! results.empty() ) {
     821                                // build combinations for all remaining arguments
     822                                for ( ArgPack& result : results ) {
     823                                        // keep if used all arguments
     824                                        if ( result.nextArg >= args.size() ) {
     825                                                finalResults.emplace_back( std::move(result) );
     826                                                continue;
     827                                        }
     828
     829                                        // add each possible next argument
     830                                        for ( const Alternative& actual : args[result.nextArg] ) {
     831                                                nextResults.emplace_back( result, actual.expr, actual.cost );
     832                                        }
     833                                }
     834
     835                                // reset for next round
     836                                results.swap( nextResults );
     837                                nextResults.clear();
     838                        }
     839                } else {
     840                        // filter out results that don't use all the arguments
     841                        for ( ArgPack& result : results ) {
     842                                if ( result.nextArg >= args.size() ) {
     843                                        finalResults.emplace_back( std::move(result) );
     844                                }
     845                        }
     846                }
     847
     848                // validate matching combos, add to final result list
     849                for ( ArgPack& result : finalResults ) {
    687850                        ApplicationExpr *appExpr = new ApplicationExpr( func.expr->clone() );
    688                         Alternative newAlt( appExpr, resultEnv, sumCost( instantiatedActuals ) );
    689                         makeExprList( instantiatedActuals, appExpr->get_args() );
     851                        Alternative newAlt( appExpr, result.env, sumCost( result.actuals ) );
     852                        makeExprList( result.actuals, appExpr->get_args() );
    690853                        PRINT(
    691854                                std::cerr << "instantiate function success: " << appExpr << std::endl;
    692855                                std::cerr << "need assertions:" << std::endl;
    693                                 printAssertionSet( resultNeed, std::cerr, 8 );
     856                                printAssertionSet( result.need, std::cerr, 8 );
    694857                        )
    695                         inferParameters( resultNeed, resultHave, newAlt, openVars, out );
     858                        inferParameters( result.need, result.have, newAlt, result.openVars, out );
    696859                }
    697860        }
     
    703866                if ( funcFinder.alternatives.empty() ) return;
    704867
    705                 std::list< AlternativeFinder > argAlternatives;
    706                 findSubExprs( untypedExpr->begin_args(), untypedExpr->end_args(), back_inserter( argAlternatives ) );
    707 
    708                 std::list< AltList > possibilities;
    709                 combos( argAlternatives.begin(), argAlternatives.end(), back_inserter( possibilities ) );
     868                std::vector< AlternativeFinder > argAlternatives;
     869                findSubExprs( untypedExpr->begin_args(), untypedExpr->end_args(),
     870                        back_inserter( argAlternatives ) );
    710871
    711872                // take care of possible tuple assignments
    712873                // if not tuple assignment, assignment is taken care of as a normal function call
    713                 Tuples::handleTupleAssignment( *this, untypedExpr, possibilities );
    714 
     874/*FIX   Tuples::handleTupleAssignment( *this, untypedExpr, possibilities );
     875*/
    715876                // find function operators
    716877                AlternativeFinder funcOpFinder( indexer, env );
     
    739900                                                Alternative newFunc( *func );
    740901                                                referenceToRvalueConversion( newFunc.expr );
    741                                                 for ( std::list< AltList >::iterator actualAlt = possibilities.begin(); actualAlt != possibilities.end(); ++actualAlt ) {
    742                                                         // XXX
    743                                                         //Designators::check_alternative( function, *actualAlt );
    744                                                         makeFunctionAlternatives( newFunc, function, *actualAlt, std::back_inserter( candidates ) );
    745                                                 }
     902                                                makeFunctionAlternatives( newFunc, function, argAlternatives,
     903                                                        std::back_inserter( candidates ) );
    746904                                        }
    747905                                } else if ( TypeInstType *typeInst = dynamic_cast< TypeInstType* >( func->expr->get_result()->stripReferences() ) ) { // handle ftype (e.g. *? on function pointer)
     
    751909                                                        Alternative newFunc( *func );
    752910                                                        referenceToRvalueConversion( newFunc.expr );
    753                                                         for ( std::list< AltList >::iterator actualAlt = possibilities.begin(); actualAlt != possibilities.end(); ++actualAlt ) {
    754                                                                 makeFunctionAlternatives( newFunc, function, *actualAlt, std::back_inserter( candidates ) );
    755                                                         } // for
     911                                                        makeFunctionAlternatives( newFunc, function, argAlternatives,
     912                                                                std::back_inserter( candidates ) );
    756913                                                } // if
    757914                                        } // if
    758                                 }
    759 
    760                                 // try each function operator ?() with the current function alternative and each of the argument combinations
    761                                 for ( AltList::iterator funcOp = funcOpFinder.alternatives.begin(); funcOp != funcOpFinder.alternatives.end(); ++funcOp ) {
    762                                         // check if the type is pointer to function
    763                                         if ( PointerType *pointer = dynamic_cast< PointerType* >( funcOp->expr->get_result()->stripReferences() ) ) {
    764                                                 if ( FunctionType *function = dynamic_cast< FunctionType* >( pointer->get_base() ) ) {
     915                                }                       
     916                        } catch ( SemanticError &e ) {
     917                                errors.append( e );
     918                        }
     919                } // for
     920
     921                // try each function operator ?() with each function alternative
     922                if ( ! funcOpFinder.alternatives.empty() ) {
     923                        // add function alternatives to front of argument list
     924                        argAlternatives.insert( argAlternatives.begin(), std::move(funcFinder) );
     925
     926                        for ( AltList::iterator funcOp = funcOpFinder.alternatives.begin();
     927                                        funcOp != funcOpFinder.alternatives.end(); ++funcOp ) {
     928                                try {
     929                                        // check if type is a pointer to function
     930                                        if ( PointerType* pointer = dynamic_cast<PointerType*>(
     931                                                        funcOp->expr->get_result()->stripReferences() ) ) {
     932                                                if ( FunctionType* function =
     933                                                                dynamic_cast<FunctionType*>( pointer->get_base() ) ) {
    765934                                                        Alternative newFunc( *funcOp );
    766935                                                        referenceToRvalueConversion( newFunc.expr );
    767                                                         for ( std::list< AltList >::iterator actualAlt = possibilities.begin(); actualAlt != possibilities.end(); ++actualAlt ) {
    768                                                                 AltList currentAlt;
    769                                                                 currentAlt.push_back( *func );
    770                                                                 currentAlt.insert( currentAlt.end(), actualAlt->begin(), actualAlt->end() );
    771                                                                 makeFunctionAlternatives( newFunc, function, currentAlt, std::back_inserter( candidates ) );
    772                                                         } // for
    773                                                 } // if
    774                                         } // if
    775                                 } // for
    776                         } catch ( SemanticError &e ) {
    777                                 errors.append( e );
    778                         }
    779                 } // for
     936                                                        makeFunctionAlternatives( newFunc, function, argAlternatives,
     937                                                                std::back_inserter( candidates ) );
     938                                                }
     939                                        }
     940                                } catch ( SemanticError &e ) {
     941                                        errors.append( e );
     942                                }
     943                        }
     944                }
    780945
    781946                // Implement SFINAE; resolution errors are only errors if there aren't any non-erroneous resolutions
  • src/ResolvExpr/AlternativeFinder.h

    r9bae71f raeb75b1  
    3434          public:
    3535                AlternativeFinder( const SymTab::Indexer &indexer, const TypeEnvironment &env );
     36
     37                AlternativeFinder( const AlternativeFinder& o )
     38                        : indexer(o.indexer), alternatives(o.alternatives), env(o.env),
     39                          targetType(o.targetType) {}
     40               
     41                AlternativeFinder( AlternativeFinder&& o )
     42                        : indexer(o.indexer), alternatives(std::move(o.alternatives)), env(o.env),
     43                          targetType(o.targetType) {}
     44               
     45                AlternativeFinder& operator= ( const AlternativeFinder& o ) {
     46                        if (&o == this) return *this;
     47                       
     48                        // horrific nasty hack to rebind references...
     49                        alternatives.~AltList();
     50                        new(this) AlternativeFinder(o);
     51                        return *this;
     52                }
     53
     54                AlternativeFinder& operator= ( AlternativeFinder&& o ) {
     55                        if (&o == this) return *this;
     56                       
     57                        // horrific nasty hack to rebind references...
     58                        alternatives.~AltList();
     59                        new(this) AlternativeFinder(std::move(o));
     60                        return *this;
     61                }
     62
    3663                void find( Expression *expr, bool adjust = false, bool prune = true );
    3764                /// Calls find with the adjust flag set; adjustment turns array and function types into equivalent pointer types
     
    94121                /// Adds alternatives for offsetof expressions, given the base type and name of the member
    95122                template< typename StructOrUnionType > void addOffsetof( StructOrUnionType *aggInst, const std::string &name );
    96                 bool instantiateFunction( std::list< DeclarationWithType* >& formals, const AltList &actuals, bool isVarArgs, OpenVarSet& openVars, TypeEnvironment &resultEnv, AssertionSet &resultNeed, AssertionSet &resultHave, AltList & out );
     123/*CUT   bool instantiateFunction( std::list< DeclarationWithType* >& formals, const AltList &actuals, bool isVarArgs, OpenVarSet& openVars, TypeEnvironment &resultEnv, AssertionSet &resultNeed, AssertionSet &resultHave, AltList & out );
    97124                template< typename OutputIterator >
    98125                void makeFunctionAlternatives( const Alternative &func, FunctionType *funcType, const AltList &actualAlt, OutputIterator out );
     126*/              template<typename OutputIterator>
     127                void makeFunctionAlternatives( const Alternative &func, FunctionType *funcType, const std::vector< AlternativeFinder >& args, OutputIterator out );
    99128                template< typename OutputIterator >
    100129                void inferParameters( const AssertionSet &need, AssertionSet &have, const Alternative &newAlt, OpenVarSet &openVars, OutputIterator out );
Note: See TracChangeset for help on using the changeset viewer.