Changeset b10c9959


Ignore:
Timestamp:
Feb 5, 2016, 4:41:20 PM (7 years ago)
Author:
Aaron Moss <a3moss@…>
Branches:
aaron-thesis, arm-eh, 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:
408d460
Parents:
2a4b088
Message:

First draft of fixing polymorphic generic return types

File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/GenPoly/Box.cc

    r2a4b088 rb10c9959  
    989989                }
    990990
     991                /// Wraps a function declaration in a new pointer-to-function variable expression
     992                VariableExpr *wrapFunctionDecl( DeclarationWithType *functionDecl ) {
     993                        // line below cloned from FixFunction.cc
     994                        ObjectDecl *functionObj = new ObjectDecl( functionDecl->get_name(), functionDecl->get_storageClass(), functionDecl->get_linkage(), 0,
     995                                                                  new PointerType( Type::Qualifiers(), functionDecl->get_type()->clone() ), 0 );
     996                        functionObj->set_mangleName( functionDecl->get_mangleName() );
     997                        return new VariableExpr( functionObj );
     998                }
     999               
    9911000                Statement * Pass1::mutate( ReturnStmt *returnStmt ) {
    9921001                        if ( retval && returnStmt->get_expr() ) {
     
    10041013
    10051014                                // find assignment operator for (polymorphic) return type
    1006                                 DeclarationWithType *assignDecl = 0;
     1015                                ApplicationExpr *assignExpr = 0;
    10071016                                if ( TypeInstType *typeInst = dynamic_cast< TypeInstType *>( retval->get_type() ) ) {
     1017                                        // find assignment operator for type variable
    10081018                                        std::map< std::string, DeclarationWithType *>::const_iterator assignIter = assignOps.find( typeInst->get_name() );
    10091019                                        if ( assignIter == assignOps.end() ) {
    10101020                                                throw SemanticError( "Attempt to return dtype or ftype object in ", returnStmt->get_expr() );
    10111021                                        } // if
    1012                                         assignDecl = assignIter->second;
     1022                                        assignExpr = new ApplicationExpr( new VariableExpr( assignIter->second ) );
    10131023                                } else if ( ReferenceToType *refType = dynamic_cast< ReferenceToType *>( retval->get_type() ) ) {
     1024                                        // find assignment operator for generic type
    10141025                                        ScopedMap< std::string, DeclarationWithType *>::const_iterator assignIter = scopedAssignOps.find( refType->get_name() );
    10151026                                        if ( assignIter == scopedAssignOps.end() ) {
    10161027                                                throw SemanticError( "Attempt to return dtype or ftype generic object in ", returnStmt->get_expr() );
    10171028                                        }
     1029
     1030                                        // wrap it up in an application expression
    10181031                                        DeclarationWithType *functionDecl = assignIter->second;
    1019                                         // line below cloned from FixFunction.cc
    1020                                         assignDecl = new ObjectDecl( functionDecl->get_name(), functionDecl->get_storageClass(), functionDecl->get_linkage(), 0,
    1021                                                                      new PointerType( Type::Qualifiers(), functionDecl->get_type()->clone() ), 0 );
    1022                                         assignDecl->set_mangleName( functionDecl->get_mangleName() );
     1032                                        assignExpr = new ApplicationExpr( wrapFunctionDecl( functionDecl ) );
     1033                                        assignExpr->set_env( env->clone() );
     1034
     1035                                        // find each of its needed secondary assignment operators
     1036                                        std::list< Expression* > &tyParams = refType->get_parameters();
     1037                                        std::list< TypeDecl* > &forallParams = functionDecl->get_type()->get_forall();
     1038                                        std::list< Expression* >::const_iterator tyIt = tyParams.begin();
     1039                                        std::list< TypeDecl* >::const_iterator forallIt = forallParams.begin();
     1040                                        for ( ; tyIt != tyParams.end() && forallIt != forallParams.end(); ++tyIt, ++forallIt ) {
     1041                                                if ( (*forallIt)->get_kind() != TypeDecl::Any ) continue; // skip types with no assign op (ftype/dtype)
     1042
     1043                                                std::list< DeclarationWithType* > &asserts = (*forallIt)->get_assertions();
     1044                                                assert( ! asserts.empty() && "Type param needs assignment operator assertion" );
     1045                                                DeclarationWithType *actualDecl = asserts.front();
     1046                                                ReferenceToType *actualType = isAssignment( actualDecl );
     1047                                                assert( actualType && "First assertion of type with assertions should be assignment operator" );
     1048                                                TypeExpr *formalTypeExpr = dynamic_cast< TypeExpr* >( *tyIt );
     1049                                                assert( formalTypeExpr && "type parameters must be type expressions" );
     1050                                                Type *formalType = formalTypeExpr->get_type();
     1051                                                assignExpr->get_env()->add( actualType->get_name(), formalType );
     1052                                               
     1053                                                DeclarationWithType *assertAssign = 0;
     1054                                                if ( TypeInstType *formalTypeInstType = dynamic_cast< TypeInstType* >( formalType ) ) {
     1055                                                        std::map< std::string, DeclarationWithType *>::const_iterator assertAssignIt = assignOps.find( formalTypeInstType->get_name() );
     1056                                                        if ( assertAssignIt == assignOps.end() ) {
     1057                                                                throw SemanticError( "No assignment operation found for ", formalTypeInstType );
     1058                                                        }
     1059                                                        assertAssign = assertAssignIt->second;
     1060                                                        //assignExpr->get_env()->add( formalTypeInstType->get_name(), actualType );
     1061                                                } else if ( ReferenceToType *formalReferenceType = dynamic_cast< ReferenceToType* >( formalType ) )  {
     1062                                                        ScopedMap< std::string, DeclarationWithType *>::const_iterator assertAssignIt = scopedAssignOps.find( formalReferenceType->get_name() );
     1063                                                        if ( assertAssignIt == scopedAssignOps.end() ) {
     1064                                                                throw SemanticError( "No assignment operation found for ", formalReferenceType );
     1065                                                        }
     1066                                                        assertAssign = assertAssignIt->second;
     1067                                                } else assert( false && "returning polymorphic types with non struct/polymorphic parameters not yet supported" );
     1068                                               
     1069
     1070                                                assignExpr->get_inferParams()[ actualDecl->get_uniqueId() ]
     1071                                                        = ParamEntry( assertAssign->get_uniqueId(), assertAssign->get_type()->clone(), actualDecl->get_type()->clone(), wrapFunctionDecl( assertAssign ) );
     1072                                        }
    10231073                                }
    1024                                 assert( assignDecl );
     1074                                assert( assignExpr );
    10251075
    10261076                                // replace return statement with appropriate assignment to out parameter
    1027                                 ApplicationExpr *assignExpr = new ApplicationExpr( new VariableExpr( assignDecl ) );
    10281077                                Expression *retParm = new NameExpr( retval->get_name() );
    10291078                                retParm->get_results().push_back( new PointerType( Type::Qualifiers(), retval->get_type()->clone() ) );
Note: See TracChangeset for help on using the changeset viewer.