Changeset 178e4ec


Ignore:
Timestamp:
Nov 23, 2017, 5:12:22 PM (4 years ago)
Author:
Rob Schluntz <rschlunt@…>
Branches:
aaron-thesis, arm-eh, cleanup-dtors, deferred_resn, demangler, jacob/cs343-translation, jenkins-sandbox, master, new-ast, new-ast-unique-expr, new-env, no_list, persistent-indexer, resolv-new, with_gc
Children:
3787dc1
Parents:
8dceeb7 (diff), 62194cb (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:/u/cforall/software/cfa/cfa-cc

Location:
src
Files:
2 added
6 edited

Legend:

Unmodified
Added
Removed
  • src/Makefile.in

    r8dceeb7 r178e4ec  
    210210        ResolvExpr/driver_cfa_cpp-TypeEnvironment.$(OBJEXT) \
    211211        ResolvExpr/driver_cfa_cpp-CurrentObject.$(OBJEXT) \
     212        ResolvExpr/driver_cfa_cpp-ExplodedActual.$(OBJEXT) \
    212213        SymTab/driver_cfa_cpp-Indexer.$(OBJEXT) \
    213214        SymTab/driver_cfa_cpp-Mangler.$(OBJEXT) \
     
    511512        ResolvExpr/FindOpenVars.cc ResolvExpr/PolyCost.cc \
    512513        ResolvExpr/Occurs.cc ResolvExpr/TypeEnvironment.cc \
    513         ResolvExpr/CurrentObject.cc SymTab/Indexer.cc \
    514         SymTab/Mangler.cc SymTab/Validate.cc SymTab/FixFunction.cc \
    515         SymTab/ImplementationType.cc SymTab/TypeEquality.cc \
    516         SymTab/Autogen.cc SynTree/Type.cc SynTree/VoidType.cc \
    517         SynTree/BasicType.cc SynTree/PointerType.cc \
    518         SynTree/ArrayType.cc SynTree/ReferenceType.cc \
    519         SynTree/FunctionType.cc SynTree/ReferenceToType.cc \
    520         SynTree/TupleType.cc SynTree/TypeofType.cc SynTree/AttrType.cc \
     514        ResolvExpr/CurrentObject.cc ResolvExpr/ExplodedActual.cc \
     515        SymTab/Indexer.cc SymTab/Mangler.cc SymTab/Validate.cc \
     516        SymTab/FixFunction.cc SymTab/ImplementationType.cc \
     517        SymTab/TypeEquality.cc SymTab/Autogen.cc SynTree/Type.cc \
     518        SynTree/VoidType.cc SynTree/BasicType.cc \
     519        SynTree/PointerType.cc SynTree/ArrayType.cc \
     520        SynTree/ReferenceType.cc SynTree/FunctionType.cc \
     521        SynTree/ReferenceToType.cc SynTree/TupleType.cc \
     522        SynTree/TypeofType.cc SynTree/AttrType.cc \
    521523        SynTree/VarArgsType.cc SynTree/ZeroOneType.cc \
    522524        SynTree/Constant.cc SynTree/Expression.cc SynTree/TupleExpr.cc \
     
    825827        ResolvExpr/$(am__dirstamp) \
    826828        ResolvExpr/$(DEPDIR)/$(am__dirstamp)
     829ResolvExpr/driver_cfa_cpp-ExplodedActual.$(OBJEXT):  \
     830        ResolvExpr/$(am__dirstamp) \
     831        ResolvExpr/$(DEPDIR)/$(am__dirstamp)
    827832SymTab/$(am__dirstamp):
    828833        @$(MKDIR_P) SymTab
     
    10221027@AMDEP_TRUE@@am__include@ @am__quote@ResolvExpr/$(DEPDIR)/driver_cfa_cpp-ConversionCost.Po@am__quote@
    10231028@AMDEP_TRUE@@am__include@ @am__quote@ResolvExpr/$(DEPDIR)/driver_cfa_cpp-CurrentObject.Po@am__quote@
     1029@AMDEP_TRUE@@am__include@ @am__quote@ResolvExpr/$(DEPDIR)/driver_cfa_cpp-ExplodedActual.Po@am__quote@
    10241030@AMDEP_TRUE@@am__include@ @am__quote@ResolvExpr/$(DEPDIR)/driver_cfa_cpp-FindOpenVars.Po@am__quote@
    10251031@AMDEP_TRUE@@am__include@ @am__quote@ResolvExpr/$(DEPDIR)/driver_cfa_cpp-Occurs.Po@am__quote@
     
    19641970@am__fastdepCXX_FALSE@  $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o ResolvExpr/driver_cfa_cpp-CurrentObject.obj `if test -f 'ResolvExpr/CurrentObject.cc'; then $(CYGPATH_W) 'ResolvExpr/CurrentObject.cc'; else $(CYGPATH_W) '$(srcdir)/ResolvExpr/CurrentObject.cc'; fi`
    19651971
     1972ResolvExpr/driver_cfa_cpp-ExplodedActual.o: ResolvExpr/ExplodedActual.cc
     1973@am__fastdepCXX_TRUE@   $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT ResolvExpr/driver_cfa_cpp-ExplodedActual.o -MD -MP -MF ResolvExpr/$(DEPDIR)/driver_cfa_cpp-ExplodedActual.Tpo -c -o ResolvExpr/driver_cfa_cpp-ExplodedActual.o `test -f 'ResolvExpr/ExplodedActual.cc' || echo '$(srcdir)/'`ResolvExpr/ExplodedActual.cc
     1974@am__fastdepCXX_TRUE@   $(AM_V_at)$(am__mv) ResolvExpr/$(DEPDIR)/driver_cfa_cpp-ExplodedActual.Tpo ResolvExpr/$(DEPDIR)/driver_cfa_cpp-ExplodedActual.Po
     1975@AMDEP_TRUE@@am__fastdepCXX_FALSE@      $(AM_V_CXX)source='ResolvExpr/ExplodedActual.cc' object='ResolvExpr/driver_cfa_cpp-ExplodedActual.o' libtool=no @AMDEPBACKSLASH@
     1976@AMDEP_TRUE@@am__fastdepCXX_FALSE@      DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
     1977@am__fastdepCXX_FALSE@  $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o ResolvExpr/driver_cfa_cpp-ExplodedActual.o `test -f 'ResolvExpr/ExplodedActual.cc' || echo '$(srcdir)/'`ResolvExpr/ExplodedActual.cc
     1978
     1979ResolvExpr/driver_cfa_cpp-ExplodedActual.obj: ResolvExpr/ExplodedActual.cc
     1980@am__fastdepCXX_TRUE@   $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT ResolvExpr/driver_cfa_cpp-ExplodedActual.obj -MD -MP -MF ResolvExpr/$(DEPDIR)/driver_cfa_cpp-ExplodedActual.Tpo -c -o ResolvExpr/driver_cfa_cpp-ExplodedActual.obj `if test -f 'ResolvExpr/ExplodedActual.cc'; then $(CYGPATH_W) 'ResolvExpr/ExplodedActual.cc'; else $(CYGPATH_W) '$(srcdir)/ResolvExpr/ExplodedActual.cc'; fi`
     1981@am__fastdepCXX_TRUE@   $(AM_V_at)$(am__mv) ResolvExpr/$(DEPDIR)/driver_cfa_cpp-ExplodedActual.Tpo ResolvExpr/$(DEPDIR)/driver_cfa_cpp-ExplodedActual.Po
     1982@AMDEP_TRUE@@am__fastdepCXX_FALSE@      $(AM_V_CXX)source='ResolvExpr/ExplodedActual.cc' object='ResolvExpr/driver_cfa_cpp-ExplodedActual.obj' libtool=no @AMDEPBACKSLASH@
     1983@AMDEP_TRUE@@am__fastdepCXX_FALSE@      DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
     1984@am__fastdepCXX_FALSE@  $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o ResolvExpr/driver_cfa_cpp-ExplodedActual.obj `if test -f 'ResolvExpr/ExplodedActual.cc'; then $(CYGPATH_W) 'ResolvExpr/ExplodedActual.cc'; else $(CYGPATH_W) '$(srcdir)/ResolvExpr/ExplodedActual.cc'; fi`
     1985
    19661986SymTab/driver_cfa_cpp-Indexer.o: SymTab/Indexer.cc
    19671987@am__fastdepCXX_TRUE@   $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT SymTab/driver_cfa_cpp-Indexer.o -MD -MP -MF SymTab/$(DEPDIR)/driver_cfa_cpp-Indexer.Tpo -c -o SymTab/driver_cfa_cpp-Indexer.o `test -f 'SymTab/Indexer.cc' || echo '$(srcdir)/'`SymTab/Indexer.cc
  • src/ResolvExpr/Alternative.h

    r8dceeb7 r178e4ec  
    3737                void print( std::ostream &os, Indenter indent = {} ) const;
    3838
     39                /// Returns the stored expression, but released from management of this Alternative
     40                Expression* release_expr() {
     41                        Expression* tmp = expr;
     42                        expr = nullptr;
     43                        return tmp;
     44                }
     45
    3946                Cost cost;
    4047                Cost cvtCost;
  • src/ResolvExpr/AlternativeFinder.cc

    r8dceeb7 r178e4ec  
    3030#include "Common/utility.h"        // for deleteAll, printAll, CodeLocation
    3131#include "Cost.h"                  // for Cost, Cost::zero, operator<<, Cost...
     32#include "ExplodedActual.h"        // for ExplodedActual
    3233#include "InitTweak/InitTweak.h"   // for getFunctionName
    3334#include "RenameVars.h"            // for RenameVars, global_renamer
     
    590591                unsigned nextArg;                  ///< Index of next argument in arguments list
    591592                unsigned tupleStart;               ///< Number of tuples that start at this index
    592                 // TODO fix this somehow
    593                 std::vector<Alternative> expls;    ///< Exploded actuals left over from last match
     593                unsigned nextExpl;                 ///< Index of next exploded element
     594                unsigned explAlt;                  ///< Index of alternative for nextExpl > 0
    594595
    595596                ArgPack()
    596597                        : parent(0), expr(), cost(Cost::zero), env(), need(), have(), openVars(), nextArg(0),
    597                           tupleStart(0), expls() {}
     598
     599                          tupleStart(0), nextExpl(0), explAlt(0) {}
    598600
    599601                ArgPack(const TypeEnvironment& env, const AssertionSet& need, const AssertionSet& have,
    600602                                const OpenVarSet& openVars)
    601603                        : parent(0), expr(), cost(Cost::zero), env(env), need(need), have(have),
    602                           openVars(openVars), nextArg(0), tupleStart(0), expls() {}
     604                          openVars(openVars), nextArg(0), tupleStart(0), nextExpl(0), explAlt(0) {}
    603605
    604606                ArgPack(std::size_t parent, Expression* expr, TypeEnvironment&& env, AssertionSet&& need,
    605607                                AssertionSet&& have, OpenVarSet&& openVars, unsigned nextArg,
    606                                 unsigned tupleStart = 0, Cost cost = Cost::zero,
    607                                 std::vector<Alternative>&& expls = std::vector<Alternative>{} )
     608                                unsigned tupleStart = 0, Cost cost = Cost::zero, unsigned nextExpl = 0,
     609                                unsigned explAlt = 0 )
    608610                        : parent(parent), expr(expr->clone()), cost(cost), env(move(env)), need(move(need)),
    609611                          have(move(have)), openVars(move(openVars)), nextArg(nextArg), tupleStart(tupleStart),
    610                           expls(move(expls)) {}
     612                          nextExpl(nextExpl), explAlt(explAlt) {}
    611613
    612614                ArgPack(const ArgPack& o, TypeEnvironment&& env, AssertionSet&& need, AssertionSet&& have,
     
    614616                        : parent(o.parent), expr(o.expr ? o.expr->clone() : nullptr), cost(o.cost + added),
    615617                          env(move(env)), need(move(need)), have(move(have)), openVars(move(openVars)),
    616                           nextArg(nextArg), tupleStart(o.tupleStart), expls() {}
    617 
    618 
    619                 // ArgPack(const ArgPack& o)
    620                 //      : parent(o.parent), expr(o.expr ? o.expr->clone() : nullptr), env(o.env),
    621                 //        need(o.need), have(o.have), openVars(o.openVars), nextArg(o.nextArg),
    622                 //        tupleStart(o.tupleStart), expls(o.expls) {}
    623 
    624                 // ArgPack(ArgPack&&) = default;
     618                          nextArg(nextArg), tupleStart(o.tupleStart), nextExpl(0), explAlt(0) {}
     619
     620                /// true iff this pack is in the middle of an exploded argument
     621                bool hasExpl() const { return nextExpl > 0; }
     622
     623                /// Gets the list of exploded alternatives for this pack
     624                const ExplodedActual& getExpl( const ExplodedArgs& args ) const {
     625                        return args[nextArg-1][explAlt];
     626                }
    625627
    626628                /// Ends a tuple expression, consolidating the appropriate actuals
     
    644646        /// Instantiates an argument to match a formal, returns false if no results left
    645647        bool instantiateArgument( Type* formalType, Initializer* initializer,
    646                         const std::vector< AlternativeFinder >& args, std::vector<ArgPack>& results,
    647                         std::size_t& genStart, const SymTab::Indexer& indexer, unsigned nTuples = 0 ) {
     648                        const ExplodedArgs& args, std::vector<ArgPack>& results, std::size_t& genStart,
     649                        const SymTab::Indexer& indexer, unsigned nTuples = 0 ) {
    648650                if ( TupleType* tupleType = dynamic_cast<TupleType*>( formalType ) ) {
    649651                        // formalType is a TupleType - group actuals into a TupleExpr
     
    676678                                // add another argument to results
    677679                                for ( std::size_t i = genStart; i < genEnd; ++i ) {
    678                                         // use remainder of exploded tuple if present
    679                                         if ( ! results[i].expls.empty() ) {
    680                                                 const Alternative& actual = results[i].expls.front();
    681 
    682                                                 TypeEnvironment env = results[i].env;
    683                                                 OpenVarSet openVars = results[i].openVars;
    684 
    685                                                 env.addActual( actual.env, openVars );
    686 
    687                                                 std::vector<Alternative> newExpls(
    688                                                         std::next( results[i].expls.begin() ), results[i].expls.end() );
     680                                        auto nextArg = results[i].nextArg;
     681
     682                                        // use next element of exploded tuple if present
     683                                        if ( results[i].hasExpl() ) {
     684                                                const ExplodedActual& expl = results[i].getExpl( args );
     685
     686                                                unsigned nextExpl = results[i].nextExpl + 1;
     687                                                if ( nextExpl == expl.exprs.size() ) {
     688                                                        nextExpl = 0;
     689                                                }
     690
    689691                                                results.emplace_back(
    690                                                         i, actual.expr, move(env), copy(results[i].need),
    691                                                         copy(results[i].have), move(openVars), results[i].nextArg, nTuples,
    692                                                         Cost::zero, move(newExpls) );
     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 );
    693696
    694697                                                continue;
     
    696699
    697700                                        // finish result when out of arguments
    698                                         if ( results[i].nextArg >= args.size() ) {
     701                                        if ( nextArg >= args.size() ) {
    699702                                                ArgPack newResult{
    700703                                                        results[i].env, results[i].need, results[i].have,
    701704                                                        results[i].openVars };
    702                                                 newResult.nextArg = results[i].nextArg;
     705                                                newResult.nextArg = nextArg;
    703706                                                Type* argType;
    704707
     
    744747
    745748                                        // add each possible next argument
    746                                         auto j = results[i].nextArg;
    747                                         for ( const Alternative& actual : args[j] ) {
     749                                        for ( std::size_t j = 0; j < args[nextArg].size(); ++j ) {
     750                                                const ExplodedActual& expl = args[nextArg][j];
     751
    748752                                                // fresh copies of parent parameters for this iteration
    749753                                                TypeEnvironment env = results[i].env;
    750754                                                OpenVarSet openVars = results[i].openVars;
    751755
    752                                                 env.addActual( actual.env, openVars );
    753 
    754                                                 // explode argument
    755                                                 std::vector<Alternative> exploded;
    756                                                 Tuples::explode( actual, indexer, back_inserter( exploded ) );
    757                                                 if ( exploded.empty() ) {
    758                                                         // skip empty tuple arguments by (near-)cloning parent into next gen
     756                                                env.addActual( expl.env, openVars );
     757
     758                                                // skip empty tuple arguments by (near-)cloning parent into next gen
     759                                                if ( expl.exprs.empty() ) {
    759760                                                        results.emplace_back(
    760761                                                                results[i], move(env), copy(results[i].need),
    761                                                                 copy(results[i].have), move(openVars), j + 1, actual.cost );
     762                                                                copy(results[i].have), move(openVars), nextArg + 1, expl.cost );
    762763
    763764                                                        continue;
    764765                                                }
    765766
    766                                                 // trim first element from exploded
    767                                                 std::vector<Alternative> newExpls;
    768                                                 newExpls.reserve( exploded.size() - 1 );
    769                                                 for ( std::size_t i = 1; i < exploded.size(); ++i ) {
    770                                                         newExpls.push_back( move(exploded[i]) );
    771                                                 }
    772767                                                // add new result
    773768                                                results.emplace_back(
    774                                                         i, exploded.front().expr, move(env), copy(results[i].need),
    775                                                         copy(results[i].have), move(openVars), results[i].nextArg + 1,
    776                                                         nTuples, actual.cost, move(newExpls) );
     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 );
    777772                                        }
    778773                                }
     
    793788                std::size_t genEnd = results.size();
    794789                for ( std::size_t i = genStart; i < genEnd; ++i ) {
     790                        auto nextArg = results[i].nextArg;
     791
    795792                        // use remainder of exploded tuple if present
    796                         if ( ! results[i].expls.empty() ) {
    797                                 const Alternative& actual = results[i].expls.front();
     793                        if ( results[i].hasExpl() ) {
     794                                const ExplodedActual& expl = results[i].getExpl( args );
     795                                Expression* expr = expl.exprs[results[i].nextExpl].get();
    798796
    799797                                TypeEnvironment env = results[i].env;
     
    801799                                OpenVarSet openVars = results[i].openVars;
    802800
    803                                 env.addActual( actual.env, openVars );
    804                                 Type* actualType = actual.expr->get_result();
     801                                Type* actualType = expr->get_result();
    805802
    806803                                PRINT(
     
    813810
    814811                                if ( unify( formalType, actualType, env, need, have, openVars, indexer ) ) {
    815                                         std::vector<Alternative> newExpls(
    816                                                 std::next( results[i].expls.begin() ), results[i].expls.end() );
     812                                        unsigned nextExpl = results[i].nextExpl + 1;
     813                                        if ( nextExpl == expl.exprs.size() ) {
     814                                                nextExpl = 0;
     815                                        }
     816
    817817                                        results.emplace_back(
    818                                                 i, actual.expr, move(env), move(need), move(have), move(openVars),
    819                                                 results[i].nextArg, nTuples, Cost::zero, move(newExpls) );;
     818                                                i, expr, move(env), move(need), move(have), move(openVars), nextArg,
     819                                                nTuples, Cost::zero, nextExpl, results[i].explAlt );
    820820                                }
    821821
     
    824824
    825825                        // use default initializers if out of arguments
    826                         if ( results[i].nextArg >= args.size() ) {
     826                        if ( nextArg >= args.size() ) {
    827827                                if ( ConstantExpr* cnstExpr = getDefaultValue( initializer ) ) {
    828828                                        if ( Constant* cnst = dynamic_cast<Constant*>( cnstExpr->get_constant() ) ) {
     
    835835                                                        results.emplace_back(
    836836                                                                i, cnstExpr, move(env), move(need), move(have),
    837                                                                 move(openVars), results[i].nextArg, nTuples );
     837                                                                move(openVars), nextArg, nTuples );
    838838                                                }
    839839                                        }
     
    844844
    845845                        // Check each possible next argument
    846                         auto j = results[i].nextArg;
    847                         for ( const Alternative& actual : args[j] ) {
     846                        for ( std::size_t j = 0; j < args[nextArg].size(); ++j ) {
     847                                const ExplodedActual& expl = args[nextArg][j];
     848
    848849                                // fresh copies of parent parameters for this iteration
    849850                                TypeEnvironment env = results[i].env;
     
    851852                                OpenVarSet openVars = results[i].openVars;
    852853
    853                                 env.addActual( actual.env, openVars );
    854 
    855                                 // explode argument
    856                                 std::vector<Alternative> exploded;
    857                                 Tuples::explode( actual, indexer, back_inserter( exploded ) );
    858                                 if ( exploded.empty() ) {
    859                                         // skip empty tuple arguments by (near-)cloning parent into next gen
     854                                env.addActual( expl.env, openVars );
     855
     856                                // skip empty tuple arguments by (near-)cloning parent into next gen
     857                                if ( expl.exprs.empty() ) {
    860858                                        results.emplace_back(
    861                                                 results[i], move(env), move(need), move(have), move(openVars), j + 1,
    862                                                 actual.cost );
     859                                                results[i], move(env), move(need), move(have), move(openVars),
     860                                                nextArg + 1, expl.cost );
    863861
    864862                                        continue;
     
    866864
    867865                                // consider only first exploded actual
    868                                 const Alternative& aActual = exploded.front();
    869                                 Type* actualType = aActual.expr->get_result()->clone();
     866                                Expression* expr = expl.exprs.front().get();
     867                                Type* actualType = expr->get_result()->clone();
    870868
    871869                                PRINT(
     
    879877                                // attempt to unify types
    880878                                if ( unify( formalType, actualType, env, need, have, openVars, indexer ) ) {
    881                                         // trim first element from exploded
    882                                         std::vector<Alternative> newExpls;
    883                                         newExpls.reserve( exploded.size() - 1 );
    884                                         for ( std::size_t i = 1; i < exploded.size(); ++i ) {
    885                                                 newExpls.push_back( move(exploded[i]) );
    886                                         }
    887879                                        // add new result
    888880                                        results.emplace_back(
    889                                                 i, aActual.expr, move(env), move(need), move(have), move(openVars),
    890                                                 j + 1, nTuples, actual.cost, move(newExpls) );
     881                                                i, expr, move(env), move(need), move(have), move(openVars), nextArg + 1,
     882                                                nTuples, expl.cost, expl.exprs.size() == 1 ? 0 : 1, j );
    891883                                }
    892884                        }
     
    924916        template<typename OutputIterator>
    925917        void AlternativeFinder::makeFunctionAlternatives( const Alternative &func,
    926                         FunctionType *funcType, const std::vector< AlternativeFinder > &args,
    927                         OutputIterator out ) {
     918                        FunctionType *funcType, const ExplodedArgs &args, OutputIterator out ) {
    928919                OpenVarSet funcOpenVars;
    929920                AssertionSet funcNeed, funcHave;
     
    964955                                // iterate results
    965956                                for ( std::size_t i = genStart; i < genEnd; ++i ) {
     957                                        auto nextArg = results[i].nextArg;
     958
    966959                                        // use remainder of exploded tuple if present
    967                                         if ( ! results[i].expls.empty() ) {
    968                                                 const Alternative& actual = results[i].expls.front();
    969 
    970                                                 TypeEnvironment env = results[i].env;
    971                                                 OpenVarSet openVars = results[i].openVars;
    972 
    973                                                 env.addActual( actual.env, openVars );
    974 
    975                                                 std::vector<Alternative> newExpls(
    976                                                         std::next( results[i].expls.begin() ), results[i].expls.end() );
     960                                        if ( results[i].hasExpl() ) {
     961                                                const ExplodedActual& expl = results[i].getExpl( args );
     962
     963                                                unsigned nextExpl = results[i].nextExpl + 1;
     964                                                if ( nextExpl == expl.exprs.size() ) {
     965                                                        nextExpl = 0;
     966                                                }
     967
    977968                                                results.emplace_back(
    978                                                         i, actual.expr, move(env), copy(results[i].need),
    979                                                         copy(results[i].have), move(openVars), results[i].nextArg, 0,
    980                                                         Cost::zero, move(newExpls) );
     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 );
    981973
    982974                                                continue;
     
    984976
    985977                                        // finish result when out of arguments
    986                                         if ( results[i].nextArg >= args.size() ) {
     978                                        if ( nextArg >= args.size() ) {
    987979                                                validateFunctionAlternative( func, results[i], results, out );
    988980
     
    991983
    992984                                        // add each possible next argument
    993                                         auto j = results[i].nextArg;
    994                                         for ( const Alternative& actual : args[j] ) {
     985                                        for ( std::size_t j = 0; j < args[nextArg].size(); ++j ) {
     986                                                const ExplodedActual& expl = args[nextArg][j];
     987
    995988                                                // fresh copies of parent parameters for this iteration
    996989                                                TypeEnvironment env = results[i].env;
    997990                                                OpenVarSet openVars = results[i].openVars;
    998991
    999                                                 env.addActual( actual.env, openVars );
    1000 
    1001                                                 // explode argument
    1002                                                 std::vector<Alternative> exploded;
    1003                                                 Tuples::explode( actual, indexer, back_inserter( exploded ) );
    1004                                                 if ( exploded.empty() ) {
    1005                                                         // skip empty tuple arguments by (near-)cloning parent into next gen
     992                                                env.addActual( expl.env, openVars );
     993
     994                                                // skip empty tuple arguments by (near-)cloning parent into next gen
     995                                                if ( expl.exprs.empty() ) {
    1006996                                                        results.emplace_back(
    1007997                                                                results[i], move(env), copy(results[i].need),
    1008                                                                 copy(results[i].have), move(openVars), j + 1, actual.cost );
     998                                                                copy(results[i].have), move(openVars), nextArg + 1, expl.cost );
     999
    10091000                                                        continue;
    10101001                                                }
    10111002
    1012                                                 // trim first element from exploded
    1013                                                 std::vector<Alternative> newExpls;
    1014                                                 newExpls.reserve( exploded.size() - 1 );
    1015                                                 for ( std::size_t i = 1; i < exploded.size(); ++i ) {
    1016                                                         newExpls.push_back( move(exploded[i]) );
    1017                                                 }
    10181003                                                // add new result
    10191004                                                results.emplace_back(
    1020                                                         i, exploded.front().expr, move(env), copy(results[i].need),
    1021                                                         copy(results[i].have), move(openVars), j + 1, 0,
    1022                                                         actual.cost, move(newExpls) );
     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 );
    10231008                                        }
    10241009                                }
     
    10301015                        for ( std::size_t i = genStart; i < results.size(); ++i ) {
    10311016                                ArgPack& result = results[i];
    1032                                 if ( result.expls.empty() && result.nextArg >= args.size() ) {
     1017                                if ( ! result.hasExpl() && result.nextArg >= args.size() ) {
    10331018                                        validateFunctionAlternative( func, result, results, out );
    10341019                                }
     
    10601045                        printAlts( funcOpFinder.alternatives, std::cerr, 1 );
    10611046                )
     1047
     1048                // pre-explode arguments
     1049                ExplodedArgs argExpansions;
     1050                argExpansions.reserve( argAlternatives.size() );
     1051
     1052                for ( const AlternativeFinder& arg : argAlternatives ) {
     1053                        argExpansions.emplace_back();
     1054                        auto& argE = argExpansions.back();
     1055                        argE.reserve( arg.alternatives.size() );
     1056
     1057                        for ( const Alternative& actual : arg ) {
     1058                                argE.emplace_back( actual, indexer );
     1059                        }
     1060                }
    10621061
    10631062                AltList candidates;
     
    10741073                                                Alternative newFunc( *func );
    10751074                                                referenceToRvalueConversion( newFunc.expr );
    1076                                                 makeFunctionAlternatives( newFunc, function, argAlternatives,
     1075                                                makeFunctionAlternatives( newFunc, function, argExpansions,
    10771076                                                        std::back_inserter( candidates ) );
    10781077                                        }
     
    10831082                                                        Alternative newFunc( *func );
    10841083                                                        referenceToRvalueConversion( newFunc.expr );
    1085                                                         makeFunctionAlternatives( newFunc, function, argAlternatives,
     1084                                                        makeFunctionAlternatives( newFunc, function, argExpansions,
    10861085                                                                std::back_inserter( candidates ) );
    10871086                                                } // if
     
    10951094                // try each function operator ?() with each function alternative
    10961095                if ( ! funcOpFinder.alternatives.empty() ) {
    1097                         // add function alternatives to front of argument list
    1098                         argAlternatives.insert( argAlternatives.begin(), move(funcFinder) );
     1096                        // add exploded function alternatives to front of argument list
     1097                        std::vector<ExplodedActual> funcE;
     1098                        funcE.reserve( funcFinder.alternatives.size() );
     1099                        for ( const Alternative& actual : funcFinder ) {
     1100                                funcE.emplace_back( actual, indexer );
     1101                        }
     1102                        argExpansions.insert( argExpansions.begin(), move(funcE) );
    10991103
    11001104                        for ( AltList::iterator funcOp = funcOpFinder.alternatives.begin();
     
    11081112                                                        Alternative newFunc( *funcOp );
    11091113                                                        referenceToRvalueConversion( newFunc.expr );
    1110                                                         makeFunctionAlternatives( newFunc, function, argAlternatives,
     1114                                                        makeFunctionAlternatives( newFunc, function, argExpansions,
    11111115                                                                std::back_inserter( candidates ) );
    11121116                                                }
  • src/ResolvExpr/AlternativeFinder.h

    r8dceeb7 r178e4ec  
    2121
    2222#include "Alternative.h"                 // for AltList, Alternative
     23#include "ExplodedActual.h"              // for ExplodedActual
    2324#include "ResolvExpr/Cost.h"             // for Cost, Cost::infinity
    2425#include "ResolvExpr/TypeEnvironment.h"  // for AssertionSet, OpenVarSet
     
    3233namespace ResolvExpr {
    3334        struct ArgPack;
     35
     36        /// First index is which argument, second index is which alternative for that argument,
     37        /// third index is which exploded element of that alternative
     38        using ExplodedArgs = std::vector< std::vector< ExplodedActual > >;
    3439
    3540        class AlternativeFinder : public Visitor {
     
    133138                /// Finds matching alternatives for a function, given a set of arguments
    134139                template<typename OutputIterator>
    135                 void makeFunctionAlternatives( const Alternative &func, FunctionType *funcType, const std::vector< AlternativeFinder >& args, OutputIterator out );
     140                void makeFunctionAlternatives( const Alternative &func, FunctionType *funcType, const ExplodedArgs& args, OutputIterator out );
    136141                /// Checks if assertion parameters match for a new alternative
    137142                template< typename OutputIterator >
  • src/ResolvExpr/module.mk

    r8dceeb7 r178e4ec  
    3232       ResolvExpr/Occurs.cc \
    3333       ResolvExpr/TypeEnvironment.cc \
    34        ResolvExpr/CurrentObject.cc
     34       ResolvExpr/CurrentObject.cc \
     35       ResolvExpr/ExplodedActual.cc
  • src/Tuples/Explode.h

    r8dceeb7 r178e4ec  
    1616#pragma once
    1717
    18 #include <iterator>                  // for back_inserter, back_insert_iterator
     18#include <iterator>                     // for back_inserter, back_insert_iterator
     19#include <utility>                      // for forward
    1920
    20 #include "ResolvExpr/Alternative.h"  // for Alternative, AltList
    21 #include "SynTree/Expression.h"      // for Expression, UniqueExpr, AddressExpr
    22 #include "SynTree/Type.h"            // for TupleType, Type
    23 #include "Tuples.h"                  // for maybeImpure
     21#include "ResolvExpr/Alternative.h"     // for Alternative, AltList
     22#include "ResolvExpr/ExplodedActual.h"  // for ExplodedActual
     23#include "SynTree/Expression.h"         // for Expression, UniqueExpr, AddressExpr
     24#include "SynTree/Type.h"               // for TupleType, Type
     25#include "Tuples.h"                     // for maybeImpure
    2426
    2527namespace SymTab {
     
    3941        }
    4042
     43        /// Append alternative to an OutputIterator of Alternatives
     44        template<typename OutputIterator>
     45        void append( OutputIterator out, Expression* expr, const ResolvExpr::TypeEnvironment& env,
     46                        const ResolvExpr::Cost& cost, const ResolvExpr::Cost& cvtCost ) {
     47                *out++ = ResolvExpr::Alternative{ expr, env, cost, cvtCost };
     48        }
     49
     50        /// Append alternative to an ExplodedActual
     51        static inline void append( ResolvExpr::ExplodedActual& ea, Expression* expr,
     52                        const ResolvExpr::TypeEnvironment&, const ResolvExpr::Cost&, const ResolvExpr::Cost& ) {
     53                ea.exprs.emplace_back( expr );
     54                /// xxx -- merge environment, cost?
     55        }
     56
    4157        /// helper function used by explode
    42         template< typename OutputIterator >
    43         void explodeUnique( Expression * expr, const ResolvExpr::Alternative & alt, const SymTab::Indexer & indexer, OutputIterator out, bool isTupleAssign ) {
     58        template< typename Output >
     59        void explodeUnique( Expression * expr, const ResolvExpr::Alternative & alt,
     60                        const SymTab::Indexer & indexer, Output&& out, bool isTupleAssign ) {
    4461                if ( isTupleAssign ) {
    4562                        // tuple assignment needs CastExprs to be recursively exploded to easily get at all of the components
    4663                        if ( CastExpr * castExpr = isReferenceCast( expr ) ) {
    4764                                ResolvExpr::AltList alts;
    48                                 explodeUnique( castExpr->get_arg(), alt, indexer, back_inserter( alts ), isTupleAssign );
     65                                explodeUnique(
     66                                        castExpr->get_arg(), alt, indexer, back_inserter( alts ), isTupleAssign );
    4967                                for ( ResolvExpr::Alternative & alt : alts ) {
    5068                                        // distribute reference cast over all components
    51                                         alt.expr = distributeReference( alt.expr );
    52                                         *out++ = alt;
     69                                        append( std::forward<Output>(out), distributeReference( alt.release_expr() ),
     70                                                alt.env, alt.cost, alt.cvtCost );
    5371                                }
    5472                                // in tuple assignment, still need to handle the other cases, but only if not already handled here (don't want to output too many alternatives)
     
    6179                                // can open tuple expr and dump its exploded components
    6280                                for ( Expression * expr : tupleExpr->get_exprs() ) {
    63                                         explodeUnique( expr, alt, indexer, out, isTupleAssign );
     81                                        explodeUnique( expr, alt, indexer, std::forward<Output>(out), isTupleAssign );
    6482                                }
    6583                        } else {
     
    7795                                for ( unsigned int i = 0; i < tupleType->size(); i++ ) {
    7896                                        TupleIndexExpr * idx = new TupleIndexExpr( arg->clone(), i );
    79                                         explodeUnique( idx, alt, indexer, out, isTupleAssign );
     97                                        explodeUnique( idx, alt, indexer, std::forward<Output>(out), isTupleAssign );
    8098                                        delete idx;
    8199                                }
     
    84102                } else {
    85103                        // atomic (non-tuple) type - output a clone of the expression in a new alternative
    86                         *out++ = ResolvExpr::Alternative( expr->clone(), alt.env, alt.cost, alt.cvtCost );
     104                        append( std::forward<Output>(out), expr->clone(), alt.env, alt.cost, alt.cvtCost );
    87105                }
    88106        }
    89107
    90108        /// expands a tuple-valued alternative into multiple alternatives, each with a non-tuple-type
    91         template< typename OutputIterator >
    92         void explode( const ResolvExpr::Alternative &alt, const SymTab::Indexer & indexer, OutputIterator out, bool isTupleAssign = false ) {
    93                 explodeUnique( alt.expr, alt, indexer, out, isTupleAssign );
     109        template< typename Output >
     110        void explode( const ResolvExpr::Alternative &alt, const SymTab::Indexer & indexer,
     111                        Output&& out, bool isTupleAssign = false ) {
     112                explodeUnique( alt.expr, alt, indexer, std::forward<Output>(out), isTupleAssign );
    94113        }
    95114
    96115        // explode list of alternatives
    97         template< typename AltIterator, typename OutputIterator >
    98         void explode( AltIterator altBegin, AltIterator altEnd, const SymTab::Indexer & indexer, OutputIterator out, bool isTupleAssign = false ) {
     116        template< typename AltIterator, typename Output >
     117        void explode( AltIterator altBegin, AltIterator altEnd, const SymTab::Indexer & indexer,
     118                        Output&& out, bool isTupleAssign = false ) {
    99119                for ( ; altBegin != altEnd; ++altBegin ) {
    100                         explode( *altBegin, indexer, out, isTupleAssign );
     120                        explode( *altBegin, indexer, std::forward<Output>(out), isTupleAssign );
    101121                }
    102122        }
    103123
    104         template< typename OutputIterator >
    105         void explode( const ResolvExpr::AltList & alts, const SymTab::Indexer & indexer, OutputIterator out, bool isTupleAssign = false ) {
    106                 explode( alts.begin(), alts.end(), indexer, out, isTupleAssign );
     124        template< typename Output >
     125        void explode( const ResolvExpr::AltList & alts, const SymTab::Indexer & indexer, Output&& out,
     126                        bool isTupleAssign = false ) {
     127                explode( alts.begin(), alts.end(), indexer, std::forward<Output>(out), isTupleAssign );
    107128        }
    108129} // namespace Tuples
Note: See TracChangeset for help on using the changeset viewer.