Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/ResolvExpr/AlternativeFinder.cc

    r25fcb84 r00ac42e  
    102102                void addAnonConversions( const Alternative & alt );
    103103                /// Adds alternatives for member expressions, given the aggregate, conversion cost for that aggregate, and name of the member
    104                 template< typename StructOrUnionType > void addAggMembers( StructOrUnionType *aggInst, Expression *expr, const Cost &newCost, const TypeEnvironment & env, Expression * member );
     104                template< typename StructOrUnionType > void addAggMembers( StructOrUnionType *aggInst, Expression *expr, const Cost &newCost, const TypeEnvironment & env, const std::string & name );
    105105                /// Adds alternatives for member expressions where the left side has tuple type
    106106                void addTupleMembers( TupleType * tupleType, Expression *expr, const Cost &newCost, const TypeEnvironment & env, Expression * member );
     
    307307
    308308                if ( StructInstType *structInst = dynamic_cast< StructInstType* >( aggrExpr->result ) ) {
    309                         NameExpr nameExpr( "" );
    310                         addAggMembers( structInst, aggrExpr.get(), alt.cost+Cost::safe, alt.env, &nameExpr );
     309                        addAggMembers( structInst, aggrExpr.get(), alt.cost+Cost::safe, alt.env, "" );
    311310                } else if ( UnionInstType *unionInst = dynamic_cast< UnionInstType* >( aggrExpr->result ) ) {
    312                         NameExpr nameExpr( "" );
    313                         addAggMembers( unionInst, aggrExpr.get(), alt.cost+Cost::safe, alt.env, &nameExpr );
     311                        addAggMembers( unionInst, aggrExpr.get(), alt.cost+Cost::safe, alt.env, "" );
    314312                } // if
    315313        }
    316314
    317315        template< typename StructOrUnionType >
    318         void AlternativeFinder::Finder::addAggMembers( StructOrUnionType *aggInst, Expression *expr, const Cost &newCost, const TypeEnvironment & env, Expression * member ) {
    319                 // by this point, member must be a name expr
    320                 NameExpr * nameExpr = dynamic_cast< NameExpr * >( member );
    321                 if ( ! nameExpr ) return;
    322                 const std::string & name = nameExpr->name;
     316        void AlternativeFinder::Finder::addAggMembers( StructOrUnionType *aggInst, Expression *expr, const Cost &newCost, const TypeEnvironment & env, const std::string & name ) {
    323317                std::list< Declaration* > members;
    324318                aggInst->lookup( name, members );
    325319
    326                 for ( std::list< Declaration* >::const_iterator i = members.begin(); i != members.end(); ++i ) {
    327                         if ( DeclarationWithType *dwt = dynamic_cast< DeclarationWithType* >( *i ) ) {
    328                                 alternatives.push_back( Alternative( new MemberExpr( dwt, expr->clone() ), env, newCost ) );
    329                                 renameTypes( alternatives.back().expr );
    330                                 addAnonConversions( alternatives.back() ); // add anonymous member interpretations whenever an aggregate value type is seen as a member expression.
     320                for ( Declaration * decl : members ) {
     321                        if ( DeclarationWithType *dwt = dynamic_cast< DeclarationWithType* >( decl ) ) {
     322                                // addAnonAlternatives uses vector::push_back, which invalidates references to existing elements, so
     323                                // can't construct in place and use vector::back
     324                                Alternative newAlt( new MemberExpr( dwt, expr->clone() ), env, newCost );
     325                                renameTypes( newAlt.expr );
     326                                addAnonConversions( newAlt ); // add anonymous member interpretations whenever an aggregate value type is seen as a member expression.
     327                                alternatives.push_back( std::move(newAlt) );
    331328                        } else {
    332329                                assert( false );
     
    469466        }
    470467
    471         // /// Map of declaration uniqueIds (intended to be the assertions in an AssertionSet) to their parents and the number of times they've been included
    472         //typedef std::unordered_map< UniqueId, std::unordered_map< UniqueId, unsigned > > AssertionParentSet;
    473 
    474468        static const int recursionLimit = /*10*/ 4;  ///< Limit to depth of recursion satisfaction
    475         //static const unsigned recursionParentLimit = 1;  ///< Limit to the number of times an assertion can recursively use itself
    476469
    477470        void addToIndexer( AssertionSet &assertSet, SymTab::Indexer &indexer ) {
     
    484477
    485478        template< typename ForwardIterator, typename OutputIterator >
    486         void inferRecursive( ForwardIterator begin, ForwardIterator end, const Alternative &newAlt, OpenVarSet &openVars, const SymTab::Indexer &decls, const AssertionSet &newNeed, /*const AssertionParentSet &needParents,*/
    487                                                  int level, const SymTab::Indexer &indexer, OutputIterator out ) {
     479        void inferRecursive( ForwardIterator begin, ForwardIterator end, const Alternative &newAlt, OpenVarSet &openVars, const SymTab::Indexer &decls, const AssertionSet &newNeed, int level, const SymTab::Indexer &indexer, OutputIterator out ) {
    488480                if ( begin == end ) {
    489481                        if ( newNeed.empty() ) {
     
    503495                                        printAssertionSet( newNeed, std::cerr, 8 );
    504496                                )
    505                                 inferRecursive( newNeed.begin(), newNeed.end(), newAlt, openVars, decls, newerNeed, /*needParents,*/ level+1, indexer, out );
     497                                inferRecursive( newNeed.begin(), newNeed.end(), newAlt, openVars, decls, newerNeed, level+1, indexer, out );
    506498                                return;
    507499                        }
     
    510502                ForwardIterator cur = begin++;
    511503                if ( ! cur->second.isUsed ) {
    512                         inferRecursive( begin, end, newAlt, openVars, decls, newNeed, /*needParents,*/ level, indexer, out );
     504                        inferRecursive( begin, end, newAlt, openVars, decls, newNeed, level, indexer, out );
    513505                        return; // xxx - should this continue? previously this wasn't here, and it looks like it should be
    514506                }
     
    563555                                }
    564556
    565                                 //AssertionParentSet newNeedParents( needParents );
    566                                 // skip repeatingly-self-recursive assertion satisfaction
    567                                 // DOESN'T WORK: grandchild nodes conflict with their cousins
    568                                 //if ( newNeedParents[ curDecl->get_uniqueId() ][ candDecl->get_uniqueId() ]++ > recursionParentLimit ) continue;
    569 
    570557                                Expression *varExpr = data.combine( newerAlt.cvtCost );
    571558                                delete varExpr->get_result();
     
    585572                                // XXX: this is a memory leak, but adjType can't be deleted because it might contain assertions
    586573                                (*inferParameters)[ curDecl->get_uniqueId() ] = ParamEntry( candidate->get_uniqueId(), adjType->clone(), curDecl->get_type()->clone(), varExpr );
    587                                 inferRecursive( begin, end, newerAlt, newOpenVars, newDecls, newerNeed, /*newNeedParents,*/ level, indexer, out );
     574                                inferRecursive( begin, end, newerAlt, newOpenVars, newDecls, newerNeed, level, indexer, out );
    588575                        } else {
    589576                                delete adjType;
     
    607594                addToIndexer( have, decls );
    608595                AssertionSet newNeed;
    609                 //AssertionParentSet needParents;
    610596                PRINT(
    611597                        std::cerr << "env is: " << std::endl;
     
    614600                )
    615601
    616                 inferRecursive( need.begin(), need.end(), newAlt, openVars, decls, newNeed, /*needParents,*/ 0, indexer, out );
     602                inferRecursive( need.begin(), need.end(), newAlt, openVars, decls, newNeed, 0, indexer, out );
    617603//      PRINT(
    618604//          std::cerr << "declaration 14 is ";
     
    10931079                AlternativeFinder funcOpFinder( indexer, env );
    10941080                // it's ok if there aren't any defined function ops
    1095                 funcOpFinder.maybeFind( opExpr);
     1081                funcOpFinder.maybeFind( opExpr );
    10961082                PRINT(
    10971083                        std::cerr << "known function ops:" << std::endl;
     
    11301116                                        }
    11311117                                } else if ( TypeInstType *typeInst = dynamic_cast< TypeInstType* >( func->expr->result->stripReferences() ) ) { // handle ftype (e.g. *? on function pointer)
    1132                                         EqvClass eqvClass;
    1133                                         if ( func->env.lookup( typeInst->name, eqvClass ) && eqvClass.type ) {
    1134                                                 if ( FunctionType *function = dynamic_cast< FunctionType* >( eqvClass.type ) ) {
     1118                                        if ( const EqvClass *eqvClass = func->env.lookup( typeInst->name ) ) {
     1119                                                if ( FunctionType *function = dynamic_cast< FunctionType* >( eqvClass->type ) ) {
    11351120                                                        Alternative newFunc( *func );
    11361121                                                        referenceToRvalueConversion( newFunc.expr, newFunc.cost );
     
    13471332        }
    13481333
     1334        namespace {
     1335                /// Gets name from untyped member expression (member must be NameExpr)
     1336                const std::string& get_member_name( UntypedMemberExpr *memberExpr ) {
     1337                        NameExpr * nameExpr = dynamic_cast< NameExpr * >( memberExpr->get_member() );
     1338                        assert( nameExpr );
     1339                        return nameExpr->get_name();
     1340                }
     1341        }
     1342
    13491343        void AlternativeFinder::Finder::postvisit( UntypedMemberExpr *memberExpr ) {
    13501344                AlternativeFinder funcFinder( indexer, env );
     
    13591353                        // find member of the given type
    13601354                        if ( StructInstType *structInst = dynamic_cast< StructInstType* >( aggrExpr->get_result() ) ) {
    1361                                 addAggMembers( structInst, aggrExpr, cost, agg->env, memberExpr->get_member() );
     1355                                addAggMembers( structInst, aggrExpr, cost, agg->env, get_member_name(memberExpr) );
    13621356                        } else if ( UnionInstType *unionInst = dynamic_cast< UnionInstType* >( aggrExpr->get_result() ) ) {
    1363                                 addAggMembers( unionInst, aggrExpr, cost, agg->env, memberExpr->get_member() );
     1357                                addAggMembers( unionInst, aggrExpr, cost, agg->env, get_member_name(memberExpr) );
    13641358                        } else if ( TupleType * tupleType = dynamic_cast< TupleType * >( aggrExpr->get_result() ) ) {
    13651359                                addTupleMembers( tupleType, aggrExpr, cost, agg->env, memberExpr->get_member() );
     
    13791373                        Cost cost = Cost::zero;
    13801374                        Expression * newExpr = data.combine( cost );
    1381                         alternatives.push_back( Alternative( newExpr, env, Cost::zero, cost ) );
     1375
     1376                        // addAnonAlternatives uses vector::push_back, which invalidates references to existing elements, so
     1377                        // can't construct in place and use vector::back
     1378                        Alternative newAlt( newExpr, env, Cost::zero, cost );
    13821379                        PRINT(
    13831380                                std::cerr << "decl is ";
     
    13881385                                std::cerr << std::endl;
    13891386                        )
    1390                         renameTypes( alternatives.back().expr );
    1391                         addAnonConversions( alternatives.back() ); // add anonymous member interpretations whenever an aggregate value type is seen as a name expression.
     1387                        renameTypes( newAlt.expr );
     1388                        addAnonConversions( newAlt ); // add anonymous member interpretations whenever an aggregate value type is seen as a name expression.
     1389                        alternatives.push_back( std::move(newAlt) );
    13921390                } // for
    13931391        }
Note: See TracChangeset for help on using the changeset viewer.