Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/ResolvExpr/AlternativeFinder.cc

    rb1bead1 ra5f0529  
    99// Author           : Richard C. Bilson
    1010// Created On       : Sat May 16 23:52:08 2015
    11 // Last Modified By : Peter A. Buhr
    12 // Last Modified On : Fri Mar 17 09:14:17 2017
    13 // Update Count     : 30
     11// Last Modified By : Andrew Beach
     12// Last Modified On : Wed Jul 26 11:33:00 2017
     13// Update Count     : 31
    1414//
    1515
     
    6767
    6868        Cost sumCost( const AltList &in ) {
    69                 Cost total = Cost::zero;
     69                Cost total;
    7070                for ( AltList::const_iterator i = in.begin(); i != in.end(); ++i ) {
    7171                        total += i->cost;
     
    144144                        expr->get_result()->accept( global_renamer );
    145145                }
    146 
    147                 void referenceToRvalueConversion( Expression *& expr ) {
    148                         if ( dynamic_cast< ReferenceType * >( expr->get_result() ) ) {
    149                                 // cast away reference from expr
    150                                 expr = new CastExpr( expr, expr->get_result()->stripReferences()->clone() );
    151                         }
    152                 }
    153         } // namespace
     146        }
    154147
    155148        template< typename InputIterator, typename OutputIterator >
     
    220213        void AlternativeFinder::addAnonConversions( const Alternative & alt ) {
    221214                // adds anonymous member interpretations whenever an aggregate value type is seen.
    222                 // 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
    223                 std::unique_ptr<Expression> aggrExpr( alt.expr->clone() );
    224                 alt.env.apply( aggrExpr->get_result() );
    225                 Type * aggrType = aggrExpr->get_result();
    226                 if ( dynamic_cast< ReferenceType * >( aggrType ) ) {
    227                         aggrType = aggrType->stripReferences();
    228                         aggrExpr.reset( new CastExpr( aggrExpr.release(), aggrType->clone() ) );
    229                 }
    230 
    231                 if ( StructInstType *structInst = dynamic_cast< StructInstType* >( aggrExpr->get_result() ) ) {
     215                Expression * expr = alt.expr->clone();
     216                std::unique_ptr< Expression > manager( expr ); // RAII for expr
     217                alt.env.apply( expr->get_result() );
     218                if ( StructInstType *structInst = dynamic_cast< StructInstType* >( expr->get_result() ) ) {
    232219                        NameExpr nameExpr( "" );
    233                         addAggMembers( structInst, aggrExpr.get(), alt.cost+Cost::safe, alt.env, &nameExpr );
    234                 } else if ( UnionInstType *unionInst = dynamic_cast< UnionInstType* >( aggrExpr->get_result() ) ) {
     220                        addAggMembers( structInst, expr, alt.cost+Cost( 0, 0, 1 ), alt.env, &nameExpr );
     221                } else if ( UnionInstType *unionInst = dynamic_cast< UnionInstType* >( expr->get_result() ) ) {
    235222                        NameExpr nameExpr( "" );
    236                         addAggMembers( unionInst, aggrExpr.get(), alt.cost+Cost::safe, alt.env, &nameExpr );
     223                        addAggMembers( unionInst, expr, alt.cost+Cost( 0, 0, 1 ), alt.env, &nameExpr );
    237224                } // if
    238225        }
     
    290277                FunctionType *function = safe_dynamic_cast< FunctionType* >( pointer->get_base() );
    291278
    292                 Cost convCost = Cost::zero;
     279                Cost convCost( 0, 0, 0 );
    293280                std::list< DeclarationWithType* >& formals = function->get_parameters();
    294281                std::list< DeclarationWithType* >::iterator formal = formals.begin();
     
    303290                                actualType->print( std::cerr, 8 );
    304291                        )
    305                         Cost actualCost = Cost::zero;
     292                        Cost actualCost;
    306293                        if ( formal == formals.end() ) {
    307294                                if ( function->get_isVarArgs() ) {
    308                                         convCost.incUnsafe();
    309                                         // convert reference-typed expressions to value-typed expressions
    310                                         referenceToRvalueConversion( *actualExpr );
     295                                        convCost += Cost( 1, 0, 0 );
    311296                                        continue;
    312297                                } else {
     
    320305                                std::cerr << std::endl << " to ";
    321306                                formalType->print( std::cerr, 8 );
    322                                 std::cerr << std::endl << "environment is: ";
    323                                 alt.env.print( std::cerr, 8 );
    324                                 std::cerr << std::endl;
    325307                        )
    326308                        Cost newCost = conversionCost( actualType, formalType, indexer, alt.env );
     
    334316                        convCost += newCost;
    335317                        actualCost += newCost;
    336                         if ( actualCost != Cost::zero ) {
     318                        if ( actualCost != Cost( 0, 0, 0 ) ) {
    337319                                Type *newType = formalType->clone();
    338320                                alt.env.apply( newType );
    339321                                *actualExpr = new CastExpr( *actualExpr, newType );
    340322                        }
    341                         convCost.incPoly( polyCost( formalType, alt.env, indexer ) + polyCost( actualType, alt.env, indexer ) );
     323                        convCost += Cost( 0, polyCost( formalType, alt.env, indexer ) + polyCost( actualType, alt.env, indexer ), 0 );
    342324                        ++formal; // can't be in for-loop update because of the continue
    343325                }
     
    361343                        }
    362344                        convCost += newCost;
    363                         convCost.incPoly( polyCost( assert->second.formalType, alt.env, indexer ) + polyCost( assert->second.actualType, alt.env, indexer ) );
     345                        convCost += Cost( 0, polyCost( assert->second.formalType, alt.env, indexer ) + polyCost( assert->second.actualType, alt.env, indexer ), 0 );
    364346                }
    365347
     
    418400                        Expression * actual = actualIt->expr;
    419401                        Type * actualType = actual->get_result();
    420 
    421402                        PRINT(
    422403                                std::cerr << "formal type is ";
     
    427408                        )
    428409                        if ( ! unify( formalType, actualType, resultEnv, resultNeed, resultHave, openVars, indexer ) ) {
    429                                 // std::cerr << "unify failed" << std::endl;
    430410                                return false;
    431411                        }
     
    472452                        // match flattened actuals with formal parameters - actuals will be grouped to match
    473453                        // with formals as appropriate
    474                         Cost cost = Cost::zero;
     454                        Cost cost;
    475455                        std::list< Expression * > newExprs;
    476456                        ObjectDecl * obj = safe_dynamic_cast< ObjectDecl * >( formal );
     
    663643                        makeExprList( instantiatedActuals, appExpr->get_args() );
    664644                        PRINT(
    665                                 std::cerr << "instantiate function success: " << appExpr << std::endl;
    666645                                std::cerr << "need assertions:" << std::endl;
    667646                                printAssertionSet( resultNeed, std::cerr, 8 );
     
    684663                                UntypedExpr *vexpr = untypedExpr->clone();
    685664                                vexpr->set_result( pt.clone() );
    686                                 alternatives.push_back( Alternative( vexpr, env, Cost::zero) );
     665                                alternatives.push_back( Alternative( vexpr, env, Cost()) );
    687666                                return;
    688667                        }
     
    702681                AltList candidates;
    703682                SemanticError errors;
    704                 for ( AltList::iterator func = funcFinder.alternatives.begin(); func != funcFinder.alternatives.end(); ++func ) {
     683                for ( AltList::const_iterator func = funcFinder.alternatives.begin(); func != funcFinder.alternatives.end(); ++func ) {
    705684                        try {
    706685                                PRINT(
     
    709688                                )
    710689                                // check if the type is pointer to function
    711                                 if ( PointerType *pointer = dynamic_cast< PointerType* >( func->expr->get_result()->stripReferences() ) ) {
     690                                PointerType *pointer;
     691                                if ( ( pointer = dynamic_cast< PointerType* >( func->expr->get_result() ) ) ) {
    712692                                        if ( FunctionType *function = dynamic_cast< FunctionType* >( pointer->get_base() ) ) {
    713                                                 referenceToRvalueConversion( func->expr );
    714693                                                for ( std::list< AltList >::iterator actualAlt = possibilities.begin(); actualAlt != possibilities.end(); ++actualAlt ) {
    715694                                                        // XXX
     
    717696                                                        makeFunctionAlternatives( *func, function, *actualAlt, std::back_inserter( candidates ) );
    718697                                                }
    719                                         }
    720                                 } else if ( TypeInstType *typeInst = dynamic_cast< TypeInstType* >( func->expr->get_result()->stripReferences() ) ) { // handle ftype (e.g. *? on function pointer)
    721                                         referenceToRvalueConversion( func->expr );
    722                                         EqvClass eqvClass;
    723                                         if ( func->env.lookup( typeInst->get_name(), eqvClass ) && eqvClass.type ) {
    724                                                 if ( FunctionType *function = dynamic_cast< FunctionType* >( eqvClass.type ) ) {
    725                                                         for ( std::list< AltList >::iterator actualAlt = possibilities.begin(); actualAlt != possibilities.end(); ++actualAlt ) {
    726                                                                 makeFunctionAlternatives( *func, function, *actualAlt, std::back_inserter( candidates ) );
    727                                                         } // for
     698                                        } else if ( TypeInstType *typeInst = dynamic_cast< TypeInstType* >( pointer->get_base() ) ) {
     699                                                EqvClass eqvClass;
     700                                                if ( func->env.lookup( typeInst->get_name(), eqvClass ) && eqvClass.type ) {
     701                                                        if ( FunctionType *function = dynamic_cast< FunctionType* >( eqvClass.type ) ) {
     702                                                                for ( std::list< AltList >::iterator actualAlt = possibilities.begin(); actualAlt != possibilities.end(); ++actualAlt ) {
     703                                                                        makeFunctionAlternatives( *func, function, *actualAlt, std::back_inserter( candidates ) );
     704                                                                } // for
     705                                                        } // if
    728706                                                } // if
    729707                                        } // if
     
    744722                                        }
    745723
    746                                         for ( AltList::iterator funcOp = funcOpFinder.alternatives.begin(); funcOp != funcOpFinder.alternatives.end(); ++funcOp ) {
     724                                        for ( AltList::const_iterator funcOp = funcOpFinder.alternatives.begin(); funcOp != funcOpFinder.alternatives.end(); ++funcOp ) {
    747725                                                // check if the type is pointer to function
    748                                                 if ( PointerType *pointer = dynamic_cast< PointerType* >( funcOp->expr->get_result()->stripReferences() ) ) {
     726                                                PointerType *pointer;
     727                                                if ( ( pointer = dynamic_cast< PointerType* >( funcOp->expr->get_result() ) ) ) {
    749728                                                        if ( FunctionType *function = dynamic_cast< FunctionType* >( pointer->get_base() ) ) {
    750                                                                 referenceToRvalueConversion( funcOp->expr );
    751729                                                                for ( std::list< AltList >::iterator actualAlt = possibilities.begin(); actualAlt != possibilities.end(); ++actualAlt ) {
    752730                                                                        AltList currentAlt;
     
    775753                                PointerType *pointer = safe_dynamic_cast< PointerType* >( appExpr->get_function()->get_result() );
    776754                                FunctionType *function = safe_dynamic_cast< FunctionType* >( pointer->get_base() );
    777                                 std::cerr << "Case +++++++++++++ " << appExpr->get_function() << std::endl;
     755                                std::cerr << "Case +++++++++++++" << std::endl;
    778756                                std::cerr << "formals are:" << std::endl;
    779757                                printAll( function->get_parameters(), std::cerr, 8 );
     
    818796        bool isLvalue( Expression *expr ) {
    819797                // xxx - recurse into tuples?
    820                 return expr->has_result() && ( expr->get_result()->get_lvalue() || dynamic_cast< ReferenceType * >( expr->get_result() ) );
     798                return expr->has_result() && expr->get_result()->get_lvalue();
    821799        }
    822800
     
    832810
    833811        Expression * restructureCast( Expression * argExpr, Type * toType ) {
    834                 if ( argExpr->get_result()->size() > 1 && ! toType->isVoid() && ! dynamic_cast<ReferenceType *>( toType ) ) {
    835                         // Argument expression is a tuple and the target type is not void and not a reference type.
    836                         // Cast each member of the tuple to its corresponding target type, producing the tuple of those
    837                         // cast expressions. If there are more components of the tuple than components in the target type,
    838                         // then excess components do not come out in the result expression (but UniqueExprs ensure that
    839                         // side effects will still be done).
     812                if ( argExpr->get_result()->size() > 1 && ! toType->isVoid() ) {
     813                        // Argument expression is a tuple and the target type is not void. Cast each member of the tuple
     814                        // to its corresponding target type, producing the tuple of those cast expressions. If there are
     815                        // more components of the tuple than components in the target type, then excess components do not
     816                        // come out in the result expression (but UniqueExprs ensure that side effects will still be done).
    840817                        if ( Tuples::maybeImpure( argExpr ) && ! dynamic_cast< UniqueExpr * >( argExpr ) ) {
    841818                                // expressions which may contain side effects require a single unique instance of the expression.
     
    878855                        // that are cast directly.  The candidate is invalid if it has fewer results than there are types to cast
    879856                        // to.
    880                         int discardedValues = i->expr->get_result()->size() - castExpr->get_result()->size();
     857                        int discardedValues = (*i).expr->get_result()->size() - castExpr->get_result()->size();
    881858                        if ( discardedValues < 0 ) continue;
    882859                        // xxx - may need to go into tuple types and extract relevant types and use unifyList. Note that currently, this does not
    883860                        // allow casting a tuple to an atomic type (e.g. (int)([1, 2, 3]))
    884861                        // unification run for side-effects
    885                         unify( castExpr->get_result(), i->expr->get_result(), i->env, needAssertions, haveAssertions, openVars, indexer );
    886                         Cost thisCost = castCost( i->expr->get_result(), castExpr->get_result(), indexer, i->env );
     862                        unify( castExpr->get_result(), (*i).expr->get_result(), i->env, needAssertions, haveAssertions, openVars, indexer );
     863                        Cost thisCost = castCost( (*i).expr->get_result(), castExpr->get_result(), indexer, i->env );
    887864                        if ( thisCost != Cost::infinity ) {
    888865                                // count one safe conversion for each value that is thrown away
    889                                 thisCost.incSafe( discardedValues );
     866                                thisCost += Cost( 0, 0, discardedValues );
    890867
    891868                                candidates.push_back( Alternative( restructureCast( i->expr->clone(), toType ), i->env, i->cost, thisCost ) );
     
    901878        }
    902879
     880        void AlternativeFinder::visit( VirtualCastExpr * castExpr ) {
     881                assertf( castExpr->get_result(), "Implicate virtual cast targets not yet supported." );
     882                AlternativeFinder finder( indexer, env );
     883                // don't prune here, since it's guaranteed all alternatives will have the same type
     884                // (giving the alternatives different types is half of the point of ConstructorExpr nodes)
     885                finder.findWithAdjustment( castExpr->get_arg(), false );
     886                for ( Alternative & alt : finder.alternatives ) {
     887                        alternatives.push_back( Alternative(
     888                                new VirtualCastExpr( alt.expr->clone(), castExpr->get_result()->clone() ),
     889                                alt.env, alt.cost ) );
     890                }
     891        }
     892
    903893        void AlternativeFinder::visit( UntypedMemberExpr *memberExpr ) {
    904894                AlternativeFinder funcFinder( indexer, env );
    905895                funcFinder.findWithAdjustment( memberExpr->get_aggregate() );
    906896                for ( AltList::const_iterator agg = funcFinder.alternatives.begin(); agg != funcFinder.alternatives.end(); ++agg ) {
    907                         // 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
    908                         std::unique_ptr<Expression> aggrExpr( agg->expr->clone() );
    909                         Type * aggrType = aggrExpr->get_result();
    910                         if ( dynamic_cast< ReferenceType * >( aggrType ) ) {
    911                                 aggrType = aggrType->stripReferences();
    912                                 aggrExpr.reset( new CastExpr( aggrExpr.release(), aggrType->clone() ) );
    913                         }
    914                         // find member of the given type
    915                         if ( StructInstType *structInst = dynamic_cast< StructInstType* >( aggrExpr->get_result() ) ) {
    916                                 addAggMembers( structInst, aggrExpr.get(), agg->cost, agg->env, memberExpr->get_member() );
    917                         } else if ( UnionInstType *unionInst = dynamic_cast< UnionInstType* >( aggrExpr->get_result() ) ) {
    918                                 addAggMembers( unionInst, aggrExpr.get(), agg->cost, agg->env, memberExpr->get_member() );
    919                         } else if ( TupleType * tupleType = dynamic_cast< TupleType * >( aggrExpr->get_result() ) ) {
    920                                 addTupleMembers( tupleType, aggrExpr.get(), agg->cost, agg->env, memberExpr->get_member() );
     897                        if ( StructInstType *structInst = dynamic_cast< StructInstType* >( agg->expr->get_result() ) ) {
     898                                addAggMembers( structInst, agg->expr, agg->cost, agg->env, memberExpr->get_member() );
     899                        } else if ( UnionInstType *unionInst = dynamic_cast< UnionInstType* >( agg->expr->get_result() ) ) {
     900                                addAggMembers( unionInst, agg->expr, agg->cost, agg->env, memberExpr->get_member() );
     901                        } else if ( TupleType * tupleType = dynamic_cast< TupleType * >( agg->expr->get_result() ) ) {
     902                                addTupleMembers( tupleType, agg->expr, agg->cost, agg->env, memberExpr->get_member() );
    921903                        } // if
    922904                } // for
     
    933915                for ( std::list< DeclarationWithType* >::iterator i = declList.begin(); i != declList.end(); ++i ) {
    934916                        VariableExpr newExpr( *i, nameExpr->get_argName() );
    935                         alternatives.push_back( Alternative( newExpr.clone(), env, Cost::zero ) );
     917                        alternatives.push_back( Alternative( newExpr.clone(), env, Cost() ) );
    936918                        PRINT(
    937919                                std::cerr << "decl is ";
     
    10771059                        for ( std::list< DeclarationWithType* >::iterator i = attrList.begin(); i != attrList.end(); ++i ) {
    10781060                                VariableExpr newExpr( *i );
    1079                                 alternatives.push_back( Alternative( newExpr.clone(), env, Cost::zero ) );
     1061                                alternatives.push_back( Alternative( newExpr.clone(), env, Cost() ) );
    10801062                                renameTypes( alternatives.back().expr );
    10811063                        } // for
     
    12501232                                if ( thisCost != Cost::infinity ) {
    12511233                                        // count one safe conversion for each value that is thrown away
    1252                                         thisCost.incSafe( discardedValues );
     1234                                        thisCost += Cost( 0, 0, discardedValues );
    12531235                                        candidates.push_back( Alternative( new InitExpr( restructureCast( alt.expr->clone(), toType ), initAlt.designation->clone() ), newEnv, alt.cost, thisCost ) );
    12541236                                }
Note: See TracChangeset for help on using the changeset viewer.