Changeset b1bead1 for src/ResolvExpr


Ignore:
Timestamp:
Aug 8, 2017, 8:36:48 PM (7 years ago)
Author:
Rob Schluntz <rschlunt@…>
Branches:
ADT, aaron-thesis, arm-eh, ast-experimental, cleanup-dtors, deferred_resn, demangler, enum, forall-pointer-decay, jacob/cs343-translation, jenkins-sandbox, master, new-ast, new-ast-unique-expr, new-env, no_list, persistent-indexer, pthread-emulation, qualifiedEnum, resolv-new, with_gc
Children:
8499c707
Parents:
83794e1
Message:

Add reference to rvalue conversions to functions when resolving UntypedExpr?

File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/ResolvExpr/AlternativeFinder.cc

    r83794e1 rb1bead1  
    144144                        expr->get_result()->accept( global_renamer );
    145145                }
    146         }
     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
    147154
    148155        template< typename InputIterator, typename OutputIterator >
     
    300307                                if ( function->get_isVarArgs() ) {
    301308                                        convCost.incUnsafe();
     309                                        // convert reference-typed expressions to value-typed expressions
     310                                        referenceToRvalueConversion( *actualExpr );
    302311                                        continue;
    303312                                } else {
     
    693702                AltList candidates;
    694703                SemanticError errors;
    695                 for ( AltList::const_iterator func = funcFinder.alternatives.begin(); func != funcFinder.alternatives.end(); ++func ) {
     704                for ( AltList::iterator func = funcFinder.alternatives.begin(); func != funcFinder.alternatives.end(); ++func ) {
    696705                        try {
    697706                                PRINT(
     
    700709                                )
    701710                                // check if the type is pointer to function
    702                                 PointerType *pointer;
    703                                 if ( ( pointer = dynamic_cast< PointerType* >( func->expr->get_result() ) ) ) {
     711                                if ( PointerType *pointer = dynamic_cast< PointerType* >( func->expr->get_result()->stripReferences() ) ) {
    704712                                        if ( FunctionType *function = dynamic_cast< FunctionType* >( pointer->get_base() ) ) {
     713                                                referenceToRvalueConversion( func->expr );
    705714                                                for ( std::list< AltList >::iterator actualAlt = possibilities.begin(); actualAlt != possibilities.end(); ++actualAlt ) {
    706715                                                        // XXX
     
    708717                                                        makeFunctionAlternatives( *func, function, *actualAlt, std::back_inserter( candidates ) );
    709718                                                }
    710                                         } else if ( TypeInstType *typeInst = dynamic_cast< TypeInstType* >( pointer->get_base() ) ) {
    711                                                 EqvClass eqvClass;
    712                                                 if ( func->env.lookup( typeInst->get_name(), eqvClass ) && eqvClass.type ) {
    713                                                         if ( FunctionType *function = dynamic_cast< FunctionType* >( eqvClass.type ) ) {
    714                                                                 for ( std::list< AltList >::iterator actualAlt = possibilities.begin(); actualAlt != possibilities.end(); ++actualAlt ) {
    715                                                                         makeFunctionAlternatives( *func, function, *actualAlt, std::back_inserter( candidates ) );
    716                                                                 } // for
    717                                                         } // if
     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
    718728                                                } // if
    719729                                        } // if
     
    734744                                        }
    735745
    736                                         for ( AltList::const_iterator funcOp = funcOpFinder.alternatives.begin(); funcOp != funcOpFinder.alternatives.end(); ++funcOp ) {
     746                                        for ( AltList::iterator funcOp = funcOpFinder.alternatives.begin(); funcOp != funcOpFinder.alternatives.end(); ++funcOp ) {
    737747                                                // check if the type is pointer to function
    738                                                 PointerType *pointer;
    739                                                 if ( ( pointer = dynamic_cast< PointerType* >( funcOp->expr->get_result() ) ) ) {
     748                                                if ( PointerType *pointer = dynamic_cast< PointerType* >( funcOp->expr->get_result()->stripReferences() ) ) {
    740749                                                        if ( FunctionType *function = dynamic_cast< FunctionType* >( pointer->get_base() ) ) {
     750                                                                referenceToRvalueConversion( funcOp->expr );
    741751                                                                for ( std::list< AltList >::iterator actualAlt = possibilities.begin(); actualAlt != possibilities.end(); ++actualAlt ) {
    742752                                                                        AltList currentAlt;
     
    868878                        // that are cast directly.  The candidate is invalid if it has fewer results than there are types to cast
    869879                        // to.
    870                         int discardedValues = (*i).expr->get_result()->size() - castExpr->get_result()->size();
     880                        int discardedValues = i->expr->get_result()->size() - castExpr->get_result()->size();
    871881                        if ( discardedValues < 0 ) continue;
    872882                        // xxx - may need to go into tuple types and extract relevant types and use unifyList. Note that currently, this does not
    873883                        // allow casting a tuple to an atomic type (e.g. (int)([1, 2, 3]))
    874884                        // unification run for side-effects
    875                         unify( castExpr->get_result(), (*i).expr->get_result(), i->env, needAssertions, haveAssertions, openVars, indexer );
    876                         Cost thisCost = castCost( (*i).expr->get_result(), castExpr->get_result(), indexer, i->env );
     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 );
    877887                        if ( thisCost != Cost::infinity ) {
    878888                                // count one safe conversion for each value that is thrown away
Note: See TracChangeset for help on using the changeset viewer.