Ignore:
Timestamp:
Jun 29, 2018, 4:14:15 PM (7 years ago)
Author:
Aaron Moss <a3moss@…>
Branches:
new-env
Children:
184557e
Parents:
97397a26 (diff), 28f3a19 (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 remote-tracking branch 'origin/with_gc' into new-env

File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/ResolvExpr/AlternativeFinder.cc

    r97397a26 rb21c77a  
    100100                void postvisit( InitExpr * initExpr );
    101101                void postvisit( DeletedExpr * delExpr );
     102                void postvisit( GenericExpr * genExpr );
    102103
    103104                /// Adds alternatives for anonymous members
     
    177178                                                selected[ mangleName ] = current;
    178179                                        } else if ( candidate->cost == mapPlace->second.candidate->cost ) {
    179                                                 PRINT(
    180                                                         std::cerr << "marking ambiguous" << std::endl;
    181                                                 )
    182                                                 mapPlace->second.isAmbiguous = true;
     180                                                // if one of the candidates contains a deleted identifier, can pick the other, since
     181                                                // deleted expressions should not be ambiguous if there is another option that is at least as good
     182                                                if ( findDeletedExpr( candidate->expr ) ) {
     183                                                        // do nothing
     184                                                        PRINT( std::cerr << "candidate is deleted" << std::endl; )
     185                                                } else if ( findDeletedExpr( mapPlace->second.candidate->expr ) ) {
     186                                                        PRINT( std::cerr << "current is deleted" << std::endl; )
     187                                                        selected[ mangleName ] = current;
     188                                                } else {
     189                                                        PRINT(
     190                                                                std::cerr << "marking ambiguous" << std::endl;
     191                                                        )
     192                                                        mapPlace->second.isAmbiguous = true;
     193                                                }
    183194                                        } else {
    184195                                                PRINT(
     
    300311                // 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
    301312                Expression* aggrExpr = alt.expr->clone();
    302                 alt.env.apply( aggrExpr->get_result() );
    303                 Type * aggrType = aggrExpr->get_result();
     313                alt.env.apply( aggrExpr->result );
     314                Type * aggrType = aggrExpr->result;
    304315                if ( dynamic_cast< ReferenceType * >( aggrType ) ) {
    305316                        aggrType = aggrType->stripReferences();
     
    307318                }
    308319
    309                 if ( StructInstType *structInst = dynamic_cast< StructInstType* >( aggrExpr->get_result() ) ) {
     320                if ( StructInstType *structInst = dynamic_cast< StructInstType* >( aggrExpr->result ) ) {
    310321                        addAggMembers( structInst, aggrExpr, alt.cost+Cost::safe, alt.env, "" );
    311                 } else if ( UnionInstType *unionInst = dynamic_cast< UnionInstType* >( aggrExpr->get_result() ) ) {
     322                } else if ( UnionInstType *unionInst = dynamic_cast< UnionInstType* >( aggrExpr->result ) ) {
    312323                        addAggMembers( unionInst, aggrExpr, alt.cost+Cost::safe, alt.env, "" );
    313324                } // if
     
    319330                aggInst->lookup( name, members );
    320331
    321                 for ( std::list< Declaration* >::const_iterator i = members.begin(); i != members.end(); ++i ) {
    322                         if ( DeclarationWithType *dwt = dynamic_cast< DeclarationWithType* >( *i ) ) {
    323                                 alternatives.push_back( Alternative( new MemberExpr( dwt, expr->clone() ), env, newCost ) );
    324                                 renameTypes( alternatives.back().expr );
    325                                 addAnonConversions( alternatives.back() ); // add anonymous member interpretations whenever an aggregate value type is seen as a member expression.
     332                for ( Declaration * decl : members ) {
     333                        if ( DeclarationWithType *dwt = dynamic_cast< DeclarationWithType* >( decl ) ) {
     334                                // addAnonAlternatives uses vector::push_back, which invalidates references to existing elements, so
     335                                // can't construct in place and use vector::back
     336                                Alternative newAlt( new MemberExpr( dwt, expr->clone() ), env, newCost );
     337                                renameTypes( newAlt.expr );
     338                                addAnonConversions( newAlt ); // add anonymous member interpretations whenever an aggregate value type is seen as a member expression.
     339                                alternatives.push_back( std::move(newAlt) );
    326340                        } else {
    327341                                assert( false );
     
    333347                if ( ConstantExpr * constantExpr = dynamic_cast< ConstantExpr * >( member ) ) {
    334348                        // get the value of the constant expression as an int, must be between 0 and the length of the tuple type to have meaning
    335                         // xxx - this should be improved by memoizing the value of constant exprs
    336                         // during parsing and reusing that information here.
    337                         std::stringstream ss( constantExpr->get_constant()->get_value() );
    338                         int val = 0;
     349                        auto val = constantExpr->intValue();
    339350                        std::string tmp;
    340                         if ( ss >> val && ! (ss >> tmp) ) {
    341                                 if ( val >= 0 && (unsigned int)val < tupleType->size() ) {
    342                                         alternatives.push_back( Alternative( new TupleIndexExpr( expr, val ), env, newCost ) );
    343                                 } // if
     351                        if ( val >= 0 && (unsigned long long)val < tupleType->size() ) {
     352                                alternatives.push_back( Alternative( new TupleIndexExpr( expr->clone(), val ), env, newCost ) );
    344353                        } // if
    345                 } else if ( NameExpr * nameExpr = dynamic_cast< NameExpr * >( member ) ) {
    346                         // xxx - temporary hack until 0/1 are int constants
    347                         if ( nameExpr->get_name() == "0" || nameExpr->get_name() == "1" ) {
    348                                 std::stringstream ss( nameExpr->get_name() );
    349                                 int val;
    350                                 ss >> val;
    351                                 alternatives.push_back( Alternative( new TupleIndexExpr( expr, val ), env, newCost ) );
    352                         }
    353354                } // if
    354355        }
     
    437438                                        return Cost::infinity;
    438439                                }
     440                        }
     441                        if ( DefaultArgExpr * def = dynamic_cast< DefaultArgExpr * >( *actualExpr ) ) {
     442                                // default arguments should be free - don't include conversion cost.
     443                                // Unwrap them here because they are not relevant to the rest of the system.
     444                                *actualExpr = def->expr;
     445                                ++formal;
     446                                continue;
    439447                        }
    440448                        Type * formalType = (*formal)->get_type();
     
    764772        ConstantExpr* getDefaultValue( Initializer* init ) {
    765773                if ( SingleInit* si = dynamic_cast<SingleInit*>( init ) ) {
    766                         if ( CastExpr* ce = dynamic_cast<CastExpr*>( si->get_value() ) ) {
    767                                 return dynamic_cast<ConstantExpr*>( ce->get_arg() );
     774                        if ( CastExpr* ce = dynamic_cast<CastExpr*>( si->value ) ) {
     775                                return dynamic_cast<ConstantExpr*>( ce->arg );
     776                        } else {
     777                                return dynamic_cast<ConstantExpr*>( si->value );
    768778                        }
    769779                }
     
    10261036                                                                indexer ) ) {
    10271037                                                        results.emplace_back(
    1028                                                                 i, cnstExpr, move(env), move(need), move(have),
     1038                                                                i, new DefaultArgExpr( cnstExpr ), move(env), move(need), move(have),
    10291039                                                                move(openVars), nextArg, nTuples );
    10301040                                                }
     
    13591369                funcFinder.findWithAdjustment( untypedExpr->function );
    13601370                // if there are no function alternatives, then proceeding is a waste of time.
     1371                // xxx - findWithAdjustment throws, so this check and others like it shouldn't be necessary.
    13611372                if ( funcFinder.alternatives.empty() ) return;
    13621373
     
    13861397                        argExpansions.emplace_back();
    13871398                        auto& argE = argExpansions.back();
    1388                         argE.reserve( arg.alternatives.size() );
     1399                        // argE.reserve( arg.alternatives.size() );
    13891400
    13901401                        for ( const Alternative& actual : arg ) {
     
    14091420                                                        std::back_inserter( candidates ) );
    14101421                                        }
    1411                                 } else if ( TypeInstType *typeInst = dynamic_cast< TypeInstType* >( func->expr->get_result()->stripReferences() ) ) { // handle ftype (e.g. *? on function pointer)
    1412                                         if ( ClassRef eqvClass = func->env.lookup( typeInst->get_name() ) ) {
     1422                                } else if ( TypeInstType *typeInst = dynamic_cast< TypeInstType* >( func->expr->result->stripReferences() ) ) { // handle ftype (e.g. *? on function pointer)
     1423                                        if ( ClassRef eqvClass = func->env.lookup( typeInst->name ) ) {
    14131424                                                if ( FunctionType *function = dynamic_cast< FunctionType* >( eqvClass.get_bound().type ) ) {
    14141425                                                        Alternative newFunc( *func );
     
    16651676                        Cost cost = Cost::zero;
    16661677                        Expression * newExpr = data.combine( cost );
    1667                         alternatives.push_back( Alternative( newExpr, env, Cost::zero, cost ) );
     1678
     1679                        // addAnonAlternatives uses vector::push_back, which invalidates references to existing elements, so
     1680                        // can't construct in place and use vector::back
     1681                        Alternative newAlt( newExpr, env, Cost::zero, cost );
    16681682                        PRINT(
    16691683                                std::cerr << "decl is ";
     
    16741688                                std::cerr << std::endl;
    16751689                        )
    1676                         renameTypes( alternatives.back().expr );
    1677                         addAnonConversions( alternatives.back() ); // add anonymous member interpretations whenever an aggregate value type is seen as a name expression.
     1690                        renameTypes( newAlt.expr );
     1691                        addAnonConversions( newAlt ); // add anonymous member interpretations whenever an aggregate value type is seen as a name expression.
     1692                        alternatives.push_back( std::move(newAlt) );
    16781693                } // for
    16791694        }
     
    20422057                assertf( false, "AlternativeFinder should never see a DeletedExpr." );
    20432058        }
     2059
     2060        void AlternativeFinder::Finder::postvisit( GenericExpr * ) {
     2061                assertf( false, "_Generic is not yet supported." );
     2062        }
    20442063} // namespace ResolvExpr
    20452064
Note: See TracChangeset for help on using the changeset viewer.