Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/GenPoly/GenPoly.cc

    rc6b4432 r3df4cd9  
    2929#include "GenPoly/ErasableScopedMap.h"  // for ErasableScopedMap<>::const_it...
    3030#include "ResolvExpr/typeops.h"         // for flatten
     31#include "SynTree/Constant.h"           // for Constant
     32#include "SynTree/Expression.h"         // for Expression, TypeExpr, Constan...
     33#include "SynTree/Type.h"               // for Type, StructInstType, UnionIn...
     34#include "SynTree/TypeSubstitution.h"   // for TypeSubstitution
    3135
    3236using namespace std;
     
    3539        namespace {
    3640                /// Checks a parameter list for polymorphic parameters; will substitute according to env if present
     41                bool hasPolyParams( std::list< Expression* >& params, const TypeSubstitution *env ) {
     42                        for ( std::list< Expression* >::iterator param = params.begin(); param != params.end(); ++param ) {
     43                                TypeExpr *paramType = dynamic_cast< TypeExpr* >( *param );
     44                                assertf(paramType, "Aggregate parameters should be type expressions");
     45                                if ( isPolyType( paramType->get_type(), env ) ) return true;
     46                        }
     47                        return false;
     48                }
     49
    3750                bool hasPolyParams( const std::vector<ast::ptr<ast::Expr>> & params, const ast::TypeSubstitution * env ) {
    3851                        for ( auto &param : params ) {
     
    4558
    4659                /// Checks a parameter list for polymorphic parameters from tyVars; will substitute according to env if present
     60                bool hasPolyParams( std::list< Expression* >& params, const TyVarMap &tyVars, const TypeSubstitution *env ) {
     61                        for ( std::list< Expression* >::iterator param = params.begin(); param != params.end(); ++param ) {
     62                                TypeExpr *paramType = dynamic_cast< TypeExpr* >( *param );
     63                                assertf(paramType, "Aggregate parameters should be type expressions");
     64                                if ( isPolyType( paramType->get_type(), tyVars, env ) ) return true;
     65                        }
     66                        return false;
     67                }
     68
    4769                bool hasPolyParams( const std::vector<ast::ptr<ast::Expr>> & params, const TypeVarMap & typeVars, const ast::TypeSubstitution * env ) {
    4870                        for ( auto & param : params ) {
     
    5577
    5678                /// Checks a parameter list for dynamic-layout parameters from tyVars; will substitute according to env if present
     79                bool hasDynParams( std::list< Expression* >& params, const TyVarMap &tyVars, const TypeSubstitution *env ) {
     80                        for ( std::list< Expression* >::iterator param = params.begin(); param != params.end(); ++param ) {
     81                                TypeExpr *paramType = dynamic_cast< TypeExpr* >( *param );
     82                                assertf(paramType, "Aggregate parameters should be type expressions");
     83                                if ( isDynType( paramType->get_type(), tyVars, env ) ) return true;
     84                        }
     85                        return false;
     86                }
     87
    5788                bool hasDynParams(
    5889                                const std::vector<ast::ptr<ast::Expr>> & params,
     
    6899                        return false;
    69100                }
     101
     102                /// Checks a parameter list for inclusion of polymorphic parameters; will substitute according to env if present
     103                bool includesPolyParams( std::list< Expression* >& params, const TypeSubstitution *env ) {
     104                        for ( std::list< Expression* >::iterator param = params.begin(); param != params.end(); ++param ) {
     105                                TypeExpr *paramType = dynamic_cast< TypeExpr* >( *param );
     106                                assertf(paramType, "Aggregate parameters should be type expressions");
     107                                if ( includesPolyType( paramType->get_type(), env ) ) return true;
     108                        }
     109                        return false;
     110                }
     111
     112                /// Checks a parameter list for inclusion of polymorphic parameters from tyVars; will substitute according to env if present
     113                bool includesPolyParams( std::list< Expression* >& params, const TyVarMap &tyVars, const TypeSubstitution *env ) {
     114                        for ( std::list< Expression* >::iterator param = params.begin(); param != params.end(); ++param ) {
     115                                TypeExpr *paramType = dynamic_cast< TypeExpr* >( *param );
     116                                assertf(paramType, "Aggregate parameters should be type expressions");
     117                                if ( includesPolyType( paramType->get_type(), tyVars, env ) ) return true;
     118                        }
     119                        return false;
     120                }
     121        }
     122
     123        Type* replaceTypeInst( Type* type, const TypeSubstitution* env ) {
     124                if ( ! env ) return type;
     125                if ( TypeInstType *typeInst = dynamic_cast< TypeInstType* >( type ) ) {
     126                        Type *newType = env->lookup( typeInst->get_name() );
     127                        if ( newType ) return newType;
     128                }
     129                return type;
     130        }
     131
     132        const Type* replaceTypeInst( const Type* type, const TypeSubstitution* env ) {
     133                if ( ! env ) return type;
     134                if ( auto typeInst = dynamic_cast< const TypeInstType* >( type ) ) {
     135                        Type *newType = env->lookup( typeInst->get_name() );
     136                        if ( newType ) return newType;
     137                }
     138                return type;
    70139        }
    71140
     
    77146                }
    78147                return type;
     148        }
     149
     150        Type *isPolyType( Type *type, const TypeSubstitution *env ) {
     151                type = replaceTypeInst( type, env );
     152
     153                if ( dynamic_cast< TypeInstType * >( type ) ) {
     154                        return type;
     155                } else if ( ArrayType * arrayType = dynamic_cast< ArrayType * >( type ) ) {
     156                        return isPolyType( arrayType->base, env );
     157                } else if ( StructInstType *structType = dynamic_cast< StructInstType* >( type ) ) {
     158                        if ( hasPolyParams( structType->get_parameters(), env ) ) return type;
     159                } else if ( UnionInstType *unionType = dynamic_cast< UnionInstType* >( type ) ) {
     160                        if ( hasPolyParams( unionType->get_parameters(), env ) ) return type;
     161                }
     162                return 0;
    79163        }
    80164
     
    94178        }
    95179
     180        Type *isPolyType( Type *type, const TyVarMap &tyVars, const TypeSubstitution *env ) {
     181                type = replaceTypeInst( type, env );
     182
     183                if ( TypeInstType *typeInst = dynamic_cast< TypeInstType * >( type ) ) {
     184                        if ( tyVars.contains( typeInst->get_name() ) ) {
     185                                return type;
     186                        }
     187                } else if ( ArrayType * arrayType = dynamic_cast< ArrayType * >( type ) ) {
     188                        return isPolyType( arrayType->base, tyVars, env );
     189                } else if ( StructInstType *structType = dynamic_cast< StructInstType* >( type ) ) {
     190                        if ( hasPolyParams( structType->get_parameters(), tyVars, env ) ) return type;
     191                } else if ( UnionInstType *unionType = dynamic_cast< UnionInstType* >( type ) ) {
     192                        if ( hasPolyParams( unionType->get_parameters(), tyVars, env ) ) return type;
     193                }
     194                return 0;
     195        }
     196
    96197const ast::Type * isPolyType( const ast::Type * type,
    97198                const TypeVarMap & typeVars, const ast::TypeSubstitution * subst ) {
     
    110211}
    111212
     213        ReferenceToType *isDynType( Type *type, const TyVarMap &tyVars, const TypeSubstitution *env ) {
     214                type = replaceTypeInst( type, env );
     215
     216                if ( TypeInstType *typeInst = dynamic_cast< TypeInstType * >( type ) ) {
     217                        auto var = tyVars.find( typeInst->get_name() );
     218                        if ( var != tyVars.end() && var->second.isComplete ) {
     219                                return typeInst;
     220                        }
     221                } else if ( StructInstType *structType = dynamic_cast< StructInstType* >( type ) ) {
     222                        if ( hasDynParams( structType->get_parameters(), tyVars, env ) ) return structType;
     223                } else if ( UnionInstType *unionType = dynamic_cast< UnionInstType* >( type ) ) {
     224                        if ( hasDynParams( unionType->get_parameters(), tyVars, env ) ) return unionType;
     225                }
     226                return 0;
     227        }
     228
    112229const ast::BaseInstType * isDynType(
    113230                const ast::Type * type, const TypeVarMap & typeVars,
     
    132249}
    133250
     251        ReferenceToType *isDynRet( FunctionType *function, const TyVarMap &forallTypes ) {
     252                if ( function->get_returnVals().empty() ) return 0;
     253
     254                return (ReferenceToType*)isDynType( function->get_returnVals().front()->get_type(), forallTypes );
     255        }
     256
    134257const ast::BaseInstType *isDynRet(
    135258                const ast::FunctionType * type, const TypeVarMap & typeVars ) {
     
    139262}
    140263
     264        ReferenceToType *isDynRet( FunctionType *function ) {
     265                if ( function->get_returnVals().empty() ) return 0;
     266
     267                TyVarMap forallTypes( TypeDecl::Data{} );
     268                makeTyVarMap( function, forallTypes );
     269                return (ReferenceToType*)isDynType( function->get_returnVals().front()->get_type(), forallTypes );
     270        }
     271
    141272const ast::BaseInstType *isDynRet( const ast::FunctionType * func ) {
    142273        if ( func->returns.empty() ) return nullptr;
    143274
    144         TypeVarMap forallTypes;
     275        TypeVarMap forallTypes = { ast::TypeData() };
    145276        makeTypeVarMap( func, forallTypes );
    146277        return isDynType( func->returns.front(), forallTypes );
    147278}
     279
     280        bool needsAdapter( FunctionType *adaptee, const TyVarMap &tyVars ) {
     281//              if ( ! adaptee->get_returnVals().empty() && isPolyType( adaptee->get_returnVals().front()->get_type(), tyVars ) ) {
     282//                      return true;
     283//              } // if
     284                if ( isDynRet( adaptee, tyVars ) ) return true;
     285
     286                for ( std::list< DeclarationWithType* >::const_iterator innerArg = adaptee->get_parameters().begin(); innerArg != adaptee->get_parameters().end(); ++innerArg ) {
     287//                      if ( isPolyType( (*innerArg)->get_type(), tyVars ) ) {
     288                        if ( isDynType( (*innerArg)->get_type(), tyVars ) ) {
     289                                return true;
     290                        } // if
     291                } // for
     292                return false;
     293        }
    148294
    149295bool needsAdapter(
     
    158304        return false;
    159305}
     306
     307        Type *isPolyPtr( Type *type, const TypeSubstitution *env ) {
     308                type = replaceTypeInst( type, env );
     309
     310                if ( PointerType *ptr = dynamic_cast< PointerType *>( type ) ) {
     311                        return isPolyType( ptr->get_base(), env );
     312                }
     313                return 0;
     314        }
     315
     316        Type *isPolyPtr( Type *type, const TyVarMap &tyVars, const TypeSubstitution *env ) {
     317                type = replaceTypeInst( type, env );
     318
     319                if ( PointerType *ptr = dynamic_cast< PointerType *>( type ) ) {
     320                        return isPolyType( ptr->get_base(), tyVars, env );
     321                }
     322                return 0;
     323        }
    160324
    161325const ast::Type * isPolyPtr(
     
    169333        return nullptr;
    170334}
     335
     336        Type * hasPolyBase( Type *type, int *levels, const TypeSubstitution *env ) {
     337                int dummy;
     338                if ( ! levels ) { levels = &dummy; }
     339                *levels = 0;
     340
     341                while ( true ) {
     342                        type = replaceTypeInst( type, env );
     343
     344                        if ( PointerType *ptr = dynamic_cast< PointerType *>( type ) ) {
     345                                type = ptr->get_base();
     346                                ++(*levels);
     347                        } else break;
     348                }
     349
     350                return isPolyType( type, env );
     351        }
     352
     353        Type * hasPolyBase( Type *type, const TyVarMap &tyVars, int *levels, const TypeSubstitution *env ) {
     354                int dummy;
     355                if ( ! levels ) { levels = &dummy; }
     356                *levels = 0;
     357
     358                while ( true ) {
     359                        type = replaceTypeInst( type, env );
     360
     361                        if ( PointerType *ptr = dynamic_cast< PointerType *>( type ) ) {
     362                                type = ptr->get_base();
     363                                ++(*levels);
     364                        } else break;
     365                }
     366
     367                return isPolyType( type, tyVars, env );
     368        }
    171369
    172370ast::Type const * hasPolyBase(
     
    190388}
    191389
     390        bool includesPolyType( Type *type, const TypeSubstitution *env ) {
     391                type = replaceTypeInst( type, env );
     392
     393                if ( dynamic_cast< TypeInstType * >( type ) ) {
     394                        return true;
     395                } else if ( PointerType *pointerType = dynamic_cast< PointerType* >( type ) ) {
     396                        if ( includesPolyType( pointerType->get_base(), env ) ) return true;
     397                } else if ( StructInstType *structType = dynamic_cast< StructInstType* >( type ) ) {
     398                        if ( includesPolyParams( structType->get_parameters(), env ) ) return true;
     399                } else if ( UnionInstType *unionType = dynamic_cast< UnionInstType* >( type ) ) {
     400                        if ( includesPolyParams( unionType->get_parameters(), env ) ) return true;
     401                }
     402                return false;
     403        }
     404
     405        bool includesPolyType( Type *type, const TyVarMap &tyVars, const TypeSubstitution *env ) {
     406                type = replaceTypeInst( type, env );
     407
     408                if ( TypeInstType *typeInstType = dynamic_cast< TypeInstType * >( type ) ) {
     409                        if ( tyVars.contains( typeInstType->get_name() ) ) {
     410                                return true;
     411                        }
     412                } else if ( PointerType *pointerType = dynamic_cast< PointerType* >( type ) ) {
     413                        if ( includesPolyType( pointerType->get_base(), tyVars, env ) ) return true;
     414                } else if ( StructInstType *structType = dynamic_cast< StructInstType* >( type ) ) {
     415                        if ( includesPolyParams( structType->get_parameters(), tyVars, env ) ) return true;
     416                } else if ( UnionInstType *unionType = dynamic_cast< UnionInstType* >( type ) ) {
     417                        if ( includesPolyParams( unionType->get_parameters(), tyVars, env ) ) return true;
     418                }
     419                return false;
     420        }
     421
     422        FunctionType * getFunctionType( Type *ty ) {
     423                PointerType *ptrType;
     424                if ( ( ptrType = dynamic_cast< PointerType* >( ty ) ) ) {
     425                        return dynamic_cast< FunctionType* >( ptrType->get_base() ); // pointer if FunctionType, NULL otherwise
     426                } else {
     427                        return dynamic_cast< FunctionType* >( ty ); // pointer if FunctionType, NULL otherwise
     428                }
     429        }
     430
    192431        const ast::FunctionType * getFunctionType( const ast::Type * ty ) {
    193432                if ( auto pty = dynamic_cast< const ast::PointerType * >( ty ) ) {
     
    198437        }
    199438
     439        VariableExpr * getBaseVar( Expression *expr, int *levels ) {
     440                int dummy;
     441                if ( ! levels ) { levels = &dummy; }
     442                *levels = 0;
     443
     444                while ( true ) {
     445                        if ( VariableExpr *varExpr = dynamic_cast< VariableExpr* >( expr ) ) {
     446                                return varExpr;
     447                        } else if ( MemberExpr *memberExpr = dynamic_cast< MemberExpr* >( expr ) ) {
     448                                expr = memberExpr->get_aggregate();
     449                        } else if ( AddressExpr *addressExpr = dynamic_cast< AddressExpr* >( expr ) ) {
     450                                expr = addressExpr->get_arg();
     451                        } else if ( UntypedExpr *untypedExpr = dynamic_cast< UntypedExpr* >( expr ) ) {
     452                                // look for compiler-inserted dereference operator
     453                                NameExpr *fn = dynamic_cast< NameExpr* >( untypedExpr->get_function() );
     454                                if ( ! fn || fn->get_name() != std::string("*?") ) return 0;
     455                                expr = *untypedExpr->begin_args();
     456                        } else if ( CommaExpr *commaExpr = dynamic_cast< CommaExpr* >( expr ) ) {
     457                                // copy constructors insert comma exprs, look at second argument which contains the variable
     458                                expr = commaExpr->get_arg2();
     459                                continue;
     460                        } else if ( ConditionalExpr * condExpr = dynamic_cast< ConditionalExpr * >( expr ) ) {
     461                                int lvl1;
     462                                int lvl2;
     463                                VariableExpr * var1 = getBaseVar( condExpr->get_arg2(), &lvl1 );
     464                                VariableExpr * var2 = getBaseVar( condExpr->get_arg3(), &lvl2 );
     465                                if ( lvl1 == lvl2 && var1 && var2 && var1->get_var() == var2->get_var() ) {
     466                                        *levels = lvl1;
     467                                        return var1;
     468                                }
     469                                break;
     470                        } else break;
     471
     472                        ++(*levels);
     473                }
     474
     475                return 0;
     476        }
     477
    200478        namespace {
    201479                /// Checks if is a pointer to D
     
    210488                inline D const * as( B const * p ) {
    211489                        return reinterpret_cast<D const *>( p );
     490                }
     491
     492                /// Flattens a declaration list
     493                template<typename Output>
     494                void flattenList( list< DeclarationWithType* > src, Output out ) {
     495                        for ( DeclarationWithType* decl : src ) {
     496                                ResolvExpr::flatten( decl->get_type(), out );
     497                        }
     498                }
     499
     500                /// Flattens a list of types
     501                template<typename Output>
     502                void flattenList( list< Type* > src, Output out ) {
     503                        for ( Type* ty : src ) {
     504                                ResolvExpr::flatten( ty, out );
     505                        }
    212506                }
    213507
     
    221515                }
    222516
     517                /// Checks if two lists of parameters are equal up to polymorphic substitution.
     518                bool paramListsPolyCompatible( const list< Expression* >& aparams, const list< Expression* >& bparams ) {
     519                        if ( aparams.size() != bparams.size() ) return false;
     520
     521                        for ( list< Expression* >::const_iterator at = aparams.begin(), bt = bparams.begin();
     522                                        at != aparams.end(); ++at, ++bt ) {
     523                                TypeExpr *aparam = dynamic_cast< TypeExpr* >(*at);
     524                                assertf(aparam, "Aggregate parameters should be type expressions");
     525                                TypeExpr *bparam = dynamic_cast< TypeExpr* >(*bt);
     526                                assertf(bparam, "Aggregate parameters should be type expressions");
     527
     528                                // xxx - might need to let VoidType be a wildcard here too; could have some voids
     529                                // stuffed in for dtype-statics.
     530                                // if ( is<VoidType>( aparam->get_type() ) || is<VoidType>( bparam->get_type() ) ) continue;
     531                                if ( ! typesPolyCompatible( aparam->get_type(), bparam->get_type() ) ) return false;
     532                        }
     533
     534                        return true;
     535                }
     536
    223537                bool paramListsPolyCompatible(
    224538                                std::vector<ast::ptr<ast::Expr>> const & lparams,
     
    245559                        return true;
    246560                }
     561        }
     562
     563        bool typesPolyCompatible( Type *a, Type *b ) {
     564                type_index aid{ typeid(*a) };
     565                // polymorphic types always match
     566                if ( aid == type_index{typeid(TypeInstType)} ) return true;
     567
     568                type_index bid{ typeid(*b) };
     569                // polymorphic types always match
     570                if ( bid == type_index{typeid(TypeInstType)} ) return true;
     571
     572                // can't match otherwise if different types
     573                if ( aid != bid ) return false;
     574
     575                // recurse through type structure (conditions borrowed from Unify.cc)
     576                if ( aid == type_index{typeid(BasicType)} ) {
     577                        return as<BasicType>(a)->get_kind() == as<BasicType>(b)->get_kind();
     578                } else if ( aid == type_index{typeid(PointerType)} ) {
     579                        PointerType *ap = as<PointerType>(a), *bp = as<PointerType>(b);
     580
     581                        // void pointers should match any other pointer type
     582                        return is<VoidType>( ap->get_base() ) || is<VoidType>( bp->get_base() )
     583                                || typesPolyCompatible( ap->get_base(), bp->get_base() );
     584                } else if ( aid == type_index{typeid(ReferenceType)} ) {
     585                        ReferenceType *ap = as<ReferenceType>(a), *bp = as<ReferenceType>(b);
     586                        return is<VoidType>( ap->get_base() ) || is<VoidType>( bp->get_base() )
     587                                || typesPolyCompatible( ap->get_base(), bp->get_base() );
     588                } else if ( aid == type_index{typeid(ArrayType)} ) {
     589                        ArrayType *aa = as<ArrayType>(a), *ba = as<ArrayType>(b);
     590
     591                        if ( aa->get_isVarLen() ) {
     592                                if ( ! ba->get_isVarLen() ) return false;
     593                        } else {
     594                                if ( ba->get_isVarLen() ) return false;
     595
     596                                ConstantExpr *ad = dynamic_cast<ConstantExpr*>( aa->get_dimension() );
     597                                ConstantExpr *bd = dynamic_cast<ConstantExpr*>( ba->get_dimension() );
     598                                if ( ad && bd
     599                                                && ad->get_constant()->get_value() != bd->get_constant()->get_value() )
     600                                        return false;
     601                        }
     602
     603                        return typesPolyCompatible( aa->get_base(), ba->get_base() );
     604                } else if ( aid == type_index{typeid(FunctionType)} ) {
     605                        FunctionType *af = as<FunctionType>(a), *bf = as<FunctionType>(b);
     606
     607                        vector<Type*> aparams, bparams;
     608                        flattenList( af->get_parameters(), back_inserter( aparams ) );
     609                        flattenList( bf->get_parameters(), back_inserter( bparams ) );
     610                        if ( aparams.size() != bparams.size() ) return false;
     611
     612                        vector<Type*> areturns, breturns;
     613                        flattenList( af->get_returnVals(), back_inserter( areturns ) );
     614                        flattenList( bf->get_returnVals(), back_inserter( breturns ) );
     615                        if ( areturns.size() != breturns.size() ) return false;
     616
     617                        for ( unsigned i = 0; i < aparams.size(); ++i ) {
     618                                if ( ! typesPolyCompatible( aparams[i], bparams[i] ) ) return false;
     619                        }
     620                        for ( unsigned i = 0; i < areturns.size(); ++i ) {
     621                                if ( ! typesPolyCompatible( areturns[i], breturns[i] ) ) return false;
     622                        }
     623                        return true;
     624                } else if ( aid == type_index{typeid(StructInstType)} ) {
     625                        StructInstType *aa = as<StructInstType>(a), *ba = as<StructInstType>(b);
     626
     627                        if ( aa->get_name() != ba->get_name() ) return false;
     628                        return paramListsPolyCompatible( aa->get_parameters(), ba->get_parameters() );
     629                } else if ( aid == type_index{typeid(UnionInstType)} ) {
     630                        UnionInstType *aa = as<UnionInstType>(a), *ba = as<UnionInstType>(b);
     631
     632                        if ( aa->get_name() != ba->get_name() ) return false;
     633                        return paramListsPolyCompatible( aa->get_parameters(), ba->get_parameters() );
     634                } else if ( aid == type_index{typeid(EnumInstType)} ) {
     635                        return as<EnumInstType>(a)->get_name() == as<EnumInstType>(b)->get_name();
     636                } else if ( aid == type_index{typeid(TraitInstType)} ) {
     637                        return as<TraitInstType>(a)->get_name() == as<TraitInstType>(b)->get_name();
     638                } else if ( aid == type_index{typeid(TupleType)} ) {
     639                        TupleType *at = as<TupleType>(a), *bt = as<TupleType>(b);
     640
     641                        vector<Type*> atypes, btypes;
     642                        flattenList( at->get_types(), back_inserter( atypes ) );
     643                        flattenList( bt->get_types(), back_inserter( btypes ) );
     644                        if ( atypes.size() != btypes.size() ) return false;
     645
     646                        for ( unsigned i = 0; i < atypes.size(); ++i ) {
     647                                if ( ! typesPolyCompatible( atypes[i], btypes[i] ) ) return false;
     648                        }
     649                        return true;
     650                } else return true; // VoidType, VarArgsType, ZeroType & OneType just need the same type
    247651        }
    248652
     
    359763}
    360764
     765        bool needsBoxing( Type * param, Type * arg, const TyVarMap &exprTyVars, const TypeSubstitution * env ) {
     766                // is parameter is not polymorphic, don't need to box
     767                if ( ! isPolyType( param, exprTyVars ) ) return false;
     768                Type * newType = arg->clone();
     769                if ( env ) env->apply( newType );
     770                std::unique_ptr<Type> manager( newType );
     771                // if the argument's type is polymorphic, we don't need to box again!
     772                return ! isPolyType( newType );
     773        }
     774
    361775bool needsBoxing( const ast::Type * param, const ast::Type * arg,
    362776                const TypeVarMap & typeVars, const ast::TypeSubstitution * subst ) {
     
    372786        return !isPolyType( newType );
    373787}
     788
     789        bool needsBoxing( Type * param, Type * arg, ApplicationExpr * appExpr, const TypeSubstitution * env ) {
     790                FunctionType * function = getFunctionType( appExpr->function->result );
     791                assertf( function, "ApplicationExpr has non-function type: %s", toString( appExpr->function->result ).c_str() );
     792                TyVarMap exprTyVars( TypeDecl::Data{} );
     793                makeTyVarMap( function, exprTyVars );
     794                return needsBoxing( param, arg, exprTyVars, env );
     795        }
    374796
    375797bool needsBoxing(
     
    379801        const ast::FunctionType * function = getFunctionType( expr->func->result );
    380802        assertf( function, "ApplicationExpr has non-function type: %s", toString( expr->func->result ).c_str() );
    381         TypeVarMap exprTyVars;
     803        TypeVarMap exprTyVars = { ast::TypeData() };
    382804        makeTypeVarMap( function, exprTyVars );
    383805        return needsBoxing( param, arg, exprTyVars, subst );
    384806}
    385807
     808        void addToTyVarMap( TypeDecl * tyVar, TyVarMap &tyVarMap ) {
     809                tyVarMap.insert( tyVar->name, TypeDecl::Data{ tyVar } );
     810        }
     811
    386812void addToTypeVarMap( const ast::TypeDecl * decl, TypeVarMap & typeVars ) {
    387813        typeVars.insert( ast::TypeEnvKey( decl, 0, 0 ), ast::TypeData( decl ) );
     
    391817        typeVars.insert( ast::TypeEnvKey( *type ), ast::TypeData( type->base ) );
    392818}
     819
     820        void makeTyVarMap( Type *type, TyVarMap &tyVarMap ) {
     821                for ( Type::ForallList::const_iterator tyVar = type->get_forall().begin(); tyVar != type->get_forall().end(); ++tyVar ) {
     822                        assert( *tyVar );
     823                        addToTyVarMap( *tyVar, tyVarMap );
     824                }
     825                if ( PointerType *pointer = dynamic_cast< PointerType* >( type ) ) {
     826                        makeTyVarMap( pointer->get_base(), tyVarMap );
     827                }
     828        }
    393829
    394830void makeTypeVarMap( const ast::Type * type, TypeVarMap & typeVars ) {
     
    410846}
    411847
     848        void printTyVarMap( std::ostream &os, const TyVarMap &tyVarMap ) {
     849                for ( TyVarMap::const_iterator i = tyVarMap.begin(); i != tyVarMap.end(); ++i ) {
     850                        os << i->first << " (" << i->second << ") ";
     851                } // for
     852                os << std::endl;
     853        }
     854
    412855} // namespace GenPoly
    413856
Note: See TracChangeset for help on using the changeset viewer.