Ignore:
Timestamp:
Oct 12, 2018, 3:19:35 PM (3 years ago)
Author:
Aaron Moss <a3moss@…>
Branches:
aaron-thesis, arm-eh, cleanup-dtors, deferred_resn, jacob/cs343-translation, jenkins-sandbox, master, new-ast, new-ast-unique-expr, no_list, persistent-indexer
Children:
da48183
Parents:
59cf83b
Message:

First compiling draft of deferred assertions (build failure)

File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/ResolvExpr/AlternativeFinder.cc

    r59cf83b r6d6e829  
    3434#include "InitTweak/InitTweak.h"   // for getFunctionName
    3535#include "RenameVars.h"            // for RenameVars, global_renamer
     36#include "ResolveAssertions.h"     // for resolveAssertions
    3637#include "ResolveTypeof.h"         // for resolveTypeof
    3738#include "Resolver.h"              // for resolveStmtExpr
     
    102103                void addAnonConversions( const Alternative & alt );
    103104                /// Adds alternatives for member expressions, given the aggregate, conversion cost for that aggregate, and name of the member
    104                 template< typename StructOrUnionType > void addAggMembers( StructOrUnionType *aggInst, Expression *expr, const Cost &newCost, const TypeEnvironment & env, const std::string & name );
     105                template< typename StructOrUnionType > void addAggMembers( StructOrUnionType *aggInst, Expression *expr, const Alternative &alt, const Cost &newCost, const std::string & name );
    105106                /// Adds alternatives for member expressions where the left side has tuple type
    106                 void addTupleMembers( TupleType * tupleType, Expression *expr, const Cost &newCost, const TypeEnvironment & env, Expression * member );
     107                void addTupleMembers( TupleType *tupleType, Expression *expr, const Alternative &alt, const Cost &newCost, Expression *member );
    107108                /// Adds alternatives for offsetof expressions, given the base type and name of the member
    108109                template< typename StructOrUnionType > void addOffsetof( StructOrUnionType *aggInst, const std::string &name );
     
    253254                        SemanticError( expr, "No reasonable alternatives for expression " );
    254255                }
     256                if ( mode.resolveAssns ) {
     257                        // trim candidates just to those where the assertions resolve
     258                        AltList candidates;
     259                        for ( unsigned i = 0; i < alternatives.size(); ++i ) {
     260                                resolveAssertions( alternatives[i], indexer, candidates );
     261                        }
     262                        // fail early if none such
     263                        if ( mode.failFast && candidates.empty() ) {
     264                                std::ostringstream stream;
     265                                stream << "No resolvable alternatives for expression " << expr << "\n"
     266                                       << "Alternatives with failing assertions are:\n";
     267                                printAlts( alternatives, stream, 1 );
     268                                SemanticError( expr->location, stream.str() );
     269                        }
     270                        // reset alternatives
     271                        alternatives = std::move( candidates );
     272                }
    255273                if ( mode.prune ) {
    256274                        auto oldsize = alternatives.size();
     
    317335
    318336                if ( StructInstType *structInst = dynamic_cast< StructInstType* >( aggrExpr->result ) ) {
    319                         addAggMembers( structInst, aggrExpr.get(), alt.cost+Cost::safe, alt.env, "" );
     337                        addAggMembers( structInst, aggrExpr.get(), alt, alt.cost+Cost::safe, "" );
    320338                } else if ( UnionInstType *unionInst = dynamic_cast< UnionInstType* >( aggrExpr->result ) ) {
    321                         addAggMembers( unionInst, aggrExpr.get(), alt.cost+Cost::safe, alt.env, "" );
     339                        addAggMembers( unionInst, aggrExpr.get(), alt, alt.cost+Cost::safe, "" );
    322340                } // if
    323341        }
    324342
    325343        template< typename StructOrUnionType >
    326         void AlternativeFinder::Finder::addAggMembers( StructOrUnionType *aggInst, Expression *expr, const Cost &newCost, const TypeEnvironment & env, const std::string & name ) {
     344        void AlternativeFinder::Finder::addAggMembers( StructOrUnionType *aggInst, Expression *expr, const Alternative& alt, const Cost &newCost, const std::string & name ) {
    327345                std::list< Declaration* > members;
    328346                aggInst->lookup( name, members );
     
    332350                                // addAnonAlternatives uses vector::push_back, which invalidates references to existing elements, so
    333351                                // can't construct in place and use vector::back
    334                                 Alternative newAlt( new MemberExpr( dwt, expr->clone() ), env, newCost );
     352                                Alternative newAlt{ alt, new MemberExpr{ dwt, expr->clone() }, newCost };
    335353                                renameTypes( newAlt.expr );
    336354                                addAnonConversions( newAlt ); // add anonymous member interpretations whenever an aggregate value type is seen as a member expression.
     
    342360        }
    343361
    344         void AlternativeFinder::Finder::addTupleMembers( TupleType * tupleType, Expression *expr, const Cost &newCost, const TypeEnvironment & env, Expression * member ) {
     362        void AlternativeFinder::Finder::addTupleMembers( TupleType *tupleType, Expression *expr,                        const Alternative &alt, const Cost &newCost, Expression *member ) {
    345363                if ( ConstantExpr * constantExpr = dynamic_cast< ConstantExpr * >( member ) ) {
    346364                        // get the value of the constant expression as an int, must be between 0 and the length of the tuple type to have meaning
     
    348366                        std::string tmp;
    349367                        if ( val >= 0 && (unsigned long long)val < tupleType->size() ) {
    350                                 alternatives.push_back( Alternative( new TupleIndexExpr( expr->clone(), val ), env, newCost ) );
     368                                alternatives.push_back( Alternative{
     369                                        alt, new TupleIndexExpr( expr->clone(), val ), newCost } );
    351370                        } // if
    352371                } // if
     
    354373
    355374        void AlternativeFinder::Finder::postvisit( ApplicationExpr *applicationExpr ) {
    356                 alternatives.push_back( Alternative( applicationExpr->clone(), env, Cost::zero ) );
     375                alternatives.push_back( Alternative{ applicationExpr->clone(), env } );
    357376        }
    358377
     
    484503        }
    485504
    486         static const int recursionLimit = /*10*/ 4;  ///< Limit to depth of recursion satisfaction
    487 
    488         void addToIndexer( AssertionSet &assertSet, SymTab::Indexer &indexer ) {
    489                 for ( AssertionSet::iterator i = assertSet.begin(); i != assertSet.end(); ++i ) {
    490                         if ( i->second.isUsed ) {
    491                                 indexer.addId( i->first );
    492                         }
    493                 }
    494         }
    495 
    496         template< typename ForwardIterator, typename OutputIterator >
    497         void inferRecursive( ForwardIterator begin, ForwardIterator end, const Alternative &newAlt, OpenVarSet &openVars, const SymTab::Indexer &decls, const AssertionSet &newNeed, int level, const SymTab::Indexer &indexer, OutputIterator out ) {
    498                 if ( newAlt.cost == Cost::infinity ) return; // don't proceed down this dead end
    499                 if ( begin == end ) {
    500                         if ( newNeed.empty() ) {
    501                                 PRINT(
    502                                         std::cerr << "all assertions satisfied, output alternative: ";
    503                                         newAlt.print( std::cerr );
    504                                         std::cerr << std::endl;
    505                                 );
    506                                 *out++ = newAlt;
    507                                 return;
    508                         } else if ( level >= recursionLimit ) {
    509                                 SemanticError( newAlt.expr->location, "Too many recursive assertions" );
    510                         } else {
    511                                 AssertionSet newerNeed;
    512                                 PRINT(
    513                                         std::cerr << "recursing with new set:" << std::endl;
    514                                         printAssertionSet( newNeed, std::cerr, 8 );
    515                                 )
    516                                 inferRecursive( newNeed.begin(), newNeed.end(), newAlt, openVars, decls, newerNeed, level+1, indexer, out );
    517                                 return;
    518                         }
    519                 }
    520 
    521                 ForwardIterator cur = begin++;
    522                 if ( ! cur->second.isUsed ) {
    523                         inferRecursive( begin, end, newAlt, openVars, decls, newNeed, level, indexer, out );
    524                         return; // xxx - should this continue? previously this wasn't here, and it looks like it should be
    525                 }
    526                 DeclarationWithType *curDecl = cur->first;
    527 
    528                 PRINT(
    529                         std::cerr << "inferRecursive: assertion is ";
    530                         curDecl->print( std::cerr );
    531                         std::cerr << std::endl;
    532                 )
    533                 std::list< SymTab::Indexer::IdData > candidates;
    534                 decls.lookupId( curDecl->get_name(), candidates );
    535 ///   if ( candidates.empty() ) { std::cerr << "no candidates!" << std::endl; }
    536                 for ( const auto & data : candidates ) {
    537                         DeclarationWithType * candidate = data.id;
    538                         PRINT(
    539                                 std::cerr << "inferRecursive: candidate is ";
    540                                 candidate->print( std::cerr );
    541                                 std::cerr << std::endl;
    542                         )
    543 
    544                         AssertionSet newHave, newerNeed( newNeed );
    545                         TypeEnvironment newEnv( newAlt.env );
    546                         OpenVarSet newOpenVars( openVars );
    547                         Type *adjType = candidate->get_type()->clone();
    548                         adjustExprType( adjType, newEnv, indexer );
    549                         renameTyVars( adjType );
    550                         PRINT(
    551                                 std::cerr << "unifying ";
    552                                 curDecl->get_type()->print( std::cerr );
    553                                 std::cerr << " with ";
    554                                 adjType->print( std::cerr );
    555                                 std::cerr << std::endl;
    556                         )
    557                         if ( unify( curDecl->get_type(), adjType, newEnv, newerNeed, newHave, newOpenVars, indexer ) ) {
    558                                 PRINT(
    559                                         std::cerr << "success!" << std::endl;
    560                                 )
    561                                 SymTab::Indexer newDecls( decls );
    562                                 addToIndexer( newHave, newDecls );
    563                                 Alternative newerAlt( newAlt );
    564                                 newerAlt.env = newEnv;
    565                                 assertf( candidate->get_uniqueId(), "Assertion candidate does not have a unique ID: %s", toString( candidate ).c_str() );
    566 
    567                                 // everything with an empty idChain was pulled in by the current assertion.
    568                                 // add current assertion's idChain + current assertion's ID so that the correct inferParameters can be found.
    569                                 for ( auto & a : newerNeed ) {
    570                                         if ( a.second.idChain.empty() ) {
    571                                                 a.second.idChain = cur->second.idChain;
    572                                                 a.second.idChain.push_back( curDecl->get_uniqueId() );
    573                                         }
    574                                 }
    575 
    576                                 Expression *varExpr = data.combine( newerAlt.cvtCost );
    577                                 delete varExpr->get_result();
    578                                 varExpr->set_result( adjType->clone() );
    579                                 PRINT(
    580                                         std::cerr << "satisfying assertion " << curDecl->get_uniqueId() << " ";
    581                                         curDecl->print( std::cerr );
    582                                         std::cerr << " with declaration " << candidate->get_uniqueId() << " ";
    583                                         candidate->print( std::cerr );
    584                                         std::cerr << std::endl;
    585                                 )
    586                                 // follow the current assertion's ID chain to find the correct set of inferred parameters to add the candidate to (i.e. the set of inferred parameters belonging to the entity which requested the assertion parameter).
    587                                 InferredParams * inferParameters = &newerAlt.expr->get_inferParams();
    588                                 for ( UniqueId id : cur->second.idChain ) {
    589                                         inferParameters = (*inferParameters)[ id ].inferParams.get();
    590                                 }
    591                                 // XXX: this is a memory leak, but adjType can't be deleted because it might contain assertions
    592                                 (*inferParameters)[ curDecl->get_uniqueId() ] = ParamEntry( candidate->get_uniqueId(), adjType->clone(), curDecl->get_type()->clone(), varExpr );
    593                                 inferRecursive( begin, end, newerAlt, newOpenVars, newDecls, newerNeed, level, indexer, out );
    594                         } else {
    595                                 delete adjType;
    596                         }
    597                 }
    598         }
     505//      template< typename ForwardIterator, typename OutputIterator >
     506//      void inferRecursive( ForwardIterator begin, ForwardIterator end, const Alternative &newAlt, OpenVarSet &openVars, const SymTab::Indexer &decls, const AssertionSet &newNeed, int level, const SymTab::Indexer &indexer, OutputIterator out ) {
     507//              if ( newAlt.cost == Cost::infinity ) return; // don't proceed down this dead end
     508//              if ( begin == end ) {
     509//                      if ( newNeed.empty() ) {
     510//                              PRINT(
     511//                                      std::cerr << "all assertions satisfied, output alternative: ";
     512//                                      newAlt.print( std::cerr );
     513//                                      std::cerr << std::endl;
     514//                              );
     515//                              *out++ = newAlt;
     516//                              return;
     517//                      } else if ( level >= recursionLimit ) {
     518//                              SemanticError( newAlt.expr->location, "Too many recursive assertions" );
     519//                      } else {
     520//                              AssertionSet newerNeed;
     521//                              PRINT(
     522//                                      std::cerr << "recursing with new set:" << std::endl;
     523//                                      printAssertionSet( newNeed, std::cerr, 8 );
     524//                              )
     525//                              inferRecursive( newNeed.begin(), newNeed.end(), newAlt, openVars, decls, newerNeed, level+1, indexer, out );
     526//                              return;
     527//                      }
     528//              }
     529
     530//              ForwardIterator cur = begin++;
     531//              if ( ! cur->second.isUsed ) {
     532//                      inferRecursive( begin, end, newAlt, openVars, decls, newNeed, level, indexer, out );
     533//                      return; // xxx - should this continue? previously this wasn't here, and it looks like it should be
     534//              }
     535//              DeclarationWithType *curDecl = cur->first;
     536
     537//              PRINT(
     538//                      std::cerr << "inferRecursive: assertion is ";
     539//                      curDecl->print( std::cerr );
     540//                      std::cerr << std::endl;
     541//              )
     542//              std::list< SymTab::Indexer::IdData > candidates;
     543//              decls.lookupId( curDecl->get_name(), candidates );
     544// ///   if ( candidates.empty() ) { std::cerr << "no candidates!" << std::endl; }
     545//              for ( const auto & data : candidates ) {
     546//                      DeclarationWithType * candidate = data.id;
     547//                      PRINT(
     548//                              std::cerr << "inferRecursive: candidate is ";
     549//                              candidate->print( std::cerr );
     550//                              std::cerr << std::endl;
     551//                      )
     552
     553//                      AssertionSet newHave, newerNeed( newNeed );
     554//                      TypeEnvironment newEnv( newAlt.env );
     555//                      OpenVarSet newOpenVars( openVars );
     556//                      Type *adjType = candidate->get_type()->clone();
     557//                      adjustExprType( adjType, newEnv, indexer );
     558//                      renameTyVars( adjType );
     559//                      PRINT(
     560//                              std::cerr << "unifying ";
     561//                              curDecl->get_type()->print( std::cerr );
     562//                              std::cerr << " with ";
     563//                              adjType->print( std::cerr );
     564//                              std::cerr << std::endl;
     565//                      )
     566//                      if ( unify( curDecl->get_type(), adjType, newEnv, newerNeed, newHave, newOpenVars, indexer ) ) {
     567//                              PRINT(
     568//                                      std::cerr << "success!" << std::endl;
     569//                              )
     570//                              SymTab::Indexer newDecls( decls );
     571//                              addToIndexer( newHave, newDecls );
     572//                              Alternative newerAlt( newAlt );
     573//                              newerAlt.env = newEnv;
     574//                              assertf( candidate->get_uniqueId(), "Assertion candidate does not have a unique ID: %s", toString( candidate ).c_str() );
     575
     576//                              // everything with an empty idChain was pulled in by the current assertion.
     577//                              // add current assertion's idChain + current assertion's ID so that the correct inferParameters can be found.
     578//                              for ( auto & a : newerNeed ) {
     579//                                      if ( a.second.idChain.empty() ) {
     580//                                              a.second.idChain = cur->second.idChain;
     581//                                              a.second.idChain.push_back( curDecl->get_uniqueId() );
     582//                                      }
     583//                              }
     584
     585//                              Expression *varExpr = data.combine( newerAlt.cvtCost );
     586//                              delete varExpr->get_result();
     587//                              varExpr->set_result( adjType->clone() );
     588//                              PRINT(
     589//                                      std::cerr << "satisfying assertion " << curDecl->get_uniqueId() << " ";
     590//                                      curDecl->print( std::cerr );
     591//                                      std::cerr << " with declaration " << candidate->get_uniqueId() << " ";
     592//                                      candidate->print( std::cerr );
     593//                                      std::cerr << std::endl;
     594//                              )
     595//                              // follow the current assertion's ID chain to find the correct set of inferred parameters to add the candidate to (i.e. the set of inferred parameters belonging to the entity which requested the assertion parameter).
     596//                              InferredParams * inferParameters = &newerAlt.expr->get_inferParams();
     597//                              for ( UniqueId id : cur->second.idChain ) {
     598//                                      inferParameters = (*inferParameters)[ id ].inferParams.get();
     599//                              }
     600//                              // XXX: this is a memory leak, but adjType can't be deleted because it might contain assertions
     601//                              (*inferParameters)[ curDecl->get_uniqueId() ] = ParamEntry( candidate->get_uniqueId(), adjType->clone(), curDecl->get_type()->clone(), varExpr );
     602//                              inferRecursive( begin, end, newerAlt, newOpenVars, newDecls, newerNeed, level, indexer, out );
     603//                      } else {
     604//                              delete adjType;
     605//                      }
     606//              }
     607//      }
    599608
    600609        template< typename OutputIterator >
    601         void AlternativeFinder::Finder::inferParameters( const AssertionSet &need, AssertionSet &have, const Alternative &newAlt, OpenVarSet &openVars, OutputIterator out ) {
    602 //      PRINT(
    603 //          std::cerr << "inferParameters: assertions needed are" << std::endl;
    604 //          printAll( need, std::cerr, 8 );
    605 //          )
    606                 SymTab::Indexer decls( indexer );
     610        void AlternativeFinder::Finder::inferParameters( const AssertionSet &, AssertionSet &, const Alternative &newAlt, OpenVarSet &, OutputIterator out ) {
     611                // SymTab::Indexer decls( indexer );
     612                // addToIndexer( have, decls );
     613                // AssertionSet newNeed;
    607614                // PRINT(
    608                 //      std::cerr << "============= original indexer" << std::endl;
    609                 //      indexer.print( std::cerr );
    610                 //      std::cerr << "============= new indexer" << std::endl;
    611                 //      decls.print( std::cerr );
     615                //      std::cerr << "env is: " << std::endl;
     616                //      newAlt.env.print( std::cerr, 0 );
     617                //      std::cerr << std::endl;
    612618                // )
    613                 addToIndexer( have, decls );
    614                 AssertionSet newNeed;
    615                 PRINT(
    616                         std::cerr << "env is: " << std::endl;
    617                         newAlt.env.print( std::cerr, 0 );
    618                         std::cerr << std::endl;
    619                 )
    620 
    621                 inferRecursive( need.begin(), need.end(), newAlt, openVars, decls, newNeed, 0, indexer, out );
    622 //      PRINT(
    623 //          std::cerr << "declaration 14 is ";
    624 //          Declaration::declFromId
    625 //          *out++ = newAlt;
    626 //          )
     619
     620                // inferRecursive( need.begin(), need.end(), newAlt, openVars, decls, newNeed, 0, indexer, out );
     621
     622                // add to output list, assertion resolution is defered
     623                *out++ = newAlt;
    627624        }
    628625
     
    965962                }
    966963                // build and validate new alternative
    967                 Alternative newAlt( appExpr, result.env, cost );
     964                Alternative newAlt{
     965                        appExpr, result.env, result.openVars,
     966                        AssertionList( result.need.begin(), result.need.end() ), cost };
    968967                PRINT(
    969968                        std::cerr << "instantiate function success: " << appExpr << std::endl;
     
    12481247                        if ( isLvalue( alt.expr ) ) {
    12491248                                alternatives.push_back(
    1250                                         Alternative{ new AddressExpr( alt.expr->clone() ), alt.env, alt.cost } );
     1249                                        Alternative{ alt, new AddressExpr( alt.expr->clone() ), alt.cost } );
    12511250                        } // if
    12521251                } // for
     
    12541253
    12551254        void AlternativeFinder::Finder::postvisit( LabelAddressExpr * expr ) {
    1256                 alternatives.push_back( Alternative{ expr->clone(), env, Cost::zero } );
     1255                alternatives.push_back( Alternative{ expr->clone(), env } );
    12571256        }
    12581257
     
    12991298                AltList candidates;
    13001299                for ( Alternative & alt : finder.alternatives ) {
    1301                         AssertionSet needAssertions, haveAssertions;
    1302                         OpenVarSet openVars;
     1300                        AssertionSet needAssertions( alt.need.begin(), alt.need.end() );
     1301                        AssertionSet haveAssertions;
     1302                        OpenVarSet openVars{ alt.openVars };
    13031303
    13041304                        alt.env.extractOpenVars( openVars );
     
    13281328                                // count one safe conversion for each value that is thrown away
    13291329                                thisCost.incSafe( discardedValues );
    1330                                 Alternative newAlt( restructureCast( alt.expr->clone(), toType, castExpr->isGenerated ), alt.env,
    1331                                         alt.cost, thisCost );
     1330                                Alternative newAlt{
     1331                                        restructureCast( alt.expr->clone(), toType, castExpr->isGenerated ),
     1332                                        alt.env, openVars,
     1333                                        AssertionList( needAssertions.begin(), needAssertions.end() ), alt.cost,
     1334                                        thisCost };
    13321335                                inferParameters( needAssertions, haveAssertions, newAlt, openVars,
    13331336                                        back_inserter( candidates ) );
     
    13441347
    13451348        void AlternativeFinder::Finder::postvisit( VirtualCastExpr * castExpr ) {
    1346                 assertf( castExpr->get_result(), "Implicate virtual cast targets not yet supported." );
     1349                assertf( castExpr->get_result(), "Implicit virtual cast targets not yet supported." );
    13471350                AlternativeFinder finder( indexer, env );
    13481351                // don't prune here, since it's guaranteed all alternatives will have the same type
    13491352                finder.findWithoutPrune( castExpr->get_arg() );
    13501353                for ( Alternative & alt : finder.alternatives ) {
    1351                         alternatives.push_back( Alternative(
    1352                                 new VirtualCastExpr( alt.expr->clone(), castExpr->get_result()->clone() ),
    1353                                 alt.env, alt.cost ) );
     1354                        alternatives.push_back( Alternative{
     1355                                alt, new VirtualCastExpr{ alt.expr->clone(), castExpr->get_result()->clone() },
     1356                                alt.cost } );
    13541357                }
    13551358        }
     
    13761379                        // find member of the given type
    13771380                        if ( StructInstType *structInst = dynamic_cast< StructInstType* >( aggrExpr->get_result() ) ) {
    1378                                 addAggMembers( structInst, aggrExpr, cost, agg->env, get_member_name(memberExpr) );
     1381                                addAggMembers( structInst, aggrExpr, *agg, cost, get_member_name(memberExpr) );
    13791382                        } else if ( UnionInstType *unionInst = dynamic_cast< UnionInstType* >( aggrExpr->get_result() ) ) {
    1380                                 addAggMembers( unionInst, aggrExpr, cost, agg->env, get_member_name(memberExpr) );
     1383                                addAggMembers( unionInst, aggrExpr, *agg, cost, get_member_name(memberExpr) );
    13811384                        } else if ( TupleType * tupleType = dynamic_cast< TupleType * >( aggrExpr->get_result() ) ) {
    1382                                 addTupleMembers( tupleType, aggrExpr, cost, agg->env, memberExpr->get_member() );
     1385                                addTupleMembers( tupleType, aggrExpr, *agg, cost, memberExpr->get_member() );
    13831386                        } // if
    13841387                } // for
     
    13861389
    13871390        void AlternativeFinder::Finder::postvisit( MemberExpr *memberExpr ) {
    1388                 alternatives.push_back( Alternative( memberExpr->clone(), env, Cost::zero ) );
     1391                alternatives.push_back( Alternative{ memberExpr->clone(), env } );
    13891392        }
    13901393
     
    13991402                        // addAnonAlternatives uses vector::push_back, which invalidates references to existing elements, so
    14001403                        // can't construct in place and use vector::back
    1401                         Alternative newAlt( newExpr, env, Cost::zero, cost );
     1404                        Alternative newAlt{ newExpr, env, OpenVarSet{}, AssertionList{}, Cost::zero, cost };
    14021405                        PRINT(
    14031406                                std::cerr << "decl is ";
     
    14171420                // not sufficient to clone here, because variable's type may have changed
    14181421                // since the VariableExpr was originally created.
    1419                 alternatives.push_back( Alternative( new VariableExpr( variableExpr->var ), env, Cost::zero ) );
     1422                alternatives.push_back( Alternative{ new VariableExpr{ variableExpr->var }, env } );
    14201423        }
    14211424
    14221425        void AlternativeFinder::Finder::postvisit( ConstantExpr *constantExpr ) {
    1423                 alternatives.push_back( Alternative( constantExpr->clone(), env, Cost::zero ) );
     1426                alternatives.push_back( Alternative{ constantExpr->clone(), env } );
    14241427        }
    14251428
     
    14271430                if ( sizeofExpr->get_isType() ) {
    14281431                        Type * newType = sizeofExpr->get_type()->clone();
    1429                         alternatives.push_back( Alternative( new SizeofExpr( resolveTypeof( newType, indexer ) ), env, Cost::zero ) );
     1432                        alternatives.push_back( Alternative{
     1433                                new SizeofExpr{ resolveTypeof( newType, indexer ) }, env } );
    14301434                } else {
    14311435                        // find all alternatives for the argument to sizeof
     
    14411445                        Alternative &choice = winners.front();
    14421446                        referenceToRvalueConversion( choice.expr, choice.cost );
    1443                         alternatives.push_back( Alternative( new SizeofExpr( choice.expr->clone() ), choice.env, Cost::zero ) );
     1447                        alternatives.push_back( Alternative{
     1448                                choice, new SizeofExpr( choice.expr->clone() ), Cost::zero } );
    14441449                } // if
    14451450        }
     
    14481453                if ( alignofExpr->get_isType() ) {
    14491454                        Type * newType = alignofExpr->get_type()->clone();
    1450                         alternatives.push_back( Alternative( new AlignofExpr( resolveTypeof( newType, indexer ) ), env, Cost::zero ) );
     1455                        alternatives.push_back( Alternative{
     1456                                new AlignofExpr{ resolveTypeof( newType, indexer ) }, env } );
    14511457                } else {
    14521458                        // find all alternatives for the argument to sizeof
     
    14621468                        Alternative &choice = winners.front();
    14631469                        referenceToRvalueConversion( choice.expr, choice.cost );
    1464                         alternatives.push_back( Alternative( new AlignofExpr( choice.expr->clone() ), choice.env, Cost::zero ) );
     1470                        alternatives.push_back( Alternative{
     1471                                choice, new AlignofExpr{ choice.expr->clone() }, Cost::zero } );
    14651472                } // if
    14661473        }
     
    14721479                for ( std::list< Declaration* >::const_iterator i = members.begin(); i != members.end(); ++i ) {
    14731480                        if ( DeclarationWithType *dwt = dynamic_cast< DeclarationWithType* >( *i ) ) {
    1474                                 alternatives.push_back( Alternative( new OffsetofExpr( aggInst->clone(), dwt ), env, Cost::zero ) );
     1481                                alternatives.push_back( Alternative{
     1482                                        new OffsetofExpr{ aggInst->clone(), dwt }, env } );
    14751483                                renameTypes( alternatives.back().expr );
    14761484                        } else {
     
    14911499
    14921500        void AlternativeFinder::Finder::postvisit( OffsetofExpr *offsetofExpr ) {
    1493                 alternatives.push_back( Alternative( offsetofExpr->clone(), env, Cost::zero ) );
     1501                alternatives.push_back( Alternative{ offsetofExpr->clone(), env } );
    14941502        }
    14951503
    14961504        void AlternativeFinder::Finder::postvisit( OffsetPackExpr *offsetPackExpr ) {
    1497                 alternatives.push_back( Alternative( offsetPackExpr->clone(), env, Cost::zero ) );
     1505                alternatives.push_back( Alternative{ offsetPackExpr->clone(), env } );
    14981506        }
    14991507
     
    15151523                                Cost cost = Cost::zero;
    15161524                                Expression * newExpr = data.combine( cost );
    1517                                 alternatives.push_back( Alternative( new AttrExpr( newExpr, argType->clone() ), env, Cost::zero, cost ) );
     1525                                alternatives.push_back( Alternative{
     1526                                        new AttrExpr{ newExpr, argType->clone() }, env, OpenVarSet{}, AssertionList{}, 
     1527                                        Cost::zero, cost } );
    15181528                                for ( DeclarationWithType * retVal : function->returnVals ) {
    15191529                                        alternatives.back().expr->result = retVal->get_type()->clone();
     
    15541564                                Cost cost = Cost::zero;
    15551565                                Expression * newExpr = data.combine( cost );
    1556                                 alternatives.push_back( Alternative( newExpr, env, Cost::zero, cost ) );
     1566                                alternatives.push_back( Alternative{
     1567                                        newExpr, env, OpenVarSet{}, AssertionList{}, Cost::zero, cost } );
    15571568                                renameTypes( alternatives.back().expr );
    15581569                        } // for
     
    15691580                for ( const Alternative & first : firstFinder.alternatives ) {
    15701581                        for ( const Alternative & second : secondFinder.alternatives ) {
    1571                                 TypeEnvironment compositeEnv;
    1572                                 compositeEnv.simpleCombine( first.env );
     1582                                TypeEnvironment compositeEnv{ first.env };
    15731583                                compositeEnv.simpleCombine( second.env );
    1574 
    1575                                 LogicalExpr *newExpr = new LogicalExpr( first.expr->clone(), second.expr->clone(), logicalExpr->get_isAnd() );
    1576                                 alternatives.push_back( Alternative( newExpr, compositeEnv, first.cost + second.cost ) );
     1584                                OpenVarSet openVars{ first.openVars };
     1585                                mergeOpenVars( openVars, second.openVars );
     1586                                AssertionList need{ first.need };
     1587                                need.insert( need.end(), second.need.begin(), second.need.end() );
     1588
     1589                                LogicalExpr *newExpr = new LogicalExpr{
     1590                                        first.expr->clone(), second.expr->clone(), logicalExpr->get_isAnd() };
     1591                                alternatives.push_back( Alternative{
     1592                                        newExpr, compositeEnv, openVars, need, first.cost + second.cost } );
    15771593                        }
    15781594                }
     
    15951611                        for ( const Alternative & second : secondFinder.alternatives ) {
    15961612                                for ( const Alternative & third : thirdFinder.alternatives ) {
    1597                                         TypeEnvironment compositeEnv;
    1598                                         compositeEnv.simpleCombine( first.env );
     1613                                        TypeEnvironment compositeEnv{ first.env };
    15991614                                        compositeEnv.simpleCombine( second.env );
    16001615                                        compositeEnv.simpleCombine( third.env );
    1601 
     1616                                        OpenVarSet openVars{ first.openVars };
     1617                                        mergeOpenVars( openVars, second.openVars );
     1618                                        mergeOpenVars( openVars, third.openVars );
     1619                                        AssertionSet needAssertions( first.need.begin(), first.need.end() );
     1620                                        needAssertions.insert( second.need.begin(), second.need.end() );
     1621                                        needAssertions.insert( third.need.begin(), third.need.end() );
     1622                                        AssertionSet haveAssertions;
     1623                                       
    16021624                                        // unify true and false types, then infer parameters to produce new alternatives
    1603                                         OpenVarSet openVars;
    1604                                         AssertionSet needAssertions, haveAssertions;
    1605                                         Alternative newAlt( 0, compositeEnv, first.cost + second.cost + third.cost );
    16061625                                        Type* commonType = nullptr;
    1607                                         if ( unify( second.expr->result, third.expr->result, newAlt.env, needAssertions, haveAssertions, openVars, indexer, commonType ) ) {
    1608                                                 ConditionalExpr *newExpr = new ConditionalExpr( first.expr->clone(), second.expr->clone(), third.expr->clone() );
     1626                                        if ( unify( second.expr->result, third.expr->result, compositeEnv,
     1627                                                        needAssertions, haveAssertions, openVars, indexer, commonType ) ) {
     1628                                                ConditionalExpr *newExpr = new ConditionalExpr{
     1629                                                        first.expr->clone(), second.expr->clone(), third.expr->clone() };
    16091630                                                newExpr->result = commonType ? commonType : second.expr->result->clone();
    16101631                                                // convert both options to the conditional result type
    1611                                                 newAlt.cost += computeExpressionConversionCost( newExpr->arg2, newExpr->result, indexer, newAlt.env );
    1612                                                 newAlt.cost += computeExpressionConversionCost( newExpr->arg3, newExpr->result, indexer, newAlt.env );
    1613                                                 newAlt.expr = newExpr;
     1632                                                Cost cost = first.cost + second.cost + third.cost;
     1633                                                cost += computeExpressionConversionCost(
     1634                                                        newExpr->arg2, newExpr->result, indexer, compositeEnv );
     1635                                                cost += computeExpressionConversionCost(
     1636                                                        newExpr->arg3, newExpr->result, indexer, compositeEnv );
     1637                                                // output alternative
     1638                                                Alternative newAlt{
     1639                                                        newExpr, compositeEnv, openVars,
     1640                                                        AssertionList( needAssertions.begin(), needAssertions.end() ), cost };
    16141641                                                inferParameters( needAssertions, haveAssertions, newAlt, openVars, back_inserter( alternatives ) );
    16151642                                        } // if
     
    16251652                secondFinder.findWithAdjustment( commaExpr->get_arg2() );
    16261653                for ( const Alternative & alt : secondFinder.alternatives ) {
    1627                         alternatives.push_back( Alternative( new CommaExpr( newFirstArg->clone(), alt.expr->clone() ), alt.env, alt.cost ) );
     1654                        alternatives.push_back( Alternative{
     1655                                alt, new CommaExpr{ newFirstArg->clone(), alt.expr->clone() }, alt.cost } );
    16281656                } // for
    16291657                delete newFirstArg;
     
    16401668                for ( const Alternative & first : firstFinder.alternatives ) {
    16411669                        for ( const Alternative & second : secondFinder.alternatives ) {
    1642                                 TypeEnvironment compositeEnv;
    1643                                 compositeEnv.simpleCombine( first.env );
     1670                                TypeEnvironment compositeEnv{ first.env };
    16441671                                compositeEnv.simpleCombine( second.env );
    1645                                 OpenVarSet openVars;
    1646                                 AssertionSet needAssertions, haveAssertions;
    1647                                 Alternative newAlt( 0, compositeEnv, first.cost + second.cost );
     1672                                OpenVarSet openVars{ first.openVars };
     1673                                mergeOpenVars( openVars, second.openVars );
     1674                                AssertionSet needAssertions( first.need.begin(), first.need.end() );
     1675                                needAssertions.insert( second.need.begin(), second.need.end() );
     1676                                AssertionSet haveAssertions;
     1677
    16481678                                Type* commonType = nullptr;
    1649                                 if ( unify( first.expr->result, second.expr->result, newAlt.env, needAssertions, haveAssertions, openVars, indexer, commonType ) ) {
    1650                                         RangeExpr * newExpr = new RangeExpr( first.expr->clone(), second.expr->clone() );
     1679                                if ( unify( first.expr->result, second.expr->result, compositeEnv, needAssertions,
     1680                                                haveAssertions, openVars, indexer, commonType ) ) {
     1681                                        RangeExpr * newExpr =
     1682                                                new RangeExpr{ first.expr->clone(), second.expr->clone() };
    16511683                                        newExpr->result = commonType ? commonType : first.expr->result->clone();
    1652                                         newAlt.expr = newExpr;
     1684                                        Alternative newAlt{
     1685                                                newExpr, compositeEnv, openVars,
     1686                                                AssertionList( needAssertions.begin(), needAssertions.end() ),
     1687                                                first.cost + second.cost };
    16531688                                        inferParameters( needAssertions, haveAssertions, newAlt, openVars, back_inserter( alternatives ) );
    16541689                                } // if
     
    16691704
    16701705                        TypeEnvironment compositeEnv;
    1671                         simpleCombineEnvironments( alts.begin(), alts.end(), compositeEnv );
    1672                         alternatives.push_back(
    1673                                 Alternative{ new TupleExpr( exprs ), compositeEnv, sumCost( alts ) } );
     1706                        OpenVarSet openVars;
     1707                        AssertionSet need;
     1708                        for ( const Alternative& alt : alts ) {
     1709                                compositeEnv.simpleCombine( alt.env );
     1710                                mergeOpenVars( openVars, alt.openVars );
     1711                                need.insert( alt.need.begin(), alt.need.end() );
     1712                        }
     1713                       
     1714                        alternatives.push_back( Alternative{
     1715                                new TupleExpr{ exprs }, compositeEnv, openVars,
     1716                                AssertionList( need.begin(), need.end() ), sumCost( alts ) } );
    16741717                } // for
    16751718        }
    16761719
    16771720        void AlternativeFinder::Finder::postvisit( TupleExpr *tupleExpr ) {
    1678                 alternatives.push_back( Alternative( tupleExpr->clone(), env, Cost::zero ) );
     1721                alternatives.push_back( Alternative{ tupleExpr->clone(), env } );
    16791722        }
    16801723
    16811724        void AlternativeFinder::Finder::postvisit( ImplicitCopyCtorExpr * impCpCtorExpr ) {
    1682                 alternatives.push_back( Alternative( impCpCtorExpr->clone(), env, Cost::zero ) );
     1725                alternatives.push_back( Alternative{ impCpCtorExpr->clone(), env } );
    16831726        }
    16841727
     
    16891732                finder.findWithoutPrune( ctorExpr->get_callExpr() );
    16901733                for ( Alternative & alt : finder.alternatives ) {
    1691                         alternatives.push_back( Alternative( new ConstructorExpr( alt.expr->clone() ), alt.env, alt.cost ) );
     1734                        alternatives.push_back( Alternative{
     1735                                alt, new ConstructorExpr( alt.expr->clone() ), alt.cost } );
    16921736                }
    16931737        }
    16941738
    16951739        void AlternativeFinder::Finder::postvisit( TupleIndexExpr *tupleExpr ) {
    1696                 alternatives.push_back( Alternative( tupleExpr->clone(), env, Cost::zero ) );
     1740                alternatives.push_back( Alternative{ tupleExpr->clone(), env } );
    16971741        }
    16981742
    16991743        void AlternativeFinder::Finder::postvisit( TupleAssignExpr *tupleAssignExpr ) {
    1700                 alternatives.push_back( Alternative( tupleAssignExpr->clone(), env, Cost::zero ) );
     1744                alternatives.push_back( Alternative{ tupleAssignExpr->clone(), env } );
    17011745        }
    17021746
     
    17071751                        // ensure that the id is passed on to the UniqueExpr alternative so that the expressions are "linked"
    17081752                        UniqueExpr * newUnqExpr = new UniqueExpr( alt.expr->clone(), unqExpr->get_id() );
    1709                         alternatives.push_back( Alternative( newUnqExpr, alt.env, alt.cost ) );
     1753                        alternatives.push_back( Alternative{ alt, newUnqExpr, alt.cost } );
    17101754                }
    17111755        }
     
    17151759                ResolvExpr::resolveStmtExpr( newStmtExpr, indexer );
    17161760                // xxx - this env is almost certainly wrong, and needs to somehow contain the combined environments from all of the statements in the stmtExpr...
    1717                 alternatives.push_back( Alternative( newStmtExpr, env, Cost::zero ) );
     1761                alternatives.push_back( Alternative{ newStmtExpr, env } );
    17181762        }
    17191763
     
    17371781                        for ( Alternative & alt : finder.get_alternatives() ) {
    17381782                                TypeEnvironment newEnv( alt.env );
    1739                                 AssertionSet needAssertions, haveAssertions;
    1740                                 OpenVarSet openVars;  // find things in env that don't have a "representative type" and claim those are open vars?
     1783                                AssertionSet needAssertions( alt.need.begin(), alt.need.end() );
     1784                                AssertionSet haveAssertions;
     1785                                OpenVarSet openVars( alt.openVars ); 
     1786                                // xxx - find things in env that don't have a "representative type" and claim
     1787                                // those are open vars?
    17411788                                PRINT(
    17421789                                        std::cerr << "  @ " << toType << " " << initAlt.designation << std::endl;
    17431790                                )
    1744                                 // It's possible that a cast can throw away some values in a multiply-valued expression.  (An example is a
    1745                                 // cast-to-void, which casts from one value to zero.)  Figure out the prefix of the subexpression results
    1746                                 // that are cast directly.  The candidate is invalid if it has fewer results than there are types to cast
    1747                                 // to.
     1791                                // It's possible that a cast can throw away some values in a multiply-valued
     1792                                // expression. (An example is a cast-to-void, which casts from one value to
     1793                                // zero.)  Figure out the prefix of the subexpression results that are cast
     1794                                // directly.  The candidate is invalid if it has fewer results than there are
     1795                                // types to cast to.
    17481796                                int discardedValues = alt.expr->result->size() - toType->size();
    17491797                                if ( discardedValues < 0 ) continue;
    1750                                 // xxx - may need to go into tuple types and extract relevant types and use unifyList. Note that currently, this does not
    1751                                 // allow casting a tuple to an atomic type (e.g. (int)([1, 2, 3]))
     1798                                // xxx - may need to go into tuple types and extract relevant types and use
     1799                                // unifyList. Note that currently, this does not allow casting a tuple to an
     1800                                // atomic type (e.g. (int)([1, 2, 3]))
     1801                               
    17521802                                // unification run for side-effects
    1753                                 unify( toType, alt.expr->result, newEnv, needAssertions, haveAssertions, openVars, indexer ); // xxx - do some inspecting on this line... why isn't result bound to initAlt.type??
     1803                                unify( toType, alt.expr->result, newEnv, needAssertions, haveAssertions, openVars,
     1804                                        indexer );
     1805                                // xxx - do some inspecting on this line... why isn't result bound to initAlt.type?
    17541806
    17551807                                Cost thisCost = castCost( alt.expr->result, toType, indexer, newEnv );
     
    17571809                                        // count one safe conversion for each value that is thrown away
    17581810                                        thisCost.incSafe( discardedValues );
    1759                                         Alternative newAlt( new InitExpr( restructureCast( alt.expr->clone(), toType, true ), initAlt.designation->clone() ), newEnv, alt.cost, thisCost );
     1811                                        Alternative newAlt{
     1812                                                new InitExpr{
     1813                                                        restructureCast( alt.expr->clone(), toType, true ), initAlt.designation->clone() },
     1814                                                newEnv, openVars,
     1815                                                AssertionList( needAssertions.begin(), needAssertions.end() ),
     1816                                                alt.cost, thisCost };
    17601817                                        inferParameters( needAssertions, haveAssertions, newAlt, openVars, back_inserter( candidates ) );
    17611818                                }
Note: See TracChangeset for help on using the changeset viewer.