Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/ResolvExpr/AlternativeFinder.cc

    rddf8a29 r322b97e  
    1414//
    1515
    16 #include <algorithm>               // for copy
    17 #include <cassert>                 // for safe_dynamic_cast, assert, assertf
    18 #include <iostream>                // for operator<<, cerr, ostream, endl
    19 #include <iterator>                // for back_insert_iterator, back_inserter
    20 #include <list>                    // for _List_iterator, list, _List_const_...
    21 #include <map>                     // for _Rb_tree_iterator, map, _Rb_tree_c...
    22 #include <memory>                  // for allocator_traits<>::value_type
    23 #include <utility>                 // for pair
    24 
    25 #include "Alternative.h"           // for AltList, Alternative
     16#include <list>
     17#include <iterator>
     18#include <algorithm>
     19#include <functional>
     20#include <cassert>
     21#include <unordered_map>
     22#include <utility>
     23#include <vector>
     24
    2625#include "AlternativeFinder.h"
    27 #include "Common/SemanticError.h"  // for SemanticError
    28 #include "Common/utility.h"        // for deleteAll, printAll, CodeLocation
    29 #include "Cost.h"                  // for Cost, Cost::zero, operator<<, Cost...
    30 #include "InitTweak/InitTweak.h"   // for getFunctionName
    31 #include "RenameVars.h"            // for RenameVars, global_renamer
    32 #include "ResolveTypeof.h"         // for resolveTypeof
    33 #include "Resolver.h"              // for resolveStmtExpr
    34 #include "SymTab/Indexer.h"        // for Indexer
    35 #include "SymTab/Mangler.h"        // for Mangler
    36 #include "SymTab/Validate.h"       // for validateType
    37 #include "SynTree/Constant.h"      // for Constant
    38 #include "SynTree/Declaration.h"   // for DeclarationWithType, TypeDecl, Dec...
    39 #include "SynTree/Expression.h"    // for Expression, CastExpr, NameExpr
    40 #include "SynTree/Initializer.h"   // for SingleInit, operator<<, Designation
    41 #include "SynTree/SynTree.h"       // for UniqueId
    42 #include "SynTree/Type.h"          // for Type, FunctionType, PointerType
    43 #include "Tuples/Explode.h"        // for explode
    44 #include "Tuples/Tuples.h"         // for isTtype, handleTupleAssignment
    45 #include "Unify.h"                 // for unify
    46 #include "typeops.h"               // for adjustExprType, polyCost, castCost
     26#include "Alternative.h"
     27#include "Cost.h"
     28#include "typeops.h"
     29#include "Unify.h"
     30#include "RenameVars.h"
     31#include "SynTree/Type.h"
     32#include "SynTree/Declaration.h"
     33#include "SynTree/Expression.h"
     34#include "SynTree/Initializer.h"
     35#include "SynTree/Visitor.h"
     36#include "SymTab/Indexer.h"
     37#include "SymTab/Mangler.h"
     38#include "SynTree/TypeSubstitution.h"
     39#include "SymTab/Validate.h"
     40#include "Tuples/Tuples.h"
     41#include "Tuples/Explode.h"
     42#include "Common/utility.h"
     43#include "InitTweak/InitTweak.h"
     44#include "InitTweak/GenInit.h"
     45#include "ResolveTypeof.h"
     46#include "Resolver.h"
    4747
    4848extern bool resolvep;
     
    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 >
     
    193186                        if ( alternatives.begin() == oldBegin ) {
    194187                                std::ostringstream stream;
     188                                stream << "Can't choose between " << alternatives.size() << " alternatives for expression ";
     189                                expr->print( stream );
     190                                stream << "Alternatives are:";
    195191                                AltList winners;
    196192                                findMinCost( alternatives.begin(), alternatives.end(), back_inserter( winners ) );
    197                                 stream << "Can't choose between " << winners.size() << " alternatives for expression ";
    198                                 expr->print( stream );
    199                                 stream << "Alternatives are:";
    200193                                printAlts( winners, stream, 8 );
    201194                                throw SemanticError( stream.str() );
     
    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        }
     
    241228        void AlternativeFinder::addAggMembers( StructOrUnionType *aggInst, Expression *expr, const Cost &newCost, const TypeEnvironment & env, Expression * member ) {
    242229                // by this point, member must be a name expr
    243                 NameExpr * nameExpr = dynamic_cast< NameExpr * >( member );
    244                 if ( ! nameExpr ) return;
     230                NameExpr * nameExpr = safe_dynamic_cast< NameExpr * >( member );
    245231                const std::string & name = nameExpr->get_name();
    246232                std::list< Declaration* > members;
     
    264250                        // during parsing and reusing that information here.
    265251                        std::stringstream ss( constantExpr->get_constant()->get_value() );
    266                         int val = 0;
     252                        int val;
    267253                        std::string tmp;
    268254                        if ( ss >> val && ! (ss >> tmp) ) {
     
    286272        }
    287273
    288         Cost computeConversionCost( Type * actualType, Type * formalType, const SymTab::Indexer &indexer, const TypeEnvironment & env ) {
    289                 PRINT(
    290                         std::cerr << std::endl << "converting ";
    291                         actualType->print( std::cerr, 8 );
    292                         std::cerr << std::endl << " to ";
    293                         formalType->print( std::cerr, 8 );
    294                         std::cerr << std::endl << "environment is: ";
    295                         env.print( std::cerr, 8 );
    296                         std::cerr << std::endl;
    297                 )
    298                 Cost convCost = conversionCost( actualType, formalType, indexer, env );
    299                 PRINT(
    300                         std::cerr << std::endl << "cost is" << convCost << std::endl;
    301                 )
    302                 if ( convCost == Cost::infinity ) {
    303                         return convCost;
    304                 }
    305                 convCost.incPoly( polyCost( formalType, env, indexer ) + polyCost( actualType, env, indexer ) );
    306                 return convCost;
    307         }
    308 
    309         Cost computeExpressionConversionCost( Expression *& actualExpr, Type * formalType, const SymTab::Indexer &indexer, const TypeEnvironment & env ) {
    310                 Cost convCost = computeConversionCost( actualExpr->result, formalType, indexer, env );
    311                 // if ( convCost != Cost::zero ) {
    312 
    313                 // xxx - temporary -- ignore poly cost, since this causes some polymorphic functions to be cast, which causes the specialize
    314                 // pass to try to specialize them, which currently does not work. Once that is fixed, remove the next 3 lines and uncomment the
    315                 // previous line.
    316                 Cost tmpCost = convCost;
    317                 tmpCost.incPoly( -tmpCost.get_polyCost() );
    318                 if ( tmpCost != Cost::zero ) {
    319                         Type *newType = formalType->clone();
    320                         env.apply( newType );
    321                         actualExpr = new CastExpr( actualExpr, newType );
    322                         // xxx - SHOULD be able to resolve this cast, but at the moment pointers are not castable to zero_t, but are implicitly convertible. This is clearly
    323                         // inconsistent, once this is fixed it should be possible to resolve the cast.
    324                         // xxx - this isn't working, it appears because type1 (the formal type) is seen as widenable, but it shouldn't be, because this makes the conversion from DT* to DT* since commontype(zero_t, DT*) is DT*, rather than just nothing.
    325 
    326                         // AlternativeFinder finder( indexer, env );
    327                         // finder.findWithAdjustment( actualExpr );
    328                         // assertf( finder.get_alternatives().size() > 0, "Somehow castable expression failed to find alternatives." );
    329                         // assertf( finder.get_alternatives().size() == 1, "Somehow got multiple alternatives for known cast expression." );
    330                         // Alternative & alt = finder.get_alternatives().front();
    331                         // delete actualExpr;
    332                         // actualExpr = alt.expr->clone();
    333                 }
    334                 return convCost;
    335         }
    336 
    337         Cost computeApplicationConversionCost( Alternative &alt, const SymTab::Indexer &indexer ) {
     274        Cost computeConversionCost( Alternative &alt, const SymTab::Indexer &indexer ) {
    338275                ApplicationExpr *appExpr = safe_dynamic_cast< ApplicationExpr* >( alt.expr );
    339276                PointerType *pointer = safe_dynamic_cast< PointerType* >( appExpr->get_function()->get_result() );
    340277                FunctionType *function = safe_dynamic_cast< FunctionType* >( pointer->get_base() );
    341278
    342                 Cost convCost = Cost::zero;
     279                Cost convCost( 0, 0, 0 );
    343280                std::list< DeclarationWithType* >& formals = function->get_parameters();
    344281                std::list< DeclarationWithType* >::iterator formal = formals.begin();
     
    353290                                actualType->print( std::cerr, 8 );
    354291                        )
     292                        Cost actualCost;
    355293                        if ( formal == formals.end() ) {
    356294                                if ( function->get_isVarArgs() ) {
    357                                         convCost.incUnsafe();
    358                                         // convert reference-typed expressions to value-typed expressions
    359                                         referenceToRvalueConversion( *actualExpr );
     295                                        convCost += Cost( 1, 0, 0 );
    360296                                        continue;
    361297                                } else {
     
    369305                                std::cerr << std::endl << " to ";
    370306                                formalType->print( std::cerr, 8 );
    371                                 std::cerr << std::endl << "environment is: ";
    372                                 alt.env.print( std::cerr, 8 );
    373                                 std::cerr << std::endl;
    374                         )
    375                         convCost += computeExpressionConversionCost( *actualExpr, formalType, indexer, alt.env );
     307                        )
     308                        Cost newCost = conversionCost( actualType, formalType, indexer, alt.env );
     309                        PRINT(
     310                                std::cerr << std::endl << "cost is" << newCost << std::endl;
     311                        )
     312
     313                        if ( newCost == Cost::infinity ) {
     314                                return newCost;
     315                        }
     316                        convCost += newCost;
     317                        actualCost += newCost;
     318                        if ( actualCost != Cost( 0, 0, 0 ) ) {
     319                                Type *newType = formalType->clone();
     320                                alt.env.apply( newType );
     321                                *actualExpr = new CastExpr( *actualExpr, newType );
     322                        }
     323                        convCost += Cost( 0, polyCost( formalType, alt.env, indexer ) + polyCost( actualType, alt.env, indexer ), 0 );
    376324                        ++formal; // can't be in for-loop update because of the continue
    377325                }
     
    381329
    382330                for ( InferredParams::const_iterator assert = appExpr->get_inferParams().begin(); assert != appExpr->get_inferParams().end(); ++assert ) {
    383                         convCost += computeConversionCost( assert->second.actualType, assert->second.formalType, indexer, alt.env );
     331                        PRINT(
     332                                std::cerr << std::endl << "converting ";
     333                                assert->second.actualType->print( std::cerr, 8 );
     334                                std::cerr << std::endl << " to ";
     335                                assert->second.formalType->print( std::cerr, 8 );
     336                        )
     337                        Cost newCost = conversionCost( assert->second.actualType, assert->second.formalType, indexer, alt.env );
     338                        PRINT(
     339                                std::cerr << std::endl << "cost of conversion is " << newCost << std::endl;
     340                        )
     341                        if ( newCost == Cost::infinity ) {
     342                                return newCost;
     343                        }
     344                        convCost += newCost;
     345                        convCost += Cost( 0, polyCost( assert->second.formalType, alt.env, indexer ) + polyCost( assert->second.actualType, alt.env, indexer ), 0 );
    384346                }
    385347
     
    438400                        Expression * actual = actualIt->expr;
    439401                        Type * actualType = actual->get_result();
    440 
    441402                        PRINT(
    442403                                std::cerr << "formal type is ";
     
    447408                        )
    448409                        if ( ! unify( formalType, actualType, resultEnv, resultNeed, resultHave, openVars, indexer ) ) {
    449                                 // std::cerr << "unify failed" << std::endl;
    450410                                return false;
    451411                        }
     
    492452                        // match flattened actuals with formal parameters - actuals will be grouped to match
    493453                        // with formals as appropriate
    494                         Cost cost = Cost::zero;
     454                        Cost cost;
    495455                        std::list< Expression * > newExprs;
    496456                        ObjectDecl * obj = safe_dynamic_cast< ObjectDecl * >( formal );
     
    653613                AssertionSet newNeed;
    654614                //AssertionParentSet needParents;
    655                 PRINT(
    656                         std::cerr << "env is: " << std::endl;
    657                         newAlt.env.print( std::cerr, 0 );
    658                         std::cerr << std::endl;
    659                 )
    660 
    661615                inferRecursive( need.begin(), need.end(), newAlt, openVars, decls, newNeed, /*needParents,*/ 0, indexer, out );
    662616//      PRINT(
     
    689643                        makeExprList( instantiatedActuals, appExpr->get_args() );
    690644                        PRINT(
    691                                 std::cerr << "instantiate function success: " << appExpr << std::endl;
    692645                                std::cerr << "need assertions:" << std::endl;
    693646                                printAssertionSet( resultNeed, std::cerr, 8 );
     
    710663                                UntypedExpr *vexpr = untypedExpr->clone();
    711664                                vexpr->set_result( pt.clone() );
    712                                 alternatives.push_back( Alternative( vexpr, env, Cost::zero) );
     665                                alternatives.push_back( Alternative( vexpr, env, Cost()) );
    713666                                return;
    714667                        }
     
    728681                AltList candidates;
    729682                SemanticError errors;
    730                 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 ) {
    731684                        try {
    732685                                PRINT(
     
    735688                                )
    736689                                // check if the type is pointer to function
    737                                 if ( PointerType *pointer = dynamic_cast< PointerType* >( func->expr->get_result()->stripReferences() ) ) {
     690                                PointerType *pointer;
     691                                if ( ( pointer = dynamic_cast< PointerType* >( func->expr->get_result() ) ) ) {
    738692                                        if ( FunctionType *function = dynamic_cast< FunctionType* >( pointer->get_base() ) ) {
    739                                                 referenceToRvalueConversion( func->expr );
    740693                                                for ( std::list< AltList >::iterator actualAlt = possibilities.begin(); actualAlt != possibilities.end(); ++actualAlt ) {
    741694                                                        // XXX
     
    743696                                                        makeFunctionAlternatives( *func, function, *actualAlt, std::back_inserter( candidates ) );
    744697                                                }
    745                                         }
    746                                 } else if ( TypeInstType *typeInst = dynamic_cast< TypeInstType* >( func->expr->get_result()->stripReferences() ) ) { // handle ftype (e.g. *? on function pointer)
    747                                         referenceToRvalueConversion( func->expr );
    748                                         EqvClass eqvClass;
    749                                         if ( func->env.lookup( typeInst->get_name(), eqvClass ) && eqvClass.type ) {
    750                                                 if ( FunctionType *function = dynamic_cast< FunctionType* >( eqvClass.type ) ) {
    751                                                         for ( std::list< AltList >::iterator actualAlt = possibilities.begin(); actualAlt != possibilities.end(); ++actualAlt ) {
    752                                                                 makeFunctionAlternatives( *func, function, *actualAlt, std::back_inserter( candidates ) );
    753                                                         } // 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
    754706                                                } // if
    755707                                        } // if
     
    770722                                        }
    771723
    772                                         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 ) {
    773725                                                // check if the type is pointer to function
    774                                                 if ( PointerType *pointer = dynamic_cast< PointerType* >( funcOp->expr->get_result()->stripReferences() ) ) {
     726                                                PointerType *pointer;
     727                                                if ( ( pointer = dynamic_cast< PointerType* >( funcOp->expr->get_result() ) ) ) {
    775728                                                        if ( FunctionType *function = dynamic_cast< FunctionType* >( pointer->get_base() ) ) {
    776                                                                 referenceToRvalueConversion( funcOp->expr );
    777729                                                                for ( std::list< AltList >::iterator actualAlt = possibilities.begin(); actualAlt != possibilities.end(); ++actualAlt ) {
    778730                                                                        AltList currentAlt;
     
    795747                // compute conversionsion costs
    796748                for ( AltList::iterator withFunc = candidates.begin(); withFunc != candidates.end(); ++withFunc ) {
    797                         Cost cvtCost = computeApplicationConversionCost( *withFunc, indexer );
     749                        Cost cvtCost = computeConversionCost( *withFunc, indexer );
    798750
    799751                        PRINT(
     
    801753                                PointerType *pointer = safe_dynamic_cast< PointerType* >( appExpr->get_function()->get_result() );
    802754                                FunctionType *function = safe_dynamic_cast< FunctionType* >( pointer->get_base() );
    803                                 std::cerr << "Case +++++++++++++ " << appExpr->get_function() << std::endl;
     755                                std::cerr << "Case +++++++++++++" << std::endl;
    804756                                std::cerr << "formals are:" << std::endl;
    805757                                printAll( function->get_parameters(), std::cerr, 8 );
     
    844796        bool isLvalue( Expression *expr ) {
    845797                // xxx - recurse into tuples?
    846                 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();
    847799        }
    848800
     
    858810
    859811        Expression * restructureCast( Expression * argExpr, Type * toType ) {
    860                 if ( argExpr->get_result()->size() > 1 && ! toType->isVoid() && ! dynamic_cast<ReferenceType *>( toType ) ) {
    861                         // Argument expression is a tuple and the target type is not void and not a reference type.
    862                         // Cast each member of the tuple to its corresponding target type, producing the tuple of those
    863                         // cast expressions. If there are more components of the tuple than components in the target type,
    864                         // then excess components do not come out in the result expression (but UniqueExprs ensure that
    865                         // side effects will still be done).
    866                         if ( Tuples::maybeImpureIgnoreUnique( argExpr ) ) {
     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).
     817                        if ( Tuples::maybeImpure( argExpr ) && ! dynamic_cast< UniqueExpr * >( argExpr ) ) {
    867818                                // expressions which may contain side effects require a single unique instance of the expression.
    868819                                argExpr = new UniqueExpr( argExpr );
     
    904855                        // that are cast directly.  The candidate is invalid if it has fewer results than there are types to cast
    905856                        // to.
    906                         int discardedValues = i->expr->get_result()->size() - castExpr->get_result()->size();
     857                        int discardedValues = (*i).expr->get_result()->size() - castExpr->get_result()->size();
    907858                        if ( discardedValues < 0 ) continue;
    908859                        // xxx - may need to go into tuple types and extract relevant types and use unifyList. Note that currently, this does not
    909860                        // allow casting a tuple to an atomic type (e.g. (int)([1, 2, 3]))
    910861                        // unification run for side-effects
    911                         unify( castExpr->get_result(), i->expr->get_result(), i->env, needAssertions, haveAssertions, openVars, indexer );
    912                         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 );
    913864                        if ( thisCost != Cost::infinity ) {
    914865                                // count one safe conversion for each value that is thrown away
    915                                 thisCost.incSafe( discardedValues );
    916                                 Alternative newAlt( restructureCast( i->expr->clone(), toType ), i->env, i->cost, thisCost );
    917                                 // xxx - this doesn't work at the moment, since inferParameters requires an ApplicationExpr as the alternative.
    918                                 // Once this works, it should be possible to infer parameters on a cast expression and specialize any function.
    919 
    920                                 // inferParameters( needAssertions, haveAssertions, newAlt, openVars, back_inserter( candidates ) );
    921                                 candidates.emplace_back( std::move( newAlt ) );
     866                                thisCost += Cost( 0, 0, discardedValues );
     867
     868                                candidates.push_back( Alternative( restructureCast( i->expr->clone(), toType ), i->env, i->cost, thisCost ) );
    922869                        } // if
    923870                } // for
     
    948895                funcFinder.findWithAdjustment( memberExpr->get_aggregate() );
    949896                for ( AltList::const_iterator agg = funcFinder.alternatives.begin(); agg != funcFinder.alternatives.end(); ++agg ) {
    950                         // 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
    951                         std::unique_ptr<Expression> aggrExpr( agg->expr->clone() );
    952                         Type * aggrType = aggrExpr->get_result();
    953                         if ( dynamic_cast< ReferenceType * >( aggrType ) ) {
    954                                 aggrType = aggrType->stripReferences();
    955                                 aggrExpr.reset( new CastExpr( aggrExpr.release(), aggrType->clone() ) );
    956                         }
    957                         // find member of the given type
    958                         if ( StructInstType *structInst = dynamic_cast< StructInstType* >( aggrExpr->get_result() ) ) {
    959                                 addAggMembers( structInst, aggrExpr.get(), agg->cost, agg->env, memberExpr->get_member() );
    960                         } else if ( UnionInstType *unionInst = dynamic_cast< UnionInstType* >( aggrExpr->get_result() ) ) {
    961                                 addAggMembers( unionInst, aggrExpr.get(), agg->cost, agg->env, memberExpr->get_member() );
    962                         } else if ( TupleType * tupleType = dynamic_cast< TupleType * >( aggrExpr->get_result() ) ) {
    963                                 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() );
    964903                        } // if
    965904                } // for
     
    976915                for ( std::list< DeclarationWithType* >::iterator i = declList.begin(); i != declList.end(); ++i ) {
    977916                        VariableExpr newExpr( *i, nameExpr->get_argName() );
    978                         alternatives.push_back( Alternative( newExpr.clone(), env, Cost::zero ) );
     917                        alternatives.push_back( Alternative( newExpr.clone(), env, Cost() ) );
    979918                        PRINT(
    980919                                std::cerr << "decl is ";
     
    1016955                        // return the lowest cost alternative for the argument
    1017956                        Alternative &choice = winners.front();
    1018                         referenceToRvalueConversion( choice.expr );
    1019957                        alternatives.push_back( Alternative( new SizeofExpr( choice.expr->clone() ), choice.env, Cost::zero ) );
    1020958                } // if
     
    1037975                        // return the lowest cost alternative for the argument
    1038976                        Alternative &choice = winners.front();
    1039                         referenceToRvalueConversion( choice.expr );
    1040977                        alternatives.push_back( Alternative( new AlignofExpr( choice.expr->clone() ), choice.env, Cost::zero ) );
    1041978                } // if
     
    11221059                        for ( std::list< DeclarationWithType* >::iterator i = attrList.begin(); i != attrList.end(); ++i ) {
    11231060                                VariableExpr newExpr( *i );
    1124                                 alternatives.push_back( Alternative( newExpr.clone(), env, Cost::zero ) );
     1061                                alternatives.push_back( Alternative( newExpr.clone(), env, Cost() ) );
    11251062                                renameTypes( alternatives.back().expr );
    11261063                        } // for
     
    11621099                                                ConditionalExpr *newExpr = new ConditionalExpr( first->expr->clone(), second->expr->clone(), third->expr->clone() );
    11631100                                                newExpr->set_result( commonType ? commonType : second->expr->get_result()->clone() );
    1164                                                 // convert both options to the conditional result type
    1165                                                 newAlt.cost += computeExpressionConversionCost( newExpr->arg2, newExpr->result, indexer, newAlt.env );
    1166                                                 newAlt.cost += computeExpressionConversionCost( newExpr->arg3, newExpr->result, indexer, newAlt.env );
    11671101                                                newAlt.expr = newExpr;
    11681102                                                inferParameters( needAssertions, haveAssertions, newAlt, openVars, back_inserter( alternatives ) );
     
    12981232                                if ( thisCost != Cost::infinity ) {
    12991233                                        // count one safe conversion for each value that is thrown away
    1300                                         thisCost.incSafe( discardedValues );
     1234                                        thisCost += Cost( 0, 0, discardedValues );
    13011235                                        candidates.push_back( Alternative( new InitExpr( restructureCast( alt.expr->clone(), toType ), initAlt.designation->clone() ), newEnv, alt.cost, thisCost ) );
    13021236                                }
Note: See TracChangeset for help on using the changeset viewer.