Changeset ae63a18 for src/GenPoly


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

Location:
src/GenPoly
Files:
8 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();
  • src/GenPoly/GenPoly.cc

    rbaf7fee rae63a18  
    99// Author           : Richard C. Bilson
    1010// Created On       : Mon May 18 07:44:20 2015
    11 // Last Modified By : Rob Schluntz
    12 // Last Modified On : Tue Nov 24 15:23:08 2015
    13 // Update Count     : 11
     11// Last Modified By : Peter A. Buhr
     12// Last Modified On : Tue Dec 15 16:11:18 2015
     13// Update Count     : 13
    1414//
    1515
    1616#include "GenPoly.h"
     17
     18#include "SymTab/Mangler.h"
     19#include "SynTree/Expression.h"
    1720#include "SynTree/Type.h"
    1821
     
    2124
    2225namespace GenPoly {
    23         /// A function needs an adapter if it returns a polymorphic value or if any of its
    24         /// parameters have polymorphic type
    2526        bool needsAdapter( FunctionType *adaptee, const TyVarMap &tyVars ) {
    26                 if ( ! adaptee->get_returnVals().empty() && isPolyVal( adaptee->get_returnVals().front()->get_type(), tyVars ) ) {
     27                if ( ! adaptee->get_returnVals().empty() && isPolyType( adaptee->get_returnVals().front()->get_type(), tyVars ) ) {
    2728                        return true;
    2829                } // if
    2930                for ( std::list< DeclarationWithType* >::const_iterator innerArg = adaptee->get_parameters().begin(); innerArg != adaptee->get_parameters().end(); ++innerArg ) {
    30                         if ( isPolyVal( (*innerArg)->get_type(), tyVars ) ) {
     31                        if ( isPolyType( (*innerArg)->get_type(), tyVars ) ) {
    3132                                return true;
    3233                        } // if
     
    6667        }
    6768
    68         bool isPolyVal( Type *type, const TyVarMap &tyVars ) {
     69        namespace {
     70                /// Checks a parameter list for polymorphic parameters; will substitute according to env if present
     71                bool hasPolyParams( std::list< Expression* >& params, const TypeSubstitution *env ) {
     72                        for ( std::list< Expression* >::iterator param = params.begin(); param != params.end(); ++param ) {
     73                                TypeExpr *paramType = dynamic_cast< TypeExpr* >( *param );
     74                                assert(paramType && "Aggregate parameters should be type expressions");
     75                                if ( isPolyType( paramType->get_type(), env ) ) return true;
     76                        }
     77                        return false;
     78                }
     79
     80                /// Checks a parameter list for polymorphic parameters from tyVars; will substitute according to env if present
     81                bool hasPolyParams( std::list< Expression* >& params, const TyVarMap &tyVars, const TypeSubstitution *env ) {
     82                        for ( std::list< Expression* >::iterator param = params.begin(); param != params.end(); ++param ) {
     83                                TypeExpr *paramType = dynamic_cast< TypeExpr* >( *param );
     84                                assert(paramType && "Aggregate parameters should be type expressions");
     85                                if ( isPolyType( paramType->get_type(), tyVars, env ) ) return true;
     86                        }
     87                        return false;
     88                }
     89        }
     90
     91        Type *isPolyType( Type *type, const TypeSubstitution *env ) {
    6992                if ( TypeInstType *typeInst = dynamic_cast< TypeInstType * >( type ) ) {
     93                        if ( env ) {
     94                                if ( Type *newType = env->lookup( typeInst->get_name() ) ) {
     95                                        return isPolyType( newType, env );
     96                                } // if
     97                        } // if
     98                        return type;
     99                } else if ( StructInstType *structType = dynamic_cast< StructInstType* >( type ) ) {
     100                        if ( hasPolyParams( structType->get_parameters(), env ) ) return type;
     101                } else if ( UnionInstType *unionType = dynamic_cast< UnionInstType* >( type ) ) {
     102                        if ( hasPolyParams( unionType->get_parameters(), env ) ) return type;
     103                }
     104                return 0;
     105        }
     106       
     107        Type *isPolyType( Type *type, const TyVarMap &tyVars, const TypeSubstitution *env ) {
     108                if ( TypeInstType *typeInst = dynamic_cast< TypeInstType * >( type ) ) {
     109                        if ( env ) {
     110                                if ( Type *newType = env->lookup( typeInst->get_name() ) ) {
     111                                        return isPolyType( newType, tyVars, env );
     112                                } // if
     113                        } // if
    70114                        if ( tyVars.find( typeInst->get_name() ) != tyVars.end() ) {
    71                                 return true;
     115                                return type;
     116                        }
     117                } else if ( StructInstType *structType = dynamic_cast< StructInstType* >( type ) ) {
     118                        if ( hasPolyParams( structType->get_parameters(), tyVars, env ) ) return type;
     119                } else if ( UnionInstType *unionType = dynamic_cast< UnionInstType* >( type ) ) {
     120                        if ( hasPolyParams( unionType->get_parameters(), tyVars, env ) ) return type;
     121                }
     122                return 0;
     123        }
     124
     125        Type *isPolyPtr( Type *type, const TypeSubstitution *env ) {
     126                if ( PointerType *ptr = dynamic_cast< PointerType *>( type ) ) {
     127                        return isPolyType( ptr->get_base(), env );
     128                } else if ( env ) {
     129                        if ( TypeInstType *typeInst = dynamic_cast< TypeInstType *>( type ) ) {
     130                                if ( Type *newType = env->lookup( typeInst->get_name() ) ) {
     131                                        return isPolyPtr( newType, env );
     132                                } // if
    72133                        } // if
    73134                } // if
    74                 return false;
     135                return 0;
     136        }
     137       
     138        Type *isPolyPtr( Type *type, const TyVarMap &tyVars, const TypeSubstitution *env ) {
     139                if ( PointerType *ptr = dynamic_cast< PointerType *>( type ) ) {
     140                        return isPolyType( ptr->get_base(), tyVars, env );
     141                } else if ( env ) {
     142                        if ( TypeInstType *typeInst = dynamic_cast< TypeInstType *>( type ) ) {
     143                                if ( Type *newType = env->lookup( typeInst->get_name() ) ) {
     144                                        return isPolyPtr( newType, tyVars, env );
     145                                } // if
     146                        } // if
     147                } // if
     148                return 0;
    75149        }
    76150
    77         bool isPolyObj( Type *type, const TyVarMap &tyVars ) {
    78                 if ( isPolyVal( type, tyVars ) ) {
    79                         return true;
    80                 } else if ( PointerType *pt = dynamic_cast<PointerType*>( type ) ) {
    81                         return isPolyObj( pt->get_base(), tyVars );
     151        FunctionType * getFunctionType( Type *ty ) {
     152                PointerType *ptrType;
     153                if ( ( ptrType = dynamic_cast< PointerType* >( ty ) ) ) {
     154                        return dynamic_cast< FunctionType* >( ptrType->get_base() ); // pointer if FunctionType, NULL otherwise
    82155                } else {
    83                         return false;
     156                        return dynamic_cast< FunctionType* >( ty ); // pointer if FunctionType, NULL otherwise
    84157                }
    85158        }
     
    91164                os << std::endl;
    92165        }
     166
     167        std::string sizeofName( Type *ty ) {
     168                return std::string( "_sizeof_" ) + SymTab::Mangler::mangleType( ty );
     169        }
     170
     171        std::string alignofName( Type *ty ) {
     172                return std::string( "_alignof_" ) + SymTab::Mangler::mangleType( ty );
     173        }
    93174} // namespace GenPoly
    94175
  • src/GenPoly/GenPoly.h

    rbaf7fee rae63a18  
    2020#include <string>
    2121#include <iostream>
     22
    2223#include "SynTree/Declaration.h"
     24#include "SynTree/TypeSubstitution.h"
    2325
    2426namespace GenPoly {
    2527        typedef std::map< std::string, TypeDecl::Kind > TyVarMap;
    2628
     29        /// A function needs an adapter if it returns a polymorphic value or if any of its
     30        /// parameters have polymorphic type
    2731        bool needsAdapter( FunctionType *adaptee, const TyVarMap &tyVarr );
     32
     33        /// true iff function has polymorphic return type
    2834        bool isPolyRet( FunctionType *function, std::string &name, const TyVarMap &otherTyVars );
    2935        bool isPolyRet( FunctionType *function, std::string &name );
    3036        bool isPolyRet( FunctionType *function, const TyVarMap &otherTyVars );
    31 //      bool isPolyFun( FunctionType *fun, const TyVarMap &tyVars );
    32         bool isPolyVal( Type *type, const TyVarMap &tyVars );
    3337
    34   // true if type variable or any number of pointers to type variable
    35   bool isPolyObj( Type *type, const TyVarMap &tyVars );
     38        /// returns polymorphic type if is polymorphic type, NULL otherwise; will look up substitution in env if provided
     39        Type *isPolyType( Type *type, const TypeSubstitution *env = 0 );
     40       
     41        /// returns polymorphic type if is polymorphic type in tyVars, NULL otherwise; will look up substitution in env if provided
     42        Type *isPolyType( Type *type, const TyVarMap &tyVars, const TypeSubstitution *env = 0 );
     43
     44        /// returns polymorphic type if is pointer to polymorphic type, NULL otherwise; will look up substitution in env if provided
     45        Type *isPolyPtr( Type *type, const TypeSubstitution *env = 0 );
     46       
     47        /// returns polymorphic type if is pointer to polymorphic type in tyVars, NULL otherwise; will look up substitution in env if provided
     48        Type *isPolyPtr( Type *type, const TyVarMap &tyVars, const TypeSubstitution *env = 0 );
     49
     50        /// Returns a pointer to the base FunctionType if ty is the type of a function (or pointer to one), NULL otherwise
     51        FunctionType * getFunctionType( Type *ty );
     52
     53        /// Prints type variable map
    3654        void printTyVarMap( std::ostream &os, const TyVarMap &tyVarMap );
     55
     56        /// Gets the name of the sizeof parameter for the type
     57        std::string sizeofName( Type *ty );
     58
     59        /// Gets the name of the alignof parameter for the type
     60        std::string alignofName( Type *ty );
    3761} // namespace GenPoly
    3862
  • src/GenPoly/InstantiateGeneric.cc

    rbaf7fee rae63a18  
    7777                std::list< Type* > params;  ///< Instantiation parameters
    7878        };
    79 
     79       
    8080        /// Maps a concrete type to the instantiated struct type, accounting for scope
    8181        class InstantiationMap {
     
    143143        /// Mutator pass that replaces concrete instantiations of generic types with actual struct declarations, scoped appropriately
    144144        class Instantiate : public DeclMutator {
     145                /// Map of (generic type, parameter list) pairs to concrete type instantiations
    145146                InstantiationMap instantiations;
     147                /// Namer for concrete types
    146148                UniqueName typeNamer;
    147149
     
    149151                Instantiate() : DeclMutator(), instantiations(), typeNamer("_conc_") {}
    150152
    151 //              virtual Declaration* mutate( StructDecl *aggregateDecl );
    152 //              virtual Declaration* mutate( UnionDecl *aggregateDecl );
    153 
    154153                virtual Type* mutate( StructInstType *inst );
    155154                virtual Type* mutate( UnionInstType *inst );
     155
     156//              virtual Expression* mutate( MemberExpr *memberExpr );
    156157               
    157158                virtual void doBeginScope();
     
    166167        /// Makes substitutions of params into baseParams; returns true if all parameters substituted for a concrete type
    167168        bool makeSubstitutions( const std::list< TypeDecl* >& baseParams, const std::list< Expression* >& params, std::list< TypeExpr* >& out ) {
    168                 bool allConcrete = true;  // will finish the substitution list even if they're not all concrete
     169                bool allConcrete = true;  // will finish the substitution list even if they're not all concrete
    169170
    170171                // substitute concrete types for given parameters, and incomplete types for placeholders
     
    172173                std::list< Expression* >::const_iterator param = params.begin();
    173174                for ( ; baseParam != baseParams.end() && param != params.end(); ++baseParam, ++param ) {
    174                         switch ( (*baseParam)->get_kind() ) {
    175                         case TypeDecl::Any: {   // any type is a valid substitution here; complete types can be used to instantiate generics
     175//                      switch ( (*baseParam)->get_kind() ) {
     176//                      case TypeDecl::Any: {   // any type is a valid substitution here; complete types can be used to instantiate generics
    176177                                TypeExpr *paramType = dynamic_cast< TypeExpr* >( *param );
    177178                                assert(paramType && "Aggregate parameters should be type expressions");
     
    179180                                // check that the substituted type isn't a type variable itself
    180181                                if ( dynamic_cast< TypeInstType* >( paramType->get_type() ) ) {
    181                                         allConcrete = false;
     182                                        allConcrete = false;
    182183                                }
    183                                 break;
    184                         }
    185                         case TypeDecl::Dtype:  // dtype can be consistently replaced with void [only pointers, which become void*]
    186                                 out.push_back( new TypeExpr( new VoidType( Type::Qualifiers() ) ) );
    187                                 break;
    188                         case TypeDecl::Ftype:  // pointer-to-ftype can be consistently replaced with void (*)(void) [similar to dtype]
    189                                 out.push_back( new TypeExpr( new FunctionType( Type::Qualifiers(), false ) ) );
    190                                 break;
    191                         }
    192                 }
    193 
    194                 // if not enough parameters given, substitute remaining incomplete types for placeholders
    195                 for ( ; baseParam != baseParams.end(); ++baseParam ) {
    196                         switch ( (*baseParam)->get_kind() ) {
    197                         case TypeDecl::Any:    // no more substitutions here, fail early
    198                                 return false;
    199                         case TypeDecl::Dtype:  // dtype can be consistently replaced with void [only pointers, which become void*]
    200                                 out.push_back( new TypeExpr( new VoidType( Type::Qualifiers() ) ) );
    201                                 break;
    202                         case TypeDecl::Ftype:  // pointer-to-ftype can be consistently replaced with void (*)(void) [similar to dtype]
    203                                 out.push_back( new TypeExpr( new FunctionType( Type::Qualifiers(), false ) ) );
    204                                 break;
    205                         }
    206                 }
    207 
    208                 return allConcrete;
    209         }
    210        
     184//                              break;
     185//                      }
     186//                      case TypeDecl::Dtype:  // dtype can be consistently replaced with void [only pointers, which become void*]
     187//                              out.push_back( new TypeExpr( new VoidType( Type::Qualifiers() ) ) );
     188//                              break;
     189//                      case TypeDecl::Ftype:  // pointer-to-ftype can be consistently replaced with void (*)(void) [similar to dtype]
     190//                              out.push_back( new TypeExpr( new FunctionType( Type::Qualifiers(), false ) ) );
     191//                              break;
     192//                      }
     193                }
     194
     195                // if any parameters left over, not done
     196                if ( baseParam != baseParams.end() ) return false;
     197//              // if not enough parameters given, substitute remaining incomplete types for placeholders
     198//              for ( ; baseParam != baseParams.end(); ++baseParam ) {
     199//                      switch ( (*baseParam)->get_kind() ) {
     200//                      case TypeDecl::Any:    // no more substitutions here, fail early
     201//                              return false;
     202//                      case TypeDecl::Dtype:  // dtype can be consistently replaced with void [only pointers, which become void*]
     203//                              out.push_back( new TypeExpr( new VoidType( Type::Qualifiers() ) ) );
     204//                              break;
     205//                      case TypeDecl::Ftype:  // pointer-to-ftype can be consistently replaced with void (*)(void) [similar to dtype]
     206//                              out.push_back( new TypeExpr( new FunctionType( Type::Qualifiers(), false ) ) );
     207//                              break;
     208//                      }
     209//              }
     210
     211                return allConcrete;
     212        }
     213
    211214        /// Substitutes types of members of in according to baseParams => typeSubs, appending the result to out
    212215        void substituteMembers( const std::list< Declaration* >& in, const std::list< TypeDecl* >& baseParams, const std::list< TypeExpr* >& typeSubs,
     
    288291                return newInst;
    289292        }
     293
     294//      /// Gets the base struct or union declaration for a member expression; NULL if not applicable
     295//      AggregateDecl* getMemberBaseDecl( MemberExpr *memberExpr ) {
     296//              // get variable for member aggregate
     297//              VariableExpr *varExpr = dynamic_cast< VariableExpr* >( memberExpr->get_aggregate() );
     298//              if ( ! varExpr ) return NULL;
     299//
     300//              // get object for variable
     301//              ObjectDecl *objectDecl = dynamic_cast< ObjectDecl* >( varExpr->get_var() );
     302//              if ( ! objectDecl ) return NULL;
     303//
     304//              // get base declaration from object type
     305//              Type *objectType = objectDecl->get_type();
     306//              StructInstType *structType = dynamic_cast< StructInstType* >( objectType );
     307//              if ( structType ) return structType->get_baseStruct();
     308//              UnionInstType *unionType = dynamic_cast< UnionInstType* >( objectType );
     309//              if ( unionType ) return unionType->get_baseUnion();
     310//
     311//              return NULL;
     312//      }
     313//
     314//      /// Finds the declaration with the given name, returning decls.end() if none such
     315//      std::list< Declaration* >::const_iterator findDeclNamed( const std::list< Declaration* > &decls, const std::string &name ) {
     316//              for( std::list< Declaration* >::const_iterator decl = decls.begin(); decl != decls.end(); ++decl ) {
     317//                      if ( (*decl)->get_name() == name ) return decl;
     318//              }
     319//              return decls.end();
     320//      }
     321//     
     322//      Expression* Instantiate::mutate( MemberExpr *memberExpr ) {
     323//              // mutate, exiting early if no longer MemberExpr
     324//              Expression *expr = Mutator::mutate( memberExpr );
     325//              memberExpr = dynamic_cast< MemberExpr* >( expr );
     326//              if ( ! memberExpr ) return expr;
     327//
     328//              // get declaration of member and base declaration of member, exiting early if not found
     329//              AggregateDecl *memberBase = getMemberBaseDecl( memberExpr );
     330//              if ( ! memberBase ) return memberExpr;
     331//              DeclarationWithType *memberDecl = memberExpr->get_member();
     332//              std::list< Declaration* >::const_iterator baseIt = findDeclNamed( memberBase->get_members(), memberDecl->get_name() );
     333//              if ( baseIt == memberBase->get_members().end() ) return memberExpr;
     334//              DeclarationWithType *baseDecl = dynamic_cast< DeclarationWithType* >( *baseIt );
     335//              if ( ! baseDecl ) return memberExpr;
     336//
     337//              // check if stated type of the member is not the type of the member's declaration; if so, need a cast
     338//              // this *SHOULD* be safe, I don't think anything but the void-replacements I put in for dtypes would make it past the typechecker
     339//              SymTab::Indexer dummy;
     340//              if ( ResolvExpr::typesCompatible( memberDecl->get_type(), baseDecl->get_type(), dummy ) ) return memberExpr;
     341//              else return new CastExpr( memberExpr, memberDecl->get_type() );
     342//      }
    290343       
    291344        void Instantiate::doBeginScope() {
    292345                DeclMutator::doBeginScope();
    293                 // push a new concrete type scope
    294346                instantiations.beginScope();
    295347        }
     
    297349        void Instantiate::doEndScope() {
    298350                DeclMutator::doEndScope();
    299                 // pop the last concrete type scope
    300351                instantiations.endScope();
    301352        }
  • src/GenPoly/Lvalue.cc

    rbaf7fee rae63a18  
    1010// Created On       : Mon May 18 07:44:20 2015
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Tue May 19 07:41:33 2015
    13 // Update Count     : 1
     12// Last Modified On : Tue Dec 15 15:33:13 2015
     13// Update Count     : 3
    1414//
    1515
     
    122122                        if ( retval && retStmt->get_expr() ) {
    123123                                assert( ! retStmt->get_expr()->get_results().empty() );
    124                                 while ( CastExpr *castExpr = dynamic_cast< CastExpr* >( retStmt->get_expr() ) ) {
    125                                         retStmt->set_expr( castExpr->get_arg() );
    126                                         retStmt->get_expr()->set_env( castExpr->get_env() );
    127                                         castExpr->set_env( 0 );
    128                                         castExpr->set_arg( 0 );
    129                                         delete castExpr;
    130                                 } // while
    131124                                if ( retStmt->get_expr()->get_results().front()->get_isLvalue() ) {
     125                                        // ***** Code Removal ***** because casts may be stripped already
     126
     127                                        // strip casts because not allowed to take address of cast
     128                                        // while ( CastExpr *castExpr = dynamic_cast< CastExpr* >( retStmt->get_expr() ) ) {
     129                                        //      retStmt->set_expr( castExpr->get_arg() );
     130                                        //      retStmt->get_expr()->set_env( castExpr->get_env() );
     131                                        //      castExpr->set_env( 0 );
     132                                        //      castExpr->set_arg( 0 );
     133                                        //      delete castExpr;
     134                                        // } // while
    132135                                        retStmt->set_expr( new AddressExpr( retStmt->get_expr()->acceptMutator( *this ) ) );
    133136                                } else {
  • src/GenPoly/ScrubTyVars.cc

    rbaf7fee rae63a18  
    1313// Update Count     : 2
    1414//
     15
     16#include <sstream>
     17#include <string>
    1518
    1619#include "GenPoly.h"
     
    4245
    4346        Expression * ScrubTyVars::mutate( SizeofExpr *szeof ) {
    44                 // sizeof( T ) => T parameter, which is the size of T
    45                 if ( TypeInstType *typeInst = dynamic_cast< TypeInstType * >( szeof->get_type() ) ) {
    46                         Expression *expr = new NameExpr( typeInst->get_name() );
     47                // sizeof( T ) => _sizeof_T parameter, which is the size of T
     48                if ( Type *polyType = isPolyType( szeof->get_type() ) ) {
     49                        Expression *expr = new NameExpr( sizeofName( polyType ) );
    4750                        return expr;
    4851                } else {
    4952                        return Mutator::mutate( szeof );
     53                } // if
     54        }
     55
     56        Expression * ScrubTyVars::mutate( AlignofExpr *algnof ) {
     57                // alignof( T ) => _alignof_T parameter, which is the alignment of T
     58                if ( Type *polyType = isPolyType( algnof->get_type() ) ) {
     59                        Expression *expr = new NameExpr( alignofName( polyType ) );
     60                        return expr;
     61                } else {
     62                        return Mutator::mutate( algnof );
    5063                } // if
    5164        }
  • src/GenPoly/ScrubTyVars.h

    rbaf7fee rae63a18  
    1616#ifndef _SCRUBTYVARS_H
    1717#define _SCRUBTYVARS_H
     18
     19#include <string>
    1820
    1921#include "GenPoly.h"
     
    3638                virtual Type* mutate( TypeInstType *typeInst );
    3739                Expression* mutate( SizeofExpr *szeof );
     40                Expression* mutate( AlignofExpr *algnof );
    3841                virtual Type* mutate( PointerType *pointer );
    3942          private:
  • src/GenPoly/Specialize.cc

    rbaf7fee rae63a18  
    1717
    1818#include "Specialize.h"
     19#include "GenPoly.h"
    1920#include "PolyMutator.h"
    2021
     
    8788        }
    8889
    89         /// Returns a pointer to the base FunctionType if ty is the type of a function (or pointer to one), NULL otherwise
    90         FunctionType * getFunctionType( Type *ty ) {
    91                 PointerType *ptrType;
    92                 if ( ( ptrType = dynamic_cast< PointerType* >( ty ) ) ) {
    93                         return dynamic_cast< FunctionType* >( ptrType->get_base() ); // pointer if FunctionType, NULL otherwise
    94                 } else {
    95                         return dynamic_cast< FunctionType* >( ty ); // pointer if FunctionType, NULL otherwise
    96                 }
    97         }
    98 
    9990        /// Generates a thunk that calls `actual` with type `funType` and returns its address
    10091        Expression * Specialize::createThunkFunction( FunctionType *funType, Expression *actual, InferredParams *inferParams ) {
Note: See TracChangeset for help on using the changeset viewer.