Changeset ae63a18 for src/GenPoly/Box.cc


Ignore:
Timestamp:
Dec 18, 2015, 2:56:11 PM (9 years ago)
Author:
Rob Schluntz <rschlunt@…>
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:
8762501
Parents:
baf7fee (diff), c23f807 (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the (diff) links above to see all the changes relative to each parent.
Message:

resolving conflicts

File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/GenPoly/Box.cc

    rbaf7fee rae63a18  
    55// file "LICENCE" distributed with Cforall.
    66//
    7 // Box.cc -- 
     7// Box.cc --
    88//
    99// Author           : Richard C. Bilson
    1010// Created On       : Mon May 18 07:44:20 2015
    1111// Last Modified By : Rob Schluntz
    12 // Last Modified On : Wed Dec 02 11:52:37 2015
    13 // Update Count     : 201
     12// Last Modified On : Fri Dec 18 14:53:08 2015
     13// Update Count     : 217
    1414//
    1515
     
    2828#include "Parser/ParseNode.h"
    2929
     30#include "SynTree/Constant.h"
    3031#include "SynTree/Type.h"
    3132#include "SynTree/Expression.h"
     
    6162                        virtual Expression *mutate( CommaExpr *commaExpr );
    6263                        virtual Expression *mutate( ConditionalExpr *condExpr );
    63                         virtual Statement *mutate(ReturnStmt *catchStmt);
     64                        virtual Statement * mutate( ReturnStmt *returnStmt );
    6465                        virtual Type *mutate( PointerType *pointerType );
    65                         virtual Type *mutate( FunctionType *pointerType );
    66  
     66                        virtual Type * mutate( FunctionType *functionType );
     67
    6768                        virtual void doBeginScope();
    6869                        virtual void doEndScope();
     
    9293                class Pass2 : public PolyMutator {
    9394                  public:
    94                         Pass2();
    9595                        template< typename DeclClass >
    9696                        DeclClass *handleDecl( DeclClass *decl, Type *type );
     
    103103                  private:
    104104                        void addAdapters( FunctionType *functionType );
    105  
     105
    106106                        std::map< UniqueId, std::string > adapterName;
    107107                };
     
    151151                        // the correct thing in some situations. It's not clear to me why this wasn't working.
    152152
    153                         // if the return type or a parameter type involved polymorphic types, then the adapter will need 
    154                         // to take those polymorphic types as pointers. Therefore, there can be two different functions 
     153                        // if the return type or a parameter type involved polymorphic types, then the adapter will need
     154                        // to take those polymorphic types as pointers. Therefore, there can be two different functions
    155155                        // with the same mangled name, so we need to further mangle the names.
    156156                        for ( std::list< DeclarationWithType *>::iterator retval = function->get_returnVals().begin(); retval != function->get_returnVals().end(); ++retval ) {
    157                                 if ( isPolyVal( (*retval)->get_type(), tyVars ) ) {
     157                                if ( isPolyType( (*retval)->get_type(), tyVars ) ) {
    158158                                        name << "P";
    159159                                } else {
     
    164164                        std::list< DeclarationWithType *> &paramList = function->get_parameters();
    165165                        for ( std::list< DeclarationWithType *>::iterator arg = paramList.begin(); arg != paramList.end(); ++arg ) {
    166                                 if ( isPolyVal( (*arg)->get_type(), tyVars ) ) {
     166                                if ( isPolyType( (*arg)->get_type(), tyVars ) ) {
    167167                                        name << "P";
    168168                                } else {
    169                                         name << "M";                           
     169                                        name << "M";
    170170                                }
    171171                        } // for
     
    181181                }
    182182
    183                 Pass1::Pass1()
    184                         : useRetval( false ), tempNamer( "_temp" ) {
     183                Pass1::Pass1() : useRetval( false ), tempNamer( "_temp" ) {
    185184                        adapters.push(AdapterMap());
    186185                }
     
    194193                                                        if ( PointerType *pointer = dynamic_cast< PointerType *>( funType->get_parameters().front()->get_type() ) ) {
    195194                                                                if ( TypeInstType *typeInst = dynamic_cast< TypeInstType *>( pointer->get_base() ) ) {
    196                                                                         name = typeInst->get_name();
    197                                                                         return true;
     195                                                                        if ( TypeInstType *typeInst2 = dynamic_cast< TypeInstType *>( funType->get_parameters().back()->get_type() ) ) {
     196                                                                                if ( typeInst->get_name() == typeInst2->get_name() ) {
     197                                                                                        name = typeInst->get_name();
     198                                                                                        return true;
     199                                                                                } // if
     200                                                                        } // if
    198201                                                                } // if
    199202                                                        } // if
     
    231234                                if ( isPolyRet( functionDecl->get_functionType(), typeName ) && functionDecl->get_linkage() == LinkageSpec::Cforall ) {
    232235                                        retval = functionDecl->get_functionType()->get_returnVals().front();
    233  
     236
    234237                                        // give names to unnamed return values
    235238                                        if ( retval->get_name() == "" ) {
     
    238241                                        } // if
    239242                                } // if
    240        
     243
    241244                                FunctionType *functionType = functionDecl->get_functionType();
    242245                                makeTyVarMap( functionDecl->get_functionType(), scopeTyVars );
     
    263266
    264267                                functionDecl->set_statements( functionDecl->get_statements()->acceptMutator( *this ) );
    265  
     268
    266269                                scopeTyVars = oldtyVars;
    267270                                assignOps = oldassignOps;
     
    279282
    280283                TypeDecl *Pass1::mutate( TypeDecl *typeDecl ) {
    281 ///     std::cerr << "add " << typeDecl->get_name() << "\n";
    282284                        scopeTyVars[ typeDecl->get_name() ] = typeDecl->get_kind();
    283285                        return Mutator::mutate( typeDecl );
     
    305307
    306308                void Pass1::passTypeVars( ApplicationExpr *appExpr, std::list< Expression *>::iterator &arg, const TyVarMap &exprTyVars ) {
     309                        // pass size/align for type variables
    307310                        for ( TyVarMap::const_iterator tyParm = exprTyVars.begin(); tyParm != exprTyVars.end(); ++tyParm ) {
    308311                                ResolvExpr::EqvClass eqvClass;
     
    313316                                                arg = appExpr->get_args().insert( arg, new SizeofExpr( concrete->clone() ) );
    314317                                                arg++;
     318                                                arg = appExpr->get_args().insert( arg, new AlignofExpr( concrete->clone() ) );
     319                                                arg++;
    315320                                        } else {
    316321                                                throw SemanticError( "unbound type variable in application ", appExpr );
     
    318323                                } // if
    319324                        } // for
     325
     326                        // add size/align for generic types to parameter list
     327                        //assert( ! appExpr->get_function()->get_results().empty() );
     328                        if ( appExpr->get_function()->get_results().empty() ) return;
     329                        FunctionType *funcType = getFunctionType( appExpr->get_function()->get_results().front() );
     330                        assert( funcType );
     331
     332                        std::list< DeclarationWithType* >::const_iterator fnParm = funcType->get_parameters().begin();
     333                        std::list< Expression* >::const_iterator fnArg = arg;
     334                        std::set< std::string > seenTypes; //< names for generic types we've seen
     335                        for ( ; fnParm != funcType->get_parameters().end() && fnArg != appExpr->get_args().end(); ++fnParm, ++fnArg ) {
     336                                Type *parmType = (*fnParm)->get_type();
     337                                if ( ! dynamic_cast< TypeInstType* >( parmType ) && isPolyType( parmType, exprTyVars ) ) {
     338                                        std::string sizeName = sizeofName( parmType );
     339                                        if ( seenTypes.count( sizeName ) ) continue;
     340
     341                                        assert( ! (*fnArg)->get_results().empty() );
     342                                        Type *argType = (*fnArg)->get_results().front();
     343                                        arg = appExpr->get_args().insert( arg, new SizeofExpr( argType->clone() ) );
     344                                        arg++;
     345                                        arg = appExpr->get_args().insert( arg, new AlignofExpr( argType->clone() ) );
     346                                        arg++;
     347
     348                                        seenTypes.insert( sizeName );
     349                                }
     350                        }
    320351                }
    321352
     
    326357                }
    327358
    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
    340                         } else {
    341                                 return 0;
    342                         } // if
    343                 }
    344 
    345359                Expression *Pass1::addRetParam( ApplicationExpr *appExpr, FunctionType *function, Type *retType, std::list< Expression *>::iterator &arg ) {
    346                         if ( useRetval ) {
    347                                 assert( retval );
    348                                 arg = appExpr->get_args().insert( arg, new VariableExpr( retval ) );
    349                                 arg++;
    350                         } else {
    351                                 ObjectDecl *newObj = makeTemporary( retType->clone() );
    352                                 Expression *paramExpr = new VariableExpr( newObj );
    353                                 if ( ! isPolyType( newObj->get_type(), env, scopeTyVars ) ) {
    354                                         paramExpr = new AddressExpr( paramExpr );
    355                                 } // if
    356                                 arg = appExpr->get_args().insert( arg, paramExpr );
    357                                 arg++;
    358 ///     stmtsToAdd.push_back( new ExprStmt( noLabels, appExpr ) );
    359                                 CommaExpr *commaExpr = new CommaExpr( appExpr, new VariableExpr( newObj ) );
    360                                 commaExpr->set_env( appExpr->get_env() );
    361                                 appExpr->set_env( 0 );
    362                                 return commaExpr;
    363                         } // if
    364                         return appExpr;
     360                        // ***** Code Removal ***** After introducing a temporary variable for all return expressions, the following code appears superfluous.
     361                        // if ( useRetval ) {
     362                        //      assert( retval );
     363                        //      arg = appExpr->get_args().insert( arg, new VariableExpr( retval ) );
     364                        //      arg++;
     365                        // } else {
     366
     367                        // Create temporary to hold return value of polymorphic function and produce that temporary as a result
     368                        // using a comma expression.  Possibly change comma expression into statement expression "{}" for multiple
     369                        // return values.
     370                        ObjectDecl *newObj = makeTemporary( retType->clone() );
     371                        Expression *paramExpr = new VariableExpr( newObj );
     372                        // If the type of the temporary is not polymorphic, box temporary by taking its address; otherwise the
     373                        // temporary is already boxed and can be used directly.
     374                        if ( ! isPolyType( newObj->get_type(), scopeTyVars, env ) ) {
     375                                paramExpr = new AddressExpr( paramExpr );
     376                        } // if
     377                        arg = appExpr->get_args().insert( arg, paramExpr ); // add argument to function call
     378                        arg++;
     379                        // Build a comma expression to call the function and emulate a normal return.
     380                        CommaExpr *commaExpr = new CommaExpr( appExpr, new VariableExpr( newObj ) );
     381                        commaExpr->set_env( appExpr->get_env() );
     382                        appExpr->set_env( 0 );
     383                        return commaExpr;
     384                        // } // if
     385                        // return appExpr;
    365386                }
    366387
     
    377398                Expression *Pass1::applyAdapter( ApplicationExpr *appExpr, FunctionType *function, std::list< Expression *>::iterator &arg, const TyVarMap &tyVars ) {
    378399                        Expression *ret = appExpr;
    379                         if ( ! function->get_returnVals().empty() && isPolyVal( function->get_returnVals().front()->get_type(), tyVars ) ) {
     400                        if ( ! function->get_returnVals().empty() && isPolyType( function->get_returnVals().front()->get_type(), tyVars ) ) {
    380401                                ret = addRetParam( appExpr, function, function->get_returnVals().front()->get_type(), arg );
    381402                        } // if
     
    385406                        appExpr->get_args().push_front( appExpr->get_function() );
    386407                        appExpr->set_function( new NameExpr( adapterName ) );
    387  
     408
    388409                        return ret;
    389410                }
     
    391412                void Pass1::boxParam( Type *param, Expression *&arg, const TyVarMap &exprTyVars ) {
    392413                        assert( ! arg->get_results().empty() );
    393 ///   if ( ! dynamic_cast< PointerType *>( arg->get_results().front() ) ) {
     414//   if ( ! dynamic_cast< PointerType *>( arg->get_results().front() ) ) {
    394415                        TypeInstType *typeInst = dynamic_cast< TypeInstType *>( param );
    395416                        if ( typeInst && exprTyVars.find( typeInst->get_name() ) != exprTyVars.end() ) {
     
    411432                                } // if
    412433                        } // if
    413 ///   }
     434//   }
    414435                }
    415436
     
    428449
    429450                void Pass1::boxParams( ApplicationExpr *appExpr, FunctionType *function, std::list< Expression *>::iterator &arg, const TyVarMap &exprTyVars ) {
    430 ///   std::cout << "function is ";
    431 ///   function->print( std::cout );
    432451                        for ( std::list< DeclarationWithType *>::const_iterator param = function->get_parameters().begin(); param != function->get_parameters().end(); ++param, ++arg ) {
    433 ///     std::cout << "parameter is ";
    434 ///     (*param)->print( std::fcout );
    435 ///     std::cout << std::endl << "argument is ";
    436 ///     (*arg)->print( std::cout );
    437452                                assert( arg != appExpr->get_args().end() );
    438453                                addCast( *arg, (*param)->get_type(), exprTyVars );
     
    469484                        // actually make the adapter type
    470485                        FunctionType *adapter = adaptee->clone();
    471                         if ( ! adapter->get_returnVals().empty() && isPolyVal( adapter->get_returnVals().front()->get_type(), tyVars ) ) {
     486                        if ( ! adapter->get_returnVals().empty() && isPolyType( adapter->get_returnVals().front()->get_type(), tyVars ) ) {
    472487                                makeRetParm( adapter );
    473488                        } // if
     
    479494                        assert( param );
    480495                        assert( arg );
    481 ///   std::cout << "arg type is ";
    482 ///   arg->get_type()->print( std::cout );
    483 ///   std::cout << "param type is ";
    484 ///   param->get_type()->print( std::cout );
    485 ///   std::cout << " tyVars are: ";
    486 ///   printTyVarMap( std::cout, tyVars );
    487                         if ( isPolyVal( realParam->get_type(), tyVars ) ) {
    488 ///     if ( dynamic_cast< PointerType *>( arg->get_type() ) ) {
    489 ///       return new CastExpr( new VariableExpr( param ), arg->get_type()->clone() );
    490 ///     } else {
     496                        if ( isPolyType( realParam->get_type(), tyVars ) ) {
     497//     if ( dynamic_cast< PointerType *>( arg->get_type() ) ) {
     498//       return new CastExpr( new VariableExpr( param ), arg->get_type()->clone() );
     499//     } else {
    491500                                if ( dynamic_cast<TypeInstType *>(arg->get_type()) == NULL ) {
    492501                                        UntypedExpr *deref = new UntypedExpr( new NameExpr( "*?" ) );
     
    495504                                        return deref;
    496505                                } // if
    497 ///     }
     506//     }
    498507                        } // if
    499508                        return new VariableExpr( param );
     
    520529                        ApplicationExpr *adapteeApp = new ApplicationExpr( new CastExpr( new VariableExpr( adapteeDecl ), new PointerType( Type::Qualifiers(), realType ) ) );
    521530                        Statement *bodyStmt;
    522  
     531
    523532                        std::list< TypeDecl *>::iterator tyArg = realType->get_forall().begin();
    524533                        std::list< TypeDecl *>::iterator tyParam = adapterType->get_forall().begin();
     
    534543                                } // for
    535544                        } // for
    536  
     545
    537546                        std::list< DeclarationWithType *>::iterator arg = realType->get_parameters().begin();
    538547                        std::list< DeclarationWithType *>::iterator param = adapterType->get_parameters().begin();
     
    542551                                addAdapterParams( adapteeApp, arg, param, adapterType->get_parameters().end(), realParam, tyVars );
    543552                                bodyStmt = new ExprStmt( noLabels, adapteeApp );
    544                         } else if ( isPolyVal( adaptee->get_returnVals().front()->get_type(), tyVars ) ) {
     553                        } else if ( isPolyType( adaptee->get_returnVals().front()->get_type(), tyVars ) ) {
    545554                                if ( (*param)->get_name() == "" ) {
    546555                                        (*param)->set_name( "_ret" );
     
    591600                                if ( adaptersDone.find( mangleName ) == adaptersDone.end() ) {
    592601                                        adaptersDone.insert( adaptersDone.begin(), mangleName );
    593                                        
     602
    594603                                        // apply substitution to type variables to figure out what the adapter's type should look like
    595604                                        assert( env );
    596605                                        env->apply( realFunction );
    597                                         mangleName = SymTab::Mangler::mangle( realFunction ); 
     606                                        mangleName = SymTab::Mangler::mangle( realFunction );
    598607                                        mangleName += makePolyMonoSuffix( originalFunction, exprTyVars );
    599608
     
    614623                } // passAdapters
    615624
    616                 TypeInstType *isPolyPtr( Type *type, const TypeSubstitution *env, const TyVarMap &tyVars ) {
    617                         if ( PointerType *ptr = dynamic_cast< PointerType *>( type ) ) {
    618                                 return isPolyType( ptr->get_base(), env, tyVars );
    619                         } else if ( env ) {
    620                                 if ( TypeInstType *typeInst = dynamic_cast< TypeInstType *>( type ) ) {
    621                                         if ( Type *newType = env->lookup( typeInst->get_name() ) ) {
    622                                                 return isPolyPtr( newType, env, tyVars );
    623                                         } // if
    624                                 } // if
    625                         } // if
    626                         return 0;
    627                 }
    628 
    629                 TypeInstType *isPolyPtrPtr( Type *type, const TypeSubstitution *env, const TyVarMap &tyVars ) {
    630                         if ( PointerType *ptr = dynamic_cast< PointerType *>( type ) ) {
    631                                 return isPolyPtr( ptr->get_base(), env, tyVars );
    632                         } else if ( env ) {
    633                                 if ( TypeInstType *typeInst = dynamic_cast< TypeInstType *>( type ) ) {
    634                                         if ( Type *newType = env->lookup( typeInst->get_name() ) ) {
    635                                                 return isPolyPtrPtr( newType, env, tyVars );
    636                                         } // if
    637                                 } // if
    638                         } // if
    639                         return 0;
    640                 }
    641 
    642                 Expression *makeIncrDecrExpr( ApplicationExpr *appExpr, std::string polyName, bool isIncr ) {
     625                Expression *makeIncrDecrExpr( ApplicationExpr *appExpr, Type *polyType, bool isIncr ) {
    643626                        NameExpr *opExpr;
    644627                        if ( isIncr ) {
     
    653636                                addAssign->get_args().push_back( appExpr->get_args().front() );
    654637                        } // if
    655                         addAssign->get_args().push_back( new NameExpr( polyName ) );
     638                        addAssign->get_args().push_back( new NameExpr( sizeofName( polyType ) ) );
    656639                        addAssign->get_results().front() = appExpr->get_results().front()->clone();
    657640                        if ( appExpr->get_env() ) {
     
    670653                                                assert( ! appExpr->get_results().empty() );
    671654                                                assert( appExpr->get_args().size() == 2 );
    672                                                 TypeInstType *typeInst1 = isPolyPtr( appExpr->get_args().front()->get_results().front(), env, scopeTyVars );
    673                                                 TypeInstType *typeInst2 = isPolyPtr( appExpr->get_args().back()->get_results().front(), env, scopeTyVars );
    674                                                 assert( ! typeInst1 || ! typeInst2 ); // the arguments cannot both be polymorphic pointers
     655                                                Type *baseType1 = isPolyPtr( appExpr->get_args().front()->get_results().front(), scopeTyVars, env );
     656                                                Type *baseType2 = isPolyPtr( appExpr->get_args().back()->get_results().front(), scopeTyVars, env );
     657                                                assert( ! baseType1 || ! baseType2 ); // the arguments cannot both be polymorphic pointers
    675658                                                UntypedExpr *ret = 0;
    676                                                 if ( typeInst1 || typeInst2 ) { // one of the arguments is a polymorphic pointer
     659                                                if ( baseType1 || baseType2 ) { // one of the arguments is a polymorphic pointer
    677660                                                        ret = new UntypedExpr( new NameExpr( "?+?" ) );
    678661                                                } // if
    679                                                 if ( typeInst1 ) {
     662                                                if ( baseType1 ) {
    680663                                                        UntypedExpr *multiply = new UntypedExpr( new NameExpr( "?*?" ) );
    681664                                                        multiply->get_args().push_back( appExpr->get_args().back() );
    682                                                         multiply->get_args().push_back( new NameExpr( typeInst1->get_name() ) );
     665                                                        multiply->get_args().push_back( new NameExpr( sizeofName( baseType1 ) ) );
    683666                                                        ret->get_args().push_back( appExpr->get_args().front() );
    684667                                                        ret->get_args().push_back( multiply );
    685                                                 } else if ( typeInst2 ) {
     668                                                } else if ( baseType2 ) {
    686669                                                        UntypedExpr *multiply = new UntypedExpr( new NameExpr( "?*?" ) );
    687670                                                        multiply->get_args().push_back( appExpr->get_args().front() );
    688                                                         multiply->get_args().push_back( new NameExpr( typeInst2->get_name() ) );
     671                                                        multiply->get_args().push_back( new NameExpr( sizeofName( baseType2 ) ) );
    689672                                                        ret->get_args().push_back( multiply );
    690673                                                        ret->get_args().push_back( appExpr->get_args().back() );
    691674                                                } // if
    692                                                 if ( typeInst1 || typeInst2 ) {
     675                                                if ( baseType1 || baseType2 ) {
    693676                                                        ret->get_results().push_front( appExpr->get_results().front()->clone() );
    694677                                                        if ( appExpr->get_env() ) {
     
    703686                                                assert( ! appExpr->get_results().empty() );
    704687                                                assert( ! appExpr->get_args().empty() );
    705                                                 if ( isPolyType( appExpr->get_results().front(), env, scopeTyVars ) ) {
     688                                                if ( isPolyType( appExpr->get_results().front(), scopeTyVars, env ) ) {
    706689                                                        Expression *ret = appExpr->get_args().front();
    707690                                                        delete ret->get_results().front();
     
    718701                                                assert( ! appExpr->get_results().empty() );
    719702                                                assert( appExpr->get_args().size() == 1 );
    720                                                 if ( TypeInstType *typeInst = isPolyPtr( appExpr->get_results().front(), env, scopeTyVars ) ) {
     703                                                if ( Type *baseType = isPolyPtr( appExpr->get_results().front(), scopeTyVars, env ) ) {
    721704                                                        Type *tempType = appExpr->get_results().front()->clone();
    722705                                                        if ( env ) {
     
    732715                                                                assignExpr->get_args().push_back( appExpr->get_args().front()->clone() );
    733716                                                        } // if
    734                                                         CommaExpr *firstComma = new CommaExpr( assignExpr, makeIncrDecrExpr( appExpr, typeInst->get_name(), varExpr->get_var()->get_name() == "?++" ) );
     717                                                        CommaExpr *firstComma = new CommaExpr( assignExpr, makeIncrDecrExpr( appExpr, baseType, varExpr->get_var()->get_name() == "?++" ) );
    735718                                                        return new CommaExpr( firstComma, tempExpr );
    736719                                                } // if
     
    738721                                                assert( ! appExpr->get_results().empty() );
    739722                                                assert( appExpr->get_args().size() == 1 );
    740                                                 if ( TypeInstType *typeInst = isPolyPtr( appExpr->get_results().front(), env, scopeTyVars ) ) {
    741                                                         return makeIncrDecrExpr( appExpr, typeInst->get_name(), varExpr->get_var()->get_name() == "++?" );
     723                                                if ( Type *baseType = isPolyPtr( appExpr->get_results().front(), scopeTyVars, env ) ) {
     724                                                        return makeIncrDecrExpr( appExpr, baseType, varExpr->get_var()->get_name() == "++?" );
    742725                                                } // if
    743726                                        } else if ( varExpr->get_var()->get_name() == "?+?" || varExpr->get_var()->get_name() == "?-?" ) {
    744727                                                assert( ! appExpr->get_results().empty() );
    745728                                                assert( appExpr->get_args().size() == 2 );
    746                                                 TypeInstType *typeInst1 = isPolyPtr( appExpr->get_args().front()->get_results().front(), env, scopeTyVars );
    747                                                 TypeInstType *typeInst2 = isPolyPtr( appExpr->get_args().back()->get_results().front(), env, scopeTyVars );
    748                                                 if ( typeInst1 && typeInst2 ) {
     729                                                Type *baseType1 = isPolyPtr( appExpr->get_args().front()->get_results().front(), scopeTyVars, env );
     730                                                Type *baseType2 = isPolyPtr( appExpr->get_args().back()->get_results().front(), scopeTyVars, env );
     731                                                if ( baseType1 && baseType2 ) {
    749732                                                        UntypedExpr *divide = new UntypedExpr( new NameExpr( "?/?" ) );
    750733                                                        divide->get_args().push_back( appExpr );
    751                                                         divide->get_args().push_back( new NameExpr( typeInst1->get_name() ) );
     734                                                        divide->get_args().push_back( new NameExpr( sizeofName( baseType1 ) ) );
    752735                                                        divide->get_results().push_front( appExpr->get_results().front()->clone() );
    753736                                                        if ( appExpr->get_env() ) {
     
    756739                                                        } // if
    757740                                                        return divide;
    758                                                 } else if ( typeInst1 ) {
     741                                                } else if ( baseType1 ) {
    759742                                                        UntypedExpr *multiply = new UntypedExpr( new NameExpr( "?*?" ) );
    760743                                                        multiply->get_args().push_back( appExpr->get_args().back() );
    761                                                         multiply->get_args().push_back( new NameExpr( typeInst1->get_name() ) );
     744                                                        multiply->get_args().push_back( new NameExpr( sizeofName( baseType1 ) ) );
    762745                                                        appExpr->get_args().back() = multiply;
    763                                                 } else if ( typeInst2 ) {
     746                                                } else if ( baseType2 ) {
    764747                                                        UntypedExpr *multiply = new UntypedExpr( new NameExpr( "?*?" ) );
    765748                                                        multiply->get_args().push_back( appExpr->get_args().front() );
    766                                                         multiply->get_args().push_back( new NameExpr( typeInst2->get_name() ) );
     749                                                        multiply->get_args().push_back( new NameExpr( sizeofName( baseType2 ) ) );
    767750                                                        appExpr->get_args().front() = multiply;
    768751                                                } // if
     
    770753                                                assert( ! appExpr->get_results().empty() );
    771754                                                assert( appExpr->get_args().size() == 2 );
    772                                                 TypeInstType *typeInst = isPolyPtr( appExpr->get_results().front(), env, scopeTyVars );
    773                                                 if ( typeInst ) {
     755                                                Type *baseType = isPolyPtr( appExpr->get_results().front(), scopeTyVars, env );
     756                                                if ( baseType ) {
    774757                                                        UntypedExpr *multiply = new UntypedExpr( new NameExpr( "?*?" ) );
    775758                                                        multiply->get_args().push_back( appExpr->get_args().back() );
    776                                                         multiply->get_args().push_back( new NameExpr( typeInst->get_name() ) );
     759                                                        multiply->get_args().push_back( new NameExpr( sizeofName( baseType ) ) );
    777760                                                        appExpr->get_args().back() = multiply;
    778761                                                } // if
     
    795778                        mutateAll( appExpr->get_args(), *this );
    796779                        useRetval = oldUseRetval;
    797  
     780
    798781                        assert( ! appExpr->get_function()->get_results().empty() );
    799782                        PointerType *pointer = dynamic_cast< PointerType *>( appExpr->get_function()->get_results().front() );
     
    801784                        FunctionType *function = dynamic_cast< FunctionType *>( pointer->get_base() );
    802785                        assert( function );
    803  
     786
    804787                        if ( Expression *newExpr = handleIntrinsics( appExpr ) ) {
    805788                                return newExpr;
    806789                        } // if
    807  
     790
    808791                        Expression *ret = appExpr;
    809  
     792
    810793                        std::list< Expression *>::iterator arg = appExpr->get_args().begin();
    811794                        std::list< Expression *>::iterator paramBegin = appExpr->get_args().begin();
    812  
     795
    813796                        std::string typeName;
    814797                        if ( isPolyRet( function, typeName ) ) {
     
    824807                        } // if
    825808                        arg = appExpr->get_args().begin();
    826  
     809
    827810                        TyVarMap exprTyVars;
    828811                        makeTyVarMap( function, exprTyVars );
    829  
     812
    830813                        passTypeVars( appExpr, arg, exprTyVars );
    831814                        addInferredParams( appExpr, function, arg, exprTyVars );
    832815
    833816                        arg = paramBegin;
    834  
     817
    835818                        boxParams( appExpr, function, arg, exprTyVars );
    836819
     
    841824
    842825                Expression *Pass1::mutate( UntypedExpr *expr ) {
    843                         if ( ! expr->get_results().empty() && isPolyType( expr->get_results().front(), env, scopeTyVars ) ) {
     826                        if ( ! expr->get_results().empty() && isPolyType( expr->get_results().front(), scopeTyVars, env ) ) {
    844827                                if ( NameExpr *name = dynamic_cast< NameExpr *>( expr->get_function() ) ) {
    845828                                        if ( name->get_name() == "*?" ) {
     
    856839                Expression *Pass1::mutate( AddressExpr *addrExpr ) {
    857840                        assert( ! addrExpr->get_arg()->get_results().empty() );
     841
     842                        bool needs = false;
     843                        if ( UntypedExpr *expr = dynamic_cast< UntypedExpr *>( addrExpr->get_arg() ) ) {
     844                                if ( ! expr->get_results().empty() && isPolyType( expr->get_results().front(), scopeTyVars, env ) ) {
     845                                        if ( NameExpr *name = dynamic_cast< NameExpr *>( expr->get_function() ) ) {
     846                                                if ( name->get_name() == "*?" ) {
     847                                                        if ( ApplicationExpr * appExpr = dynamic_cast< ApplicationExpr * >( expr->get_args().front() ) ) {
     848                                                                assert( ! appExpr->get_function()->get_results().empty() );
     849                                                                PointerType *pointer = dynamic_cast< PointerType *>( appExpr->get_function()->get_results().front() );
     850                                                                assert( pointer );
     851                                                                FunctionType *function = dynamic_cast< FunctionType *>( pointer->get_base() );
     852                                                                assert( function );
     853                                                                needs = needsAdapter( function, scopeTyVars );
     854                                                        } // if
     855                                                } // if
     856                                        } // if
     857                                } // if
     858                        } // if
    858859                        addrExpr->set_arg( mutateExpression( addrExpr->get_arg() ) );
    859                         if ( isPolyType( addrExpr->get_arg()->get_results().front(), env, scopeTyVars ) ) {
     860                        if ( isPolyType( addrExpr->get_arg()->get_results().front(), scopeTyVars, env ) || needs ) {
    860861                                Expression *ret = addrExpr->get_arg();
    861862                                delete ret->get_results().front();
     
    869870                }
    870871
    871                 Statement * Pass1::mutate(ReturnStmt *retStmt) {
    872                         // by this point, a cast expr on a polymorphic return value is redundant
    873                         while ( CastExpr *castExpr = dynamic_cast< CastExpr *>( retStmt->get_expr() ) ) {
    874                                 retStmt->set_expr( castExpr->get_arg() );
    875                                 retStmt->get_expr()->set_env( castExpr->get_env() );
    876                                 castExpr->set_env( 0 );
    877                                 castExpr->set_arg( 0 );
    878                                 delete castExpr;
    879                         }
    880                         if ( retval && retStmt->get_expr() ) {
    881                                 assert( ! retStmt->get_expr()->get_results().empty() );
    882                                 if ( retStmt->get_expr()->get_results().front()->get_isLvalue() ) {
    883 ///       retStmt->set_expr( mutateExpression( retStmt->get_expr() ) );
    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 ", retStmt->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( retStmt->get_expr() );
    895                                         stmtsToAdd.push_back( new ExprStmt( noLabels, mutateExpression( assignExpr ) ) );
    896                                 } else {
    897                                         useRetval = true;
    898                                         stmtsToAdd.push_back( new ExprStmt( noLabels, mutateExpression( retStmt->get_expr() ) ) );
    899                                         useRetval = false;
     872                Statement * Pass1::mutate( ReturnStmt *returnStmt ) {
     873                        if ( retval && returnStmt->get_expr() ) {
     874                                assert( ! returnStmt->get_expr()->get_results().empty() );
     875                                // ***** Code Removal ***** After introducing a temporary variable for all return expressions, the following code appears superfluous.
     876                                // if ( returnStmt->get_expr()->get_results().front()->get_isLvalue() ) {
     877                                // by this point, a cast expr on a polymorphic return value is redundant
     878                                while ( CastExpr *castExpr = dynamic_cast< CastExpr *>( returnStmt->get_expr() ) ) {
     879                                        returnStmt->set_expr( castExpr->get_arg() );
     880                                        returnStmt->get_expr()->set_env( castExpr->get_env() );
     881                                        castExpr->set_env( 0 );
     882                                        castExpr->set_arg( 0 );
     883                                        delete castExpr;
     884                                } //while
     885                                TypeInstType *typeInst = dynamic_cast< TypeInstType *>( retval->get_type() );
     886                                assert( typeInst );
     887                                std::map< std::string, DeclarationWithType *>::const_iterator assignIter = assignOps.find( typeInst->get_name() );
     888                                if ( assignIter == assignOps.end() ) {
     889                                        throw SemanticError( "Attempt to return dtype or ftype object in ", returnStmt->get_expr() );
    900890                                } // if
    901                                 retStmt->set_expr( 0 );
     891                                ApplicationExpr *assignExpr = new ApplicationExpr( new VariableExpr( assignIter->second ) );
     892                                Expression *retParm = new NameExpr( retval->get_name() );
     893                                retParm->get_results().push_back( new PointerType( Type::Qualifiers(), retval->get_type()->clone() ) );
     894                                assignExpr->get_args().push_back( retParm );
     895                                assignExpr->get_args().push_back( returnStmt->get_expr() );
     896                                stmtsToAdd.push_back( new ExprStmt( noLabels, mutateExpression( assignExpr ) ) );
     897                                // } else {
     898                                //      useRetval = true;
     899                                //      stmtsToAdd.push_back( new ExprStmt( noLabels, mutateExpression( returnStmt->get_expr() ) ) );
     900                                //      useRetval = false;
     901                                // } // if
     902                                returnStmt->set_expr( 0 );
    902903                        } else {
    903                                 retStmt->set_expr( mutateExpression( retStmt->get_expr() ) );
    904                         } // if
    905                         return retStmt;
     904                                returnStmt->set_expr( mutateExpression( returnStmt->get_expr() ) );
     905                        } // if
     906                        return returnStmt;
    906907                }
    907908
     
    909910                        TyVarMap oldtyVars = scopeTyVars;
    910911                        makeTyVarMap( pointerType, scopeTyVars );
    911  
     912
    912913                        Type *ret = Mutator::mutate( pointerType );
    913  
     914
    914915                        scopeTyVars = oldtyVars;
    915916                        return ret;
     
    919920                        TyVarMap oldtyVars = scopeTyVars;
    920921                        makeTyVarMap( functionType, scopeTyVars );
    921  
     922
    922923                        Type *ret = Mutator::mutate( functionType );
    923  
     924
    924925                        scopeTyVars = oldtyVars;
    925926                        return ret;
     
    936937
    937938////////////////////////////////////////// Pass2 ////////////////////////////////////////////////////
    938 
    939                 Pass2::Pass2() {}
    940939
    941940                void Pass2::addAdapters( FunctionType *functionType ) {
     
    956955                                }
    957956                        }
    958 ///  deleteAll( functions );
     957//  deleteAll( functions );
    959958                }
    960959
     
    990989                        TyVarMap oldtyVars = scopeTyVars;
    991990                        makeTyVarMap( pointerType, scopeTyVars );
    992  
     991
    993992                        Type *ret = Mutator::mutate( pointerType );
    994  
     993
    995994                        scopeTyVars = oldtyVars;
    996995                        return ret;
     
    1000999                        TyVarMap oldtyVars = scopeTyVars;
    10011000                        makeTyVarMap( funcType, scopeTyVars );
    1002  
     1001
     1002                        // move polymorphic return type to parameter list
    10031003                        std::string typeName;
    10041004                        if ( isPolyRet( funcType, typeName ) ) {
     
    10081008                                funcType->get_returnVals().pop_front();
    10091009                        }
    1010  
     1010
     1011                        // add size/align and assertions for type parameters to parameter list
    10111012                        std::list< DeclarationWithType *>::iterator last = funcType->get_parameters().begin();
    10121013                        std::list< DeclarationWithType *> inferredParams;
    1013                         ObjectDecl *newObj = new ObjectDecl( "", DeclarationNode::NoStorageClass, LinkageSpec::C, 0, new BasicType( Type::Qualifiers(), BasicType::LongUnsignedInt ), 0 );
     1014                        ObjectDecl newObj( "", DeclarationNode::NoStorageClass, LinkageSpec::C, 0, new BasicType( Type::Qualifiers(), BasicType::LongUnsignedInt ), 0 );
    10141015//   ObjectDecl *newFunPtr = new ObjectDecl( "", DeclarationNode::NoStorageClass, LinkageSpec::Cforall, 0, new PointerType( Type::Qualifiers(), new FunctionType( Type::Qualifiers(), true ) ), 0 );
    10151016                        for ( std::list< TypeDecl *>::const_iterator tyParm = funcType->get_forall().begin(); tyParm != funcType->get_forall().end(); ++tyParm ) {
    1016                                 ObjectDecl *thisParm;
    1017                                 // add all size parameters to parameter list
     1017                                ObjectDecl *sizeParm, *alignParm;
     1018                                // add all size and alignment parameters to parameter list
    10181019                                if ( (*tyParm)->get_kind() == TypeDecl::Any ) {
    1019                                         thisParm = newObj->clone();
    1020                                         thisParm->set_name( (*tyParm)->get_name() );
    1021                                         last = funcType->get_parameters().insert( last, thisParm );
     1020                                        TypeInstType parmType( Type::Qualifiers(), (*tyParm)->get_name(), *tyParm );
     1021
     1022                                        sizeParm = newObj.clone();
     1023                                        sizeParm->set_name( sizeofName( &parmType ) );
     1024                                        last = funcType->get_parameters().insert( last, sizeParm );
     1025                                        ++last;
     1026
     1027                                        alignParm = newObj.clone();
     1028                                        alignParm->set_name( alignofName( &parmType ) );
     1029                                        last = funcType->get_parameters().insert( last, alignParm );
    10221030                                        ++last;
    10231031                                }
     
    10291037                                (*tyParm)->get_assertions().clear();
    10301038                        }
    1031                         delete newObj;
     1039
     1040                        // add size/align for generic types to parameter list
     1041                        std::set< std::string > seenTypes; //< sizeofName for generic types we've seen
     1042                        for ( std::list< DeclarationWithType* >::const_iterator fnParm = last; fnParm != funcType->get_parameters().end(); ++fnParm ) {
     1043                                Type *parmType = (*fnParm)->get_type();
     1044                                if ( ! dynamic_cast< TypeInstType* >( parmType ) && isPolyType( parmType, scopeTyVars ) ) {
     1045                                        std::string sizeName = sizeofName( parmType );
     1046                                        if ( seenTypes.count( sizeName ) ) continue;
     1047
     1048                                        ObjectDecl *sizeParm, *alignParm;
     1049                                        sizeParm = newObj.clone();
     1050                                        sizeParm->set_name( sizeName );
     1051                                        last = funcType->get_parameters().insert( last, sizeParm );
     1052                                        ++last;
     1053
     1054                                        alignParm = newObj.clone();
     1055                                        alignParm->set_name( alignofName( parmType ) );
     1056                                        last = funcType->get_parameters().insert( last, alignParm );
     1057                                        ++last;
     1058
     1059                                        seenTypes.insert( sizeName );
     1060                                }
     1061                        }
     1062
     1063                        // splice assertion parameters into parameter list
    10321064                        funcType->get_parameters().splice( last, inferredParams );
    10331065                        addAdapters( funcType );
    10341066                        mutateAll( funcType->get_returnVals(), *this );
    10351067                        mutateAll( funcType->get_parameters(), *this );
    1036  
     1068
    10371069                        scopeTyVars = oldtyVars;
    10381070                        return funcType;
     
    10451077                        TyVarMap oldtyVars = scopeTyVars;
    10461078                        makeTyVarMap( type, scopeTyVars );
    1047  
     1079
    10481080                        DeclClass *ret = static_cast< DeclClass *>( Mutator::mutate( decl ) );
    10491081                        ScrubTyVars::scrub( decl, scopeTyVars );
     
    10811113                        TyVarMap oldtyVars = scopeTyVars;
    10821114                        makeTyVarMap( pointerType, scopeTyVars );
    1083  
     1115
    10841116                        Type *ret = Mutator::mutate( pointerType );
    1085  
     1117
    10861118                        scopeTyVars = oldtyVars;
    10871119                        return ret;
     
    10911123                        TyVarMap oldtyVars = scopeTyVars;
    10921124                        makeTyVarMap( functionType, scopeTyVars );
    1093  
     1125
    10941126                        Type *ret = Mutator::mutate( functionType );
    1095  
     1127
    10961128                        scopeTyVars = oldtyVars;
    10971129                        return ret;
     
    11001132                Statement *Pass3::mutate( DeclStmt *declStmt ) {
    11011133                        if ( ObjectDecl *objectDecl = dynamic_cast< ObjectDecl *>( declStmt->get_decl() ) ) {
    1102                                 if ( isPolyVal( objectDecl->get_type(), scopeTyVars ) ) {
     1134                                if ( isPolyType( objectDecl->get_type(), scopeTyVars ) ) {
    11031135                                        // change initialization of a polymorphic value object
    11041136                                        // to allocate storage with alloca
    1105                                         TypeInstType *typeInst = dynamic_cast< TypeInstType *>( objectDecl->get_type() );
    1106                                         assert( typeInst );
     1137                                        Type *declType = objectDecl->get_type();
    11071138                                        UntypedExpr *alloc = new UntypedExpr( new NameExpr( "__builtin_alloca" ) );
    1108                                         alloc->get_args().push_back( new NameExpr( typeInst->get_name() ) );
     1139                                        alloc->get_args().push_back( new NameExpr( sizeofName( declType ) ) );
    11091140
    11101141                                        delete objectDecl->get_init();
Note: See TracChangeset for help on using the changeset viewer.