Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/ResolvExpr/AlternativeFinder.cc

    rd286cf68 r982f95d  
    2121#include <list>                    // for _List_iterator, list, _List_const_...
    2222#include <map>                     // for _Rb_tree_iterator, map, _Rb_tree_c...
    23 #include <memory>                  // for allocator_traits<>::value_type, unique_ptr
     23#include <memory>                  // for allocator_traits<>::value_type
    2424#include <utility>                 // for pair
    2525#include <vector>                  // for vector
     
    3535#include "ResolveTypeof.h"         // for resolveTypeof
    3636#include "Resolver.h"              // for resolveStmtExpr
     37#include "Common/GC.h"             // for new_static_root
    3738#include "SymTab/Indexer.h"        // for Indexer
    3839#include "SymTab/Mangler.h"        // for Mangler
     
    9798                void postvisit( InitExpr * initExpr );
    9899                void postvisit( DeletedExpr * delExpr );
    99                 void postvisit( GenericExpr * genExpr );
    100100
    101101                /// Adds alternatives for anonymous members
     
    166166                                        candidate->env.apply( newType );
    167167                                        mangleName = SymTab::Mangler::mangle( newType );
    168                                         delete newType;
    169168                                }
    170169                                std::map< std::string, PruneStruct >::iterator mapPlace = selected.find( mangleName );
     
    176175                                                selected[ mangleName ] = current;
    177176                                        } else if ( candidate->cost == mapPlace->second.candidate->cost ) {
    178                                                 // if one of the candidates contains a deleted identifier, can pick the other, since
    179                                                 // deleted expressions should not be ambiguous if there is another option that is at least as good
    180                                                 if ( findDeletedExpr( candidate->expr ) ) {
    181                                                         // do nothing
    182                                                         PRINT( std::cerr << "candidate is deleted" << std::endl; )
    183                                                 } else if ( findDeletedExpr( mapPlace->second.candidate->expr ) ) {
    184                                                         PRINT( std::cerr << "current is deleted" << std::endl; )
    185                                                         selected[ mangleName ] = current;
    186                                                 } else {
    187                                                         PRINT(
    188                                                                 std::cerr << "marking ambiguous" << std::endl;
    189                                                         )
    190                                                         mapPlace->second.isAmbiguous = true;
    191                                                 }
     177                                                PRINT(
     178                                                        std::cerr << "marking ambiguous" << std::endl;
     179                                                )
     180                                                mapPlace->second.isAmbiguous = true;
    192181                                        } else {
    193182                                                PRINT(
     
    244233        }
    245234
    246         void AlternativeFinder::find( Expression *expr, bool adjust, bool prune, bool failFast ) {
     235        void AlternativeFinder::find( Expression *expr, ResolvMode mode ) {
    247236                PassVisitor<Finder> finder( *this );
    248237                expr->accept( finder );
    249                 if ( failFast && alternatives.empty() ) {
     238                if ( mode.failFast && alternatives.empty() ) {
    250239                        PRINT(
    251240                                std::cerr << "No reasonable alternatives for expression " << expr << std::endl;
     
    253242                        SemanticError( expr, "No reasonable alternatives for expression " );
    254243                }
    255                 if ( prune ) {
     244                if ( mode.prune ) {
    256245                        auto oldsize = alternatives.size();
    257246                        PRINT(
     
    261250                        AltList pruned;
    262251                        pruneAlternatives( alternatives.begin(), alternatives.end(), back_inserter( pruned ) );
    263                         if ( failFast && pruned.empty() ) {
     252                        if ( mode.failFast && pruned.empty() ) {
    264253                                std::ostringstream stream;
    265254                                AltList winners;
     
    280269                }
    281270                // adjust types after pruning so that types substituted by pruneAlternatives are correctly adjusted
    282                 for ( AltList::iterator i = alternatives.begin(); i != alternatives.end(); ++i ) {
    283                         if ( adjust ) {
    284                                 adjustExprType( i->expr->get_result(), i->env, indexer );
     271                if ( mode.adjust ) {
     272                        for ( Alternative& i : alternatives ) {
     273                                adjustExprType( i.expr->result, i.env, indexer );
    285274                        }
    286275                }
     
    294283
    295284        void AlternativeFinder::findWithAdjustment( Expression *expr ) {
    296                 find( expr, true );
     285                find( expr, ResolvMode::withAdjustment() );
    297286        }
    298287
    299288        void AlternativeFinder::findWithoutPrune( Expression * expr ) {
    300                 find( expr, true, false );
     289                find( expr, ResolvMode::withoutPrune() );
    301290        }
    302291
    303292        void AlternativeFinder::maybeFind( Expression * expr ) {
    304                 find( expr, true, true, false );
     293                find( expr, ResolvMode::withoutFailFast() );
    305294        }
    306295
     
    308297                // adds anonymous member interpretations whenever an aggregate value type is seen.
    309298                // it's okay for the aggregate expression to have reference type -- cast it to the base type to treat the aggregate as the referenced value
    310                 std::unique_ptr<Expression> aggrExpr( alt.expr->clone() );
    311                 alt.env.apply( aggrExpr->result );
    312                 Type * aggrType = aggrExpr->result;
     299                Expression* aggrExpr = alt.expr->clone();
     300                alt.env.apply( aggrExpr->get_result() );
     301                Type * aggrType = aggrExpr->get_result();
    313302                if ( dynamic_cast< ReferenceType * >( aggrType ) ) {
    314303                        aggrType = aggrType->stripReferences();
    315                         aggrExpr.reset( new CastExpr( aggrExpr.release(), aggrType->clone() ) );
    316                 }
    317 
    318                 if ( StructInstType *structInst = dynamic_cast< StructInstType* >( aggrExpr->result ) ) {
    319                         addAggMembers( structInst, aggrExpr.get(), alt.cost+Cost::safe, alt.env, "" );
    320                 } else if ( UnionInstType *unionInst = dynamic_cast< UnionInstType* >( aggrExpr->result ) ) {
    321                         addAggMembers( unionInst, aggrExpr.get(), alt.cost+Cost::safe, alt.env, "" );
     304                        aggrExpr = new CastExpr{ aggrExpr, aggrType->clone() };
     305                }
     306
     307                if ( StructInstType *structInst = dynamic_cast< StructInstType* >( aggrExpr->get_result() ) ) {
     308                        addAggMembers( structInst, aggrExpr, alt.cost+Cost::safe, alt.env, "" );
     309                } else if ( UnionInstType *unionInst = dynamic_cast< UnionInstType* >( aggrExpr->get_result() ) ) {
     310                        addAggMembers( unionInst, aggrExpr, alt.cost+Cost::safe, alt.env, "" );
    322311                } // if
    323312        }
     
    328317                aggInst->lookup( name, members );
    329318
    330                 for ( Declaration * decl : members ) {
    331                         if ( DeclarationWithType *dwt = dynamic_cast< DeclarationWithType* >( decl ) ) {
    332                                 // addAnonAlternatives uses vector::push_back, which invalidates references to existing elements, so
    333                                 // can't construct in place and use vector::back
    334                                 Alternative newAlt( new MemberExpr( dwt, expr->clone() ), env, newCost );
    335                                 renameTypes( newAlt.expr );
    336                                 addAnonConversions( newAlt ); // add anonymous member interpretations whenever an aggregate value type is seen as a member expression.
    337                                 alternatives.push_back( std::move(newAlt) );
     319                for ( std::list< Declaration* >::const_iterator i = members.begin(); i != members.end(); ++i ) {
     320                        if ( DeclarationWithType *dwt = dynamic_cast< DeclarationWithType* >( *i ) ) {
     321                                alternatives.push_back( Alternative( new MemberExpr( dwt, expr->clone() ), env, newCost ) );
     322                                renameTypes( alternatives.back().expr );
     323                                addAnonConversions( alternatives.back() ); // add anonymous member interpretations whenever an aggregate value type is seen as a member expression.
    338324                        } else {
    339325                                assert( false );
     
    345331                if ( ConstantExpr * constantExpr = dynamic_cast< ConstantExpr * >( member ) ) {
    346332                        // get the value of the constant expression as an int, must be between 0 and the length of the tuple type to have meaning
    347                         auto val = constantExpr->intValue();
     333                        // xxx - this should be improved by memoizing the value of constant exprs
     334                        // during parsing and reusing that information here.
     335                        std::stringstream ss( constantExpr->get_constant()->get_value() );
     336                        int val = 0;
    348337                        std::string tmp;
    349                         if ( val >= 0 && (unsigned long long)val < tupleType->size() ) {
    350                                 alternatives.push_back( Alternative( new TupleIndexExpr( expr->clone(), val ), env, newCost ) );
     338                        if ( ss >> val && ! (ss >> tmp) ) {
     339                                if ( val >= 0 && (unsigned int)val < tupleType->size() ) {
     340                                        alternatives.push_back( Alternative( new TupleIndexExpr( expr, val ), env, newCost ) );
     341                                } // if
    351342                        } // if
     343                } else if ( NameExpr * nameExpr = dynamic_cast< NameExpr * >( member ) ) {
     344                        // xxx - temporary hack until 0/1 are int constants
     345                        if ( nameExpr->get_name() == "0" || nameExpr->get_name() == "1" ) {
     346                                std::stringstream ss( nameExpr->get_name() );
     347                                int val;
     348                                ss >> val;
     349                                alternatives.push_back( Alternative( new TupleIndexExpr( expr, val ), env, newCost ) );
     350                        }
    352351                } // if
    353352        }
    354353
    355354        void AlternativeFinder::Finder::postvisit( ApplicationExpr *applicationExpr ) {
    356                 alternatives.push_back( Alternative( applicationExpr->clone(), env, Cost::zero ) );
     355                alternatives.push_back( Alternative( applicationExpr, env, Cost::zero ) );
    357356        }
    358357
     
    436435                                        return Cost::infinity;
    437436                                }
    438                         }
    439                         if ( DefaultArgExpr * def = dynamic_cast< DefaultArgExpr * >( *actualExpr ) ) {
    440                                 // default arguments should be free - don't include conversion cost.
    441                                 // Unwrap them here because they are not relevant to the rest of the system.
    442                                 *actualExpr = def->expr;
    443                                 ++formal;
    444                                 continue;
    445437                        }
    446438                        Type * formalType = (*formal)->get_type();
     
    560552
    561553                                Expression *varExpr = data.combine( newerAlt.cvtCost );
    562                                 delete varExpr->get_result();
    563554                                varExpr->set_result( adjType->clone() );
    564555                                PRINT(
     
    574565                                        inferParameters = (*inferParameters)[ id ].inferParams.get();
    575566                                }
    576                                 // XXX: this is a memory leak, but adjType can't be deleted because it might contain assertions
    577                                 (*inferParameters)[ curDecl->get_uniqueId() ] = ParamEntry( candidate->get_uniqueId(), adjType->clone(), curDecl->get_type()->clone(), varExpr );
     567                               
     568                                (*inferParameters)[ curDecl->get_uniqueId() ] = ParamEntry( candidate->get_uniqueId(), adjType, curDecl->get_type(), varExpr );
    578569                                inferRecursive( begin, end, newerAlt, newOpenVars, newDecls, newerNeed, level, indexer, out );
    579                         } else {
    580                                 delete adjType;
    581570                        }
    582571                }
     
    615604        ConstantExpr* getDefaultValue( Initializer* init ) {
    616605                if ( SingleInit* si = dynamic_cast<SingleInit*>( init ) ) {
    617                         if ( CastExpr* ce = dynamic_cast<CastExpr*>( si->value ) ) {
    618                                 return dynamic_cast<ConstantExpr*>( ce->arg );
    619                         } else {
    620                                 return dynamic_cast<ConstantExpr*>( si->value );
     606                        if ( CastExpr* ce = dynamic_cast<CastExpr*>( si->get_value() ) ) {
     607                                return dynamic_cast<ConstantExpr*>( ce->get_arg() );
    621608                        }
    622609                }
     
    627614        struct ArgPack {
    628615                std::size_t parent;                ///< Index of parent pack
    629                 std::unique_ptr<Expression> expr;  ///< The argument stored here
     616                Expression* expr;                  ///< The argument stored here
    630617                Cost cost;                         ///< The cost of this argument
    631618                TypeEnvironment env;               ///< Environment for this pack
     
    639626
    640627                ArgPack()
    641                         : parent(0), expr(), cost(Cost::zero), env(), need(), have(), openVars(), nextArg(0),
    642                           tupleStart(0), nextExpl(0), explAlt(0) {}
     628                        : parent(0), expr(nullptr), cost(Cost::zero), env(), need(), have(), openVars(),
     629                          nextArg(0), tupleStart(0), nextExpl(0), explAlt(0) {}
    643630
    644631                ArgPack(const TypeEnvironment& env, const AssertionSet& need, const AssertionSet& have,
    645632                                const OpenVarSet& openVars)
    646                         : parent(0), expr(), cost(Cost::zero), env(env), need(need), have(have),
     633                        : parent(0), expr(nullptr), cost(Cost::zero), env(env), need(need), have(have),
    647634                          openVars(openVars), nextArg(0), tupleStart(0), nextExpl(0), explAlt(0) {}
    648635
     
    651638                                unsigned tupleStart = 0, Cost cost = Cost::zero, unsigned nextExpl = 0,
    652639                                unsigned explAlt = 0 )
    653                         : parent(parent), expr(expr->clone()), cost(cost), env(move(env)), need(move(need)),
     640                        : parent(parent), expr(expr), cost(cost), env(move(env)), need(move(need)),
    654641                          have(move(have)), openVars(move(openVars)), nextArg(nextArg), tupleStart(tupleStart),
    655642                          nextExpl(nextExpl), explAlt(explAlt) {}
     
    657644                ArgPack(const ArgPack& o, TypeEnvironment&& env, AssertionSet&& need, AssertionSet&& have,
    658645                                OpenVarSet&& openVars, unsigned nextArg, Cost added )
    659                         : parent(o.parent), expr(o.expr ? o.expr->clone() : nullptr), cost(o.cost + added),
    660                           env(move(env)), need(move(need)), have(move(have)), openVars(move(openVars)),
    661                           nextArg(nextArg), tupleStart(o.tupleStart), nextExpl(0), explAlt(0) {}
     646                        : parent(o.parent), expr(o.expr), cost(o.cost + added), env(move(env)),
     647                          need(move(need)), have(move(have)), openVars(move(openVars)), nextArg(nextArg),
     648                          tupleStart(o.tupleStart), nextExpl(0), explAlt(0) {}
    662649
    663650                /// true iff this pack is in the middle of an exploded argument
     
    674661                        std::list<Expression*> exprs;
    675662                        const ArgPack* pack = this;
    676                         if ( expr ) { exprs.push_front( expr.release() ); }
     663                        if ( expr ) { exprs.push_front( expr ); }
    677664                        while ( pack->tupleStart == 0 ) {
    678665                                pack = &packs[pack->parent];
    679                                 exprs.push_front( pack->expr->clone() );
     666                                exprs.push_front( pack->expr );
    680667                                cost += pack->cost;
    681668                        }
    682669                        // reset pack to appropriate tuple
    683                         expr.reset( new TupleExpr( exprs ) );
     670                        expr = new TupleExpr{ exprs };
    684671                        tupleStart = pack->tupleStart - 1;
    685672                        parent = pack->parent;
     
    734721
    735722                                                results.emplace_back(
    736                                                         i, expl.exprs[results[i].nextExpl].get(), copy(results[i].env),
     723                                                        i, expl.exprs[results[i].nextExpl], copy(results[i].env),
    737724                                                        copy(results[i].need), copy(results[i].have),
    738725                                                        copy(results[i].openVars), nextArg, nTuples, Cost::zero, nextExpl,
     
    755742                                                        newResult.parent = i;
    756743                                                        std::list<Expression*> emptyList;
    757                                                         newResult.expr.reset( new TupleExpr( emptyList ) );
     744                                                        newResult.expr = new TupleExpr{ emptyList };
    758745                                                        argType = newResult.expr->get_result();
    759746                                                } else {
     
    762749                                                        newResult.cost = results[i].cost;
    763750                                                        newResult.tupleStart = results[i].tupleStart;
    764                                                         newResult.expr.reset( results[i].expr->clone() );
     751                                                        newResult.expr = results[i].expr;
    765752                                                        argType = newResult.expr->get_result();
    766753
     
    812799                                                // add new result
    813800                                                results.emplace_back(
    814                                                         i, expl.exprs.front().get(), move(env), copy(results[i].need),
     801                                                        i, expl.exprs.front(), move(env), copy(results[i].need),
    815802                                                        copy(results[i].have), move(openVars), nextArg + 1,
    816803                                                        nTuples, expl.cost, expl.exprs.size() == 1 ? 0 : 1, j );
     
    838825                        if ( results[i].hasExpl() ) {
    839826                                const ExplodedActual& expl = results[i].getExpl( args );
    840                                 Expression* expr = expl.exprs[results[i].nextExpl].get();
     827                                Expression* expr = expl.exprs[results[i].nextExpl];
    841828
    842829                                TypeEnvironment env = results[i].env;
     
    879866                                                                indexer ) ) {
    880867                                                        results.emplace_back(
    881                                                                 i, new DefaultArgExpr( cnstExpr ), move(env), move(need), move(have),
     868                                                                i, cnstExpr, move(env), move(need), move(have),
    882869                                                                move(openVars), nextArg, nTuples );
    883870                                                }
     
    909896
    910897                                // consider only first exploded actual
    911                                 Expression* expr = expl.exprs.front().get();
     898                                Expression* expr = expl.exprs.front();
    912899                                Type* actualType = expr->result->clone();
    913900
     
    937924
    938925        template<typename OutputIterator>
    939         void AlternativeFinder::Finder::validateFunctionAlternative( const Alternative &func, ArgPack& result,
    940                         const std::vector<ArgPack>& results, OutputIterator out ) {
    941                 ApplicationExpr *appExpr = new ApplicationExpr( func.expr->clone() );
     926        void AlternativeFinder::Finder::validateFunctionAlternative( const Alternative &func,
     927                        ArgPack& result, const std::vector<ArgPack>& results, OutputIterator out ) {
     928                ApplicationExpr *appExpr = new ApplicationExpr( func.expr );
    942929                // sum cost and accumulate actuals
    943930                std::list<Expression*>& args = appExpr->args;
     
    945932                const ArgPack* pack = &result;
    946933                while ( pack->expr ) {
    947                         args.push_front( pack->expr->clone() );
     934                        args.push_front( pack->expr );
    948935                        cost += pack->cost;
    949936                        pack = &results[pack->parent];
     
    1012999
    10131000                                                results.emplace_back(
    1014                                                         i, expl.exprs[results[i].nextExpl].get(), copy(results[i].env),
     1001                                                        i, expl.exprs[results[i].nextExpl], copy(results[i].env),
    10151002                                                        copy(results[i].need), copy(results[i].have),
    10161003                                                        copy(results[i].openVars), nextArg, 0, Cost::zero, nextExpl,
     
    10481035                                                // add new result
    10491036                                                results.emplace_back(
    1050                                                         i, expl.exprs.front().get(), move(env), copy(results[i].need),
     1037                                                        i, expl.exprs.front(), move(env), copy(results[i].need),
    10511038                                                        copy(results[i].have), move(openVars), nextArg + 1, 0,
    10521039                                                        expl.cost, expl.exprs.size() == 1 ? 0 : 1, j );
     
    10711058                funcFinder.findWithAdjustment( untypedExpr->function );
    10721059                // if there are no function alternatives, then proceeding is a waste of time.
    1073                 // xxx - findWithAdjustment throws, so this check and others like it shouldn't be necessary.
    10741060                if ( funcFinder.alternatives.empty() ) return;
    10751061
     
    10831069
    10841070                // find function operators
    1085                 static NameExpr *opExpr = new NameExpr( "?()" );
     1071                static auto *opExpr = new_static_root<NameExpr>( "?()" );
    10861072                AlternativeFinder funcOpFinder( indexer, env );
    10871073                // it's ok if there aren't any defined function ops
     
    10991085                        argExpansions.emplace_back();
    11001086                        auto& argE = argExpansions.back();
    1101                         // argE.reserve( arg.alternatives.size() );
     1087                        argE.reserve( arg.alternatives.size() );
    11021088
    11031089                        for ( const Alternative& actual : arg ) {
     
    11151101                                )
    11161102                                // check if the type is pointer to function
    1117                                 if ( PointerType *pointer = dynamic_cast< PointerType* >( func->expr->result->stripReferences() ) ) {
    1118                                         if ( FunctionType *function = dynamic_cast< FunctionType* >( pointer->base ) ) {
     1103                                if ( PointerType *pointer = dynamic_cast< PointerType* >( func->expr->get_result()->stripReferences() ) ) {
     1104                                        if ( FunctionType *function = dynamic_cast< FunctionType* >( pointer->get_base() ) ) {
    11191105                                                Alternative newFunc( *func );
    11201106                                                referenceToRvalueConversion( newFunc.expr, newFunc.cost );
     
    11221108                                                        std::back_inserter( candidates ) );
    11231109                                        }
    1124                                 } else if ( TypeInstType *typeInst = dynamic_cast< TypeInstType* >( func->expr->result->stripReferences() ) ) { // handle ftype (e.g. *? on function pointer)
    1125                                         if ( const EqvClass *eqvClass = func->env.lookup( typeInst->name ) ) {
    1126                                                 if ( FunctionType *function = dynamic_cast< FunctionType* >( eqvClass->type ) ) {
     1110                                } else if ( TypeInstType *typeInst = dynamic_cast< TypeInstType* >( func->expr->get_result()->stripReferences() ) ) { // handle ftype (e.g. *? on function pointer)
     1111                                        if ( ClassRef eqvClass = func->env.lookup( typeInst->get_name() ) ) {
     1112                                                if ( FunctionType *function = dynamic_cast< FunctionType* >( eqvClass.get_bound().type ) ) {
    11271113                                                        Alternative newFunc( *func );
    11281114                                                        referenceToRvalueConversion( newFunc.expr, newFunc.cost );
     
    11521138                                        // check if type is a pointer to function
    11531139                                        if ( PointerType* pointer = dynamic_cast<PointerType*>(
    1154                                                         funcOp->expr->result->stripReferences() ) ) {
     1140                                                        funcOp->expr->get_result()->stripReferences() ) ) {
    11551141                                                if ( FunctionType* function =
    1156                                                                 dynamic_cast<FunctionType*>( pointer->base ) ) {
     1142                                                                dynamic_cast<FunctionType*>( pointer->get_base() ) ) {
    11571143                                                        Alternative newFunc( *funcOp );
    11581144                                                        referenceToRvalueConversion( newFunc.expr, newFunc.cost );
     
    11761162                        PRINT(
    11771163                                ApplicationExpr *appExpr = strict_dynamic_cast< ApplicationExpr* >( withFunc.expr );
    1178                                 PointerType *pointer = strict_dynamic_cast< PointerType* >( appExpr->function->result );
    1179                                 FunctionType *function = strict_dynamic_cast< FunctionType* >( pointer->base );
    1180                                 std::cerr << "Case +++++++++++++ " << appExpr->function << std::endl;
     1164                                PointerType *pointer = strict_dynamic_cast< PointerType* >( appExpr->get_function()->get_result() );
     1165                                FunctionType *function = strict_dynamic_cast< FunctionType* >( pointer->get_base() );
     1166                                std::cerr << "Case +++++++++++++ " << appExpr->get_function() << std::endl;
    11811167                                std::cerr << "formals are:" << std::endl;
    1182                                 printAll( function->parameters, std::cerr, 8 );
     1168                                printAll( function->get_parameters(), std::cerr, 8 );
    11831169                                std::cerr << "actuals are:" << std::endl;
    1184                                 printAll( appExpr->args, std::cerr, 8 );
     1170                                printAll( appExpr->get_args(), std::cerr, 8 );
    11851171                                std::cerr << "bindings are:" << std::endl;
    11861172                                withFunc.env.print( std::cerr, 8 );
     
    12231209        bool isLvalue( Expression *expr ) {
    12241210                // xxx - recurse into tuples?
    1225                 return expr->result && ( expr->result->get_lvalue() || dynamic_cast< ReferenceType * >( expr->result ) );
     1211                return expr->result && ( expr->get_result()->get_lvalue() || dynamic_cast< ReferenceType * >( expr->get_result() ) );
    12261212        }
    12271213
     
    12321218                        if ( isLvalue( alt.expr ) ) {
    12331219                                alternatives.push_back(
    1234                                         Alternative{ new AddressExpr( alt.expr->clone() ), alt.env, alt.cost } );
     1220                                        Alternative{ new AddressExpr( alt.expr ), alt.env, alt.cost } );
    12351221                        } // if
    12361222                } // for
     
    12381224
    12391225        void AlternativeFinder::Finder::postvisit( LabelAddressExpr * expr ) {
    1240                 alternatives.push_back( Alternative{ expr->clone(), env, Cost::zero } );
     1226                alternatives.push_back( Alternative{ expr, env, Cost::zero } );
    12411227        }
    12421228
     
    12581244                                componentExprs.push_back( restructureCast( idx, toType->getComponent( i ), isGenerated ) );
    12591245                        }
    1260                         delete argExpr;
    12611246                        assert( componentExprs.size() > 0 );
    12621247                        // produce the tuple of casts
     
    13341319                for ( Alternative & alt : finder.alternatives ) {
    13351320                        alternatives.push_back( Alternative(
    1336                                 new VirtualCastExpr( alt.expr->clone(), castExpr->get_result()->clone() ),
     1321                                new VirtualCastExpr( alt.expr, castExpr->get_result()->clone() ),
    13371322                                alt.env, alt.cost ) );
    13381323                }
     
    13561341                        Expression * aggrExpr = agg->expr->clone();
    13571342                        referenceToRvalueConversion( aggrExpr, cost );
    1358                         std::unique_ptr<Expression> guard( aggrExpr );
    13591343
    13601344                        // find member of the given type
     
    13701354
    13711355        void AlternativeFinder::Finder::postvisit( MemberExpr *memberExpr ) {
    1372                 alternatives.push_back( Alternative( memberExpr->clone(), env, Cost::zero ) );
     1356                alternatives.push_back( Alternative( memberExpr, env, Cost::zero ) );
    13731357        }
    13741358
     
    13801364                        Cost cost = Cost::zero;
    13811365                        Expression * newExpr = data.combine( cost );
    1382 
    1383                         // addAnonAlternatives uses vector::push_back, which invalidates references to existing elements, so
    1384                         // can't construct in place and use vector::back
    1385                         Alternative newAlt( newExpr, env, Cost::zero, cost );
     1366                        alternatives.push_back( Alternative( newExpr, env, Cost::zero, cost ) );
    13861367                        PRINT(
    13871368                                std::cerr << "decl is ";
     
    13921373                                std::cerr << std::endl;
    13931374                        )
    1394                         renameTypes( newAlt.expr );
    1395                         addAnonConversions( newAlt ); // add anonymous member interpretations whenever an aggregate value type is seen as a name expression.
    1396                         alternatives.push_back( std::move(newAlt) );
     1375                        renameTypes( alternatives.back().expr );
     1376                        addAnonConversions( alternatives.back() ); // add anonymous member interpretations whenever an aggregate value type is seen as a name expression.
    13971377                } // for
    13981378        }
     
    14051385
    14061386        void AlternativeFinder::Finder::postvisit( ConstantExpr *constantExpr ) {
    1407                 alternatives.push_back( Alternative( constantExpr->clone(), env, Cost::zero ) );
     1387                alternatives.push_back( Alternative( constantExpr, env, Cost::zero ) );
    14081388        }
    14091389
     
    14251405                        Alternative &choice = winners.front();
    14261406                        referenceToRvalueConversion( choice.expr, choice.cost );
    1427                         alternatives.push_back( Alternative( new SizeofExpr( choice.expr->clone() ), choice.env, Cost::zero ) );
     1407                        alternatives.push_back( Alternative( new SizeofExpr( choice.expr ), choice.env, Cost::zero ) );
    14281408                } // if
    14291409        }
     
    14461426                        Alternative &choice = winners.front();
    14471427                        referenceToRvalueConversion( choice.expr, choice.cost );
    1448                         alternatives.push_back( Alternative( new AlignofExpr( choice.expr->clone() ), choice.env, Cost::zero ) );
     1428                        alternatives.push_back( Alternative( new AlignofExpr( choice.expr ), choice.env, Cost::zero ) );
    14491429                } // if
    14501430        }
     
    14751455
    14761456        void AlternativeFinder::Finder::postvisit( OffsetofExpr *offsetofExpr ) {
    1477                 alternatives.push_back( Alternative( offsetofExpr->clone(), env, Cost::zero ) );
     1457                alternatives.push_back( Alternative( offsetofExpr, env, Cost::zero ) );
    14781458        }
    14791459
    14801460        void AlternativeFinder::Finder::postvisit( OffsetPackExpr *offsetPackExpr ) {
    1481                 alternatives.push_back( Alternative( offsetPackExpr->clone(), env, Cost::zero ) );
     1461                alternatives.push_back( Alternative( offsetPackExpr, env, Cost::zero ) );
    14821462        }
    14831463
     
    15571537                                compositeEnv.simpleCombine( second.env );
    15581538
    1559                                 LogicalExpr *newExpr = new LogicalExpr( first.expr->clone(), second.expr->clone(), logicalExpr->get_isAnd() );
     1539                                LogicalExpr *newExpr = new LogicalExpr( first.expr, second.expr, logicalExpr->get_isAnd() );
    15601540                                alternatives.push_back( Alternative( newExpr, compositeEnv, first.cost + second.cost ) );
    15611541                        }
     
    15901570                                        Type* commonType = nullptr;
    15911571                                        if ( unify( second.expr->result, third.expr->result, newAlt.env, needAssertions, haveAssertions, openVars, indexer, commonType ) ) {
    1592                                                 ConditionalExpr *newExpr = new ConditionalExpr( first.expr->clone(), second.expr->clone(), third.expr->clone() );
     1572                                                ConditionalExpr *newExpr = new ConditionalExpr( first.expr, second.expr, third.expr );
    15931573                                                newExpr->result = commonType ? commonType : second.expr->result->clone();
    15941574                                                // convert both options to the conditional result type
     
    16091589                secondFinder.findWithAdjustment( commaExpr->get_arg2() );
    16101590                for ( const Alternative & alt : secondFinder.alternatives ) {
    1611                         alternatives.push_back( Alternative( new CommaExpr( newFirstArg->clone(), alt.expr->clone() ), alt.env, alt.cost ) );
     1591                        alternatives.push_back( Alternative( new CommaExpr( newFirstArg, alt.expr ), alt.env, alt.cost ) );
    16121592                } // for
    1613                 delete newFirstArg;
    16141593        }
    16151594
     
    16321611                                Type* commonType = nullptr;
    16331612                                if ( unify( first.expr->result, second.expr->result, newAlt.env, needAssertions, haveAssertions, openVars, indexer, commonType ) ) {
    1634                                         RangeExpr * newExpr = new RangeExpr( first.expr->clone(), second.expr->clone() );
     1613                                        RangeExpr * newExpr = new RangeExpr( first.expr, second.expr );
    16351614                                        newExpr->result = commonType ? commonType : first.expr->result->clone();
    16361615                                        newAlt.expr = newExpr;
     
    16601639
    16611640        void AlternativeFinder::Finder::postvisit( TupleExpr *tupleExpr ) {
    1662                 alternatives.push_back( Alternative( tupleExpr->clone(), env, Cost::zero ) );
     1641                alternatives.push_back( Alternative( tupleExpr, env, Cost::zero ) );
    16631642        }
    16641643
    16651644        void AlternativeFinder::Finder::postvisit( ImplicitCopyCtorExpr * impCpCtorExpr ) {
    1666                 alternatives.push_back( Alternative( impCpCtorExpr->clone(), env, Cost::zero ) );
     1645                alternatives.push_back( Alternative( impCpCtorExpr, env, Cost::zero ) );
    16671646        }
    16681647
     
    16731652                finder.findWithoutPrune( ctorExpr->get_callExpr() );
    16741653                for ( Alternative & alt : finder.alternatives ) {
    1675                         alternatives.push_back( Alternative( new ConstructorExpr( alt.expr->clone() ), alt.env, alt.cost ) );
     1654                        alternatives.push_back( Alternative( new ConstructorExpr( alt.expr ), alt.env, alt.cost ) );
    16761655                }
    16771656        }
    16781657
    16791658        void AlternativeFinder::Finder::postvisit( TupleIndexExpr *tupleExpr ) {
    1680                 alternatives.push_back( Alternative( tupleExpr->clone(), env, Cost::zero ) );
     1659                alternatives.push_back( Alternative( tupleExpr, env, Cost::zero ) );
    16811660        }
    16821661
    16831662        void AlternativeFinder::Finder::postvisit( TupleAssignExpr *tupleAssignExpr ) {
    1684                 alternatives.push_back( Alternative( tupleAssignExpr->clone(), env, Cost::zero ) );
     1663                alternatives.push_back( Alternative( tupleAssignExpr, env, Cost::zero ) );
    16851664        }
    16861665
     
    16901669                for ( Alternative & alt : finder.alternatives ) {
    16911670                        // ensure that the id is passed on to the UniqueExpr alternative so that the expressions are "linked"
    1692                         UniqueExpr * newUnqExpr = new UniqueExpr( alt.expr->clone(), unqExpr->get_id() );
     1671                        UniqueExpr * newUnqExpr = new UniqueExpr( alt.expr, unqExpr->get_id() );
    16931672                        alternatives.push_back( Alternative( newUnqExpr, alt.env, alt.cost ) );
    16941673                }
     
    17411720                                        // count one safe conversion for each value that is thrown away
    17421721                                        thisCost.incSafe( discardedValues );
    1743                                         Alternative newAlt( new InitExpr( restructureCast( alt.expr->clone(), toType, true ), initAlt.designation->clone() ), newEnv, alt.cost, thisCost );
     1722                                        Alternative newAlt( new InitExpr( restructureCast( alt.expr, toType, true ), initAlt.designation ), newEnv, alt.cost, thisCost );
    17441723                                        inferParameters( needAssertions, haveAssertions, newAlt, openVars, back_inserter( candidates ) );
    17451724                                }
     
    17621741                assertf( false, "AlternativeFinder should never see a DeletedExpr." );
    17631742        }
    1764 
    1765         void AlternativeFinder::Finder::postvisit( GenericExpr * ) {
    1766                 assertf( false, "_Generic is not yet supported." );
    1767         }
    17681743} // namespace ResolvExpr
    17691744
Note: See TracChangeset for help on using the changeset viewer.