Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • translator/GenPoly/Box.cc

    rbdd516a rb1a6d6b  
    77
    88#include <set>
     9#include <stack>
    910#include <string>
    1011#include <iterator>
     
    5051            virtual Type *mutate( FunctionType *pointerType );
    5152 
     53            virtual void doBeginScope();
    5254            virtual void doEndScope();
    5355          private:
     
    6668 
    6769            std::map< std::string, DeclarationWithType *> assignOps;
    68             std::map< std::string, FunctionDecl *> adapters;
     70            typedef std::map< std::string, FunctionDecl *> AdapterMap;
     71            std::stack< AdapterMap > adapters;
    6972            DeclarationWithType *retval;
    7073            bool useRetval;
     
    126129
    127130    namespace {
     131        std::string makeAdapterName( const std::string &mangleName ) {
     132            return "_adapter" + mangleName;
     133        }
     134
    128135        bool isPolyRet( FunctionType *function, std::string &name, const TyVarMap &otherTyVars ) {
    129136            bool doTransform = false;
     
    219226                retval = oldRetval;
    220227                useRetval = oldUseRetval;
    221                 doEndScope();
     228                // doEndScope();
    222229            } // if
    223230            return functionDecl;
     
    316323            Type *concrete = env->lookup( typeName );
    317324            if ( concrete == 0 ) {
    318                 throw SemanticError( "Unbound type variable " + typeName + " in", appExpr );
     325                throw SemanticError( "Unbound type variable " + typeName + " in ", appExpr );
    319326            } // if
    320327            return addRetParam( appExpr, function, concrete, arg );
     
    326333                ret = addRetParam( appExpr, function, function->get_returnVals().front()->get_type(), arg );
    327334            } // if
     335            std::string mangleName = SymTab::Mangler::mangle( function );
     336            std::string adapterName = makeAdapterName( mangleName );
     337
    328338            appExpr->get_args().push_front( appExpr->get_function() );
    329             appExpr->set_function( new NameExpr( "_adapter" + SymTab::Mangler::mangle( function ) ) );
     339            appExpr->set_function( new NameExpr( adapterName ) );
    330340 
    331341            return ret;
     
    337347            TypeInstType *typeInst = dynamic_cast< TypeInstType *>( param );
    338348            if ( typeInst && exprTyVars.find( typeInst->get_name() ) != exprTyVars.end() ) {
    339                 if ( arg->get_results().front()->get_isLvalue() ) {
     349                if ( dynamic_cast< TypeInstType *>( arg->get_results().front() ) ) {
     350                    // if the argument's type is a type parameter, we don't need to box again!
     351                    return;
     352                } else if ( arg->get_results().front()->get_isLvalue() ) {
     353                    // VariableExpr and MemberExpr are lvalues
    340354                    arg = new AddressExpr( arg );
    341355                } else {
     
    371385            for ( std::list< DeclarationWithType *>::const_iterator param = function->get_parameters().begin(); param != function->get_parameters().end(); ++param, ++arg ) {
    372386///     std::cout << "parameter is ";
    373 ///     (*param)->print( std::cout );
     387///     (*param)->print( std::fcout );
    374388///     std::cout << std::endl << "argument is ";
    375389///     (*arg)->print( std::cout );
     
    448462        }
    449463
     464
     465
    450466        FunctionDecl *Pass1::makeAdapter( FunctionType *adaptee, FunctionType *realType, const std::string &mangleName, const TyVarMap &tyVars ) {
    451467            FunctionType *adapterType = makeAdapterType( adaptee, tyVars );
     
    496512            CompoundStmt *adapterBody = new CompoundStmt( noLabels );
    497513            adapterBody->get_kids().push_back( bodyStmt );
    498             return new FunctionDecl( "_adapter" + mangleName, Declaration::NoStorageClass, LinkageSpec::C, adapterType, adapterBody, false );
     514            std::string adapterName = makeAdapterName( mangleName );
     515            return new FunctionDecl( adapterName, Declaration::NoStorageClass, LinkageSpec::C, adapterType, adapterBody, false );
    499516        }
    500517
     
    515532                assert( env );
    516533                env->apply( realFunction );
     534
    517535                std::string mangleName = SymTab::Mangler::mangle( realFunction );
    518536                if ( adaptersDone.find( mangleName ) == adaptersDone.end() ) {
    519                     std::map< std::string, FunctionDecl *>::iterator adapter = adapters.find( mangleName );
    520                     if ( adapter == adapters.end() ) {
    521                         FunctionDecl *newAdapter = makeAdapter( *funType, realFunction, mangleName, exprTyVars );
     537                    AdapterMap & adapters = Pass1::adapters.top();
     538                    AdapterMap::iterator adapter = adapters.find( mangleName );
     539
     540                    if ( needsAdapter( realFunction, exprTyVars, true ) ) {
     541                        // the function still contains type variables, which means we are in a polymorphic
     542                        // context and the adapter function is a parameter - call the parameter and don't
     543                        // create a new adapter.
     544                        appExpr->get_args().push_front( new NameExpr( makeAdapterName ( mangleName ) ) );
     545                        continue;
     546                    } else if ( adapter == adapters.end() ) {
     547                        FunctionDecl *newAdapter = makeAdapter( *funType, realFunction, mangleName, exprTyVars );
    522548                        adapter = adapters.insert( adapters.begin(), std::pair< std::string, FunctionDecl *>( mangleName, newAdapter ) );
    523549                        stmtsToAdd.push_back( new DeclStmt( noLabels, newAdapter ) );
     
    525551                    assert( adapter != adapters.end() );
    526552                    appExpr->get_args().push_front( new VariableExpr( adapter->second ) );
     553                    // appExpr->get_args().push_front( new NameExpr( makeAdapterName ( mangleName ) ) );
    527554                    adaptersDone.insert( adaptersDone.begin(), mangleName );
    528555                } // if
     
    845872        }
    846873
     874        void Pass1::doBeginScope() {
     875            adapters.push(AdapterMap());
     876        }
     877
    847878        void Pass1::doEndScope() {
    848             adapters.clear();
     879            adapters.pop();
    849880        }
    850881
     
    865896                std::string mangleName = SymTab::Mangler::mangle( *funType );
    866897                if ( adaptersDone.find( mangleName ) == adaptersDone.end() ) {
    867                     paramList.push_front( new ObjectDecl( "_adapter" + mangleName, Declaration::NoStorageClass, LinkageSpec::C, 0, new PointerType( Type::Qualifiers(), makeAdapterType( *funType, scopeTyVars ) ), 0 ) );
     898                    std::string adapterName = makeAdapterName( mangleName );
     899                    paramList.push_front( new ObjectDecl( adapterName, Declaration::NoStorageClass, LinkageSpec::C, 0, new PointerType( Type::Qualifiers(), makeAdapterType( *funType, scopeTyVars ) ), 0 ) );
    868900                    adaptersDone.insert( adaptersDone.begin(), mangleName );
    869901                }
Note: See TracChangeset for help on using the changeset viewer.