Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/GenPoly/Box.cc

    rf2b2029 r698664b3  
    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 : Tue Aug 11 16:22:35 2015
     13// Update Count     : 89
    1414//
    1515
     
    4747        namespace {
    4848                const std::list<Label> noLabels;
    49 
    50                 FunctionType *makeAdapterType( FunctionType *adaptee, const TyVarMap &tyVars );
    5149
    5250                class Pass1 : public PolyMutator {
     
    8078                        ObjectDecl *makeTemporary( Type *type );
    8179
    82                         typedef std::map< std::string, DeclarationWithType *> AdapterMap;
     80                        typedef std::map< std::string, FunctionDecl *> AdapterMap;
    8381                        std::map< std::string, DeclarationWithType *> assignOps;
    8482                        std::stack< AdapterMap > adapters;
     
    142140
    143141        namespace {
    144                 std::string makePolyMonoSuffix( FunctionType * function, const TyVarMap &tyVars ) {
    145                         std::stringstream name;
    146 
    147                         // NOTE: this function previously used isPolyObj, which failed to produce
    148                         // the correct thing in some situations. It's not clear to me why this wasn't working.
    149 
    150                         // if the return type or a parameter type involved polymorphic types, then the adapter will need
    151                         // to take those polymorphic types as pointers. Therefore, there can be two different functions
    152                         // with the same mangled name, so we need to further mangle the names.
    153                         for ( std::list< DeclarationWithType *>::iterator retval = function->get_returnVals().begin(); retval != function->get_returnVals().end(); ++retval ) {
    154                                 if ( isPolyVal( (*retval)->get_type(), tyVars ) ) {
    155                                         name << "P";
    156                                 } else {
    157                                         name << "M";
    158                                 }
    159                         }
    160                         name << "_";
    161                         std::list< DeclarationWithType *> &paramList = function->get_parameters();
    162                         for ( std::list< DeclarationWithType *>::iterator arg = paramList.begin(); arg != paramList.end(); ++arg ) {
    163                                 if ( isPolyVal( (*arg)->get_type(), tyVars ) ) {
    164                                         name << "P";
    165                                 } else {
    166                                         name << "M";                           
    167                                 }
    168                         } // for
    169                         return name.str();
    170                 }
    171 
    172                 std::string mangleAdapterName( FunctionType * function, const TyVarMap &tyVars ) {
    173                         return SymTab::Mangler::mangle( function ) + makePolyMonoSuffix( function, tyVars );
    174                 }
    175 
    176142                std::string makeAdapterName( const std::string &mangleName ) {
    177143                        return "_adapter" + mangleName;
    178144                }
    179145
     146                bool isPolyRet( FunctionType *function, std::string &name, const TyVarMap &otherTyVars ) {
     147                        bool doTransform = false;
     148                        if ( ! function->get_returnVals().empty() ) {
     149                                if ( TypeInstType *typeInst = dynamic_cast< TypeInstType *>( function->get_returnVals().front()->get_type() ) ) {
     150       
     151                                        // figure out if the return type is specified by a type parameter
     152                                        for ( std::list< TypeDecl *>::const_iterator tyVar = function->get_forall().begin(); tyVar != function->get_forall().end(); ++tyVar ) {
     153                                                if ( (*tyVar)->get_name() == typeInst->get_name() ) {
     154                                                        doTransform = true;
     155                                                        name = typeInst->get_name();
     156                                                        break;
     157                                                } // if
     158                                        } // for
     159                                        if ( ! doTransform && otherTyVars.find( typeInst->get_name() ) != otherTyVars.end() ) {
     160                                                doTransform = true;
     161                                        } // if
     162                                } // if
     163                        } // if
     164                        return doTransform;
     165                }
     166
     167                bool isPolyRet( FunctionType *function, std::string &name ) {
     168                        TyVarMap dummyTyVars;
     169                        return isPolyRet( function, name, dummyTyVars );
     170                }
     171
     172                bool isPolyRet( FunctionType *function, const TyVarMap &otherTyVars ) {
     173                        std::string dummyString;
     174                        return isPolyRet( function, dummyString, otherTyVars );
     175                }
     176
    180177                Pass1::Pass1()
    181178                        : useRetval( false ), tempNamer( "_temp" ) {
    182                         adapters.push(AdapterMap());
    183                 }
    184 
    185                 // returns true if the given declaration is: (*?=?)(T *, T) for some T (return not checked, but maybe should be)
     179                }
     180
    186181                bool checkAssignment( DeclarationWithType *decl, std::string &name ) {
    187182                        if ( decl->get_name() == "?=?" ) {
     
    203198
    204199                void Pass1::findAssignOps( const std::list< TypeDecl *> &forall ) {
    205                         // what if a nested function uses an assignment operator?
    206                         // assignOps.clear();
     200                        assignOps.clear();
    207201                        for ( std::list< TypeDecl *>::const_iterator i = forall.begin(); i != forall.end(); ++i ) {
    208202                                for ( std::list< DeclarationWithType *>::const_iterator assert = (*i)->get_assertions().begin(); assert != (*i)->get_assertions().end(); ++assert ) {
     
    216210
    217211                DeclarationWithType *Pass1::mutate( FunctionDecl *functionDecl ) {
    218                         if ( functionDecl->get_statements() ) {         // empty routine body ?
    219                                 doBeginScope();
     212                        if ( functionDecl->get_statements() ) {
    220213                                TyVarMap oldtyVars = scopeTyVars;
    221                                 std::map< std::string, DeclarationWithType *> oldassignOps = assignOps;
    222214                                DeclarationWithType *oldRetval = retval;
    223215                                bool oldUseRetval = useRetval;
    224 
    225                                 // process polymorphic return value
     216       
    226217                                retval = 0;
    227218                                std::string typeName;
     
    236227                                } // if
    237228       
    238                                 FunctionType *functionType = functionDecl->get_functionType();
     229                                scopeTyVars.clear();
     230///     std::cerr << "clear\n";
    239231                                makeTyVarMap( functionDecl->get_functionType(), scopeTyVars );
    240232                                findAssignOps( functionDecl->get_functionType()->get_forall() );
    241 
    242                                 std::list< DeclarationWithType *> &paramList = functionType->get_parameters();
    243                                 std::list< FunctionType *> functions;
    244                                 for ( std::list< TypeDecl *>::iterator tyVar = functionType->get_forall().begin(); tyVar != functionType->get_forall().end(); ++tyVar ) {
    245                                         for ( std::list< DeclarationWithType *>::iterator assert = (*tyVar)->get_assertions().begin(); assert != (*tyVar)->get_assertions().end(); ++assert ) {
    246                                                 findFunction( (*assert)->get_type(), functions, scopeTyVars, needsAdapter );
    247                                         } // for
    248                                 } // for
    249                                 for ( std::list< DeclarationWithType *>::iterator arg = paramList.begin(); arg != paramList.end(); ++arg ) {
    250                                         findFunction( (*arg)->get_type(), functions, scopeTyVars, needsAdapter );
    251                                 } // for
    252                                 AdapterMap & adapters = Pass1::adapters.top();
    253                                 for ( std::list< FunctionType *>::iterator funType = functions.begin(); funType != functions.end(); ++funType ) {
    254                                         std::string mangleName = mangleAdapterName( *funType, scopeTyVars );
    255                                         if ( adapters.find( mangleName ) == adapters.end() ) {
    256                                                 std::string adapterName = makeAdapterName( mangleName );
    257                                                 adapters.insert( std::pair< std::string, DeclarationWithType *>( mangleName, new ObjectDecl( adapterName, DeclarationNode::NoStorageClass, LinkageSpec::C, 0, new PointerType( Type::Qualifiers(), makeAdapterType( *funType, scopeTyVars ) ), 0 ) ) );
    258                                         } // if
    259                                 } // for
    260 
    261233                                functionDecl->set_statements( functionDecl->get_statements()->acceptMutator( *this ) );
    262234 
    263235                                scopeTyVars = oldtyVars;
    264                                 assignOps = oldassignOps;
    265                                 // std::cerr << "end FunctionDecl: ";
    266                                 // for ( TyVarMap::iterator i = scopeTyVars.begin(); i != scopeTyVars.end(); ++i ) {
    267                                 //      std::cerr << i->first << " ";
    268                                 // }
    269                                 // std::cerr << "\n";
     236///     std::cerr << "end FunctionDecl: ";
     237///     for ( TyVarMap::iterator i = scopeTyVars.begin(); i != scopeTyVars.end(); ++i ) {
     238///       std::cerr << i->first << " ";
     239///     }
     240///     std::cerr << "\n";
    270241                                retval = oldRetval;
    271242                                useRetval = oldUseRetval;
    272                                 doEndScope();
     243                                // doEndScope();
    273244                        } // if
    274245                        return functionDecl;
     
    377348                                ret = addRetParam( appExpr, function, function->get_returnVals().front()->get_type(), arg );
    378349                        } // if
    379                         std::string mangleName = mangleAdapterName( function, tyVars );
     350                        std::string mangleName = SymTab::Mangler::mangle( function );
    380351                        std::string adapterName = makeAdapterName( mangleName );
    381352
     
    486457///       return new CastExpr( new VariableExpr( param ), arg->get_type()->clone() );
    487458///     } else {
    488                                 if ( dynamic_cast<TypeInstType *>(arg->get_type()) == NULL ) {
    489                                         UntypedExpr *deref = new UntypedExpr( new NameExpr( "*?" ) );
    490                                         deref->get_args().push_back( new CastExpr( new VariableExpr( param ), new PointerType( Type::Qualifiers(), arg->get_type()->clone() ) ) );
    491                                         deref->get_results().push_back( arg->get_type()->clone() );
    492                                         return deref;
    493                                 } // if
     459                                UntypedExpr *deref = new UntypedExpr( new NameExpr( "*?" ) );
     460                                deref->get_args().push_back( new CastExpr( new VariableExpr( param ), new PointerType( Type::Qualifiers(), arg->get_type()->clone() ) ) );
     461                                deref->get_results().push_back( arg->get_type()->clone() );
     462                                return deref;
    494463///     }
    495464                        } // if
     
    575544                        } // for
    576545
    577                         // parameter function types for which an appropriate adapter has been generated.  we cannot use the types
    578                         // after applying substitutions, since two different parameter types may be unified to the same type
     546                        // parameter function types for which an appropriate adapter has been generated.
     547                        // we cannot use the types after applying substitutions, since two different
     548                        // parameter types may be unified to the same type
    579549                        std::set< std::string > adaptersDone;
    580550
     
    584554                                std::string mangleName = SymTab::Mangler::mangle( realFunction );
    585555
    586                                 // only attempt to create an adapter or pass one as a parameter if we haven't already done so for this
    587                                 // pre-substitution parameter function type.
     556                                // only attempt to create an adapter or pass one as a parameter if we haven't
     557                                // already done so for this pre-substitution parameter function type.
    588558                                if ( adaptersDone.find( mangleName ) == adaptersDone.end() ) {
     559                                        std::string mangleName = SymTab::Mangler::mangle( realFunction );
    589560                                        adaptersDone.insert( adaptersDone.begin(), mangleName );
    590561                                       
    591                                         // apply substitution to type variables to figure out what the adapter's type should look like
     562                                        // apply substitution to type variables to figure out what the
     563                                        // adapter's type should look like
    592564                                        assert( env );
    593565                                        env->apply( realFunction );
    594                                         mangleName = SymTab::Mangler::mangle( realFunction );
    595                                         mangleName += makePolyMonoSuffix( originalFunction, exprTyVars );
    596 
    597                                         AdapterMap & adapters = Pass1::adapters.top();
    598                                         AdapterMap::iterator adapter = adapters.find( mangleName );
    599                                         if ( adapter == adapters.end() ) {
    600                                                 // adapter has not been created yet in the current scope, so define it
    601                                                 FunctionDecl *newAdapter = makeAdapter( *funType, realFunction, mangleName, exprTyVars );
    602                                                 adapter = adapters.insert( adapters.begin(), std::pair< std::string, DeclarationWithType *>( mangleName, newAdapter ) );
    603                                                 stmtsToAdd.push_back( new DeclStmt( noLabels, newAdapter ) );
     566                                        mangleName = SymTab::Mangler::mangle( realFunction );
     567
     568                                        if ( needsAdapter( realFunction, exprTyVars, true ) ) {
     569                                                // the function still contains type variables, which means we are in a polymorphic
     570                                                // context and the adapter function is a parameter - call the parameter and don't
     571                                                // create a new adapter.
     572                                                appExpr->get_args().push_front( new NameExpr( makeAdapterName ( mangleName ) ) );
     573                                        } else {
     574                                                if ( isPolyRet( originalFunction, exprTyVars ) ) {
     575                                                        // if the return type involved polymorphic types, then
     576                                                        // the adapter will need to take those polymorphic types
     577                                                        // as pointers. Therefore, there can be two different
     578                                                        // functions with the same mangled name, so we need two adapter map
     579                                                        // stacks and also we need the mangled names to be different.
     580                                                        mangleName += "polyret_";
     581                                                }
     582
     583                                                AdapterMap & adapters = Pass1::adapters.top();
     584                                                AdapterMap::iterator adapter = adapters.find( mangleName );
     585                                                if ( adapter == adapters.end() ) {
     586                                                        // adapter has not been created yet in the current scope, so define it
     587                                                        FunctionDecl *newAdapter = makeAdapter( *funType, realFunction, mangleName, exprTyVars );
     588                                                        adapter = adapters.insert( adapters.begin(), std::pair< std::string, FunctionDecl *>( mangleName, newAdapter ) );
     589                                                        stmtsToAdd.push_back( new DeclStmt( noLabels, newAdapter ) );
     590                                                } // if
     591                                                assert( adapter != adapters.end() );
     592
     593                                                // add the appropriate adapter as a parameter
     594                                                appExpr->get_args().push_front( new VariableExpr( adapter->second ) );
    604595                                        } // if
    605                                         assert( adapter != adapters.end() );
    606 
    607                                         // add the appropriate adapter as a parameter
    608                                         appExpr->get_args().push_front( new VariableExpr( adapter->second ) );
    609596                                } // if
    610597                        } // for
    611                 } // passAdapters
     598                }
    612599
    613600                TypeInstType *isPolyPtr( Type *type, const TypeSubstitution *env, const TyVarMap &tyVars ) {
     
    669656                                                TypeInstType *typeInst1 = isPolyPtr( appExpr->get_args().front()->get_results().front(), env, scopeTyVars );
    670657                                                TypeInstType *typeInst2 = isPolyPtr( appExpr->get_args().back()->get_results().front(), env, scopeTyVars );
    671                                                 assert( ! typeInst1 || ! typeInst2 );  // the arguments cannot both be polymorphic pointers
     658                                                assert( ! typeInst1 || ! typeInst2 );
    672659                                                UntypedExpr *ret = 0;
    673                                                 if ( typeInst1 || typeInst2 ) { // one of the arguments is a polymorphic pointer
     660                                                if ( typeInst1 || typeInst2 ) {
    674661                                                        ret = new UntypedExpr( new NameExpr( "?+?" ) );
    675662                                                } // if
     
    782769
    783770                Expression *Pass1::mutate( ApplicationExpr *appExpr ) {
    784                         // std::cerr << "mutate appExpr: ";
    785                         // for ( TyVarMap::iterator i = scopeTyVars.begin(); i != scopeTyVars.end(); ++i ) {
    786                         //      std::cerr << i->first << " ";
    787                         // }
    788                         // std::cerr << "\n";
     771///    std::cerr << "mutate appExpr: ";
     772///    for ( TyVarMap::iterator i = scopeTyVars.begin(); i != scopeTyVars.end(); ++i ) {
     773///       std::cerr << i->first << " ";
     774///    }
     775///    std::cerr << "\n";
    789776                        bool oldUseRetval = useRetval;
    790777                        useRetval = false;
     
    812799                                ret = addPolyRetParam( appExpr, function, typeName, arg );
    813800                        } else if ( needsAdapter( function, scopeTyVars ) ) {
    814                                 // std::cerr << "needs adapter: ";
    815                                 // for ( TyVarMap::iterator i = scopeTyVars.begin(); i != scopeTyVars.end(); ++i ) {
    816                                 //      std::cerr << i->first << " ";
    817                                 // }
    818                                 // std::cerr << "\n";
     801///    std::cerr << "needs adapter: ";
     802///    for ( TyVarMap::iterator i = scopeTyVars.begin(); i != scopeTyVars.end(); ++i ) {
     803///       std::cerr << i->first << " ";
     804///    }
     805///    std::cerr << "\n";
    819806                                // change the application so it calls the adapter rather than the passed function
    820807                                ret = applyAdapter( appExpr, function, arg, scopeTyVars );
     
    867854
    868855                Statement * Pass1::mutate(ReturnStmt *retStmt) {
    869                         // by this point, a cast expr on a polymorphic return value is redundant
     856                        // a cast expr on a polymorphic return value is either redundant or invalid
    870857                        while ( CastExpr *castExpr = dynamic_cast< CastExpr *>( retStmt->get_expr() ) ) {
    871858                                retStmt->set_expr( castExpr->get_arg() );
     
    924911
    925912                void Pass1::doBeginScope() {
    926                         // push a copy of the current map
    927                         adapters.push(adapters.top());
     913                        // actually, maybe this could (should?) push
     914                        // a copy of the current map
     915                        adapters.push(AdapterMap());
    928916                }
    929917
     
    946934                        std::set< std::string > adaptersDone;
    947935                        for ( std::list< FunctionType *>::iterator funType = functions.begin(); funType != functions.end(); ++funType ) {
    948                                 std::string mangleName = mangleAdapterName( *funType, scopeTyVars );
     936                                std::string mangleName = SymTab::Mangler::mangle( *funType );
    949937                                if ( adaptersDone.find( mangleName ) == adaptersDone.end() ) {
    950938                                        std::string adapterName = makeAdapterName( mangleName );
     
    10121000                        for ( std::list< TypeDecl *>::const_iterator tyParm = funcType->get_forall().begin(); tyParm != funcType->get_forall().end(); ++tyParm ) {
    10131001                                ObjectDecl *thisParm;
    1014                                 // add all size parameters to parameter list
    10151002                                if ( (*tyParm)->get_kind() == TypeDecl::Any ) {
    10161003                                        thisParm = newObj->clone();
     
    10191006                                        ++last;
    10201007                                }
    1021                                 // move all assertions into parameter list
    10221008                                for ( std::list< DeclarationWithType *>::iterator assert = (*tyParm)->get_assertions().begin(); assert != (*tyParm)->get_assertions().end(); ++assert ) {
    10231009///      *assert = (*assert)->acceptMutator( *this );
Note: See TracChangeset for help on using the changeset viewer.