Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/ResolvExpr/AlternativeFinder.cc

    r85517ddb r0362d42  
    4242#include "Common/utility.h"
    4343#include "InitTweak/InitTweak.h"
    44 #include "ResolveTypeof.h"
    4544
    4645extern bool resolvep;
     
    268267                std::list< DeclarationWithType* >::iterator formal = formals.begin();
    269268                std::list< Expression* >& actuals = appExpr->get_args();
     269
    270270                for ( std::list< Expression* >::iterator actualExpr = actuals.begin(); actualExpr != actuals.end(); ++actualExpr ) {
    271271                        PRINT(
     
    277277                        std::list< DeclarationWithType* >::iterator startFormal = formal;
    278278                        Cost actualCost;
    279                         for ( std::list< Type* >::iterator actual = (*actualExpr)->get_results().begin(); actual != (*actualExpr)->get_results().end(); ++actual ) {
     279                        for ( std::list< Type* >::iterator actualType = (*actualExpr)->get_results().begin(); actualType != (*actualExpr)->get_results().end(); ++actualType ) {
     280                                // xxx - need tuple handling code here
    280281                                if ( formal == formals.end() ) {
    281282                                        if ( function->get_isVarArgs() ) {
     
    288289                                PRINT(
    289290                                        std::cerr << std::endl << "converting ";
    290                                         (*actual)->print( std::cerr, 8 );
     291                                        (*actualType)->print( std::cerr, 8 );
    291292                                        std::cerr << std::endl << " to ";
    292293                                        (*formal)->get_type()->print( std::cerr, 8 );
    293294                                )
    294                                 Cost newCost = conversionCost( *actual, (*formal)->get_type(), indexer, alt.env );
     295                                Cost newCost = conversionCost( *actualType, (*formal)->get_type(), indexer, alt.env );
    295296                                PRINT(
    296297                                        std::cerr << std::endl << "cost is" << newCost << std::endl;
     
    303304                                actualCost += newCost;
    304305
    305                                 convCost += Cost( 0, polyCost( (*formal)->get_type(), alt.env, indexer ) + polyCost( *actual, alt.env, indexer ), 0 );
     306                                convCost += Cost( 0, polyCost( (*formal)->get_type(), alt.env, indexer ) + polyCost( *actualType, alt.env, indexer ), 0 );
    306307
    307308                                formal++;
     
    363364        }
    364365
     366        template< typename OutputIterator >
     367        void flatten( Type * type, OutputIterator out ) {
     368                if ( TupleType * tupleType = dynamic_cast< TupleType * >( type ) ) {
     369                        for ( Type * t : *tupleType ) {
     370                                flatten( t, out );
     371                        }
     372                } else {
     373                        *out++ = type;
     374                }
     375        }
     376
    365377        bool AlternativeFinder::instantiateFunction( std::list< DeclarationWithType* >& formals, /*const*/ AltList &actuals, bool isVarArgs, OpenVarSet& openVars, TypeEnvironment &resultEnv, AssertionSet &resultNeed, AssertionSet &resultHave ) {
    366378                simpleCombineEnvironments( actuals.begin(), actuals.end(), resultEnv );
     
    380392                */
    381393                std::list< DeclarationWithType* >::iterator formal = formals.begin();
     394
     395                std::list< Type * > formalTypes;
     396                std::list< Type * >::iterator formalType = formalTypes.end();
     397
    382398                for ( AltList::const_iterator actualExpr = actuals.begin(); actualExpr != actuals.end(); ++actualExpr ) {
    383                         for ( std::list< Type* >::iterator actual = actualExpr->expr->get_results().begin(); actual != actualExpr->expr->get_results().end(); ++actual ) {
    384                                 if ( formal == formals.end() ) {
    385                                         return isVarArgs;
     399                        std::list< Type* > & actualTypes = actualExpr->expr->get_results();
     400                        for ( std::list< Type* >::iterator actualType = actualTypes.begin(); actualType != actualTypes.end(); ++actualType ) {
     401                                if ( formalType == formalTypes.end() ) {
     402                                        // the type of the formal parameter may be a tuple type. To make this easier to work with,
     403                                        // flatten the tuple type and traverse the resulting list of types, incrementing the formal
     404                                        // iterator once its types have been extracted. Once a particular formal parameter's type has
     405                                        // been exhausted load the next formal parameter's type.
     406                                        if ( formal == formals.end() ) {
     407                                                return isVarArgs;
     408                                        }
     409                                        formalTypes.clear();
     410                                        flatten( (*formal)->get_type(), back_inserter( formalTypes ) );
     411                                        formalType = formalTypes.begin();
     412                                        ++formal;
    386413                                }
    387414                                PRINT(
     
    389416                                        (*formal)->get_type()->print( std::cerr );
    390417                                        std::cerr << std::endl << "actual type is ";
    391                                         (*actual)->print( std::cerr );
     418                                        (*actualType)->print( std::cerr );
    392419                                        std::cerr << std::endl;
    393420                                )
    394                                 if ( ! unify( (*formal)->get_type(), *actual, resultEnv, resultNeed, resultHave, openVars, indexer ) ) {
     421                                if ( ! unify( *formalType, *actualType, resultEnv, resultNeed, resultHave, openVars, indexer ) ) {
    395422                                        return false;
    396423                                }
    397                                 formal++;
    398                         }
    399                 }
     424                                ++formalType;
     425                        }
     426                }
     427
     428                // xxx - a tuple type was not completely matched
     429                // partially handle the tuple with default arguments??
     430                if ( formalType != formalTypes.end() ) return false;
     431
    400432                // Handling of default values
    401433                while ( formal != formals.end() ) {
     
    708740        void AlternativeFinder::visit( CastExpr *castExpr ) {
    709741                for ( std::list< Type* >::iterator i = castExpr->get_results().begin(); i != castExpr->get_results().end(); ++i ) {
    710                         *i = resolveTypeof( *i, indexer );
    711742                        SymTab::validateType( *i, &indexer );
    712743                        adjustExprType( *i, env, indexer );
     
    797828
    798829        void AlternativeFinder::visit( VariableExpr *variableExpr ) {
    799                 // not sufficient to clone here, because variable's type may have changed
    800                 // since the VariableExpr was originally created.
    801                 alternatives.push_back( Alternative( new VariableExpr( variableExpr->get_var() ), env, Cost::zero ) );
     830                alternatives.push_back( Alternative( variableExpr->clone(), env, Cost::zero ) );
    802831        }
    803832
     
    808837        void AlternativeFinder::visit( SizeofExpr *sizeofExpr ) {
    809838                if ( sizeofExpr->get_isType() ) {
    810                         // xxx - resolveTypeof?
    811839                        alternatives.push_back( Alternative( sizeofExpr->clone(), env, Cost::zero ) );
    812840                } else {
     
    828856        void AlternativeFinder::visit( AlignofExpr *alignofExpr ) {
    829857                if ( alignofExpr->get_isType() ) {
    830                         // xxx - resolveTypeof?
    831858                        alternatives.push_back( Alternative( alignofExpr->clone(), env, Cost::zero ) );
    832859                } else {
     
    862889        void AlternativeFinder::visit( UntypedOffsetofExpr *offsetofExpr ) {
    863890                AlternativeFinder funcFinder( indexer, env );
    864                 // xxx - resolveTypeof?
    865891                if ( StructInstType *structInst = dynamic_cast< StructInstType* >( offsetofExpr->get_type() ) ) {
    866892                        addOffsetof( structInst, offsetofExpr->get_member() );
Note: See TracChangeset for help on using the changeset viewer.