Ignore:
Timestamp:
May 25, 2018, 2:51:06 PM (6 years ago)
Author:
Aaron Moss <a3moss@…>
Branches:
new-env, with_gc
Children:
cdc4d43
Parents:
3ef35bd (diff), 58e822a (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the (diff) links above to see all the changes relative to each parent.
Message:

Merge remote-tracking branch 'origin/master' into with_gc

File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/ResolvExpr/Resolver.cc

    r3ef35bd reba74ba  
    128128
    129129        namespace {
    130                 void finishExpr( Expression *expr, const TypeEnvironment &env, TypeSubstitution * oldenv = nullptr ) {
     130                struct StripCasts {
     131                        Expression * postmutate( CastExpr * castExpr ) {
     132                                if ( castExpr->isGenerated && ResolvExpr::typesCompatible( castExpr->arg->result, castExpr->result, SymTab::Indexer() ) ) {
     133                                        // generated cast is to the same type as its argument, so it's unnecessary -- remove it
     134                                        Expression * expr = castExpr->arg;
     135                                        castExpr->arg = nullptr;
     136                                        std::swap( expr->env, castExpr->env );
     137                                        return expr;
     138                                }
     139                                return castExpr;
     140                        }
     141
     142                        static void strip( Expression *& expr ) {
     143                                PassVisitor<StripCasts> stripper;
     144                                expr = expr->acceptMutator( stripper );
     145                        }
     146                };
     147
     148                void finishExpr( Expression *&expr, const TypeEnvironment &env, TypeSubstitution * oldenv = nullptr ) {
    131149                        expr->env = oldenv ? oldenv->clone() : new TypeSubstitution;
    132                         env.makeSubstitution( *expr->get_env() );
     150                        env.makeSubstitution( *expr->env );
     151                        StripCasts::strip( expr ); // remove unnecessary casts that may be buried in an expression
    133152                }
    134153
     
    178197                        findMinCost( candidates.begin(), candidates.end(), back_inserter( winners ) );
    179198                        if ( winners.size() == 0 ) {
    180                                 SemanticError( untyped, toString(
    181                                         "No reasonable alternatives for ", kindStr, (kindStr != "" ? " " : ""),
    182                                         "expression: ") );
     199                                SemanticError( untyped, toString( "No reasonable alternatives for ", kindStr, (kindStr != "" ? " " : ""), "expression: ") );
    183200                        } else if ( winners.size() != 1 ) {
    184201                                std::ostringstream stream;
    185                                 stream << "Cannot choose between " << winners.size() << " alternatives for "
    186                                         << kindStr << (kindStr != "" ? " " : "") << "expression\n";
     202                                stream << "Cannot choose between " << winners.size() << " alternatives for " << kindStr << (kindStr != "" ? " " : "") << "expression\n";
    187203                                untyped->print( stream );
    188204                                stream << " Alternatives are:\n";
    189205                                printAlts( winners, stream, 1 );
    190                                
    191206                                SemanticError( untyped->location, stream.str() );
    192207                        }
     
    196211                        if ( findDeletedExpr( choice.expr ) ) {
    197212                                trace( choice.expr );
    198                                 SemanticError( choice.expr,
    199                                         "Unique best alternative includes deleted identifier in " );
     213                                SemanticError( choice.expr, "Unique best alternative includes deleted identifier in " );
    200214                        }
    201215                        alt = std::move( choice );
     
    416430
    417431        void Resolver::previsit( CaseStmt *caseStmt ) {
    418                 if ( caseStmt->get_condition() ) {
     432                if ( caseStmt->condition ) {
    419433                        std::list< InitAlternative > initAlts = currentObject.getOptions();
    420434                        assertf( initAlts.size() == 1, "SwitchStmt did not correctly resolve an integral expression." );
     
    422436                        Expression * newExpr = new CastExpr( caseStmt->condition, initAlts.front().type->clone() );
    423437                        findSingleExpression( newExpr, indexer );
    424                         CastExpr * castExpr = strict_dynamic_cast< CastExpr * >( newExpr );
    425                         caseStmt->condition = castExpr->arg;
    426                         castExpr->arg = nullptr;
     438                        // case condition cannot have a cast in C, so it must be removed, regardless of whether it performs a conversion.
     439                        // Ideally we would perform the conversion internally here.
     440                        if ( CastExpr * castExpr = dynamic_cast< CastExpr * >( newExpr ) ) {
     441                                newExpr = castExpr->arg;
     442                                castExpr->arg = nullptr;
     443                                std::swap( newExpr->env, castExpr->env );
     444                        }
     445                        caseStmt->condition = newExpr;
    427446                }
    428447        }
     
    719738                initExpr->expr = nullptr;
    720739                std::swap( initExpr->env, newExpr->env );
    721                 std::swap( initExpr->inferParams, newExpr->inferParams ) ;
     740                // InitExpr may have inferParams in the case where the expression specializes a function pointer,
     741                // and newExpr may already have inferParams of its own, so a simple swap is not sufficient.
     742                newExpr->spliceInferParams( initExpr );
    722743
    723744                // get the actual object's type (may not exactly match what comes back from the resolver due to conversions)
Note: See TracChangeset for help on using the changeset viewer.