Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/ResolvExpr/AlternativeFinder.cc

    r02cea2d rb6fe7e6  
    197197        }
    198198
    199         void AlternativeFinder::find( Expression *expr, bool adjust ) {
     199        void AlternativeFinder::find( Expression *expr, bool adjust, bool prune ) {
    200200                expr->accept( *this );
    201201                if ( alternatives.empty() ) {
     
    207207                        }
    208208                }
    209                 PRINT(
    210                         std::cerr << "alternatives before prune:" << std::endl;
    211                         printAlts( alternatives, std::cerr );
    212                 )
    213                 AltList::iterator oldBegin = alternatives.begin();
    214                 pruneAlternatives( alternatives.begin(), alternatives.end(), front_inserter( alternatives ), indexer );
    215                 if ( alternatives.begin() == oldBegin ) {
    216                         std::ostringstream stream;
    217                         stream << "Can't choose between alternatives for expression ";
    218                         expr->print( stream );
    219                         stream << "Alternatives are:";
    220                         AltList winners;
    221                         findMinCost( alternatives.begin(), alternatives.end(), back_inserter( winners ) );
    222                         printAlts( winners, stream, 8 );
    223                         throw SemanticError( stream.str() );
    224                 }
    225                 alternatives.erase( oldBegin, alternatives.end() );
    226                 PRINT(
    227                         std::cerr << "there are " << alternatives.size() << " alternatives after elimination" << std::endl;
    228                 )
     209                if ( prune ) {
     210                        PRINT(
     211                                std::cerr << "alternatives before prune:" << std::endl;
     212                                printAlts( alternatives, std::cerr );
     213                        )
     214                        AltList::iterator oldBegin = alternatives.begin();
     215                        pruneAlternatives( alternatives.begin(), alternatives.end(), front_inserter( alternatives ), indexer );
     216                        if ( alternatives.begin() == oldBegin ) {
     217                                std::ostringstream stream;
     218                                stream << "Can't choose between alternatives for expression ";
     219                                expr->print( stream );
     220                                stream << "Alternatives are:";
     221                                AltList winners;
     222                                findMinCost( alternatives.begin(), alternatives.end(), back_inserter( winners ) );
     223                                printAlts( winners, stream, 8 );
     224                                throw SemanticError( stream.str() );
     225                        }
     226                        alternatives.erase( oldBegin, alternatives.end() );
     227                        PRINT(
     228                                std::cerr << "there are " << alternatives.size() << " alternatives after elimination" << std::endl;
     229                        )
     230                }
    229231
    230232                // Central location to handle gcc extension keyword for all expression types.
     
    234236        }
    235237
    236         void AlternativeFinder::findWithAdjustment( Expression *expr ) {
    237                 find( expr, true );
     238        void AlternativeFinder::findWithAdjustment( Expression *expr, bool prune ) {
     239                find( expr, true, prune );
    238240        }
    239241
    240242        template< typename StructOrUnionType >
    241         void AlternativeFinder::addAggMembers( StructOrUnionType *aggInst, Expression *expr, const Cost &newCost, const std::string &name ) {
     243        void AlternativeFinder::addAggMembers( StructOrUnionType *aggInst, Expression *expr, const Cost &newCost, const TypeEnvironment & env, const std::string &name ) {
    242244                std::list< Declaration* > members;
    243245                aggInst->lookup( name, members );
     
    760762                        if ( agg->expr->get_results().size() == 1 ) {
    761763                                if ( StructInstType *structInst = dynamic_cast< StructInstType* >( agg->expr->get_results().front() ) ) {
    762                                         addAggMembers( structInst, agg->expr, agg->cost, memberExpr->get_member() );
     764                                        addAggMembers( structInst, agg->expr, agg->cost, agg->env, memberExpr->get_member() );
    763765                                } else if ( UnionInstType *unionInst = dynamic_cast< UnionInstType* >( agg->expr->get_results().front() ) ) {
    764                                         addAggMembers( unionInst, agg->expr, agg->cost, memberExpr->get_member() );
     766                                        addAggMembers( unionInst, agg->expr, agg->cost, agg->env, memberExpr->get_member() );
    765767                                } // if
    766768                        } // if
     
    789791                        renameTypes( alternatives.back().expr );
    790792                        if ( StructInstType *structInst = dynamic_cast< StructInstType* >( (*i)->get_type() ) ) {
    791                                 addAggMembers( structInst, &newExpr, Cost( 0, 0, 1 ), "" );
     793                                addAggMembers( structInst, &newExpr, Cost( 0, 0, 1 ), env, "" );
    792794                        } else if ( UnionInstType *unionInst = dynamic_cast< UnionInstType* >( (*i)->get_type() ) ) {
    793                                 addAggMembers( unionInst, &newExpr, Cost( 0, 0, 1 ), "" );
     795                                addAggMembers( unionInst, &newExpr, Cost( 0, 0, 1 ), env, "" );
    794796                        } // if
    795797                } // for
     
    10121014                alternatives.push_back( Alternative( impCpCtorExpr->clone(), env, Cost::zero ) );
    10131015        }
     1016
     1017        void AlternativeFinder::visit( ConstructorExpr * ctorExpr ) {
     1018                AlternativeFinder finder( indexer, env );
     1019                // don't prune here, since it's guaranteed all alternatives will have the same type
     1020                // (giving the alternatives different types is half of the point of ConstructorExpr nodes)
     1021                finder.findWithAdjustment( ctorExpr->get_callExpr(), false );
     1022                for ( Alternative & alt : finder.alternatives ) {
     1023                        alternatives.push_back( Alternative( new ConstructorExpr( alt.expr->clone() ), alt.env, alt.cost ) );
     1024                }
     1025        }
    10141026} // namespace ResolvExpr
    10151027
Note: See TracChangeset for help on using the changeset viewer.