Changeset 1194734 for src/GenPoly


Ignore:
Timestamp:
Jan 13, 2016, 5:01:22 PM (9 years ago)
Author:
Aaron Moss <a3moss@…>
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:
25a054f
Parents:
933667d
Message:

Continue to work on handling polymorphic generic returns

File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/GenPoly/Box.cc

    r933667d r1194734  
    2424#include "PolyMutator.h"
    2525#include "FindFunction.h"
     26#include "ScopedMap.h"
    2627#include "ScrubTyVars.h"
    2728
     
    8384                        void boxParams( ApplicationExpr *appExpr, FunctionType *function, std::list< Expression *>::iterator &arg, const TyVarMap &exprTyVars );
    8485                        void addInferredParams( ApplicationExpr *appExpr, FunctionType *functionType, std::list< Expression *>::iterator &arg, const TyVarMap &tyVars );
     86                        /// Stores assignment operators from assertion list in local map of assignment operations
    8587                        void findAssignOps( const std::list< TypeDecl *> &forall );
    8688                        void passAdapters( ApplicationExpr *appExpr, FunctionType *functionType, const TyVarMap &exprTyVars );
     
    9193                        typedef std::map< std::string, DeclarationWithType *> AdapterMap;
    9294                        std::map< std::string, DeclarationWithType *> assignOps;
     95                        ScopedMap< std::string, DeclarationWithType *> scopedAssignOps;
    9396                        std::stack< AdapterMap > adapters;
    9497                        DeclarationWithType *retval;
     
    192195                }
    193196
    194                 // returns true if the given declaration is: (*?=?)(T *, T) for some T (return not checked, but maybe should be)
    195                 bool checkAssignment( DeclarationWithType *decl, std::string &name ) {
     197                /// returns T if the given declaration is: (*?=?)(T *, T) for some T (return not checked, but maybe should be), NULL otherwise
     198                ReferenceToType *isAssignment( DeclarationWithType *decl ) {
    196199                        if ( decl->get_name() == "?=?" ) {
    197                                 if ( PointerType *ptrType = dynamic_cast< PointerType *>( decl->get_type() ) ) {
    198                                         if ( FunctionType *funType = dynamic_cast< FunctionType *>( ptrType->get_base() ) ) {
    199                                                 if ( funType->get_parameters().size() == 2 ) {
    200                                                         if ( PointerType *pointer = dynamic_cast< PointerType *>( funType->get_parameters().front()->get_type() ) ) {
    201                                                                 if ( TypeInstType *typeInst = dynamic_cast< TypeInstType *>( pointer->get_base() ) ) {
    202                                                                         if ( TypeInstType *typeInst2 = dynamic_cast< TypeInstType *>( funType->get_parameters().back()->get_type() ) ) {
    203                                                                                 if ( typeInst->get_name() == typeInst2->get_name() ) {
    204                                                                                         name = typeInst->get_name();
    205                                                                                         return true;
    206                                                                                 } // if
     200                                if ( FunctionType *funType = getFunctionType( decl->get_type() ) ) {
     201                                        if ( funType->get_parameters().size() == 2 ) {
     202                                                if ( PointerType *pointer = dynamic_cast< PointerType *>( funType->get_parameters().front()->get_type() ) ) {
     203                                                        if ( ReferenceToType *refType = dynamic_cast< ReferenceToType *>( pointer->get_base() ) ) {
     204                                                                if ( ReferenceToType *refType2 = dynamic_cast< ReferenceToType *>( funType->get_parameters().back()->get_type() ) ) {
     205                                                                        if ( refType->get_name() == refType2->get_name() ) {
     206                                                                                return refType;
    207207                                                                        } // if
    208208                                                                } // if
     
    212212                                } // if
    213213                        } // if
    214                         return false;
     214                        return 0;
    215215                }
    216216
     
    221221                                for ( std::list< DeclarationWithType *>::const_iterator assert = (*i)->get_assertions().begin(); assert != (*i)->get_assertions().end(); ++assert ) {
    222222                                        std::string typeName;
    223                                         if ( checkAssignment( *assert, typeName ) ) {
    224                                                 assignOps[ typeName ] = *assert;
     223                                        if ( TypeInstType *typeInst = dynamic_cast< TypeInstType* >( isAssignment( *assert ) ) ) {
     224                                                assignOps[ typeInst->get_name() ] = *assert;
    225225                                        } // if
    226226                                } // for
     
    229229
    230230                DeclarationWithType *Pass1::mutate( FunctionDecl *functionDecl ) {
     231                        // if this is a polymorphic assignment function, put it in the map for this scope
     232                        if ( ReferenceToType *refType = isAssignment( functionDecl ) ) {
     233                                if ( ! dynamic_cast< TypeInstType* >( refType ) ) {
     234                                        scopedAssignOps.insert( refType->get_name(), functionDecl );
     235                                }
     236                        }
     237                       
    231238                        if ( functionDecl->get_statements() ) {         // empty routine body ?
    232239                                doBeginScope();
     
    908915                                        delete castExpr;
    909916                                } //while
    910                                 TypeInstType *typeInst = dynamic_cast< TypeInstType *>( retval->get_type() );
    911                                 assert( typeInst );
    912                                 std::map< std::string, DeclarationWithType *>::const_iterator assignIter = assignOps.find( typeInst->get_name() );
    913                                 if ( assignIter == assignOps.end() ) {
    914                                         throw SemanticError( "Attempt to return dtype or ftype object in ", returnStmt->get_expr() );
    915                                 } // if
    916                                 ApplicationExpr *assignExpr = new ApplicationExpr( new VariableExpr( assignIter->second ) );
     917
     918                                // find assignment operator for (polymorphic) return type
     919                                DeclarationWithType *assignDecl = 0;
     920                                if ( TypeInstType *typeInst = dynamic_cast< TypeInstType *>( retval->get_type() ) ) {
     921                                        std::map< std::string, DeclarationWithType *>::const_iterator assignIter = assignOps.find( typeInst->get_name() );
     922                                        if ( assignIter == assignOps.end() ) {
     923                                                throw SemanticError( "Attempt to return dtype or ftype object in ", returnStmt->get_expr() );
     924                                        } // if
     925                                        assignDecl = assignIter->second;
     926                                } else if ( ReferenceToType *refType = dynamic_cast< ReferenceToType *>( retval->get_type() ) ) {
     927                                        ScopedMap< std::string, DeclarationWithType *>::const_iterator assignIter = scopedAssignOps.find( refType->get_name() );
     928                                        if ( assignIter == scopedAssignOps.end() ) {
     929                                                throw SemanticError( "Attempt to return dtype or ftype generic object in ", returnStmt->get_expr() );
     930                                        }
     931                                        assignDecl = new ObjectDecl( "", DeclarationNode::NoStorageClass, LinkageSpec::Cforall, 0,
     932                                                                                                 new PointerType( Type::Qualifiers(), assignIter->second->get_type()->clone() ), 0 );
     933                                }
     934                                assert( assignDecl );
     935
     936                                // replace return statement with appropriate assignment to out parameter
     937                                ApplicationExpr *assignExpr = new ApplicationExpr( new VariableExpr( assignDecl ) );
    917938                                Expression *retParm = new NameExpr( retval->get_name() );
    918939                                retParm->get_results().push_back( new PointerType( Type::Qualifiers(), retval->get_type()->clone() ) );
     
    955976                        // push a copy of the current map
    956977                        adapters.push(adapters.top());
     978                        scopedAssignOps.beginScope();
    957979                }
    958980
    959981                void Pass1::doEndScope() {
    960982                        adapters.pop();
     983                        scopedAssignOps.endScope();
    961984                }
    962985
Note: See TracChangeset for help on using the changeset viewer.