Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/ResolvExpr/AlternativeFinder.cc

    r00ac42e r25fcb84  
    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, const std::string & name );
     104                template< typename StructOrUnionType > void addAggMembers( StructOrUnionType *aggInst, Expression *expr, const Cost &newCost, const TypeEnvironment & env, Expression * member );
    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                         addAggMembers( structInst, aggrExpr.get(), alt.cost+Cost::safe, alt.env, "" );
     309                        NameExpr nameExpr( "" );
     310                        addAggMembers( structInst, aggrExpr.get(), alt.cost+Cost::safe, alt.env, &nameExpr );
    310311                } else if ( UnionInstType *unionInst = dynamic_cast< UnionInstType* >( aggrExpr->result ) ) {
    311                         addAggMembers( unionInst, aggrExpr.get(), alt.cost+Cost::safe, alt.env, "" );
     312                        NameExpr nameExpr( "" );
     313                        addAggMembers( unionInst, aggrExpr.get(), alt.cost+Cost::safe, alt.env, &nameExpr );
    312314                } // if
    313315        }
    314316
    315317        template< typename StructOrUnionType >
    316         void AlternativeFinder::Finder::addAggMembers( StructOrUnionType *aggInst, Expression *expr, const Cost &newCost, const TypeEnvironment & env, const std::string & name ) {
     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;
    317323                std::list< Declaration* > members;
    318324                aggInst->lookup( name, members );
    319325
    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) );
     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.
    328331                        } else {
    329332                                assert( false );
     
    466469        }
    467470
     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
    468474        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
    469476
    470477        void addToIndexer( AssertionSet &assertSet, SymTab::Indexer &indexer ) {
     
    477484
    478485        template< typename ForwardIterator, typename OutputIterator >
    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 ) {
     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 ) {
    480488                if ( begin == end ) {
    481489                        if ( newNeed.empty() ) {
     
    495503                                        printAssertionSet( newNeed, std::cerr, 8 );
    496504                                )
    497                                 inferRecursive( newNeed.begin(), newNeed.end(), newAlt, openVars, decls, newerNeed, level+1, indexer, out );
     505                                inferRecursive( newNeed.begin(), newNeed.end(), newAlt, openVars, decls, newerNeed, /*needParents,*/ level+1, indexer, out );
    498506                                return;
    499507                        }
     
    502510                ForwardIterator cur = begin++;
    503511                if ( ! cur->second.isUsed ) {
    504                         inferRecursive( begin, end, newAlt, openVars, decls, newNeed, level, indexer, out );
     512                        inferRecursive( begin, end, newAlt, openVars, decls, newNeed, /*needParents,*/ level, indexer, out );
    505513                        return; // xxx - should this continue? previously this wasn't here, and it looks like it should be
    506514                }
     
    555563                                }
    556564
     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
    557570                                Expression *varExpr = data.combine( newerAlt.cvtCost );
    558571                                delete varExpr->get_result();
     
    572585                                // XXX: this is a memory leak, but adjType can't be deleted because it might contain assertions
    573586                                (*inferParameters)[ curDecl->get_uniqueId() ] = ParamEntry( candidate->get_uniqueId(), adjType->clone(), curDecl->get_type()->clone(), varExpr );
    574                                 inferRecursive( begin, end, newerAlt, newOpenVars, newDecls, newerNeed, level, indexer, out );
     587                                inferRecursive( begin, end, newerAlt, newOpenVars, newDecls, newerNeed, /*newNeedParents,*/ level, indexer, out );
    575588                        } else {
    576589                                delete adjType;
     
    594607                addToIndexer( have, decls );
    595608                AssertionSet newNeed;
     609                //AssertionParentSet needParents;
    596610                PRINT(
    597611                        std::cerr << "env is: " << std::endl;
     
    600614                )
    601615
    602                 inferRecursive( need.begin(), need.end(), newAlt, openVars, decls, newNeed, 0, indexer, out );
     616                inferRecursive( need.begin(), need.end(), newAlt, openVars, decls, newNeed, /*needParents,*/ 0, indexer, out );
    603617//      PRINT(
    604618//          std::cerr << "declaration 14 is ";
     
    10791093                AlternativeFinder funcOpFinder( indexer, env );
    10801094                // it's ok if there aren't any defined function ops
    1081                 funcOpFinder.maybeFind( opExpr );
     1095                funcOpFinder.maybeFind( opExpr);
    10821096                PRINT(
    10831097                        std::cerr << "known function ops:" << std::endl;
     
    11161130                                        }
    11171131                                } else if ( TypeInstType *typeInst = dynamic_cast< TypeInstType* >( func->expr->result->stripReferences() ) ) { // handle ftype (e.g. *? on function pointer)
    1118                                         if ( const EqvClass *eqvClass = func->env.lookup( typeInst->name ) ) {
    1119                                                 if ( FunctionType *function = dynamic_cast< FunctionType* >( eqvClass->type ) ) {
     1132                                        EqvClass eqvClass;
     1133                                        if ( func->env.lookup( typeInst->name, eqvClass ) && eqvClass.type ) {
     1134                                                if ( FunctionType *function = dynamic_cast< FunctionType* >( eqvClass.type ) ) {
    11201135                                                        Alternative newFunc( *func );
    11211136                                                        referenceToRvalueConversion( newFunc.expr, newFunc.cost );
     
    13321347        }
    13331348
    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 
    13431349        void AlternativeFinder::Finder::postvisit( UntypedMemberExpr *memberExpr ) {
    13441350                AlternativeFinder funcFinder( indexer, env );
     
    13531359                        // find member of the given type
    13541360                        if ( StructInstType *structInst = dynamic_cast< StructInstType* >( aggrExpr->get_result() ) ) {
    1355                                 addAggMembers( structInst, aggrExpr, cost, agg->env, get_member_name(memberExpr) );
     1361                                addAggMembers( structInst, aggrExpr, cost, agg->env, memberExpr->get_member() );
    13561362                        } else if ( UnionInstType *unionInst = dynamic_cast< UnionInstType* >( aggrExpr->get_result() ) ) {
    1357                                 addAggMembers( unionInst, aggrExpr, cost, agg->env, get_member_name(memberExpr) );
     1363                                addAggMembers( unionInst, aggrExpr, cost, agg->env, memberExpr->get_member() );
    13581364                        } else if ( TupleType * tupleType = dynamic_cast< TupleType * >( aggrExpr->get_result() ) ) {
    13591365                                addTupleMembers( tupleType, aggrExpr, cost, agg->env, memberExpr->get_member() );
     
    13731379                        Cost cost = Cost::zero;
    13741380                        Expression * newExpr = data.combine( 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 );
     1381                        alternatives.push_back( Alternative( newExpr, env, Cost::zero, cost ) );
    13791382                        PRINT(
    13801383                                std::cerr << "decl is ";
     
    13851388                                std::cerr << std::endl;
    13861389                        )
    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) );
     1390                        renameTypes( alternatives.back().expr );
     1391                        addAnonConversions( alternatives.back() ); // add anonymous member interpretations whenever an aggregate value type is seen as a name expression.
    13901392                } // for
    13911393        }
Note: See TracChangeset for help on using the changeset viewer.