Changeset 5c52b06


Ignore:
Timestamp:
Feb 16, 2016, 5:31:06 PM (9 years ago)
Author:
Aaron Moss <a3moss@…>
Branches:
ADT, aaron-thesis, arm-eh, ast-experimental, cleanup-dtors, ctor, deferred_resn, demangler, enum, forall-pointer-decay, gc_noraii, jacob/cs343-translation, jenkins-sandbox, master, memory, new-ast, new-ast-unique-expr, new-env, no_list, persistent-indexer, pthread-emulation, qualifiedEnum, resolv-new, string, with_gc
Children:
9407ed8
Parents:
bed4d37c
Message:

Pass polymorphism information for generic types in function return types as well

File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/GenPoly/Box.cc

    rbed4d37c r5c52b06  
    7373                        /// Makes a new temporary array holding the offsets of the fields of `type`, and returns a new variable expression referencing it
    7474                        Expression *makeOffsetArray( StructInstType *type );
     75                        /// Pass the extra type parameters from polymorphic generic arguments or return types into a function application
     76                        void passArgTypeVars( ApplicationExpr *appExpr, Type *parmType, Type *argBaseType, std::list< Expression *>::iterator &arg, const TyVarMap &exprTyVars, std::set< std::string > &seenTypes );
    7577                        /// passes extra type parameters into a polymorphic function application
    76                         void passTypeVars( ApplicationExpr *appExpr, std::list< Expression *>::iterator &arg, const TyVarMap &exprTyVars );
     78                        void passTypeVars( ApplicationExpr *appExpr, ReferenceToType *polyRetType, std::list< Expression *>::iterator &arg, const TyVarMap &exprTyVars );
    7779                        /// wraps a function application with a new temporary for the out-parameter return value
    7880                        Expression *addRetParam( ApplicationExpr *appExpr, FunctionType *function, Type *retType, std::list< Expression *>::iterator &arg );
     
    398400                }
    399401
    400                 void Pass1::passTypeVars( ApplicationExpr *appExpr, std::list< Expression *>::iterator &arg, const TyVarMap &exprTyVars ) {
     402                void Pass1::passArgTypeVars( ApplicationExpr *appExpr, Type *parmType, Type *argBaseType, std::list< Expression *>::iterator &arg, const TyVarMap &exprTyVars, std::set< std::string > &seenTypes ) {
     403                        Type *polyBase = hasPolyBase( parmType, exprTyVars );
     404                        if ( polyBase && ! dynamic_cast< TypeInstType* >( polyBase ) ) {
     405                                std::string sizeName = sizeofName( polyBase );
     406                                if ( seenTypes.count( sizeName ) ) return;
     407
     408                                arg = appExpr->get_args().insert( arg, new SizeofExpr( argBaseType->clone() ) );
     409                                arg++;
     410                                arg = appExpr->get_args().insert( arg, new AlignofExpr( argBaseType->clone() ) );
     411                                arg++;
     412                                if ( dynamic_cast< StructInstType* >( polyBase ) ) {
     413                                        if ( StructInstType *argBaseStructType = dynamic_cast< StructInstType* >( argBaseType ) ) {
     414                                                arg = appExpr->get_args().insert( arg, makeOffsetArray( argBaseStructType ) );
     415                                                arg++;
     416                                        } else {
     417                                                throw SemanticError( "Cannot pass non-struct type for generic struct" );
     418                                        }
     419                                }
     420
     421                                seenTypes.insert( sizeName );
     422                        }
     423                }
     424
     425                void Pass1::passTypeVars( ApplicationExpr *appExpr, ReferenceToType *polyRetType, std::list< Expression *>::iterator &arg, const TyVarMap &exprTyVars ) {
    401426                        // pass size/align for type variables
    402427                        for ( TyVarMap::const_iterator tyParm = exprTyVars.begin(); tyParm != exprTyVars.end(); ++tyParm ) {
     
    424449                        std::list< Expression* >::const_iterator fnArg = arg;
    425450                        std::set< std::string > seenTypes; //< names for generic types we've seen
     451
     452                        // a polymorphic return type may need to be added to the argument list
     453                        if ( polyRetType ) {
     454                                Type *concRetType = replaceWithConcrete( appExpr, polyRetType );
     455                                passArgTypeVars( appExpr, polyRetType, concRetType, arg, exprTyVars, seenTypes );
     456                        }
     457                       
     458                        // add type information args for presently unseen types in parameter list
    426459                        for ( ; fnParm != funcType->get_parameters().end() && fnArg != appExpr->get_args().end(); ++fnParm, ++fnArg ) {
    427                                 Type *polyBase = hasPolyBase( (*fnParm)->get_type(), exprTyVars );
    428                                 if ( polyBase && ! dynamic_cast< TypeInstType* >( polyBase ) ) {
    429                                         std::string sizeName = sizeofName( polyBase );
    430                                         if ( seenTypes.count( sizeName ) ) continue;
    431 
    432                                         VariableExpr *fnArgBase = getBaseVar( *fnArg );
    433                                         assert( fnArgBase && ! fnArgBase->get_results().empty() );
    434                                         Type *argBaseType = fnArgBase->get_results().front();
    435                                         arg = appExpr->get_args().insert( arg, new SizeofExpr( argBaseType->clone() ) );
    436                                         arg++;
    437                                         arg = appExpr->get_args().insert( arg, new AlignofExpr( argBaseType->clone() ) );
    438                                         arg++;
    439                                         if ( dynamic_cast< StructInstType* >( polyBase ) ) {
    440                                                 if ( StructInstType *argBaseStructType = dynamic_cast< StructInstType* >( argBaseType ) ) {
    441                                                         arg = appExpr->get_args().insert( arg, makeOffsetArray( argBaseStructType ) );
    442                                                         arg++;
    443                                                 } else {
    444                                                         throw SemanticError( "Cannot pass non-struct type for generic struct" );
    445                                                 }
    446                                         }
    447 
    448                                         seenTypes.insert( sizeName );
    449                                 }
     460                                VariableExpr *fnArgBase = getBaseVar( *fnArg );
     461                                if ( ! fnArgBase || fnArgBase->get_results().empty() ) continue;
     462                                passArgTypeVars( appExpr, (*fnParm)->get_type(), fnArgBase->get_results().front(), arg, exprTyVars, seenTypes );
    450463                        }
    451464                }
     
    470483                        ObjectDecl *newObj = makeTemporary( retType->clone() );
    471484                        Expression *paramExpr = new VariableExpr( newObj );
    472                         // If the type of the temporary is not polymorphic, box temporary by taking its address; otherwise the
    473                         // temporary is already boxed and can be used directly.
     485
     486                        // If the type of the temporary is not polymorphic, box temporary by taking its address;
     487                        // otherwise the temporary is already boxed and can be used directly.
    474488                        if ( ! isPolyType( newObj->get_type(), scopeTyVars, env ) ) {
    475489                                paramExpr = new AddressExpr( paramExpr );
     
    520534                        assert( env );
    521535                        Type *concrete = replaceWithConcrete( appExpr, polyType );
     536                        // add out-parameter for return value   
    522537                        return addRetParam( appExpr, function, concrete, arg );
    523538                }
     
    917932                        std::list< Expression *>::iterator paramBegin = appExpr->get_args().begin();
    918933
    919                         if ( ReferenceToType *polyType = isPolyRet( function ) ) {
    920                                 ret = addPolyRetParam( appExpr, function, polyType, arg );
     934                        TyVarMap exprTyVars;
     935                        makeTyVarMap( function, exprTyVars );
     936                        ReferenceToType *polyRetType = 0;
     937
     938                        if ( polyRetType = isPolyRet( function ) ) {
     939                                ret = addPolyRetParam( appExpr, function, polyRetType, arg );
    921940                        } else if ( needsAdapter( function, scopeTyVars ) ) {
    922941                                // std::cerr << "needs adapter: ";
     
    930949                        arg = appExpr->get_args().begin();
    931950
    932                         TyVarMap exprTyVars;
    933                         makeTyVarMap( function, exprTyVars );
    934 
    935                         passTypeVars( appExpr, arg, exprTyVars );
     951                        passTypeVars( appExpr, polyRetType, arg, exprTyVars );
    936952                        addInferredParams( appExpr, function, arg, exprTyVars );
    937953
     
    12291245                        }
    12301246
    1231                         // add size/align for generic types to parameter list
     1247                        // add size/align for generic parameter types to parameter list
    12321248                        std::set< std::string > seenTypes; // sizeofName for generic types we've seen
    12331249                        for ( std::list< DeclarationWithType* >::const_iterator fnParm = last; fnParm != funcType->get_parameters().end(); ++fnParm ) {
     
    14291445                                delete offsetofExpr;
    14301446                                return offsetInd;
    1431                         } else if ( UnionInstType *unionType = dynamic_cast< UnionInstType* >( ty ) ) {
     1447                        } else if ( dynamic_cast< UnionInstType* >( ty ) ) {
    14321448                                // all union members are at offset zero
    14331449                                delete offsetofExpr;
Note: See TracChangeset for help on using the changeset viewer.