Ignore:
Timestamp:
Nov 24, 2017, 9:02:40 PM (6 years ago)
Author:
Thierry Delisle <tdelisle@…>
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:
cf966b5
Parents:
88ef2af (diff), 3de176d (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the (diff) links above to see all the changes relative to each parent.
Message:

Merge branch 'master' of plg.uwaterloo.ca:software/cfa/cfa-cc

File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/ResolvExpr/AlternativeFinder.cc

    r88ef2af rf7a4f89  
    187187                expr->accept( *this );
    188188                if ( failFast && alternatives.empty() ) {
     189                        PRINT(
     190                                std::cerr << "No reasonable alternatives for expression " << expr << std::endl;
     191                        )
    189192                        throw SemanticError( "No reasonable alternatives for expression ", expr );
    190193                }
     
    579582        /// State to iteratively build a match of parameter expressions to arguments
    580583        struct ArgPack {
    581                 std::size_t parent;                ///< Index of parent pack 
     584                std::size_t parent;                ///< Index of parent pack
    582585                std::unique_ptr<Expression> expr;  ///< The argument stored here
    583586                Cost cost;                         ///< The cost of this argument
     
    590593                unsigned nextExpl;                 ///< Index of next exploded element
    591594                unsigned explAlt;                  ///< Index of alternative for nextExpl > 0
    592                
     595
    593596                ArgPack()
    594597                        : parent(0), expr(), cost(Cost::zero), env(), need(), have(), openVars(), nextArg(0),
     598
    595599                          tupleStart(0), nextExpl(0), explAlt(0) {}
    596                
    597                 ArgPack(const TypeEnvironment& env, const AssertionSet& need, const AssertionSet& have, 
     600
     601                ArgPack(const TypeEnvironment& env, const AssertionSet& need, const AssertionSet& have,
    598602                                const OpenVarSet& openVars)
    599                         : parent(0), expr(), cost(Cost::zero), env(env), need(need), have(have), 
     603                        : parent(0), expr(), cost(Cost::zero), env(env), need(need), have(have),
    600604                          openVars(openVars), nextArg(0), tupleStart(0), nextExpl(0), explAlt(0) {}
    601                
    602                 ArgPack(std::size_t parent, Expression* expr, TypeEnvironment&& env, AssertionSet&& need, 
    603                                 AssertionSet&& have, OpenVarSet&& openVars, unsigned nextArg, 
    604                                 unsigned tupleStart = 0, Cost cost = Cost::zero, unsigned nextExpl = 0, 
     605
     606                ArgPack(std::size_t parent, Expression* expr, TypeEnvironment&& env, AssertionSet&& need,
     607                                AssertionSet&& have, OpenVarSet&& openVars, unsigned nextArg,
     608                                unsigned tupleStart = 0, Cost cost = Cost::zero, unsigned nextExpl = 0,
    605609                                unsigned explAlt = 0 )
    606                         : parent(parent), expr(expr->clone()), cost(cost), env(move(env)), need(move(need)), 
     610                        : parent(parent), expr(expr->clone()), cost(cost), env(move(env)), need(move(need)),
    607611                          have(move(have)), openVars(move(openVars)), nextArg(nextArg), tupleStart(tupleStart),
    608612                          nextExpl(nextExpl), explAlt(explAlt) {}
    609                
    610                 ArgPack(const ArgPack& o, TypeEnvironment&& env, AssertionSet&& need, AssertionSet&& have, 
     613
     614                ArgPack(const ArgPack& o, TypeEnvironment&& env, AssertionSet&& need, AssertionSet&& have,
    611615                                OpenVarSet&& openVars, unsigned nextArg, Cost added )
    612                         : parent(o.parent), expr(o.expr ? o.expr->clone() : nullptr), cost(o.cost + added), 
    613                           env(move(env)), need(move(need)), have(move(have)), openVars(move(openVars)), 
     616                        : parent(o.parent), expr(o.expr ? o.expr->clone() : nullptr), cost(o.cost + added),
     617                          env(move(env)), need(move(need)), have(move(have)), openVars(move(openVars)),
    614618                          nextArg(nextArg), tupleStart(o.tupleStart), nextExpl(0), explAlt(0) {}
    615                
     619
    616620                /// true iff this pack is in the middle of an exploded argument
    617621                bool hasExpl() const { return nextExpl > 0; }
     
    621625                        return args[nextArg-1][explAlt];
    622626                }
    623                          
     627
    624628                /// Ends a tuple expression, consolidating the appropriate actuals
    625629                void endTuple( const std::vector<ArgPack>& packs ) {
     
    641645
    642646        /// Instantiates an argument to match a formal, returns false if no results left
    643         bool instantiateArgument( Type* formalType, Initializer* initializer, 
    644                         const ExplodedArgs& args, std::vector<ArgPack>& results, std::size_t& genStart, 
     647        bool instantiateArgument( Type* formalType, Initializer* initializer,
     648                        const ExplodedArgs& args, std::vector<ArgPack>& results, std::size_t& genStart,
    645649                        const SymTab::Indexer& indexer, unsigned nTuples = 0 ) {
    646650                if ( TupleType* tupleType = dynamic_cast<TupleType*>( formalType ) ) {
     
    649653                        for ( Type* type : *tupleType ) {
    650654                                // xxx - dropping initializer changes behaviour from previous, but seems correct
    651                                 if ( ! instantiateArgument( 
    652                                                 type, nullptr, args, results, genStart, indexer, nTuples ) ) 
     655                                if ( ! instantiateArgument(
     656                                                type, nullptr, args, results, genStart, indexer, nTuples ) )
    653657                                        return false;
    654658                                nTuples = 0;
     
    676680                                        auto nextArg = results[i].nextArg;
    677681
    678                                         // use remainder of exploded tuple if present
     682                                        // use next element of exploded tuple if present
    679683                                        if ( results[i].hasExpl() ) {
    680684                                                const ExplodedActual& expl = results[i].getExpl( args );
    681                                                 const Alternative& actual = expl.alts[results[i].nextExpl];
    682                                                
    683                                                 TypeEnvironment env = results[i].env;
    684                                                 OpenVarSet openVars = results[i].openVars;
    685 
    686                                                 env.addActual( actual.env, openVars );
    687685
    688686                                                unsigned nextExpl = results[i].nextExpl + 1;
    689                                                 if ( nextExpl == expl.alts.size() ) {
     687                                                if ( nextExpl == expl.exprs.size() ) {
    690688                                                        nextExpl = 0;
    691689                                                }
    692690
    693691                                                results.emplace_back(
    694                                                         i, actual.expr, move(env), copy(results[i].need),
    695                                                         copy(results[i].have), move(openVars), nextArg, nTuples,
    696                                                         Cost::zero, nextExpl, results[i].explAlt );
    697                                                
     692                                                        i, expl.exprs[results[i].nextExpl].get(), copy(results[i].env),
     693                                                        copy(results[i].need), copy(results[i].have),
     694                                                        copy(results[i].openVars), nextArg, nTuples, Cost::zero, nextExpl,
     695                                                        results[i].explAlt );
     696
    698697                                                continue;
    699698                                        }
    700                                        
     699
    701700                                        // finish result when out of arguments
    702701                                        if ( nextArg >= args.size() ) {
    703                                                 ArgPack newResult{ 
    704                                                         results[i].env, results[i].need, results[i].have, 
     702                                                ArgPack newResult{
     703                                                        results[i].env, results[i].need, results[i].have,
    705704                                                        results[i].openVars };
    706705                                                newResult.nextArg = nextArg;
     
    722721
    723722                                                        if ( results[i].tupleStart > 0 && Tuples::isTtype( argType ) ) {
    724                                                                 // the case where a ttype value is passed directly is special, 
     723                                                                // the case where a ttype value is passed directly is special,
    725724                                                                // e.g. for argument forwarding purposes
    726                                                                 // xxx - what if passing multiple arguments, last of which is 
     725                                                                // xxx - what if passing multiple arguments, last of which is
    727726                                                                //       ttype?
    728                                                                 // xxx - what would happen if unify was changed so that unifying 
    729                                                                 //       tuple 
    730                                                                 // types flattened both before unifying lists? then pass in 
     727                                                                // xxx - what would happen if unify was changed so that unifying
     728                                                                //       tuple
     729                                                                // types flattened both before unifying lists? then pass in
    731730                                                                // TupleType (ttype) below.
    732731                                                                --newResult.tupleStart;
     
    739738
    740739                                                // check unification for ttype before adding to final
    741                                                 if ( unify( ttype, argType, newResult.env, newResult.need, newResult.have, 
     740                                                if ( unify( ttype, argType, newResult.env, newResult.need, newResult.have,
    742741                                                                newResult.openVars, indexer ) ) {
    743742                                                        finalResults.push_back( move(newResult) );
    744743                                                }
    745                                                
     744
    746745                                                continue;
    747746                                        }
     
    750749                                        for ( std::size_t j = 0; j < args[nextArg].size(); ++j ) {
    751750                                                const ExplodedActual& expl = args[nextArg][j];
    752                                        
     751
    753752                                                // fresh copies of parent parameters for this iteration
    754753                                                TypeEnvironment env = results[i].env;
     
    758757
    759758                                                // skip empty tuple arguments by (near-)cloning parent into next gen
    760                                                 if ( expl.alts.empty() ) {
     759                                                if ( expl.exprs.empty() ) {
    761760                                                        results.emplace_back(
    762                                                                 results[i], move(env), copy(results[i].need), 
     761                                                                results[i], move(env), copy(results[i].need),
    763762                                                                copy(results[i].have), move(openVars), nextArg + 1, expl.cost );
    764                                                        
     763
    765764                                                        continue;
    766765                                                }
     
    768767                                                // add new result
    769768                                                results.emplace_back(
    770                                                         i, expl.alts.front().expr, move(env), copy(results[i].need),
    771                                                         copy(results[i].have), move(openVars), nextArg + 1, 
    772                                                         nTuples, expl.cost, expl.alts.size() == 1 ? 0 : 1, j );
     769                                                        i, expl.exprs.front().get(), move(env), copy(results[i].need),
     770                                                        copy(results[i].have), move(openVars), nextArg + 1,
     771                                                        nTuples, expl.cost, expl.exprs.size() == 1 ? 0 : 1, j );
    773772                                        }
    774773                                }
     
    794793                        if ( results[i].hasExpl() ) {
    795794                                const ExplodedActual& expl = results[i].getExpl( args );
    796                                 const Alternative& actual = expl.alts[results[i].nextExpl];
    797                                
     795                                Expression* expr = expl.exprs[results[i].nextExpl].get();
     796
    798797                                TypeEnvironment env = results[i].env;
    799798                                AssertionSet need = results[i].need, have = results[i].have;
    800799                                OpenVarSet openVars = results[i].openVars;
    801800
    802                                 env.addActual( actual.env, openVars );
    803                                 Type* actualType = actual.expr->get_result();
     801                                Type* actualType = expr->get_result();
    804802
    805803                                PRINT(
     
    810808                                        std::cerr << std::endl;
    811809                                )
    812                                
     810
    813811                                if ( unify( formalType, actualType, env, need, have, openVars, indexer ) ) {
    814812                                        unsigned nextExpl = results[i].nextExpl + 1;
    815                                         if ( nextExpl == expl.alts.size() ) {
     813                                        if ( nextExpl == expl.exprs.size() ) {
    816814                                                nextExpl = 0;
    817815                                        }
    818                                        
    819                                         results.emplace_back( 
    820                                                 i, actual.expr, move(env), move(need), move(have), move(openVars),
    821                                                 nextArg, nTuples, Cost::zero, nextExpl, results[i].explAlt );
     816
     817                                        results.emplace_back(
     818                                                i, expr, move(env), move(need), move(have), move(openVars), nextArg,
     819                                                nTuples, Cost::zero, nextExpl, results[i].explAlt );
    822820                                }
    823821
    824822                                continue;
    825823                        }
    826                        
     824
    827825                        // use default initializers if out of arguments
    828826                        if ( nextArg >= args.size() ) {
     
    833831                                                OpenVarSet openVars = results[i].openVars;
    834832
    835                                                 if ( unify( formalType, cnst->get_type(), env, need, have, openVars, 
     833                                                if ( unify( formalType, cnst->get_type(), env, need, have, openVars,
    836834                                                                indexer ) ) {
    837835                                                        results.emplace_back(
    838                                                                 i, cnstExpr, move(env), move(need), move(have), 
     836                                                                i, cnstExpr, move(env), move(need), move(have),
    839837                                                                move(openVars), nextArg, nTuples );
    840838                                                }
     
    855853
    856854                                env.addActual( expl.env, openVars );
    857                                
     855
    858856                                // skip empty tuple arguments by (near-)cloning parent into next gen
    859                                 if ( expl.alts.empty() ) {
     857                                if ( expl.exprs.empty() ) {
    860858                                        results.emplace_back(
    861                                                 results[i], move(env), move(need), move(have), move(openVars), 
     859                                                results[i], move(env), move(need), move(have), move(openVars),
    862860                                                nextArg + 1, expl.cost );
    863861
     
    866864
    867865                                // consider only first exploded actual
    868                                 const Alternative& actual = expl.alts.front();
    869                                 Type* actualType = actual.expr->get_result()->clone();
     866                                Expression* expr = expl.exprs.front().get();
     867                                Type* actualType = expr->get_result()->clone();
    870868
    871869                                PRINT(
     
    881879                                        // add new result
    882880                                        results.emplace_back(
    883                                                 i, actual.expr, move(env), move(need), move(have), move(openVars),
    884                                                 nextArg + 1, nTuples, expl.cost, expl.alts.size() == 1 ? 0 : 1, j );
     881                                                i, expr, move(env), move(need), move(have), move(openVars), nextArg + 1,
     882                                                nTuples, expl.cost, expl.exprs.size() == 1 ? 0 : 1, j );
    885883                                }
    886884                        }
     
    889887                // reset for next parameter
    890888                genStart = genEnd;
    891                
     889
    892890                return genEnd != results.size();
    893891        }
    894892
    895893        template<typename OutputIterator>
    896         void AlternativeFinder::validateFunctionAlternative( const Alternative &func, ArgPack& result, 
     894        void AlternativeFinder::validateFunctionAlternative( const Alternative &func, ArgPack& result,
    897895                        const std::vector<ArgPack>& results, OutputIterator out ) {
    898896                ApplicationExpr *appExpr = new ApplicationExpr( func.expr->clone() );
     
    944942                for ( DeclarationWithType* formal : funcType->get_parameters() ) {
    945943                        ObjectDecl* obj = strict_dynamic_cast< ObjectDecl* >( formal );
    946                         if ( ! instantiateArgument( 
     944                        if ( ! instantiateArgument(
    947945                                        obj->get_type(), obj->get_init(), args, results, genStart, indexer ) )
    948946                                return;
     
    962960                                        if ( results[i].hasExpl() ) {
    963961                                                const ExplodedActual& expl = results[i].getExpl( args );
    964                                                 const Alternative& actual = expl.alts[results[i].nextExpl];
    965                                                
    966                                                 TypeEnvironment env = results[i].env;
    967                                                 OpenVarSet openVars = results[i].openVars;
    968 
    969                                                 env.addActual( actual.env, openVars );
    970962
    971963                                                unsigned nextExpl = results[i].nextExpl + 1;
    972                                                 if ( nextExpl == expl.alts.size() ) {
     964                                                if ( nextExpl == expl.exprs.size() ) {
    973965                                                        nextExpl = 0;
    974966                                                }
    975967
    976968                                                results.emplace_back(
    977                                                         i, actual.expr, move(env), copy(results[i].need),
    978                                                         copy(results[i].have), move(openVars), nextArg, 0,
    979                                                         Cost::zero, nextExpl, results[i].explAlt );
    980                                                
     969                                                        i, expl.exprs[results[i].nextExpl].get(), copy(results[i].env),
     970                                                        copy(results[i].need), copy(results[i].have),
     971                                                        copy(results[i].openVars), nextArg, 0, Cost::zero, nextExpl,
     972                                                        results[i].explAlt );
     973
    981974                                                continue;
    982975                                        }
     
    1000993
    1001994                                                // skip empty tuple arguments by (near-)cloning parent into next gen
    1002                                                 if ( expl.alts.empty() ) {
    1003                                                         results.emplace_back( 
    1004                                                                 results[i], move(env), copy(results[i].need), 
     995                                                if ( expl.exprs.empty() ) {
     996                                                        results.emplace_back(
     997                                                                results[i], move(env), copy(results[i].need),
    1005998                                                                copy(results[i].have), move(openVars), nextArg + 1, expl.cost );
    1006                                                        
     999
    10071000                                                        continue;
    10081001                                                }
     
    10101003                                                // add new result
    10111004                                                results.emplace_back(
    1012                                                         i, expl.alts.front().expr, move(env), copy(results[i].need),
    1013                                                         copy(results[i].have), move(openVars), nextArg + 1, 0, 
    1014                                                         expl.cost, expl.alts.size() == 1 ? 0 : 1, j );
     1005                                                        i, expl.exprs.front().get(), move(env), copy(results[i].need),
     1006                                                        copy(results[i].have), move(openVars), nextArg + 1, 0,
     1007                                                        expl.cost, expl.exprs.size() == 1 ? 0 : 1, j );
    10151008                                        }
    10161009                                }
     
    10611054                        auto& argE = argExpansions.back();
    10621055                        argE.reserve( arg.alternatives.size() );
    1063                        
     1056
    10641057                        for ( const Alternative& actual : arg ) {
    10651058                                argE.emplace_back( actual, indexer );
     
    11611154                findMinCost( candidates.begin(), candidates.end(), std::back_inserter( winners ) );
    11621155
    1163                 // function may return struct or union value, in which case we need to add alternatives 
    1164                 // for implicitconversions to each of the anonymous members, must happen after findMinCost 
     1156                // function may return struct or union value, in which case we need to add alternatives
     1157                // for implicitconversions to each of the anonymous members, must happen after findMinCost
    11651158                // since anon conversions are never the cheapest expression
    11661159                for ( const Alternative & alt : winners ) {
     
    11931186                for ( Alternative& alt : finder.alternatives ) {
    11941187                        if ( isLvalue( alt.expr ) ) {
    1195                                 alternatives.push_back( 
     1188                                alternatives.push_back(
    11961189                                        Alternative{ new AddressExpr( alt.expr->clone() ), alt.env, alt.cost } );
    11971190                        } // if
     
    12421235
    12431236                AltList candidates;
    1244                 for ( Alternative& alt : finder.alternatives ) {
     1237                for ( Alternative & alt : finder.alternatives ) {
    12451238                        AssertionSet needAssertions, haveAssertions;
    12461239                        OpenVarSet openVars;
     
    12551248                        // allow casting a tuple to an atomic type (e.g. (int)([1, 2, 3]))
    12561249                        // unification run for side-effects
    1257                         unify( castExpr->get_result(), alt.expr->get_result(), alt.env, needAssertions, 
     1250                        unify( castExpr->get_result(), alt.expr->get_result(), alt.env, needAssertions,
    12581251                                haveAssertions, openVars, indexer );
    1259                         Cost thisCost = castCost( alt.expr->get_result(), castExpr->get_result(), indexer, 
     1252                        Cost thisCost = castCost( alt.expr->get_result(), castExpr->get_result(), indexer,
    12601253                                alt.env );
     1254                        PRINT(
     1255                                std::cerr << "working on cast with result: " << castExpr->result << std::endl;
     1256                                std::cerr << "and expr type: " << alt.expr->result << std::endl;
     1257                                std::cerr << "env: " << alt.env << std::endl;
     1258                        )
    12611259                        if ( thisCost != Cost::infinity ) {
     1260                                PRINT(
     1261                                        std::cerr << "has finite cost." << std::endl;
     1262                                )
    12621263                                // count one safe conversion for each value that is thrown away
    12631264                                thisCost.incSafe( discardedValues );
    1264                                 Alternative newAlt( restructureCast( alt.expr->clone(), toType ), alt.env, 
     1265                                Alternative newAlt( restructureCast( alt.expr->clone(), toType ), alt.env,
    12651266                                        alt.cost, thisCost );
    1266                                 inferParameters( needAssertions, haveAssertions, newAlt, openVars, 
     1267                                inferParameters( needAssertions, haveAssertions, newAlt, openVars,
    12671268                                        back_inserter( candidates ) );
    12681269                        } // if
     
    15531554        void AlternativeFinder::visit( UntypedTupleExpr *tupleExpr ) {
    15541555                std::vector< AlternativeFinder > subExprAlternatives;
    1555                 findSubExprs( tupleExpr->get_exprs().begin(), tupleExpr->get_exprs().end(), 
     1556                findSubExprs( tupleExpr->get_exprs().begin(), tupleExpr->get_exprs().end(),
    15561557                        back_inserter( subExprAlternatives ) );
    15571558                std::vector< AltList > possibilities;
    1558                 combos( subExprAlternatives.begin(), subExprAlternatives.end(), 
     1559                combos( subExprAlternatives.begin(), subExprAlternatives.end(),
    15591560                        back_inserter( possibilities ) );
    15601561                for ( const AltList& alts : possibilities ) {
     
    15641565                        TypeEnvironment compositeEnv;
    15651566                        simpleCombineEnvironments( alts.begin(), alts.end(), compositeEnv );
    1566                         alternatives.push_back( 
     1567                        alternatives.push_back(
    15671568                                Alternative{ new TupleExpr( exprs ), compositeEnv, sumCost( alts ) } );
    15681569                } // for
Note: See TracChangeset for help on using the changeset viewer.