Ignore:
Timestamp:
Jan 11, 2017, 4:11:02 PM (9 years ago)
Author:
Thierry Delisle <tdelisle@…>
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:
075734f
Parents:
bb82c03 (diff), d3a85240 (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the (diff) links above to see all the changes relative to each parent.
Message:

Merge branch 'master' of plg.uwaterloo.ca:software/cfa/cfa-cc

File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/ResolvExpr/AlternativeFinder.cc

    rbb82c03 r2162c2c  
    267267                std::list< Expression* >& actuals = appExpr->get_args();
    268268
    269                 std::list< Type * > formalTypes;
    270                 std::list< Type * >::iterator formalType = formalTypes.end();
    271 
    272269                for ( std::list< Expression* >::iterator actualExpr = actuals.begin(); actualExpr != actuals.end(); ++actualExpr ) {
    273 
     270                        Type * actualType = (*actualExpr)->get_result();
    274271                        PRINT(
    275272                                std::cerr << "actual expression:" << std::endl;
    276273                                (*actualExpr)->print( std::cerr, 8 );
    277274                                std::cerr << "--- results are" << std::endl;
    278                                 (*actualExpr)->get_result()->print( std::cerr, 8 );
    279                         )
    280                         std::list< DeclarationWithType* >::iterator startFormal = formal;
     275                                actualType->print( std::cerr, 8 );
     276                        )
    281277                        Cost actualCost;
    282                         std::list< Type * > flatActualTypes;
    283                         flatten( (*actualExpr)->get_result(), back_inserter( flatActualTypes ) );
    284                         for ( std::list< Type* >::iterator actualType = flatActualTypes.begin(); actualType != flatActualTypes.end(); ++actualType ) {
    285 
    286 
    287                                 // tuple handling code
    288                                 if ( formalType == formalTypes.end() ) {
    289                                         // the type of the formal parameter may be a tuple type. To make this easier to work with,
    290                                         // flatten the tuple type and traverse the resulting list of types, incrementing the formal
    291                                         // iterator once its types have been extracted. Once a particular formal parameter's type has
    292                                         // been exhausted load the next formal parameter's type.
    293                                         if ( formal == formals.end() ) {
    294                                                 if ( function->get_isVarArgs() ) {
    295                                                         convCost += Cost( 1, 0, 0 );
    296                                                         break;
    297                                                 } else {
    298                                                         return Cost::infinity;
    299                                                 }
    300                                         }
    301                                         formalTypes.clear();
    302                                         flatten( (*formal)->get_type(), back_inserter( formalTypes ) );
    303                                         formalType = formalTypes.begin();
    304                                         ++formal;
     278                        if ( formal == formals.end() ) {
     279                                if ( function->get_isVarArgs() ) {
     280                                        convCost += Cost( 1, 0, 0 );
     281                                        continue;
     282                                } else {
     283                                        return Cost::infinity;
    305284                                }
    306 
    307                                 PRINT(
    308                                         std::cerr << std::endl << "converting ";
    309                                         (*actualType)->print( std::cerr, 8 );
    310                                         std::cerr << std::endl << " to ";
    311                                         (*formalType)->print( std::cerr, 8 );
    312                                 )
    313                                 Cost newCost = conversionCost( *actualType, *formalType, indexer, alt.env );
    314                                 PRINT(
    315                                         std::cerr << std::endl << "cost is" << newCost << std::endl;
    316                                 )
    317 
    318                                 if ( newCost == Cost::infinity ) {
    319                                         return newCost;
    320                                 }
    321                                 convCost += newCost;
    322                                 actualCost += newCost;
    323 
    324                                 convCost += Cost( 0, polyCost( *formalType, alt.env, indexer ) + polyCost( *actualType, alt.env, indexer ), 0 );
    325 
    326                                 formalType++;
    327                         }
     285                        }
     286                        Type * formalType = (*formal)->get_type();
     287                        PRINT(
     288                                std::cerr << std::endl << "converting ";
     289                                actualType->print( std::cerr, 8 );
     290                                std::cerr << std::endl << " to ";
     291                                formalType->print( std::cerr, 8 );
     292                        )
     293                        Cost newCost = conversionCost( actualType, formalType, indexer, alt.env );
     294                        PRINT(
     295                                std::cerr << std::endl << "cost is" << newCost << std::endl;
     296                        )
     297
     298                        if ( newCost == Cost::infinity ) {
     299                                return newCost;
     300                        }
     301                        convCost += newCost;
     302                        actualCost += newCost;
    328303                        if ( actualCost != Cost( 0, 0, 0 ) ) {
    329                                 std::list< DeclarationWithType* >::iterator startFormalPlusOne = startFormal;
    330                                 startFormalPlusOne++;
    331                                 if ( formal == startFormalPlusOne ) {
    332                                         // not a tuple type
    333                                         Type *newType = (*startFormal)->get_type()->clone();
    334                                         alt.env.apply( newType );
    335                                         *actualExpr = new CastExpr( *actualExpr, newType );
    336                                 } else {
    337                                         TupleType *newType = new TupleType( Type::Qualifiers() );
    338                                         for ( std::list< DeclarationWithType* >::iterator i = startFormal; i != formal; ++i ) {
    339                                                 newType->get_types().push_back( (*i)->get_type()->clone() );
    340                                         }
    341                                         alt.env.apply( newType );
    342                                         *actualExpr = new CastExpr( *actualExpr, newType );
    343                                 }
    344                         }
    345 
     304                                Type *newType = formalType->clone();
     305                                alt.env.apply( newType );
     306                                *actualExpr = new CastExpr( *actualExpr, newType );
     307                        }
     308                        convCost += Cost( 0, polyCost( formalType, alt.env, indexer ) + polyCost( actualType, alt.env, indexer ), 0 );
     309                        ++formal; // can't be in for-loop update because of the continue
    346310                }
    347311                if ( formal != formals.end() ) {
     
    364328                        }
    365329                        convCost += newCost;
    366 
    367330                        convCost += Cost( 0, polyCost( assert->second.formalType, alt.env, indexer ) + polyCost( assert->second.actualType, alt.env, indexer ), 0 );
    368331                }
     
    376339                        unifiableVars[ (*tyvar)->get_name() ] = TypeDecl::Data{ *tyvar };
    377340                        for ( std::list< DeclarationWithType* >::iterator assert = (*tyvar)->get_assertions().begin(); assert != (*tyvar)->get_assertions().end(); ++assert ) {
    378                                 needAssertions[ *assert ] = true;
     341                                needAssertions[ *assert ].isUsed = true;
    379342                        }
    380343///     needAssertions.insert( needAssertions.end(), (*tyvar)->get_assertions().begin(), (*tyvar)->get_assertions().end() );
     
    388351                if ( TupleType * tupleType = dynamic_cast< TupleType * >( formalType ) ) {
    389352                        // formalType is a TupleType - group actuals into a TupleExpr whose type unifies with the TupleType
    390                         TupleExpr * tupleExpr = new TupleExpr();
     353                        std::list< Expression * > exprs;
    391354                        for ( Type * type : *tupleType ) {
    392                                 if ( ! instantiateArgument( type, defaultValue, actualIt, actualEnd, openVars, resultEnv, resultNeed, resultHave, indexer, cost, back_inserter( tupleExpr->get_exprs() ) ) ) {
    393                                         delete tupleExpr;
     355                                if ( ! instantiateArgument( type, defaultValue, actualIt, actualEnd, openVars, resultEnv, resultNeed, resultHave, indexer, cost, back_inserter( exprs ) ) ) {
     356                                        deleteAll( exprs );
    394357                                        return false;
    395358                                }
    396359                        }
    397                         tupleExpr->set_result( Tuples::makeTupleType( tupleExpr->get_exprs() ) );
    398                         *out++ = tupleExpr;
     360                        *out++ = new TupleExpr( exprs );
     361                } else if ( TypeInstType * ttype = Tuples::isTtype( formalType ) ) {
     362                        // xxx - mixing default arguments with variadic??
     363                        std::list< Expression * > exprs;
     364                        for ( ; actualIt != actualEnd; ++actualIt ) {
     365                                exprs.push_back( actualIt->expr->clone() );
     366                                cost += actualIt->cost;
     367                        }
     368                        Expression * arg = nullptr;
     369                        if ( exprs.size() == 1 && Tuples::isTtype( exprs.front()->get_result() ) ) {
     370                                // the case where a ttype value is passed directly is special, e.g. for argument forwarding purposes
     371                                // xxx - what if passing multiple arguments, last of which is ttype?
     372                                // xxx - what would happen if unify was changed so that unifying tuple types flattened both before unifying lists? then pass in TupleType(ttype) below.
     373                                arg = exprs.front();
     374                        } else {
     375                                arg = new TupleExpr( exprs );
     376                        }
     377                        assert( arg && arg->get_result() );
     378                        if ( ! unify( ttype, arg->get_result(), resultEnv, resultNeed, resultHave, openVars, indexer ) ) {
     379                                return false;
     380                        }
     381                        *out++ = arg;
    399382                } else if ( actualIt != actualEnd ) {
    400383                        // both actualType and formalType are atomic (non-tuple) types - if they unify
     
    483466        void addToIndexer( AssertionSet &assertSet, SymTab::Indexer &indexer ) {
    484467                for ( AssertionSet::iterator i = assertSet.begin(); i != assertSet.end(); ++i ) {
    485                         if ( i->second == true ) {
     468                        if ( i->second.isUsed ) {
    486469                                i->first->accept( indexer );
    487470                        }
     
    494477                if ( begin == end ) {
    495478                        if ( newNeed.empty() ) {
     479                                PRINT(
     480                                        std::cerr << "all assertions satisfied, output alternative: ";
     481                                        newAlt.print( std::cerr );
     482                                        std::cerr << std::endl;
     483                                );
    496484                                *out++ = newAlt;
    497485                                return;
     
    510498
    511499                ForwardIterator cur = begin++;
    512                 if ( ! cur->second ) {
     500                if ( ! cur->second.isUsed ) {
    513501                        inferRecursive( begin, end, newAlt, openVars, decls, newNeed, /*needParents,*/ level, indexer, out );
    514502                        return; // xxx - should this continue? previously this wasn't here, and it looks like it should be
     
    554542                                assert( (*candidate)->get_uniqueId() );
    555543                                DeclarationWithType *candDecl = static_cast< DeclarationWithType* >( Declaration::declFromId( (*candidate)->get_uniqueId() ) );
     544
     545                                // everything with an empty idChain was pulled in by the current assertion.
     546                                // add current assertion's idChain + current assertion's ID so that the correct inferParameters can be found.
     547                                for ( auto & a : newerNeed ) {
     548                                        if ( a.second.idChain.empty() ) {
     549                                                a.second.idChain = cur->second.idChain;
     550                                                a.second.idChain.push_back( curDecl->get_uniqueId() );
     551                                        }
     552                                }
     553
    556554                                //AssertionParentSet newNeedParents( needParents );
    557555                                // skip repeatingly-self-recursive assertion satisfaction
     
    569567                                )
    570568                                ApplicationExpr *appExpr = static_cast< ApplicationExpr* >( newerAlt.expr );
     569                                // follow the current assertion's ID chain to find the correct set of inferred parameters to add the candidate to (i.e. the set of inferred parameters belonging to the entity which requested the assertion parameter).
     570                                InferredParams * inferParameters = &appExpr->get_inferParams();
     571                                for ( UniqueId id : cur->second.idChain ) {
     572                                        inferParameters = (*inferParameters)[ id ].inferParams.get();
     573                                }
    571574                                // XXX: this is a memory leak, but adjType can't be deleted because it might contain assertions
    572                                 appExpr->get_inferParams()[ curDecl->get_uniqueId() ] = ParamEntry( (*candidate)->get_uniqueId(), adjType->clone(), curDecl->get_type()->clone(), varExpr );
     575                                (*inferParameters)[ curDecl->get_uniqueId() ] = ParamEntry( (*candidate)->get_uniqueId(), adjType->clone(), curDecl->get_type()->clone(), varExpr );
    573576                                inferRecursive( begin, end, newerAlt, newOpenVars, newDecls, newerNeed, /*newNeedParents,*/ level, indexer, out );
    574577                        } else {
     
    609612                makeUnifiableVars( funcType, openVars, resultNeed );
    610613                AltList instantiatedActuals; // filled by instantiate function
    611                 if ( targetType && ! targetType->isVoid() ) {
     614                if ( targetType && ! targetType->isVoid() && ! funcType->get_returnVals().empty() ) {
    612615                        // attempt to narrow based on expected target type
    613616                        Type * returnType = funcType->get_returnVals().front()->get_type();
     
    10751078        }
    10761079
    1077         void AlternativeFinder::visit( TupleExpr *tupleExpr ) {
     1080        void AlternativeFinder::visit( UntypedTupleExpr *tupleExpr ) {
    10781081                std::list< AlternativeFinder > subExprAlternatives;
    10791082                findSubExprs( tupleExpr->get_exprs().begin(), tupleExpr->get_exprs().end(), back_inserter( subExprAlternatives ) );
     
    10811084                combos( subExprAlternatives.begin(), subExprAlternatives.end(), back_inserter( possibilities ) );
    10821085                for ( std::list< AltList >::const_iterator i = possibilities.begin(); i != possibilities.end(); ++i ) {
    1083                         TupleExpr *newExpr = new TupleExpr;
    1084                         makeExprList( *i, newExpr->get_exprs() );
    1085                         newExpr->set_result( Tuples::makeTupleType( newExpr->get_exprs() ) );
     1086                        std::list< Expression * > exprs;
     1087                        makeExprList( *i, exprs );
    10861088
    10871089                        TypeEnvironment compositeEnv;
    10881090                        simpleCombineEnvironments( i->begin(), i->end(), compositeEnv );
    1089                         alternatives.push_back( Alternative( newExpr, compositeEnv, sumCost( *i ) ) );
     1091                        alternatives.push_back( Alternative( new TupleExpr( exprs ) , compositeEnv, sumCost( *i ) ) );
    10901092                } // for
     1093        }
     1094
     1095        void AlternativeFinder::visit( TupleExpr *tupleExpr ) {
     1096                alternatives.push_back( Alternative( tupleExpr->clone(), env, Cost::zero ) );
    10911097        }
    10921098
Note: See TracChangeset for help on using the changeset viewer.