Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/GenPoly/Box.cc

    r69911c11 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
     
    6262                        virtual Expression *mutate( CommaExpr *commaExpr );
    6363                        virtual Expression *mutate( ConditionalExpr *condExpr );
    64                         virtual Statement * mutate( ReturnStmt *returnStmt );
     64                        virtual Statement *mutate(ReturnStmt *catchStmt);
    6565                        virtual Type *mutate( PointerType *pointerType );
    66                         virtual Type * mutate( FunctionType *functionType );
     66                        virtual Type *mutate( FunctionType *pointerType );
    6767 
    6868                        virtual void doBeginScope();
     
    192192                                                        if ( PointerType *pointer = dynamic_cast< PointerType *>( funType->get_parameters().front()->get_type() ) ) {
    193193                                                                if ( TypeInstType *typeInst = dynamic_cast< TypeInstType *>( pointer->get_base() ) ) {
    194                                                                         if ( TypeInstType *typeInst2 = dynamic_cast< TypeInstType *>( funType->get_parameters().back()->get_type() ) ) {
    195                                                                                 if ( typeInst->get_name() == typeInst2->get_name() ) {
    196                                                                                         name = typeInst->get_name();
    197                                                                                         return true;
    198                                                                                 } // if
    199                                                                         } // if
     194                                                                        name = typeInst->get_name();
     195                                                                        return true;
    200196                                                                } // if
    201197                                                        } // if
     
    281277
    282278                TypeDecl *Pass1::mutate( TypeDecl *typeDecl ) {
     279///     std::cerr << "add " << typeDecl->get_name() << "\n";
    283280                        scopeTyVars[ typeDecl->get_name() ] = typeDecl->get_kind();
    284281                        return Mutator::mutate( typeDecl );
     
    306303
    307304                void Pass1::passTypeVars( ApplicationExpr *appExpr, std::list< Expression *>::iterator &arg, const TyVarMap &exprTyVars ) {
    308                         // pass size/align for type variables
    309305                        for ( TyVarMap::const_iterator tyParm = exprTyVars.begin(); tyParm != exprTyVars.end(); ++tyParm ) {
    310306                                ResolvExpr::EqvClass eqvClass;
     
    322318                                } // if
    323319                        } // for
    324 
    325                         // add size/align for generic types to parameter list
    326                         //assert( ! appExpr->get_function()->get_results().empty() );
    327                         if ( appExpr->get_function()->get_results().empty() ) return;
    328                         FunctionType *funcType = getFunctionType( appExpr->get_function()->get_results().front() );
    329                         assert( funcType );
    330                        
    331                         std::list< DeclarationWithType* >::const_iterator fnParm = funcType->get_parameters().begin();
    332                         std::list< Expression* >::const_iterator fnArg = arg;
    333                         std::set< std::string > seenTypes; //< names for generic types we've seen
    334                         for ( ; fnParm != funcType->get_parameters().end() && fnArg != appExpr->get_args().end(); ++fnParm, ++fnArg ) {
    335                                 Type *parmType = (*fnParm)->get_type();
    336                                 if ( ! dynamic_cast< TypeInstType* >( parmType ) && isPolyType( parmType, exprTyVars ) ) {
    337                                         std::string sizeName = sizeofName( parmType );
    338                                         if ( seenTypes.count( sizeName ) ) continue;
    339 
    340                                         assert( ! (*fnArg)->get_results().empty() );
    341                                         Type *argType = (*fnArg)->get_results().front();
    342                                         arg = appExpr->get_args().insert( arg, new SizeofExpr( argType->clone() ) );
    343                                         arg++;
    344                                         arg = appExpr->get_args().insert( arg, new AlignofExpr( argType->clone() ) );
    345                                         arg++;
    346 
    347                                         seenTypes.insert( sizeName );
    348                                 }
    349                         }
    350320                }
    351321
     
    357327
    358328                Expression *Pass1::addRetParam( ApplicationExpr *appExpr, FunctionType *function, Type *retType, std::list< Expression *>::iterator &arg ) {
    359                         // ***** Code Removal ***** After introducing a temporary variable for all return expressions, the following code appears superfluous.
    360                         // if ( useRetval ) {
    361                         //      assert( retval );
    362                         //      arg = appExpr->get_args().insert( arg, new VariableExpr( retval ) );
    363                         //      arg++;
    364                         // } else {
    365 
    366                         // Create temporary to hold return value of polymorphic function and produce that temporary as a result
    367                         // using a comma expression.  Possibly change comma expression into statement expression "{}" for multiple
    368                         // return values.
    369                         ObjectDecl *newObj = makeTemporary( retType->clone() );
    370                         Expression *paramExpr = new VariableExpr( newObj );
    371                         // If the type of the temporary is not polymorphic, box temporary by taking its address; otherwise the
    372                         // temporary is already boxed and can be used directly.
    373                         if ( ! isPolyType( newObj->get_type(), scopeTyVars, env ) ) {
    374                                 paramExpr = new AddressExpr( paramExpr );
    375                         } // if
    376                         arg = appExpr->get_args().insert( arg, paramExpr ); // add argument to function call
    377                         arg++;
    378                         // Build a comma expression to call the function and emulate a normal return.
    379                         CommaExpr *commaExpr = new CommaExpr( appExpr, new VariableExpr( newObj ) );
    380                         commaExpr->set_env( appExpr->get_env() );
    381                         appExpr->set_env( 0 );
    382                         return commaExpr;
    383                         // } // if
    384                         // return appExpr;
     329                        if ( useRetval ) {
     330                                assert( retval );
     331                                arg = appExpr->get_args().insert( arg, new VariableExpr( retval ) );
     332                                arg++;
     333                        } else {
     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;
    385348                }
    386349
     
    448411
    449412                void Pass1::boxParams( ApplicationExpr *appExpr, FunctionType *function, std::list< Expression *>::iterator &arg, const TyVarMap &exprTyVars ) {
     413///   std::cout << "function is ";
     414///   function->print( std::cout );
    450415                        for ( std::list< DeclarationWithType *>::const_iterator param = function->get_parameters().begin(); param != function->get_parameters().end(); ++param, ++arg ) {
     416///     std::cout << "parameter is ";
     417///     (*param)->print( std::fcout );
     418///     std::cout << std::endl << "argument is ";
     419///     (*arg)->print( std::cout );
    451420                                assert( arg != appExpr->get_args().end() );
    452421                                addCast( *arg, (*param)->get_type(), exprTyVars );
     
    838807                Expression *Pass1::mutate( AddressExpr *addrExpr ) {
    839808                        assert( ! addrExpr->get_arg()->get_results().empty() );
    840 
    841                         bool needs = false;
    842                         if ( UntypedExpr *expr = dynamic_cast< UntypedExpr *>( addrExpr->get_arg() ) ) {
    843                                 if ( ! expr->get_results().empty() && isPolyType( expr->get_results().front(), scopeTyVars, env ) ) {
    844                                         if ( NameExpr *name = dynamic_cast< NameExpr *>( expr->get_function() ) ) {
    845                                                 if ( name->get_name() == "*?" ) {
    846                                                         if ( ApplicationExpr * appExpr = dynamic_cast< ApplicationExpr * >( expr->get_args().front() ) ) {
    847                                                                 assert( ! appExpr->get_function()->get_results().empty() );
    848                                                                 PointerType *pointer = dynamic_cast< PointerType *>( appExpr->get_function()->get_results().front() );
    849                                                                 assert( pointer );
    850                                                                 FunctionType *function = dynamic_cast< FunctionType *>( pointer->get_base() );
    851                                                                 assert( function );
    852                                                                 needs = needsAdapter( function, scopeTyVars );
    853                                                         } // if
    854                                                 } // if
    855                                         } // if
    856                                 } // if
    857                         } // if
    858809                        addrExpr->set_arg( mutateExpression( addrExpr->get_arg() ) );
    859                         if ( isPolyType( addrExpr->get_arg()->get_results().front(), scopeTyVars, env ) || needs ) {
     810                        if ( isPolyType( addrExpr->get_arg()->get_results().front(), scopeTyVars, env ) ) {
    860811                                Expression *ret = addrExpr->get_arg();
    861812                                delete ret->get_results().front();
     
    869820                }
    870821
    871                 Statement * Pass1::mutate( ReturnStmt *returnStmt ) {
    872                         if ( retval && returnStmt->get_expr() ) {
    873                                 assert( ! returnStmt->get_expr()->get_results().empty() );
    874                                 // ***** Code Removal ***** After introducing a temporary variable for all return expressions, the following code appears superfluous.
    875                                 // if ( returnStmt->get_expr()->get_results().front()->get_isLvalue() ) {
    876                                 // a cast expr on a polymorphic return value is either redundant or invalid
    877                                 while ( CastExpr *castExpr = dynamic_cast< CastExpr *>( returnStmt->get_expr() ) ) {
    878                                         returnStmt->set_expr( castExpr->get_arg() );
    879                                         returnStmt->get_expr()->set_env( castExpr->get_env() );
    880                                         castExpr->set_env( 0 );
    881                                         castExpr->set_arg( 0 );
    882                                         delete castExpr;
    883                                 } //while
    884                                 TypeInstType *typeInst = dynamic_cast< TypeInstType *>( retval->get_type() );
    885                                 assert( typeInst );
    886                                 std::map< std::string, DeclarationWithType *>::const_iterator assignIter = assignOps.find( typeInst->get_name() );
    887                                 if ( assignIter == assignOps.end() ) {
    888                                         throw SemanticError( "Attempt to return dtype or ftype object in ", returnStmt->get_expr() );
    889                                 } // if
    890                                 ApplicationExpr *assignExpr = new ApplicationExpr( new VariableExpr( assignIter->second ) );
    891                                 Expression *retParm = new NameExpr( retval->get_name() );
    892                                 retParm->get_results().push_back( new PointerType( Type::Qualifiers(), retval->get_type()->clone() ) );
    893                                 assignExpr->get_args().push_back( retParm );
    894                                 assignExpr->get_args().push_back( returnStmt->get_expr() );
    895                                 stmtsToAdd.push_back( new ExprStmt( noLabels, mutateExpression( assignExpr ) ) );
    896                                 // } else {
    897                                 //      useRetval = true;
    898                                 //      stmtsToAdd.push_back( new ExprStmt( noLabels, mutateExpression( returnStmt->get_expr() ) ) );
    899                                 //      useRetval = false;
    900                                 // } // if
    901                                 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 );
    902853                        } else {
    903                                 returnStmt->set_expr( mutateExpression( returnStmt->get_expr() ) );
    904                         } // if
    905                         return returnStmt;
     854                                retStmt->set_expr( mutateExpression( retStmt->get_expr() ) );
     855                        } // if
     856                        return retStmt;
    906857                }
    907858
     
    954905                                }
    955906                        }
    956 //  deleteAll( functions );
     907///  deleteAll( functions );
    957908                }
    958909
     
    998949                        TyVarMap oldtyVars = scopeTyVars;
    999950                        makeTyVarMap( funcType, scopeTyVars );
    1000 
    1001                         // move polymorphic return type to parameter list
     951 
    1002952                        std::string typeName;
    1003953                        if ( isPolyRet( funcType, typeName ) ) {
     
    1007957                                funcType->get_returnVals().pop_front();
    1008958                        }
    1009 
    1010                         // add size/align and assertions for type parameters to parameter list
     959 
    1011960                        std::list< DeclarationWithType *>::iterator last = funcType->get_parameters().begin();
    1012961                        std::list< DeclarationWithType *> inferredParams;
     
    1036985                                (*tyParm)->get_assertions().clear();
    1037986                        }
    1038 
    1039                         // add size/align for generic types to parameter list
    1040                         std::set< std::string > seenTypes; //< sizeofName for generic types we've seen
    1041                         for ( std::list< DeclarationWithType* >::const_iterator fnParm = last; fnParm != funcType->get_parameters().end(); ++fnParm ) {
    1042                                 Type *parmType = (*fnParm)->get_type();
    1043                                 if ( ! dynamic_cast< TypeInstType* >( parmType ) && isPolyType( parmType, scopeTyVars ) ) {
    1044                                         std::string sizeName = sizeofName( parmType );
    1045                                         if ( seenTypes.count( sizeName ) ) continue;
    1046                                        
    1047                                         ObjectDecl *sizeParm, *alignParm;
    1048                                         sizeParm = newObj.clone();
    1049                                         sizeParm->set_name( sizeName );
    1050                                         last = funcType->get_parameters().insert( last, sizeParm );
    1051                                         ++last;
    1052 
    1053                                         alignParm = newObj.clone();
    1054                                         alignParm->set_name( alignofName( parmType ) );
    1055                                         last = funcType->get_parameters().insert( last, alignParm );
    1056                                         ++last;
    1057 
    1058                                         seenTypes.insert( sizeName );
    1059                                 }
    1060                         }
    1061 
    1062                         // splice assertion parameters into parameter list
    1063987                        funcType->get_parameters().splice( last, inferredParams );
    1064988                        addAdapters( funcType );
Note: See TracChangeset for help on using the changeset viewer.