Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/ResolvExpr/Resolver.cc

    r0a60c04 r36982fc  
    2626#include "Common/utility.h"              // for ValueGuard, group_iterate
    2727#include "CurrentObject.h"               // for CurrentObject
    28 #include "InitTweak/GenInit.h"
    2928#include "InitTweak/InitTweak.h"         // for isIntrinsicSingleArgCallStmt
    3029#include "RenameVars.h"                  // for RenameVars, global_renamer
     
    4140#include "SynTree/TypeSubstitution.h"    // for TypeSubstitution
    4241#include "SynTree/Visitor.h"             // for acceptAll, maybeAccept
    43 #include "Tuples/Tuples.h"
    4442#include "typeops.h"                     // for extractResultType
    4543#include "Unify.h"                       // for unify
     
    4846
    4947namespace ResolvExpr {
    50         struct Resolver final : public WithIndexer, public WithGuards, public WithVisitorRef<Resolver>, public WithShortCircuiting, public WithStmtsToAdd {
     48        struct Resolver final : public WithIndexer, public WithGuards, public WithVisitorRef<Resolver>, public WithShortCircuiting {
    5149                Resolver() {}
    5250                Resolver( const SymTab::Indexer & other ) {
     
    7674                void previsit( CatchStmt *catchStmt );
    7775                void previsit( WaitForStmt * stmt );
    78                 void previsit( WithStmt * withStmt );
    7976
    8077                void previsit( SingleInit *singleInit );
     
    574571        }
    575572
    576         bool isStructOrUnion( Type * t ) {
    577                 t = t->stripReferences();
    578                 return dynamic_cast< StructInstType * >( t ) || dynamic_cast< UnionInstType * >( t );
    579         }
    580 
    581         void Resolver::previsit( WithStmt * withStmt ) {
    582                 for ( Expression *& expr : withStmt->exprs )  {
    583                         TypeEnvironment env;
    584                         AlternativeFinder finder( indexer, env );
    585                         finder.findWithAdjustment( expr );
    586 
    587                         // only struct- and union-typed expressions are viable candidates
    588                         AltList candidates;
    589                         for ( Alternative & alt : finder.get_alternatives() ) {
    590                                 if ( isStructOrUnion( alt.expr->result ) ) {
    591                                         candidates.push_back( std::move( alt ) );
    592                                 }
    593                         }
    594 
    595                         // choose the lowest cost expression among the candidates
    596                         AltList winners;
    597                         findMinCost( candidates.begin(), candidates.end(), back_inserter( winners ) );
    598                         if ( winners.size() == 0 ) {
    599                                 throw SemanticError( "No reasonable alternatives for with statement expression: ", expr );
    600                         } else if ( winners.size() != 1 ) {
    601                                 std::ostringstream stream;
    602                                 stream << "Cannot choose between " << winners.size() << " alternatives for with statement expression\n";
    603                                 expr->print( stream );
    604                                 stream << "Alternatives are:\n";
    605                                 printAlts( winners, stream, 1 );
    606                                 throw SemanticError( stream.str() );
    607                         }
    608 
    609                         // there is one unambiguous interpretation - move the expression into the with statement
    610                         Alternative & alt = winners.front();
    611                         finishExpr( alt.expr, alt.env, expr->env );
    612                         delete expr;
    613                         expr = alt.expr;
    614                         alt.expr = nullptr;
    615 
    616                         // if with expression might be impure, create a temporary so that it is evaluated once
    617                         if ( Tuples::maybeImpure( expr ) ) {
    618                                 static UniqueName tmpNamer( "_with_tmp_" );
    619                                 ObjectDecl * tmp = ObjectDecl::newObject( tmpNamer.newName(), expr->result->clone(), new SingleInit( expr ) );
    620                                 expr = new VariableExpr( tmp );
    621                                 stmtsToAddBefore.push_back( new DeclStmt( tmp ) );
    622                                 if ( InitTweak::isConstructable( tmp->type ) ) {
    623                                         // generate ctor/dtor and resolve them
    624                                         tmp->init = InitTweak::genCtorInit( tmp );
    625                                         tmp->accept( *visitor );
    626                                 }
    627                         }
    628                 }
    629         }
    630 
    631573        template< typename T >
    632574        bool isCharType( T t ) {
Note: See TracChangeset for help on using the changeset viewer.