Changeset 6c3a988f


Ignore:
Timestamp:
Jan 5, 2017, 3:47:36 PM (8 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:
f831177
Parents:
1e3d5b6
Message:

fix inferred parameter data structures to correctly associate parameters with the entity that requested them, modify tuple specialization and unification to work with self-recursive assertions

Location:
src
Files:
12 edited

Legend:

Unmodified
Added
Removed
  • src/GenPoly/Box.cc

    r1e3d5b6 r6c3a988f  
    783783                void Pass1::boxParams( ApplicationExpr *appExpr, FunctionType *function, std::list< Expression *>::iterator &arg, const TyVarMap &exprTyVars ) {
    784784                        for ( std::list< DeclarationWithType *>::const_iterator param = function->get_parameters().begin(); param != function->get_parameters().end(); ++param, ++arg ) {
    785                                 assert( arg != appExpr->get_args().end() );
     785                                assertf( arg != appExpr->get_args().end(), "boxParams: missing argument for param %s to %s in %s", toString( *param ).c_str(), toString( function ).c_str(), toString( appExpr ).c_str() );
    786786                                addCast( *arg, (*param)->get_type(), exprTyVars );
    787787                                boxParam( (*param)->get_type(), *arg, exprTyVars );
  • src/GenPoly/Specialize.cc

    r1e3d5b6 r6c3a988f  
    112112                FunctionType *newType = funType->clone();
    113113                if ( env ) {
    114                         TypeSubstitution newEnv( *env );
    115114                        // it is important to replace only occurrences of type variables that occur free in the
    116115                        // thunk's type
    117                         newEnv.applyFree( newType );
     116                        env->applyFree( newType );
    118117                } // if
    119118                // create new thunk with same signature as formal type (C linkage, empty body)
     
    167166                assertf( actual->has_result(), "attempting to specialize an untyped expression" );
    168167                if ( needsSpecialization( formalType, actual->get_result(), env ) ) {
    169                         FunctionType *funType;
    170                         if ( ( funType = getFunctionType( formalType ) ) ) {
     168                        if ( FunctionType *funType = getFunctionType( formalType ) ) {
    171169                                ApplicationExpr *appExpr;
    172170                                VariableExpr *varExpr;
     
    188186
    189187        bool TupleSpecializer::needsSpecialization( Type *formalType, Type *actualType, TypeSubstitution *env ) {
    190                 // std::cerr << "asking if type needs tuple spec: " << formalType << std::endl;
    191188                if ( FunctionType * ftype = getFunctionType( formalType ) ) {
    192189                        return ftype->isTtype();
     
    215212        void fixLastArg( Expression * last, Iterator begin, Iterator end, OutIterator out ) {
    216213                // safe_dynamic_cast for the assertion
    217                 safe_dynamic_cast< TupleType * >( last->get_result() ); // xxx - it's quite possible this will trigger for the unary case...
     214                safe_dynamic_cast< TupleType * >( last->get_result() );
    218215                unsigned idx = 0;
    219216                for ( ; begin != end; ++begin ) {
     
    227224        Expression * TupleSpecializer::createThunkFunction( FunctionType *funType, Expression *actual, InferredParams *inferParams ) {
    228225                static UniqueName thunkNamer( "_tupleThunk" );
    229                 // std::cerr << "creating tuple thunk for " << funType << std::endl;
    230226
    231227                FunctionType *newType = funType->clone();
    232228                if ( env ) {
    233                         TypeSubstitution newEnv( *env );
    234229                        // it is important to replace only occurrences of type variables that occur free in the
    235230                        // thunk's type
    236                         newEnv.applyFree( newType );
     231                        env->applyFree( newType );
    237232                } // if
    238233                // create new thunk with same signature as formal type (C linkage, empty body)
     
    246241                UniqueName paramNamer( paramPrefix );
    247242                ApplicationExpr *appExpr = new ApplicationExpr( actual );
    248                 // std::cerr << actual << std::endl;
    249 
    250                 FunctionType * actualType = getFunctionType( actual->get_result() );
     243
     244                FunctionType * actualType = getFunctionType( actual->get_result() )->clone();
     245                if ( env ) {
     246                        // need to apply the environment to the actual function's type, since it may itself be polymorphic
     247                        env->apply( actualType );
     248                }
     249                std::unique_ptr< FunctionType > actualTypeManager( actualType ); // for RAII
    251250                std::list< DeclarationWithType * >::iterator actualBegin = actualType->get_parameters().begin();
    252251                std::list< DeclarationWithType * >::iterator actualEnd = actualType->get_parameters().end();
     
    282281                std::list< Statement* > oldStmts;
    283282                oldStmts.splice( oldStmts.end(), stmtsToAdd );
    284                 spec.handleExplicitParams( appExpr );
     283                spec.mutate( appExpr );
    285284                paramPrefix = oldParamPrefix;
    286285                // write any statements added for recursive specializations into the thunk body
     
    297296                } // if
    298297                thunkFunc->get_statements()->get_kids().push_back( appStmt );
    299 
    300                 // std::cerr << "thunkFunc is: " << thunkFunc << std::endl;
    301298
    302299                // add thunk definition to queue of statements to add
     
    326323                        // don't need to do this for intrinsic calls, because they aren't actually passed
    327324                        for ( InferredParams::iterator inferParam = appExpr->get_inferParams().begin(); inferParam != appExpr->get_inferParams().end(); ++inferParam ) {
    328                                 inferParam->second.expr = specializer->doSpecialization( inferParam->second.formalType, inferParam->second.expr, &appExpr->get_inferParams() );
     325                                inferParam->second.expr = specializer->doSpecialization( inferParam->second.formalType, inferParam->second.expr, inferParam->second.inferParams.get() );
    329326                        }
    330327                        handleExplicitParams( appExpr );
  • src/ResolvExpr/AdjustExprType.cc

    r1e3d5b6 r6c3a988f  
    2222        class AdjustExprType : public Mutator {
    2323                typedef Mutator Parent;
     24                using Parent::mutate;
    2425          public:
    2526                AdjustExprType( const TypeEnvironment &env, const SymTab::Indexer &indexer );
  • src/ResolvExpr/AlternativeFinder.cc

    r1e3d5b6 r6c3a988f  
    339339                        unifiableVars[ (*tyvar)->get_name() ] = TypeDecl::Data{ *tyvar };
    340340                        for ( std::list< DeclarationWithType* >::iterator assert = (*tyvar)->get_assertions().begin(); assert != (*tyvar)->get_assertions().end(); ++assert ) {
    341                                 needAssertions[ *assert ] = true;
     341                                needAssertions[ *assert ].isUsed = true;
    342342                        }
    343343///     needAssertions.insert( needAssertions.end(), (*tyvar)->get_assertions().begin(), (*tyvar)->get_assertions().end() );
     
    380380                        }
    381381                        *out++ = arg;
    382                         return true;
    383382                } else if ( actualIt != actualEnd ) {
    384383                        // both actualType and formalType are atomic (non-tuple) types - if they unify
     
    467466        void addToIndexer( AssertionSet &assertSet, SymTab::Indexer &indexer ) {
    468467                for ( AssertionSet::iterator i = assertSet.begin(); i != assertSet.end(); ++i ) {
    469                         if ( i->second == true ) {
     468                        if ( i->second.isUsed ) {
    470469                                i->first->accept( indexer );
    471470                        }
     
    478477                if ( begin == end ) {
    479478                        if ( newNeed.empty() ) {
     479                                PRINT(
     480                                        std::cerr << "all assertions satisfied, output alternative: ";
     481                                        newAlt.print( std::cerr );
     482                                        std::cerr << std::endl;
     483                                );
    480484                                *out++ = newAlt;
    481485                                return;
     
    494498
    495499                ForwardIterator cur = begin++;
    496                 if ( ! cur->second ) {
     500                if ( ! cur->second.isUsed ) {
    497501                        inferRecursive( begin, end, newAlt, openVars, decls, newNeed, /*needParents,*/ level, indexer, out );
    498502                        return; // xxx - should this continue? previously this wasn't here, and it looks like it should be
     
    538542                                assert( (*candidate)->get_uniqueId() );
    539543                                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
    540554                                //AssertionParentSet newNeedParents( needParents );
    541555                                // skip repeatingly-self-recursive assertion satisfaction
     
    553567                                )
    554568                                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                                }
    555574                                // XXX: this is a memory leak, but adjType can't be deleted because it might contain assertions
    556                                 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 );
    557576                                inferRecursive( begin, end, newerAlt, newOpenVars, newDecls, newerNeed, /*newNeedParents,*/ level, indexer, out );
    558577                        } else {
  • src/ResolvExpr/FindOpenVars.cc

    r1e3d5b6 r6c3a988f  
    5050                                openVars[ (*i)->get_name() ] = TypeDecl::Data{ (*i) };
    5151                                for ( std::list< DeclarationWithType* >::const_iterator assert = (*i)->get_assertions().begin(); assert != (*i)->get_assertions().end(); ++assert ) {
    52                                         needAssertions[ *assert ] = false;
     52                                        needAssertions[ *assert ].isUsed = false;
    5353                                }
    5454///       cloneAll( (*i)->get_assertions(), needAssertions );
     
    5959                                closedVars[ (*i)->get_name() ] = TypeDecl::Data{ (*i) };
    6060                                for ( std::list< DeclarationWithType* >::const_iterator assert = (*i)->get_assertions().begin(); assert != (*i)->get_assertions().end(); ++assert ) {
    61                                         haveAssertions[ *assert ] = false;
     61                                        haveAssertions[ *assert ].isUsed = false;
    6262                                }
    6363///       cloneAll( (*i)->get_assertions(), haveAssertions );
  • src/ResolvExpr/TypeEnvironment.cc

    r1e3d5b6 r6c3a988f  
    7575                for ( AssertionSet::const_iterator i = assertions.begin(); i != assertions.end(); ++i ) {
    7676                        i->first->print( os, indent );
    77                         if ( i->second ) {
     77                        if ( i->second.isUsed ) {
    7878                                os << "(used)";
    7979                        } else {
  • src/ResolvExpr/TypeEnvironment.h

    r1e3d5b6 r6c3a988f  
    3131                bool operator()( DeclarationWithType * d1, DeclarationWithType * d2 ) const;
    3232        };
    33         typedef std::map< DeclarationWithType*, bool, AssertCompare > AssertionSet;
     33        struct AssertionSetValue {
     34                bool isUsed;
     35                // chain of Unique IDs of the assertion declarations. The first ID in the chain is the ID of an assertion on the current type,
     36                // with each successive ID being the ID of an assertion pulled in by the previous ID. The last ID in the chain is
     37                // the ID of the assertion that pulled in the current assertion.
     38                std::list< UniqueId > idChain;
     39        };
     40        typedef std::map< DeclarationWithType*, AssertionSetValue, AssertCompare > AssertionSet;
    3441        typedef std::map< std::string, TypeDecl::Data > OpenVarSet;
    3542
  • src/ResolvExpr/Unify.cc

    r1e3d5b6 r6c3a988f  
    157157                        // if the type variable is specified to be a complete type then the incoming
    158158                        // type must also be complete
     159                        // xxx - should this also check that type is not a tuple type and that it's not a ttype?
    159160                        return ! isFtype( type, indexer ) && (! data.isComplete || isComplete( type ));
    160161                  case TypeDecl::Ftype:
    161162                        return isFtype( type, indexer );
    162163                        case TypeDecl::Ttype:
    163                         // ttype eats up any remaining parameters, no matter the type
    164                         return true;
     164                        // ttype unifies with any tuple type
     165                        return dynamic_cast< TupleType * >( type );
    165166                } // switch
    166167                return false;
     
    433434                if ( i != assertions.end() ) {
    434435///     std::cerr << "found it!" << std::endl;
    435                         i->second = true;
     436                        i->second.isUsed = true;
    436437                } // if
    437438        }
     
    488489
    489490        template< typename Iterator >
    490         Type * combineTypes( Iterator begin, Iterator end ) {
     491        std::unique_ptr<Type> combineTypes( Iterator begin, Iterator end ) {
    491492                std::list< Type * > types;
    492493                for ( ; begin != end; ++begin ) {
     
    494495                        flatten( (*begin)->get_type(), back_inserter( types ) );
    495496                }
    496                 return new TupleType( Type::Qualifiers(), types );
     497                return std::unique_ptr<Type>( new TupleType( Type::Qualifiers(), types ) );
    497498        }
    498499
     
    504505                        bool isTtype1 = Tuples::isTtype( t1 );
    505506                        bool isTtype2 = Tuples::isTtype( t2 );
    506                         // xxx - assumes ttype must be last parameter; needs cleanup; use unique_ptr for combinedType
     507                        // xxx - assumes ttype must be last parameter
     508                        // xxx - there may be a nice way to refactor this, but be careful because the argument positioning might matter in some cases.
    507509                        if ( isTtype1 && ! isTtype2 ) {
    508510                                // combine all of the things in list2, then unify
    509                                 Type * combinedType = combineTypes( list2Begin, list2End );
    510                                 return unifyExact( t1, combinedType, env, needAssertions, haveAssertions, openVars, WidenMode( false, false ), indexer );
     511                                return unifyExact( t1, combineTypes( list2Begin, list2End ).get(), env, needAssertions, haveAssertions, openVars, WidenMode( false, false ), indexer );
    511512                        } else if ( isTtype2 && ! isTtype1 ) {
    512513                                // combine all of the things in list1, then unify
    513                                 Type * combinedType = combineTypes( list1Begin, list1End );
    514                                 return unifyExact( combinedType, t2, env, needAssertions, haveAssertions, openVars, WidenMode( false, false ), indexer );
     514                                return unifyExact( combineTypes( list1Begin, list1End ).get(), t2, env, needAssertions, haveAssertions, openVars, WidenMode( false, false ), indexer );
    515515                        } else if ( ! unifyExact( t1, t2, env, needAssertions, haveAssertions, openVars, WidenMode( false, false ), indexer ) ) {
    516516                                return false;
    517517                        } // if
    518518                } // for
    519                 // if ( list1Begin != list1End || list2Begin != list2End ) {
    520                 //      return false;
     519                // may get to the end of one argument list before the end of the other. This is only okay when the other is a ttype
    521520                if ( list1Begin != list1End ) {
    522521                        // try unifying empty tuple type with ttype
    523522                        Type * t1 = (*list1Begin)->get_type();
    524523                        if ( Tuples::isTtype( t1 ) ) {
    525                                 Type * combinedType = combineTypes( list2Begin, list2End );
    526                                 return unifyExact( t1, combinedType, env, needAssertions, haveAssertions, openVars, WidenMode( false, false ), indexer );
     524                                return unifyExact( t1, combineTypes( list2Begin, list2End ).get(), env, needAssertions, haveAssertions, openVars, WidenMode( false, false ), indexer );
    527525                        } else return false;
    528526                } else if ( list2Begin != list2End ) {
     
    530528                        Type * t2 = (*list2Begin)->get_type();
    531529                        if ( Tuples::isTtype( t2 ) ) {
    532                                 Type * combinedType = combineTypes( list1Begin, list1End );
    533                                 return unifyExact( combinedType, t2, env, needAssertions, haveAssertions, openVars, WidenMode( false, false ), indexer );
     530                                return unifyExact( combineTypes( list1Begin, list1End ).get(), t2, env, needAssertions, haveAssertions, openVars, WidenMode( false, false ), indexer );
    534531                        } else return false;
    535532                } else {
     
    538535        }
    539536
     537        /// Finds ttypes and replaces them with their expansion, if known.
     538        /// This needs to be done so that satisfying ttype assertions is easier.
     539        /// If this isn't done then argument lists can have wildly different
     540        /// size and structure, when they should be compatible.
     541        struct TtypeExpander : public Mutator {
     542                TypeEnvironment & env;
     543                TtypeExpander( TypeEnvironment & env ) : env( env ) {}
     544                Type * mutate( TypeInstType * typeInst ) {
     545                        EqvClass eqvClass;
     546                        if ( env.lookup( typeInst->get_name(), eqvClass ) ) {
     547                                if ( eqvClass.data.kind == TypeDecl::Ttype ) {
     548                                        // expand ttype parameter into its actual type
     549                                        if ( eqvClass.type ) {
     550                                                delete typeInst;
     551                                                return eqvClass.type->clone();
     552                                        }
     553                                }
     554                        }
     555                        return typeInst;
     556                }
     557        };
     558
     559        /// flattens a list of declarations, so that each tuple type has a single declaration.
     560        /// makes use of TtypeExpander to ensure ttypes are flat as well.
     561        void flattenList( std::list< DeclarationWithType * > src, std::list< DeclarationWithType * > & dst, TypeEnvironment & env ) {
     562                dst.clear();
     563                for ( DeclarationWithType * dcl : src ) {
     564                        TtypeExpander expander( env );
     565                        dcl->acceptMutator( expander );
     566                        std::list< Type * > types;
     567                        flatten( dcl->get_type(), back_inserter( types ) );
     568                        for ( Type * t : types ) {
     569                                dst.push_back( new ObjectDecl( "", DeclarationNode::NoStorageClass, LinkageSpec::C, nullptr, t, nullptr ) );
     570                        }
     571                        delete dcl;
     572                }
     573        }
     574
    540575        void Unify::visit(FunctionType *functionType) {
    541576                FunctionType *otherFunction = dynamic_cast< FunctionType* >( type2 );
    542577                if ( otherFunction && functionType->get_isVarArgs() == otherFunction->get_isVarArgs() ) {
     578                        // flatten the parameter lists for both functions so that tuple structure
     579                        // doesn't affect unification. Must be a clone so that the types don't change.
     580                        std::unique_ptr<FunctionType> flatFunc( functionType->clone() );
     581                        std::unique_ptr<FunctionType> flatOther( otherFunction->clone() );
     582                        flattenList( flatFunc->get_parameters(), flatFunc->get_parameters(), env );
     583                        flattenList( flatOther->get_parameters(), flatOther->get_parameters(), env );
     584
    543585                        // sizes don't have to match if ttypes are involved; need to be more precise wrt where the ttype is to prevent errors
    544                         if ( (functionType->get_parameters().size() == otherFunction->get_parameters().size() && functionType->get_returnVals().size() == otherFunction->get_returnVals().size()) || functionType->isTtype() || otherFunction->isTtype() ) {
    545                                 if ( unifyDeclList( functionType->get_parameters().begin(), functionType->get_parameters().end(), otherFunction->get_parameters().begin(), otherFunction->get_parameters().end(), env, needAssertions, haveAssertions, openVars, indexer ) ) {
    546                                         if ( unifyDeclList( functionType->get_returnVals().begin(), functionType->get_returnVals().end(), otherFunction->get_returnVals().begin(), otherFunction->get_returnVals().end(), env, needAssertions, haveAssertions, openVars, indexer ) ) {
    547 
     586                        if ( (flatFunc->get_parameters().size() == flatOther->get_parameters().size() && flatFunc->get_returnVals().size() == flatOther->get_returnVals().size()) || flatFunc->isTtype() || flatOther->isTtype() ) {
     587                                if ( unifyDeclList( flatFunc->get_parameters().begin(), flatFunc->get_parameters().end(), flatOther->get_parameters().begin(), flatOther->get_parameters().end(), env, needAssertions, haveAssertions, openVars, indexer ) ) {
     588                                        if ( unifyDeclList( flatFunc->get_returnVals().begin(), flatFunc->get_returnVals().end(), flatOther->get_returnVals().begin(), flatOther->get_returnVals().end(), env, needAssertions, haveAssertions, openVars, indexer ) ) {
     589
     590                                                // the original types must be used in mark assertions, since pointer comparisons are used
    548591                                                markAssertions( haveAssertions, needAssertions, functionType );
    549592                                                markAssertions( haveAssertions, needAssertions, otherFunction );
  • src/ResolvExpr/typeops.h

    r1e3d5b6 r6c3a988f  
    164164                        }
    165165                } else {
    166                         *out++ = type;
     166                        *out++ = type->clone();
    167167                }
    168168        }
  • src/SynTree/ApplicationExpr.cc

    r1e3d5b6 r6c3a988f  
    2424
    2525ParamEntry::ParamEntry( const ParamEntry &other ) :
    26                 decl( other.decl ), actualType( maybeClone( other.actualType ) ), formalType( maybeClone( other.formalType ) ), expr( maybeClone( other.expr ) ) {
     26                decl( other.decl ), actualType( maybeClone( other.actualType ) ), formalType( maybeClone( other.formalType ) ), expr( maybeClone( other.expr ) ), inferParams( new InferredParams( *other.inferParams ) ) {
    2727}
    2828
     
    3434        formalType = maybeClone( other.formalType );
    3535        expr = maybeClone( other.expr );
     36        *inferParams = *other.inferParams;
    3637        return *this;
    3738}
     
    6263}
    6364
     65void printInferParams( const InferredParams & inferParams, std::ostream &os, int indent, int level ) {
     66        if ( ! inferParams.empty() ) {
     67                os << std::string(indent, ' ') << "with inferred parameters " << level << ":" << std::endl;
     68                for ( InferredParams::const_iterator i = inferParams.begin(); i != inferParams.end(); ++i ) {
     69                        os << std::string(indent+2, ' ');
     70                        Declaration::declFromId( i->second.decl )->printShort( os, indent+2 );
     71                        os << std::endl;
     72                        printInferParams( *i->second.inferParams, os, indent+2, level+1 );
     73                } // for
     74        } // if
     75}
     76
    6477void ApplicationExpr::print( std::ostream &os, int indent ) const {
    6578        os << "Application of" << std::endl << std::string(indent+2, ' ');
     
    6982                printAll( args, os, indent+2 );
    7083        } // if
    71         if ( ! inferParams.empty() ) {
    72                 os << std::string(indent, ' ') << "with inferred parameters:" << std::endl;
    73                 for ( InferredParams::const_iterator i = inferParams.begin(); i != inferParams.end(); ++i ) {
    74                         os << std::string(indent+2, ' ');
    75                         Declaration::declFromId( i->second.decl )->printShort( os, indent+2 );
    76                         os << std::endl;
    77                 } // for
    78         } // if
     84        printInferParams( inferParams, os, indent+2, 0 );
    7985        Expression::print( os, indent );
    8086}
  • src/SynTree/Expression.h

    r1e3d5b6 r6c3a988f  
    5454};
    5555
     56struct ParamEntry;
     57typedef std::map< UniqueId, ParamEntry > InferredParams;
     58
    5659/// ParamEntry contains the i.d. of a declaration and a type that is derived from that declaration,
    5760/// but subject to decay-to-pointer and type parameter renaming
    5861struct ParamEntry {
    59         ParamEntry(): decl( 0 ), actualType( 0 ), formalType( 0 ), expr( 0 ) {}
    60         ParamEntry( UniqueId decl, Type *actualType, Type *formalType, Expression* expr ): decl( decl ), actualType( actualType ), formalType( formalType ), expr( expr ) {}
     62        ParamEntry(): decl( 0 ), actualType( 0 ), formalType( 0 ), expr( 0 ), inferParams( new InferredParams ) {}
     63        ParamEntry( UniqueId decl, Type *actualType, Type *formalType, Expression* expr ): decl( decl ), actualType( actualType ), formalType( formalType ), expr( expr ), inferParams( new InferredParams ) {}
    6164        ParamEntry( const ParamEntry &other );
    6265        ~ParamEntry();
     
    6770        Type *formalType;
    6871        Expression* expr;
    69 };
    70 
    71 typedef std::map< UniqueId, ParamEntry > InferredParams;
     72        std::unique_ptr< InferredParams > inferParams;
     73};
    7274
    7375/// ApplicationExpr represents the application of a function to a set of parameters.  This is the result of running an
  • src/SynTree/TupleExpr.cc

    r1e3d5b6 r6c3a988f  
    5858TupleIndexExpr::TupleIndexExpr( Expression * tuple, unsigned int index ) : tuple( tuple ), index( index )  {
    5959        TupleType * type = safe_dynamic_cast< TupleType * >( tuple->get_result() );
    60         assertf( type->size() > index, "TupleIndexExpr index out of bounds: tuple size %d, requested index %d", type->size(), index );
     60        assertf( type->size() > index, "TupleIndexExpr index out of bounds: tuple size %d, requested index %d in expr %s", type->size(), index, toString( tuple ).c_str() );
    6161        set_result( (*std::next( type->get_types().begin(), index ))->clone() );
    6262        get_result()->set_isLvalue( type->get_isLvalue() );
Note: See TracChangeset for help on using the changeset viewer.