Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/GenPoly/Box.cc

    rcf16f94 rffad73a  
    99// Author           : Richard C. Bilson
    1010// Created On       : Mon May 18 07:44:20 2015
    11 // Last Modified By : Peter A. Buhr
    12 // Last Modified On : Tue Dec 15 15:30:31 2015
    13 // Update Count     : 215
     11// Last Modified By : Rob Schluntz
     12// Last Modified On : Thu Nov 26 17:01:55 2015
     13// Update Count     : 191
    1414//
    1515
     
    2828#include "Parser/ParseNode.h"
    2929
     30#include "SynTree/Constant.h"
    3031#include "SynTree/Type.h"
    3132#include "SynTree/Expression.h"
     
    5051                FunctionType *makeAdapterType( FunctionType *adaptee, const TyVarMap &tyVars );
    5152
     53                /// Replaces polymorphic return types with out-parameters, replaces calls to polymorphic functions with adapter calls as needed, and adds appropriate type variables to the function call
    5254                class Pass1 : public PolyMutator {
    5355                  public:
    5456                        Pass1();
    55                         virtual Expression * mutate( ApplicationExpr *appExpr );
    56                         virtual Expression * mutate( AddressExpr *addrExpr );
    57                         virtual Expression * mutate( UntypedExpr *expr );
    58                         virtual DeclarationWithType * mutate( FunctionDecl *functionDecl );
    59                         virtual TypeDecl * mutate( TypeDecl *typeDecl );
    60                         virtual Expression * mutate( CommaExpr *commaExpr );
    61                         virtual Expression * mutate( ConditionalExpr *condExpr );
    62                         virtual Statement * mutate( ReturnStmt *returnStmt );
    63                         virtual Type * mutate( PointerType *pointerType );
    64                         virtual Type * mutate( FunctionType *functionType );
     57                        virtual Expression *mutate( ApplicationExpr *appExpr );
     58                        virtual Expression *mutate( AddressExpr *addrExpr );
     59                        virtual Expression *mutate( UntypedExpr *expr );
     60                        virtual DeclarationWithType* mutate( FunctionDecl *functionDecl );
     61                        virtual TypeDecl *mutate( TypeDecl *typeDecl );
     62                        virtual Expression *mutate( CommaExpr *commaExpr );
     63                        virtual Expression *mutate( ConditionalExpr *condExpr );
     64                        virtual Statement *mutate(ReturnStmt *catchStmt);
     65                        virtual Type *mutate( PointerType *pointerType );
     66                        virtual Type *mutate( FunctionType *pointerType );
    6567 
    6668                        virtual void doBeginScope();
     
    8890                };
    8991
     92                /// Moves polymorphic returns in function types to pointer-type parameters, adds type size and assertion parameters to parameter lists as well
    9093                class Pass2 : public PolyMutator {
    9194                  public:
    92                         Pass2();
    9395                        template< typename DeclClass >
    9496                        DeclClass *handleDecl( DeclClass *decl, Type *type );
     
    105107                };
    106108
     109                /// Replaces initialization of polymorphic values with alloca, declaration of dtype/ftype with appropriate void expression, and sizeof expressions of polymorphic types with the proper variable
    107110                class Pass3 : public PolyMutator {
    108111                  public:
     
    152155                        // with the same mangled name, so we need to further mangle the names.
    153156                        for ( std::list< DeclarationWithType *>::iterator retval = function->get_returnVals().begin(); retval != function->get_returnVals().end(); ++retval ) {
    154                                 if ( isPolyVal( (*retval)->get_type(), tyVars ) ) {
     157                                if ( isPolyType( (*retval)->get_type(), tyVars ) ) {
    155158                                        name << "P";
    156159                                } else {
     
    161164                        std::list< DeclarationWithType *> &paramList = function->get_parameters();
    162165                        for ( std::list< DeclarationWithType *>::iterator arg = paramList.begin(); arg != paramList.end(); ++arg ) {
    163                                 if ( isPolyVal( (*arg)->get_type(), tyVars ) ) {
     166                                if ( isPolyType( (*arg)->get_type(), tyVars ) ) {
    164167                                        name << "P";
    165168                                } else {
     
    178181                }
    179182
    180                 Pass1::Pass1()
    181                         : useRetval( false ), tempNamer( "_temp" ) {
     183                Pass1::Pass1() : useRetval( false ), tempNamer( "_temp" ) {
    182184                        adapters.push(AdapterMap());
    183185                }
     
    190192                                                        if ( PointerType *pointer = dynamic_cast< PointerType *>( funType->get_parameters().front()->get_type() ) ) {
    191193                                                                if ( TypeInstType *typeInst = dynamic_cast< TypeInstType *>( pointer->get_base() ) ) {
    192                                                                         if ( TypeInstType *typeInst2 = dynamic_cast< TypeInstType *>( funType->get_parameters().back()->get_type() ) ) {
    193                                                                                 if ( typeInst->get_name() == typeInst2->get_name() ) {
    194                                                                                         name = typeInst->get_name();
    195                                                                                         return true;
    196                                                                                 } // if
    197                                                                         } // if
     194                                                                        name = typeInst->get_name();
     195                                                                        return true;
    198196                                                                } // if
    199197                                                        } // if
     
    313311                                                arg = appExpr->get_args().insert( arg, new SizeofExpr( concrete->clone() ) );
    314312                                                arg++;
     313                                                arg = appExpr->get_args().insert( arg, new AlignofExpr( concrete->clone() ) );
     314                                                arg++;
    315315                                        } else {
    316316                                                throw SemanticError( "unbound type variable in application ", appExpr );
     
    326326                }
    327327
    328                 TypeInstType *isPolyType( Type *type, const TypeSubstitution *env, const TyVarMap &tyVars ) {
    329                         if ( TypeInstType *typeInst = dynamic_cast< TypeInstType *>( type ) ) {
    330                                 if ( env ) {
    331                                         if ( Type *newType = env->lookup( typeInst->get_name() ) ) {
    332                                                 return isPolyType( newType, env, tyVars );
    333                                         } // if
    334                                 } // if
    335                                 if ( tyVars.find( typeInst->get_name() ) != tyVars.end() ) {
    336                                         return typeInst;
    337                                 } else {
    338                                         return 0;
    339                                 } // if
     328                Expression *Pass1::addRetParam( ApplicationExpr *appExpr, FunctionType *function, Type *retType, std::list< Expression *>::iterator &arg ) {
     329                        if ( useRetval ) {
     330                                assert( retval );
     331                                arg = appExpr->get_args().insert( arg, new VariableExpr( retval ) );
     332                                arg++;
    340333                        } else {
    341                                 return 0;
    342                         } // if
    343                 }
    344 
    345                 Expression *Pass1::addRetParam( ApplicationExpr *appExpr, FunctionType *function, Type *retType, std::list< Expression *>::iterator &arg ) {
    346                         // ***** Code Removal ***** After introducing a temporary variable for all return expressions, the following code appears superfluous.
    347                         // if ( useRetval ) {
    348                         //      assert( retval );
    349                         //      arg = appExpr->get_args().insert( arg, new VariableExpr( retval ) );
    350                         //      arg++;
    351                         // } else {
    352 
    353                         // Create temporary to hold return value of polymorphic function and produce that temporary as a result
    354                         // using a comma expression.  Possibly change comma expression into statement expression "{}" for multiple
    355                         // return values.
    356                         ObjectDecl *newObj = makeTemporary( retType->clone() );
    357                         Expression *paramExpr = new VariableExpr( newObj );
    358                         // If the type of the temporary is not polymorphic, box temporary by taking its address; otherwise the
    359                         // temporary is already boxed and can be used directly.
    360                         if ( ! isPolyType( newObj->get_type(), env, scopeTyVars ) ) {
    361                                 paramExpr = new AddressExpr( paramExpr );
    362                         } // if
    363                         arg = appExpr->get_args().insert( arg, paramExpr ); // add argument to function call
    364                         arg++;
    365                         // Build a comma expression to call the function and emulate a normal return.
    366                         CommaExpr *commaExpr = new CommaExpr( appExpr, new VariableExpr( newObj ) );
    367                         commaExpr->set_env( appExpr->get_env() );
    368                         appExpr->set_env( 0 );
    369                         return commaExpr;
    370                         // } // if
    371                         // return appExpr;
     334                                ObjectDecl *newObj = makeTemporary( retType->clone() );
     335                                Expression *paramExpr = new VariableExpr( newObj );
     336                                if ( ! isPolyType( newObj->get_type(), scopeTyVars, env ) ) {
     337                                        paramExpr = new AddressExpr( paramExpr );
     338                                } // if
     339                                arg = appExpr->get_args().insert( arg, paramExpr );
     340                                arg++;
     341///     stmtsToAdd.push_back( new ExprStmt( noLabels, appExpr ) );
     342                                CommaExpr *commaExpr = new CommaExpr( appExpr, new VariableExpr( newObj ) );
     343                                commaExpr->set_env( appExpr->get_env() );
     344                                appExpr->set_env( 0 );
     345                                return commaExpr;
     346                        } // if
     347                        return appExpr;
    372348                }
    373349
     
    384360                Expression *Pass1::applyAdapter( ApplicationExpr *appExpr, FunctionType *function, std::list< Expression *>::iterator &arg, const TyVarMap &tyVars ) {
    385361                        Expression *ret = appExpr;
    386                         if ( ! function->get_returnVals().empty() && isPolyVal( function->get_returnVals().front()->get_type(), tyVars ) ) {
     362                        if ( ! function->get_returnVals().empty() && isPolyType( function->get_returnVals().front()->get_type(), tyVars ) ) {
    387363                                ret = addRetParam( appExpr, function, function->get_returnVals().front()->get_type(), arg );
    388364                        } // if
     
    398374                void Pass1::boxParam( Type *param, Expression *&arg, const TyVarMap &exprTyVars ) {
    399375                        assert( ! arg->get_results().empty() );
    400 ///   if ( ! dynamic_cast< PointerType *>( arg->get_results().front() ) ) {
     376//   if ( ! dynamic_cast< PointerType *>( arg->get_results().front() ) ) {
    401377                        TypeInstType *typeInst = dynamic_cast< TypeInstType *>( param );
    402378                        if ( typeInst && exprTyVars.find( typeInst->get_name() ) != exprTyVars.end() ) {
     
    418394                                } // if
    419395                        } // if
    420 ///   }
     396//   }
    421397                }
    422398
     
    424400                        Type *newType = formal->clone();
    425401                        std::list< FunctionType *> functions;
    426                         // instead of functions needing adapters, this really ought to look for any function mentioning a
    427                         // polymorphic type
     402                        // instead of functions needing adapters, this really ought to look for
     403                        // any function mentioning a polymorphic type
    428404                        findAndReplaceFunction( newType, functions, tyVars, needsAdapter );
    429405                        if ( ! functions.empty() ) {
     
    476452                        // actually make the adapter type
    477453                        FunctionType *adapter = adaptee->clone();
    478                         if ( ! adapter->get_returnVals().empty() && isPolyVal( adapter->get_returnVals().front()->get_type(), tyVars ) ) {
     454                        if ( ! adapter->get_returnVals().empty() && isPolyType( adapter->get_returnVals().front()->get_type(), tyVars ) ) {
    479455                                makeRetParm( adapter );
    480456                        } // if
     
    486462                        assert( param );
    487463                        assert( arg );
    488 ///   std::cout << "arg type is ";
    489 ///   arg->get_type()->print( std::cout );
    490 ///   std::cout << "param type is ";
    491 ///   param->get_type()->print( std::cout );
    492 ///   std::cout << " tyVars are: ";
    493 ///   printTyVarMap( std::cout, tyVars );
    494                         if ( isPolyVal( realParam->get_type(), tyVars ) ) {
    495 ///     if ( dynamic_cast< PointerType *>( arg->get_type() ) ) {
    496 ///       return new CastExpr( new VariableExpr( param ), arg->get_type()->clone() );
    497 ///     } else {
     464                        if ( isPolyType( realParam->get_type(), tyVars ) ) {
     465//     if ( dynamic_cast< PointerType *>( arg->get_type() ) ) {
     466//       return new CastExpr( new VariableExpr( param ), arg->get_type()->clone() );
     467//     } else {
    498468                                if ( dynamic_cast<TypeInstType *>(arg->get_type()) == NULL ) {
    499469                                        UntypedExpr *deref = new UntypedExpr( new NameExpr( "*?" ) );
     
    502472                                        return deref;
    503473                                } // if
    504 ///     }
     474//     }
    505475                        } // if
    506476                        return new VariableExpr( param );
     
    549519                                addAdapterParams( adapteeApp, arg, param, adapterType->get_parameters().end(), realParam, tyVars );
    550520                                bodyStmt = new ExprStmt( noLabels, adapteeApp );
    551                         } else if ( isPolyVal( adaptee->get_returnVals().front()->get_type(), tyVars ) ) {
     521                        } else if ( isPolyType( adaptee->get_returnVals().front()->get_type(), tyVars ) ) {
    552522                                if ( (*param)->get_name() == "" ) {
    553523                                        (*param)->set_name( "_ret" );
     
    621591                } // passAdapters
    622592
    623                 TypeInstType *isPolyPtr( Type *type, const TypeSubstitution *env, const TyVarMap &tyVars ) {
    624                         if ( PointerType *ptr = dynamic_cast< PointerType *>( type ) ) {
    625                                 return isPolyType( ptr->get_base(), env, tyVars );
    626                         } else if ( env ) {
    627                                 if ( TypeInstType *typeInst = dynamic_cast< TypeInstType *>( type ) ) {
    628                                         if ( Type *newType = env->lookup( typeInst->get_name() ) ) {
    629                                                 return isPolyPtr( newType, env, tyVars );
    630                                         } // if
    631                                 } // if
    632                         } // if
    633                         return 0;
    634                 }
    635 
    636                 TypeInstType *isPolyPtrPtr( Type *type, const TypeSubstitution *env, const TyVarMap &tyVars ) {
    637                         if ( PointerType *ptr = dynamic_cast< PointerType *>( type ) ) {
    638                                 return isPolyPtr( ptr->get_base(), env, tyVars );
    639                         } else if ( env ) {
    640                                 if ( TypeInstType *typeInst = dynamic_cast< TypeInstType *>( type ) ) {
    641                                         if ( Type *newType = env->lookup( typeInst->get_name() ) ) {
    642                                                 return isPolyPtrPtr( newType, env, tyVars );
    643                                         } // if
    644                                 } // if
    645                         } // if
    646                         return 0;
    647                 }
    648 
    649                 Expression *makeIncrDecrExpr( ApplicationExpr *appExpr, std::string polyName, bool isIncr ) {
     593                Expression *makeIncrDecrExpr( ApplicationExpr *appExpr, Type *polyType, bool isIncr ) {
    650594                        NameExpr *opExpr;
    651595                        if ( isIncr ) {
     
    660604                                addAssign->get_args().push_back( appExpr->get_args().front() );
    661605                        } // if
    662                         addAssign->get_args().push_back( new NameExpr( polyName ) );
     606                        addAssign->get_args().push_back( new NameExpr( sizeofName( polyType ) ) );
    663607                        addAssign->get_results().front() = appExpr->get_results().front()->clone();
    664608                        if ( appExpr->get_env() ) {
     
    677621                                                assert( ! appExpr->get_results().empty() );
    678622                                                assert( appExpr->get_args().size() == 2 );
    679                                                 TypeInstType *typeInst1 = isPolyPtr( appExpr->get_args().front()->get_results().front(), env, scopeTyVars );
    680                                                 TypeInstType *typeInst2 = isPolyPtr( appExpr->get_args().back()->get_results().front(), env, scopeTyVars );
    681                                                 assert( ! typeInst1 || ! typeInst2 );
     623                                                Type *baseType1 = isPolyPtr( appExpr->get_args().front()->get_results().front(), scopeTyVars, env );
     624                                                Type *baseType2 = isPolyPtr( appExpr->get_args().back()->get_results().front(), scopeTyVars, env );
     625                                                assert( ! baseType1 || ! baseType2 );
    682626                                                UntypedExpr *ret = 0;
    683                                                 if ( typeInst1 || typeInst2 ) {
     627                                                if ( baseType1 || baseType2 ) {
    684628                                                        ret = new UntypedExpr( new NameExpr( "?+?" ) );
    685629                                                } // if
    686                                                 if ( typeInst1 ) {
     630                                                if ( baseType1 ) {
    687631                                                        UntypedExpr *multiply = new UntypedExpr( new NameExpr( "?*?" ) );
    688632                                                        multiply->get_args().push_back( appExpr->get_args().back() );
    689                                                         multiply->get_args().push_back( new NameExpr( typeInst1->get_name() ) );
     633                                                        multiply->get_args().push_back( new NameExpr( sizeofName( baseType1 ) ) );
    690634                                                        ret->get_args().push_back( appExpr->get_args().front() );
    691635                                                        ret->get_args().push_back( multiply );
    692                                                 } else if ( typeInst2 ) {
     636                                                } else if ( baseType2 ) {
    693637                                                        UntypedExpr *multiply = new UntypedExpr( new NameExpr( "?*?" ) );
    694638                                                        multiply->get_args().push_back( appExpr->get_args().front() );
    695                                                         multiply->get_args().push_back( new NameExpr( typeInst2->get_name() ) );
     639                                                        multiply->get_args().push_back( new NameExpr( sizeofName( baseType2 ) ) );
    696640                                                        ret->get_args().push_back( multiply );
    697641                                                        ret->get_args().push_back( appExpr->get_args().back() );
    698642                                                } // if
    699                                                 if ( typeInst1 || typeInst2 ) {
     643                                                if ( baseType1 || baseType2 ) {
    700644                                                        ret->get_results().push_front( appExpr->get_results().front()->clone() );
    701645                                                        if ( appExpr->get_env() ) {
     
    710654                                                assert( ! appExpr->get_results().empty() );
    711655                                                assert( ! appExpr->get_args().empty() );
    712                                                 if ( isPolyType( appExpr->get_results().front(), env, scopeTyVars ) ) {
     656                                                if ( isPolyType( appExpr->get_results().front(), scopeTyVars, env ) ) {
    713657                                                        Expression *ret = appExpr->get_args().front();
    714658                                                        delete ret->get_results().front();
     
    725669                                                assert( ! appExpr->get_results().empty() );
    726670                                                assert( appExpr->get_args().size() == 1 );
    727                                                 if ( TypeInstType *typeInst = isPolyPtr( appExpr->get_results().front(), env, scopeTyVars ) ) {
     671                                                if ( Type *baseType = isPolyPtr( appExpr->get_results().front(), scopeTyVars, env ) ) {
    728672                                                        Type *tempType = appExpr->get_results().front()->clone();
    729673                                                        if ( env ) {
     
    739683                                                                assignExpr->get_args().push_back( appExpr->get_args().front()->clone() );
    740684                                                        } // if
    741                                                         CommaExpr *firstComma = new CommaExpr( assignExpr, makeIncrDecrExpr( appExpr, typeInst->get_name(), varExpr->get_var()->get_name() == "?++" ) );
     685                                                        CommaExpr *firstComma = new CommaExpr( assignExpr, makeIncrDecrExpr( appExpr, baseType, varExpr->get_var()->get_name() == "?++" ) );
    742686                                                        return new CommaExpr( firstComma, tempExpr );
    743687                                                } // if
     
    745689                                                assert( ! appExpr->get_results().empty() );
    746690                                                assert( appExpr->get_args().size() == 1 );
    747                                                 if ( TypeInstType *typeInst = isPolyPtr( appExpr->get_results().front(), env, scopeTyVars ) ) {
    748                                                         return makeIncrDecrExpr( appExpr, typeInst->get_name(), varExpr->get_var()->get_name() == "++?" );
     691                                                if ( Type *baseType = isPolyPtr( appExpr->get_results().front(), scopeTyVars, env ) ) {
     692                                                        return makeIncrDecrExpr( appExpr, baseType, varExpr->get_var()->get_name() == "++?" );
    749693                                                } // if
    750694                                        } else if ( varExpr->get_var()->get_name() == "?+?" || varExpr->get_var()->get_name() == "?-?" ) {
    751695                                                assert( ! appExpr->get_results().empty() );
    752696                                                assert( appExpr->get_args().size() == 2 );
    753                                                 TypeInstType *typeInst1 = isPolyPtr( appExpr->get_args().front()->get_results().front(), env, scopeTyVars );
    754                                                 TypeInstType *typeInst2 = isPolyPtr( appExpr->get_args().back()->get_results().front(), env, scopeTyVars );
    755                                                 if ( typeInst1 && typeInst2 ) {
     697                                                Type *baseType1 = isPolyPtr( appExpr->get_args().front()->get_results().front(), scopeTyVars, env );
     698                                                Type *baseType2 = isPolyPtr( appExpr->get_args().back()->get_results().front(), scopeTyVars, env );
     699                                                if ( baseType1 && baseType2 ) {
    756700                                                        UntypedExpr *divide = new UntypedExpr( new NameExpr( "?/?" ) );
    757701                                                        divide->get_args().push_back( appExpr );
    758                                                         divide->get_args().push_back( new NameExpr( typeInst1->get_name() ) );
     702                                                        divide->get_args().push_back( new NameExpr( sizeofName( baseType1 ) ) );
    759703                                                        divide->get_results().push_front( appExpr->get_results().front()->clone() );
    760704                                                        if ( appExpr->get_env() ) {
     
    763707                                                        } // if
    764708                                                        return divide;
    765                                                 } else if ( typeInst1 ) {
     709                                                } else if ( baseType1 ) {
    766710                                                        UntypedExpr *multiply = new UntypedExpr( new NameExpr( "?*?" ) );
    767711                                                        multiply->get_args().push_back( appExpr->get_args().back() );
    768                                                         multiply->get_args().push_back( new NameExpr( typeInst1->get_name() ) );
     712                                                        multiply->get_args().push_back( new NameExpr( sizeofName( baseType1 ) ) );
    769713                                                        appExpr->get_args().back() = multiply;
    770                                                 } else if ( typeInst2 ) {
     714                                                } else if ( baseType2 ) {
    771715                                                        UntypedExpr *multiply = new UntypedExpr( new NameExpr( "?*?" ) );
    772716                                                        multiply->get_args().push_back( appExpr->get_args().front() );
    773                                                         multiply->get_args().push_back( new NameExpr( typeInst2->get_name() ) );
     717                                                        multiply->get_args().push_back( new NameExpr( sizeofName( baseType2 ) ) );
    774718                                                        appExpr->get_args().front() = multiply;
    775719                                                } // if
     
    777721                                                assert( ! appExpr->get_results().empty() );
    778722                                                assert( appExpr->get_args().size() == 2 );
    779                                                 TypeInstType *typeInst = isPolyPtr( appExpr->get_results().front(), env, scopeTyVars );
    780                                                 if ( typeInst ) {
     723                                                Type *baseType = isPolyPtr( appExpr->get_results().front(), scopeTyVars, env );
     724                                                if ( baseType ) {
    781725                                                        UntypedExpr *multiply = new UntypedExpr( new NameExpr( "?*?" ) );
    782726                                                        multiply->get_args().push_back( appExpr->get_args().back() );
    783                                                         multiply->get_args().push_back( new NameExpr( typeInst->get_name() ) );
     727                                                        multiply->get_args().push_back( new NameExpr( sizeofName( baseType ) ) );
    784728                                                        appExpr->get_args().back() = multiply;
    785729                                                } // if
     
    848792
    849793                Expression *Pass1::mutate( UntypedExpr *expr ) {
    850                         if ( ! expr->get_results().empty() && isPolyType( expr->get_results().front(), env, scopeTyVars ) ) {
     794                        if ( ! expr->get_results().empty() && isPolyType( expr->get_results().front(), scopeTyVars, env ) ) {
    851795                                if ( NameExpr *name = dynamic_cast< NameExpr *>( expr->get_function() ) ) {
    852796                                        if ( name->get_name() == "*?" ) {
     
    863807                Expression *Pass1::mutate( AddressExpr *addrExpr ) {
    864808                        assert( ! addrExpr->get_arg()->get_results().empty() );
    865 
    866                         bool needs = false;
    867                         if ( UntypedExpr *expr = dynamic_cast< UntypedExpr *>( addrExpr->get_arg() ) ) {
    868                                 if ( ! expr->get_results().empty() && isPolyType( expr->get_results().front(), env, scopeTyVars ) ) {
    869                                         if ( NameExpr *name = dynamic_cast< NameExpr *>( expr->get_function() ) ) {
    870                                                 if ( name->get_name() == "*?" ) {
    871                                                         if ( ApplicationExpr * appExpr = dynamic_cast< ApplicationExpr * >( expr->get_args().front() ) ) {
    872                                                                 assert( ! appExpr->get_function()->get_results().empty() );
    873                                                                 PointerType *pointer = dynamic_cast< PointerType *>( appExpr->get_function()->get_results().front() );
    874                                                                 assert( pointer );
    875                                                                 FunctionType *function = dynamic_cast< FunctionType *>( pointer->get_base() );
    876                                                                 assert( function );
    877                                                                 needs = needsAdapter( function, scopeTyVars );
    878                                                         } // if
    879                                                 } // if
    880                                         } // if
    881                                 } // if
    882                         } // if
    883809                        addrExpr->set_arg( mutateExpression( addrExpr->get_arg() ) );
    884                         if ( isPolyType( addrExpr->get_arg()->get_results().front(), env, scopeTyVars ) || needs ) {
     810                        if ( isPolyType( addrExpr->get_arg()->get_results().front(), scopeTyVars, env ) ) {
    885811                                Expression *ret = addrExpr->get_arg();
    886812                                delete ret->get_results().front();
     
    894820                }
    895821
    896                 Statement * Pass1::mutate( ReturnStmt *returnStmt ) {
    897                         if ( retval && returnStmt->get_expr() ) {
    898                                 assert( ! returnStmt->get_expr()->get_results().empty() );
    899                                 // ***** Code Removal ***** After introducing a temporary variable for all return expressions, the following code appears superfluous.
    900                                 // if ( returnStmt->get_expr()->get_results().front()->get_isLvalue() ) {
    901                                 // a cast expr on a polymorphic return value is either redundant or invalid
    902                                 while ( CastExpr *castExpr = dynamic_cast< CastExpr *>( returnStmt->get_expr() ) ) {
    903                                         returnStmt->set_expr( castExpr->get_arg() );
    904                                         returnStmt->get_expr()->set_env( castExpr->get_env() );
    905                                         castExpr->set_env( 0 );
    906                                         castExpr->set_arg( 0 );
    907                                         delete castExpr;
    908                                 } // while
    909                                 TypeInstType *typeInst = dynamic_cast< TypeInstType *>( retval->get_type() );
    910                                 assert( typeInst );
    911                                 std::map< std::string, DeclarationWithType *>::const_iterator assignIter = assignOps.find( typeInst->get_name() );
    912                                 if ( assignIter == assignOps.end() ) {
    913                                         throw SemanticError( "Attempt to return dtype or ftype object in ", returnStmt->get_expr() );
    914                                 } // if
    915                                 ApplicationExpr *assignExpr = new ApplicationExpr( new VariableExpr( assignIter->second ) );
    916                                 Expression *retParm = new NameExpr( retval->get_name() );
    917                                 retParm->get_results().push_back( new PointerType( Type::Qualifiers(), retval->get_type()->clone() ) );
    918                                 assignExpr->get_args().push_back( retParm );
    919                                 assignExpr->get_args().push_back( returnStmt->get_expr() );
    920                                 stmtsToAdd.push_back( new ExprStmt( noLabels, mutateExpression( assignExpr ) ) );
    921                                 // } else {
    922                                 //      std::cerr << "THOMAS " << std::endl;
    923                                 //      useRetval = true;
    924                                 //      stmtsToAdd.push_back( new ExprStmt( noLabels, mutateExpression( returnStmt->get_expr() ) ) );
    925                                 //      useRetval = false;
    926                                 // } // if
    927                                 returnStmt->set_expr( 0 );
     822                Statement * Pass1::mutate(ReturnStmt *retStmt) {
     823                        // a cast expr on a polymorphic return value is either redundant or invalid
     824                        while ( CastExpr *castExpr = dynamic_cast< CastExpr *>( retStmt->get_expr() ) ) {
     825                                retStmt->set_expr( castExpr->get_arg() );
     826                                retStmt->get_expr()->set_env( castExpr->get_env() );
     827                                castExpr->set_env( 0 );
     828                                castExpr->set_arg( 0 );
     829                                delete castExpr;
     830                        }
     831                        if ( retval && retStmt->get_expr() ) {
     832                                assert( ! retStmt->get_expr()->get_results().empty() );
     833                                if ( retStmt->get_expr()->get_results().front()->get_isLvalue() ) {
     834///       retStmt->set_expr( mutateExpression( retStmt->get_expr() ) );
     835                                        TypeInstType *typeInst = dynamic_cast< TypeInstType *>( retval->get_type() );
     836                                        assert( typeInst );
     837                                        std::map< std::string, DeclarationWithType *>::const_iterator assignIter = assignOps.find( typeInst->get_name() );
     838                                        if ( assignIter == assignOps.end() ) {
     839                                                throw SemanticError( "Attempt to return dtype or ftype object in ", retStmt->get_expr() );
     840                                        } // if
     841                                        ApplicationExpr *assignExpr = new ApplicationExpr( new VariableExpr( assignIter->second ) );
     842                                        Expression *retParm = new NameExpr( retval->get_name() );
     843                                        retParm->get_results().push_back( new PointerType( Type::Qualifiers(), retval->get_type()->clone() ) );
     844                                        assignExpr->get_args().push_back( retParm );
     845                                        assignExpr->get_args().push_back( retStmt->get_expr() );
     846                                        stmtsToAdd.push_back( new ExprStmt( noLabels, mutateExpression( assignExpr ) ) );
     847                                } else {
     848                                        useRetval = true;
     849                                        stmtsToAdd.push_back( new ExprStmt( noLabels, mutateExpression( retStmt->get_expr() ) ) );
     850                                        useRetval = false;
     851                                } // if
     852                                retStmt->set_expr( 0 );
    928853                        } else {
    929                                 returnStmt->set_expr( mutateExpression( returnStmt->get_expr() ) );
    930                         } // if
    931                         return returnStmt;
     854                                retStmt->set_expr( mutateExpression( retStmt->get_expr() ) );
     855                        } // if
     856                        return retStmt;
    932857                }
    933858
     
    962887
    963888////////////////////////////////////////// Pass2 ////////////////////////////////////////////////////
    964 
    965                 Pass2::Pass2() {}
    966889
    967890                void Pass2::addAdapters( FunctionType *functionType ) {
     
    1037960                        std::list< DeclarationWithType *>::iterator last = funcType->get_parameters().begin();
    1038961                        std::list< DeclarationWithType *> inferredParams;
    1039                         ObjectDecl *newObj = new ObjectDecl( "", DeclarationNode::NoStorageClass, LinkageSpec::C, 0, new BasicType( Type::Qualifiers(), BasicType::LongUnsignedInt ), 0 );
    1040 ///   ObjectDecl *newFunPtr = new ObjectDecl( "", DeclarationNode::NoStorageClass, LinkageSpec::Cforall, 0, new PointerType( Type::Qualifiers(), new FunctionType( Type::Qualifiers(), true ) ), 0 );
     962                        ObjectDecl newObj( "", DeclarationNode::NoStorageClass, LinkageSpec::C, 0, new BasicType( Type::Qualifiers(), BasicType::LongUnsignedInt ), 0 );
     963//   ObjectDecl *newFunPtr = new ObjectDecl( "", DeclarationNode::NoStorageClass, LinkageSpec::Cforall, 0, new PointerType( Type::Qualifiers(), new FunctionType( Type::Qualifiers(), true ) ), 0 );
    1041964                        for ( std::list< TypeDecl *>::const_iterator tyParm = funcType->get_forall().begin(); tyParm != funcType->get_forall().end(); ++tyParm ) {
    1042                                 ObjectDecl *thisParm;
    1043                                 // add all size parameters to parameter list
     965                                ObjectDecl *sizeParm, *alignParm;
     966                                // add all size and alignment parameters to parameter list
    1044967                                if ( (*tyParm)->get_kind() == TypeDecl::Any ) {
    1045                                         thisParm = newObj->clone();
    1046                                         thisParm->set_name( (*tyParm)->get_name() );
    1047                                         last = funcType->get_parameters().insert( last, thisParm );
     968                                        TypeInstType parmType( Type::Qualifiers(), (*tyParm)->get_name(), *tyParm );
     969                                       
     970                                        sizeParm = newObj.clone();
     971                                        sizeParm->set_name( sizeofName( &parmType ) );
     972                                        last = funcType->get_parameters().insert( last, sizeParm );
     973                                        ++last;
     974
     975                                        alignParm = newObj.clone();
     976                                        alignParm->set_name( alignofName( &parmType ) );
     977                                        last = funcType->get_parameters().insert( last, alignParm );
    1048978                                        ++last;
    1049979                                }
    1050980                                // move all assertions into parameter list
    1051981                                for ( std::list< DeclarationWithType *>::iterator assert = (*tyParm)->get_assertions().begin(); assert != (*tyParm)->get_assertions().end(); ++assert ) {
    1052 ///      *assert = (*assert)->acceptMutator( *this );
     982//      *assert = (*assert)->acceptMutator( *this );
    1053983                                        inferredParams.push_back( *assert );
    1054984                                }
    1055985                                (*tyParm)->get_assertions().clear();
    1056986                        }
    1057                         delete newObj;
    1058987                        funcType->get_parameters().splice( last, inferredParams );
    1059988                        addAdapters( funcType );
     
    10921021
    10931022                TypeDecl * Pass3::mutate( TypeDecl *typeDecl ) {
    1094 ///   Initializer *init = 0;
    1095 ///   std::list< Expression *> designators;
    1096 ///   scopeTyVars[ typeDecl->get_name() ] = typeDecl->get_kind();
    1097 ///   if ( typeDecl->get_base() ) {
    1098 ///     init = new SimpleInit( new SizeofExpr( handleDecl( typeDecl, typeDecl->get_base() ) ), designators );
    1099 ///   }
    1100 ///   return new ObjectDecl( typeDecl->get_name(), Declaration::Extern, LinkageSpec::C, 0, new BasicType( Type::Qualifiers(), BasicType::UnsignedInt ), init );
     1023//   Initializer *init = 0;
     1024//   std::list< Expression *> designators;
     1025//   scopeTyVars[ typeDecl->get_name() ] = typeDecl->get_kind();
     1026//   if ( typeDecl->get_base() ) {
     1027//     init = new SimpleInit( new SizeofExpr( handleDecl( typeDecl, typeDecl->get_base() ) ), designators );
     1028//   }
     1029//   return new ObjectDecl( typeDecl->get_name(), Declaration::Extern, LinkageSpec::C, 0, new BasicType( Type::Qualifiers(), BasicType::UnsignedInt ), init );
    11011030
    11021031                        scopeTyVars[ typeDecl->get_name() ] = typeDecl->get_kind();
     
    11261055                Statement *Pass3::mutate( DeclStmt *declStmt ) {
    11271056                        if ( ObjectDecl *objectDecl = dynamic_cast< ObjectDecl *>( declStmt->get_decl() ) ) {
    1128                                 if ( isPolyVal( objectDecl->get_type(), scopeTyVars ) ) {
    1129                                         // change initialization of a polymorphic value object to allocate storage with alloca
    1130                                         TypeInstType *typeInst = dynamic_cast< TypeInstType *>( objectDecl->get_type() );
    1131                                         assert( typeInst );
     1057                                if ( isPolyType( objectDecl->get_type(), scopeTyVars ) ) {
     1058                                        // change initialization of a polymorphic value object
     1059                                        // to allocate storage with alloca
     1060                                        Type *declType = objectDecl->get_type();
    11321061                                        UntypedExpr *alloc = new UntypedExpr( new NameExpr( "__builtin_alloca" ) );
    1133                                         alloc->get_args().push_back( new NameExpr( typeInst->get_name() ) );
     1062                                        alloc->get_args().push_back( new NameExpr( sizeofName( declType ) ) );
    11341063
    11351064                                        delete objectDecl->get_init();
Note: See TracChangeset for help on using the changeset viewer.