Changes in / [178e4ec:8dceeb7]
- Location:
- src
- Files:
-
- 2 deleted
- 6 edited
-
Makefile.in (modified) (5 diffs)
-
ResolvExpr/Alternative.h (modified) (1 diff)
-
ResolvExpr/AlternativeFinder.cc (modified) (26 diffs)
-
ResolvExpr/AlternativeFinder.h (modified) (3 diffs)
-
ResolvExpr/ExplodedActual.cc (deleted)
-
ResolvExpr/ExplodedActual.h (deleted)
-
ResolvExpr/module.mk (modified) (1 diff)
-
Tuples/Explode.h (modified) (5 diffs)
Legend:
- Unmodified
- Added
- Removed
-
src/Makefile.in
r178e4ec r8dceeb7 210 210 ResolvExpr/driver_cfa_cpp-TypeEnvironment.$(OBJEXT) \ 211 211 ResolvExpr/driver_cfa_cpp-CurrentObject.$(OBJEXT) \ 212 ResolvExpr/driver_cfa_cpp-ExplodedActual.$(OBJEXT) \213 212 SymTab/driver_cfa_cpp-Indexer.$(OBJEXT) \ 214 213 SymTab/driver_cfa_cpp-Mangler.$(OBJEXT) \ … … 512 511 ResolvExpr/FindOpenVars.cc ResolvExpr/PolyCost.cc \ 513 512 ResolvExpr/Occurs.cc ResolvExpr/TypeEnvironment.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 \ 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 \ 523 521 SynTree/VarArgsType.cc SynTree/ZeroOneType.cc \ 524 522 SynTree/Constant.cc SynTree/Expression.cc SynTree/TupleExpr.cc \ … … 827 825 ResolvExpr/$(am__dirstamp) \ 828 826 ResolvExpr/$(DEPDIR)/$(am__dirstamp) 829 ResolvExpr/driver_cfa_cpp-ExplodedActual.$(OBJEXT): \830 ResolvExpr/$(am__dirstamp) \831 ResolvExpr/$(DEPDIR)/$(am__dirstamp)832 827 SymTab/$(am__dirstamp): 833 828 @$(MKDIR_P) SymTab … … 1027 1022 @AMDEP_TRUE@@am__include@ @am__quote@ResolvExpr/$(DEPDIR)/driver_cfa_cpp-ConversionCost.Po@am__quote@ 1028 1023 @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@1030 1024 @AMDEP_TRUE@@am__include@ @am__quote@ResolvExpr/$(DEPDIR)/driver_cfa_cpp-FindOpenVars.Po@am__quote@ 1031 1025 @AMDEP_TRUE@@am__include@ @am__quote@ResolvExpr/$(DEPDIR)/driver_cfa_cpp-Occurs.Po@am__quote@ … … 1970 1964 @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` 1971 1965 1972 ResolvExpr/driver_cfa_cpp-ExplodedActual.o: ResolvExpr/ExplodedActual.cc1973 @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.cc1974 @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) ResolvExpr/$(DEPDIR)/driver_cfa_cpp-ExplodedActual.Tpo ResolvExpr/$(DEPDIR)/driver_cfa_cpp-ExplodedActual.Po1975 @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.cc1978 1979 ResolvExpr/driver_cfa_cpp-ExplodedActual.obj: ResolvExpr/ExplodedActual.cc1980 @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.Po1982 @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 1986 1966 SymTab/driver_cfa_cpp-Indexer.o: SymTab/Indexer.cc 1987 1967 @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
r178e4ec r8dceeb7 37 37 void print( std::ostream &os, Indenter indent = {} ) const; 38 38 39 /// Returns the stored expression, but released from management of this Alternative40 Expression* release_expr() {41 Expression* tmp = expr;42 expr = nullptr;43 return tmp;44 }45 46 39 Cost cost; 47 40 Cost cvtCost; -
src/ResolvExpr/AlternativeFinder.cc
r178e4ec r8dceeb7 30 30 #include "Common/utility.h" // for deleteAll, printAll, CodeLocation 31 31 #include "Cost.h" // for Cost, Cost::zero, operator<<, Cost... 32 #include "ExplodedActual.h" // for ExplodedActual33 32 #include "InitTweak/InitTweak.h" // for getFunctionName 34 33 #include "RenameVars.h" // for RenameVars, global_renamer … … 591 590 unsigned nextArg; ///< Index of next argument in arguments list 592 591 unsigned tupleStart; ///< Number of tuples that start at this index 593 unsigned nextExpl; ///< Index of next exploded element594 unsigned explAlt; ///< Index of alternative for nextExpl > 0592 // TODO fix this somehow 593 std::vector<Alternative> expls; ///< Exploded actuals left over from last match 595 594 596 595 ArgPack() 597 596 : parent(0), expr(), cost(Cost::zero), env(), need(), have(), openVars(), nextArg(0), 598 599 tupleStart(0), nextExpl(0), explAlt(0) {} 597 tupleStart(0), expls() {} 600 598 601 599 ArgPack(const TypeEnvironment& env, const AssertionSet& need, const AssertionSet& have, 602 600 const OpenVarSet& openVars) 603 601 : parent(0), expr(), cost(Cost::zero), env(env), need(need), have(have), 604 openVars(openVars), nextArg(0), tupleStart(0), nextExpl(0), explAlt(0) {}602 openVars(openVars), nextArg(0), tupleStart(0), expls() {} 605 603 606 604 ArgPack(std::size_t parent, Expression* expr, TypeEnvironment&& env, AssertionSet&& need, 607 605 AssertionSet&& have, OpenVarSet&& openVars, unsigned nextArg, 608 unsigned tupleStart = 0, Cost cost = Cost::zero, unsigned nextExpl = 0,609 unsigned explAlt = 0)606 unsigned tupleStart = 0, Cost cost = Cost::zero, 607 std::vector<Alternative>&& expls = std::vector<Alternative>{} ) 610 608 : parent(parent), expr(expr->clone()), cost(cost), env(move(env)), need(move(need)), 611 609 have(move(have)), openVars(move(openVars)), nextArg(nextArg), tupleStart(tupleStart), 612 nextExpl(nextExpl), explAlt(explAlt) {}610 expls(move(expls)) {} 613 611 614 612 ArgPack(const ArgPack& o, TypeEnvironment&& env, AssertionSet&& need, AssertionSet&& have, … … 616 614 : parent(o.parent), expr(o.expr ? o.expr->clone() : nullptr), cost(o.cost + added), 617 615 env(move(env)), need(move(need)), have(move(have)), openVars(move(openVars)), 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 pack624 const ExplodedActual& getExpl( const ExplodedArgs& args ) const {625 return args[nextArg-1][explAlt]; 626 }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; 627 625 628 626 /// Ends a tuple expression, consolidating the appropriate actuals … … 646 644 /// Instantiates an argument to match a formal, returns false if no results left 647 645 bool instantiateArgument( Type* formalType, Initializer* initializer, 648 const ExplodedArgs& args, std::vector<ArgPack>& results, std::size_t& genStart,649 const SymTab::Indexer& indexer, unsigned nTuples = 0 ) {646 const std::vector< AlternativeFinder >& args, std::vector<ArgPack>& results, 647 std::size_t& genStart, const SymTab::Indexer& indexer, unsigned nTuples = 0 ) { 650 648 if ( TupleType* tupleType = dynamic_cast<TupleType*>( formalType ) ) { 651 649 // formalType is a TupleType - group actuals into a TupleExpr … … 678 676 // add another argument to results 679 677 for ( std::size_t i = genStart; i < genEnd; ++i ) { 680 auto nextArg = results[i].nextArg;681 682 // use next element of exploded tuple if present683 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 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() ); 691 689 results.emplace_back( 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 ); 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) ); 696 693 697 694 continue; … … 699 696 700 697 // finish result when out of arguments 701 if ( nextArg >= args.size() ) {698 if ( results[i].nextArg >= args.size() ) { 702 699 ArgPack newResult{ 703 700 results[i].env, results[i].need, results[i].have, 704 701 results[i].openVars }; 705 newResult.nextArg = nextArg;702 newResult.nextArg = results[i].nextArg; 706 703 Type* argType; 707 704 … … 747 744 748 745 // add each possible next argument 749 for ( std::size_t j = 0; j < args[nextArg].size(); ++j ) { 750 const ExplodedActual& expl = args[nextArg][j]; 751 746 auto j = results[i].nextArg; 747 for ( const Alternative& actual : args[j] ) { 752 748 // fresh copies of parent parameters for this iteration 753 749 TypeEnvironment env = results[i].env; 754 750 OpenVarSet openVars = results[i].openVars; 755 751 756 env.addActual( expl.env, openVars ); 757 758 // skip empty tuple arguments by (near-)cloning parent into next gen 759 if ( expl.exprs.empty() ) { 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 760 759 results.emplace_back( 761 760 results[i], move(env), copy(results[i].need), 762 copy(results[i].have), move(openVars), nextArg + 1, expl.cost );761 copy(results[i].have), move(openVars), j + 1, actual.cost ); 763 762 764 763 continue; 765 764 } 766 765 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 } 767 772 // add new result 768 773 results.emplace_back( 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);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) ); 772 777 } 773 778 } … … 788 793 std::size_t genEnd = results.size(); 789 794 for ( std::size_t i = genStart; i < genEnd; ++i ) { 790 auto nextArg = results[i].nextArg;791 792 795 // use remainder of exploded tuple if present 793 if ( results[i].hasExpl() ) { 794 const ExplodedActual& expl = results[i].getExpl( args ); 795 Expression* expr = expl.exprs[results[i].nextExpl].get(); 796 if ( ! results[i].expls.empty() ) { 797 const Alternative& actual = results[i].expls.front(); 796 798 797 799 TypeEnvironment env = results[i].env; … … 799 801 OpenVarSet openVars = results[i].openVars; 800 802 801 Type* actualType = expr->get_result(); 803 env.addActual( actual.env, openVars ); 804 Type* actualType = actual.expr->get_result(); 802 805 803 806 PRINT( … … 810 813 811 814 if ( unify( formalType, actualType, env, need, have, openVars, indexer ) ) { 812 unsigned nextExpl = results[i].nextExpl + 1; 813 if ( nextExpl == expl.exprs.size() ) { 814 nextExpl = 0; 815 } 816 815 std::vector<Alternative> newExpls( 816 std::next( results[i].expls.begin() ), results[i].expls.end() ); 817 817 results.emplace_back( 818 i, expr, move(env), move(need), move(have), move(openVars), nextArg,819 nTuples, Cost::zero, nextExpl, results[i].explAlt );818 i, actual.expr, move(env), move(need), move(have), move(openVars), 819 results[i].nextArg, nTuples, Cost::zero, move(newExpls) );; 820 820 } 821 821 … … 824 824 825 825 // use default initializers if out of arguments 826 if ( nextArg >= args.size() ) {826 if ( results[i].nextArg >= args.size() ) { 827 827 if ( ConstantExpr* cnstExpr = getDefaultValue( initializer ) ) { 828 828 if ( Constant* cnst = dynamic_cast<Constant*>( cnstExpr->get_constant() ) ) { … … 835 835 results.emplace_back( 836 836 i, cnstExpr, move(env), move(need), move(have), 837 move(openVars), nextArg, nTuples );837 move(openVars), results[i].nextArg, nTuples ); 838 838 } 839 839 } … … 844 844 845 845 // Check each possible next argument 846 for ( std::size_t j = 0; j < args[nextArg].size(); ++j ) { 847 const ExplodedActual& expl = args[nextArg][j]; 848 846 auto j = results[i].nextArg; 847 for ( const Alternative& actual : args[j] ) { 849 848 // fresh copies of parent parameters for this iteration 850 849 TypeEnvironment env = results[i].env; … … 852 851 OpenVarSet openVars = results[i].openVars; 853 852 854 env.addActual( expl.env, openVars ); 855 856 // skip empty tuple arguments by (near-)cloning parent into next gen 857 if ( expl.exprs.empty() ) { 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 858 860 results.emplace_back( 859 results[i], move(env), move(need), move(have), move(openVars), 860 nextArg + 1, expl.cost );861 results[i], move(env), move(need), move(have), move(openVars), j + 1, 862 actual.cost ); 861 863 862 864 continue; … … 864 866 865 867 // consider only first exploded actual 866 Expression* expr = expl.exprs.front().get();867 Type* actualType = expr->get_result()->clone();868 const Alternative& aActual = exploded.front(); 869 Type* actualType = aActual.expr->get_result()->clone(); 868 870 869 871 PRINT( … … 877 879 // attempt to unify types 878 880 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 } 879 887 // add new result 880 888 results.emplace_back( 881 i, expr, move(env), move(need), move(have), move(openVars), nextArg + 1,882 nTuples, expl.cost, expl.exprs.size() == 1 ? 0 : 1, j);889 i, aActual.expr, move(env), move(need), move(have), move(openVars), 890 j + 1, nTuples, actual.cost, move(newExpls) ); 883 891 } 884 892 } … … 916 924 template<typename OutputIterator> 917 925 void AlternativeFinder::makeFunctionAlternatives( const Alternative &func, 918 FunctionType *funcType, const ExplodedArgs &args, OutputIterator out ) { 926 FunctionType *funcType, const std::vector< AlternativeFinder > &args, 927 OutputIterator out ) { 919 928 OpenVarSet funcOpenVars; 920 929 AssertionSet funcNeed, funcHave; … … 955 964 // iterate results 956 965 for ( std::size_t i = genStart; i < genEnd; ++i ) { 957 auto nextArg = results[i].nextArg;958 959 966 // use remainder of exploded tuple if present 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 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() ); 968 977 results.emplace_back( 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 ); 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) ); 973 981 974 982 continue; … … 976 984 977 985 // finish result when out of arguments 978 if ( nextArg >= args.size() ) {986 if ( results[i].nextArg >= args.size() ) { 979 987 validateFunctionAlternative( func, results[i], results, out ); 980 988 … … 983 991 984 992 // add each possible next argument 985 for ( std::size_t j = 0; j < args[nextArg].size(); ++j ) { 986 const ExplodedActual& expl = args[nextArg][j]; 987 993 auto j = results[i].nextArg; 994 for ( const Alternative& actual : args[j] ) { 988 995 // fresh copies of parent parameters for this iteration 989 996 TypeEnvironment env = results[i].env; 990 997 OpenVarSet openVars = results[i].openVars; 991 998 992 env.addActual( expl.env, openVars ); 993 994 // skip empty tuple arguments by (near-)cloning parent into next gen 995 if ( expl.exprs.empty() ) { 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 996 1006 results.emplace_back( 997 1007 results[i], move(env), copy(results[i].need), 998 copy(results[i].have), move(openVars), nextArg + 1, expl.cost ); 999 1008 copy(results[i].have), move(openVars), j + 1, actual.cost ); 1000 1009 continue; 1001 1010 } 1002 1011 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 } 1003 1018 // add new result 1004 1019 results.emplace_back( 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);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) ); 1008 1023 } 1009 1024 } … … 1015 1030 for ( std::size_t i = genStart; i < results.size(); ++i ) { 1016 1031 ArgPack& result = results[i]; 1017 if ( ! result.hasExpl() && result.nextArg >= args.size() ) {1032 if ( result.expls.empty() && result.nextArg >= args.size() ) { 1018 1033 validateFunctionAlternative( func, result, results, out ); 1019 1034 } … … 1045 1060 printAlts( funcOpFinder.alternatives, std::cerr, 1 ); 1046 1061 ) 1047 1048 // pre-explode arguments1049 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 }1061 1062 1062 1063 AltList candidates; … … 1073 1074 Alternative newFunc( *func ); 1074 1075 referenceToRvalueConversion( newFunc.expr ); 1075 makeFunctionAlternatives( newFunc, function, arg Expansions,1076 makeFunctionAlternatives( newFunc, function, argAlternatives, 1076 1077 std::back_inserter( candidates ) ); 1077 1078 } … … 1082 1083 Alternative newFunc( *func ); 1083 1084 referenceToRvalueConversion( newFunc.expr ); 1084 makeFunctionAlternatives( newFunc, function, arg Expansions,1085 makeFunctionAlternatives( newFunc, function, argAlternatives, 1085 1086 std::back_inserter( candidates ) ); 1086 1087 } // if … … 1094 1095 // try each function operator ?() with each function alternative 1095 1096 if ( ! funcOpFinder.alternatives.empty() ) { 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) ); 1097 // add function alternatives to front of argument list 1098 argAlternatives.insert( argAlternatives.begin(), move(funcFinder) ); 1103 1099 1104 1100 for ( AltList::iterator funcOp = funcOpFinder.alternatives.begin(); … … 1112 1108 Alternative newFunc( *funcOp ); 1113 1109 referenceToRvalueConversion( newFunc.expr ); 1114 makeFunctionAlternatives( newFunc, function, arg Expansions,1110 makeFunctionAlternatives( newFunc, function, argAlternatives, 1115 1111 std::back_inserter( candidates ) ); 1116 1112 } -
src/ResolvExpr/AlternativeFinder.h
r178e4ec r8dceeb7 21 21 22 22 #include "Alternative.h" // for AltList, Alternative 23 #include "ExplodedActual.h" // for ExplodedActual24 23 #include "ResolvExpr/Cost.h" // for Cost, Cost::infinity 25 24 #include "ResolvExpr/TypeEnvironment.h" // for AssertionSet, OpenVarSet … … 33 32 namespace ResolvExpr { 34 33 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 alternative38 using ExplodedArgs = std::vector< std::vector< ExplodedActual > >;39 34 40 35 class AlternativeFinder : public Visitor { … … 138 133 /// Finds matching alternatives for a function, given a set of arguments 139 134 template<typename OutputIterator> 140 void makeFunctionAlternatives( const Alternative &func, FunctionType *funcType, const ExplodedArgs& args, OutputIterator out );135 void makeFunctionAlternatives( const Alternative &func, FunctionType *funcType, const std::vector< AlternativeFinder >& args, OutputIterator out ); 141 136 /// Checks if assertion parameters match for a new alternative 142 137 template< typename OutputIterator > -
src/ResolvExpr/module.mk
r178e4ec r8dceeb7 32 32 ResolvExpr/Occurs.cc \ 33 33 ResolvExpr/TypeEnvironment.cc \ 34 ResolvExpr/CurrentObject.cc \ 35 ResolvExpr/ExplodedActual.cc 34 ResolvExpr/CurrentObject.cc -
src/Tuples/Explode.h
r178e4ec r8dceeb7 16 16 #pragma once 17 17 18 #include <iterator> // for back_inserter, back_insert_iterator 19 #include <utility> // for forward 18 #include <iterator> // for back_inserter, back_insert_iterator 20 19 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 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 26 24 27 25 namespace SymTab { … … 41 39 } 42 40 43 /// Append alternative to an OutputIterator of Alternatives44 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 ExplodedActual51 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 57 41 /// helper function used by explode 58 template< typename Output > 59 void explodeUnique( Expression * expr, const ResolvExpr::Alternative & alt, 60 const SymTab::Indexer & indexer, Output&& out, bool isTupleAssign ) { 42 template< typename OutputIterator > 43 void explodeUnique( Expression * expr, const ResolvExpr::Alternative & alt, const SymTab::Indexer & indexer, OutputIterator out, bool isTupleAssign ) { 61 44 if ( isTupleAssign ) { 62 45 // tuple assignment needs CastExprs to be recursively exploded to easily get at all of the components 63 46 if ( CastExpr * castExpr = isReferenceCast( expr ) ) { 64 47 ResolvExpr::AltList alts; 65 explodeUnique( 66 castExpr->get_arg(), alt, indexer, back_inserter( alts ), isTupleAssign ); 48 explodeUnique( castExpr->get_arg(), alt, indexer, back_inserter( alts ), isTupleAssign ); 67 49 for ( ResolvExpr::Alternative & alt : alts ) { 68 50 // distribute reference cast over all components 69 a ppend( std::forward<Output>(out), distributeReference( alt.release_expr() ),70 alt.env, alt.cost, alt.cvtCost );51 alt.expr = distributeReference( alt.expr ); 52 *out++ = alt; 71 53 } 72 54 // 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) … … 79 61 // can open tuple expr and dump its exploded components 80 62 for ( Expression * expr : tupleExpr->get_exprs() ) { 81 explodeUnique( expr, alt, indexer, std::forward<Output>(out), isTupleAssign );63 explodeUnique( expr, alt, indexer, out, isTupleAssign ); 82 64 } 83 65 } else { … … 95 77 for ( unsigned int i = 0; i < tupleType->size(); i++ ) { 96 78 TupleIndexExpr * idx = new TupleIndexExpr( arg->clone(), i ); 97 explodeUnique( idx, alt, indexer, std::forward<Output>(out), isTupleAssign );79 explodeUnique( idx, alt, indexer, out, isTupleAssign ); 98 80 delete idx; 99 81 } … … 102 84 } else { 103 85 // atomic (non-tuple) type - output a clone of the expression in a new alternative 104 append( std::forward<Output>(out),expr->clone(), alt.env, alt.cost, alt.cvtCost );86 *out++ = ResolvExpr::Alternative( expr->clone(), alt.env, alt.cost, alt.cvtCost ); 105 87 } 106 88 } 107 89 108 90 /// expands a tuple-valued alternative into multiple alternatives, each with a non-tuple-type 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 ); 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 ); 113 94 } 114 95 115 96 // explode list of alternatives 116 template< typename AltIterator, typename Output > 117 void explode( AltIterator altBegin, AltIterator altEnd, const SymTab::Indexer & indexer, 118 Output&& out, bool isTupleAssign = false ) { 97 template< typename AltIterator, typename OutputIterator > 98 void explode( AltIterator altBegin, AltIterator altEnd, const SymTab::Indexer & indexer, OutputIterator out, bool isTupleAssign = false ) { 119 99 for ( ; altBegin != altEnd; ++altBegin ) { 120 explode( *altBegin, indexer, std::forward<Output>(out), isTupleAssign );100 explode( *altBegin, indexer, out, isTupleAssign ); 121 101 } 122 102 } 123 103 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 ); 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 ); 128 107 } 129 108 } // namespace Tuples
Note:
See TracChangeset
for help on using the changeset viewer.