Changeset 882ad37


Ignore:
Timestamp:
Dec 1, 2017, 2:54:30 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:
3ca540f
Parents:
d8893ca
Message:

Resolve WithStmt? exprs

File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/ResolvExpr/Resolver.cc

    rd8893ca r882ad37  
    7474                void previsit( CatchStmt *catchStmt );
    7575                void previsit( WaitForStmt * stmt );
     76                void previsit( WithStmt * withStmt );
    7677
    7778                void previsit( SingleInit *singleInit );
     
    571572        }
    572573
     574        bool isStructOrUnion( Type * t ) {
     575                t = t->stripReferences();
     576                return dynamic_cast< StructInstType * >( t ) || dynamic_cast< UnionInstType * >( t );
     577        }
     578
     579        void Resolver::previsit( WithStmt * withStmt ) {
     580                for ( Expression *& expr : withStmt->exprs )  {
     581                        TypeEnvironment env;
     582                        AlternativeFinder finder( indexer, env );
     583                        finder.findWithAdjustment( expr );
     584
     585                        // only struct- and union-typed expressions are viable candidates
     586                        AltList candidates;
     587                        for ( Alternative & alt : finder.get_alternatives() ) {
     588                                if ( isStructOrUnion( alt.expr->result ) ) {
     589                                        candidates.push_back( std::move( alt ) );
     590                                }
     591                        }
     592
     593                        // choose the lowest cost expression among the candidates
     594                        AltList winners;
     595                        findMinCost( candidates.begin(), candidates.end(), back_inserter( winners ) );
     596                        if ( winners.size() == 0 ) {
     597                                throw SemanticError( "No reasonable alternatives for with statement expression: ", expr );
     598                        } else if ( winners.size() != 1 ) {
     599                                std::ostringstream stream;
     600                                stream << "Cannot choose between " << winners.size() << " alternatives for with statement expression\n";
     601                                expr->print( stream );
     602                                stream << "Alternatives are:\n";
     603                                printAlts( winners, stream, 1 );
     604                                throw SemanticError( stream.str() );
     605                        }
     606
     607                        // there is one unambiguous interpretation - move the expression into the with statement
     608                        Alternative & alt = winners.front();
     609                        finishExpr( alt.expr, alt.env, expr->env );
     610                        delete expr;
     611                        expr = alt.expr;
     612                        alt.expr = nullptr;
     613                }
     614        }
     615
    573616        template< typename T >
    574617        bool isCharType( T t ) {
Note: See TracChangeset for help on using the changeset viewer.