Changes in / [6ce67ce:b502055]


Ignore:
Location:
src
Files:
1 added
1 edited

Legend:

Unmodified
Added
Removed
  • src/GenPoly/Box.cc

    r6ce67ce rb502055  
    2525#include "PolyMutator.h"
    2626#include "FindFunction.h"
    27 #include "ScopedMap.h"
    2827#include "ScrubTyVars.h"
    2928
     
    3837
    3938#include "ResolvExpr/TypeEnvironment.h"
     39#include "ResolvExpr/TypeMap.h"
     40#include "ResolvExpr/typeops.h"
    4041
    4142#include "SymTab/Mangler.h"
     
    101102                        typedef std::map< std::string, DeclarationWithType *> AdapterMap;
    102103                        std::map< std::string, DeclarationWithType *> assignOps;
    103                         ScopedMap< std::string, DeclarationWithType *> scopedAssignOps;
     104                        ResolvExpr::TypeMap< DeclarationWithType > scopedAssignOps;
    104105                        std::stack< AdapterMap > adapters;
    105106                        DeclarationWithType *retval;
     
    248249                }
    249250
    250                 /// returns T if the given declaration is: (*?=?)(T *, T) for some T (return not checked, but maybe should be), NULL otherwise
    251                 ReferenceToType *isAssignment( DeclarationWithType *decl ) {
     251                /// Returns T if the given declaration is (*?=?)(T *, T) for some TypeInstType T (return not checked, but maybe should be), NULL otherwise
     252                TypeInstType *isTypeInstAssignment( DeclarationWithType *decl ) {
    252253                        if ( decl->get_name() == "?=?" ) {
    253254                                if ( FunctionType *funType = getFunctionType( decl->get_type() ) ) {
    254255                                        if ( funType->get_parameters().size() == 2 ) {
    255256                                                if ( PointerType *pointer = dynamic_cast< PointerType *>( funType->get_parameters().front()->get_type() ) ) {
    256                                                         if ( ReferenceToType *refType = dynamic_cast< ReferenceToType *>( pointer->get_base() ) ) {
    257                                                                 if ( ReferenceToType *refType2 = dynamic_cast< ReferenceToType *>( funType->get_parameters().back()->get_type() ) ) {
     257                                                        if ( TypeInstType *refType = dynamic_cast< TypeInstType *>( pointer->get_base() ) ) {
     258                                                                if ( TypeInstType *refType2 = dynamic_cast< TypeInstType *>( funType->get_parameters().back()->get_type() ) ) {
    258259                                                                        if ( refType->get_name() == refType2->get_name() ) {
    259260                                                                                return refType;
     
    267268                        return 0;
    268269                }
     270               
     271                /// returns T if the given declaration is: (*?=?)(T *, T) for some type T (return not checked, but maybe should be), NULL otherwise
     272                /// Only picks assignments where neither parameter is cv-qualified
     273                Type *isAssignment( DeclarationWithType *decl ) {
     274                        if ( decl->get_name() == "?=?" ) {
     275                                if ( FunctionType *funType = getFunctionType( decl->get_type() ) ) {
     276                                        if ( funType->get_parameters().size() == 2 ) {
     277                                                Type::Qualifiers defaultQualifiers;
     278                                                Type *paramType1 = funType->get_parameters().front()->get_type();
     279                                                if ( paramType1->get_qualifiers() != defaultQualifiers ) return 0;
     280                                                Type *paramType2 = funType->get_parameters().back()->get_type();
     281                                                if ( paramType2->get_qualifiers() != defaultQualifiers ) return 0;
     282                                               
     283                                                if ( PointerType *pointerType = dynamic_cast< PointerType* >( paramType1 ) ) {
     284                                                        Type *baseType1 = pointerType->get_base();
     285                                                        if ( baseType1->get_qualifiers() != defaultQualifiers ) return 0;
     286                                                        SymTab::Indexer dummy;
     287                                                        if ( ResolvExpr::typesCompatible( baseType1, paramType2, dummy ) ) {
     288                                                                return baseType1;
     289                                                        } // if
     290                                                } // if
     291                                        } // if
     292                                } // if
     293                        } // if
     294                        return 0;
     295                }
    269296
    270297                void Pass1::findAssignOps( const std::list< TypeDecl *> &forall ) {
     
    274301                                for ( std::list< DeclarationWithType *>::const_iterator assert = (*i)->get_assertions().begin(); assert != (*i)->get_assertions().end(); ++assert ) {
    275302                                        std::string typeName;
    276                                         if ( TypeInstType *typeInst = dynamic_cast< TypeInstType* >( isAssignment( *assert ) ) ) {
     303                                        if ( TypeInstType *typeInst = isTypeInstAssignment( *assert ) ) {
    277304                                                assignOps[ typeInst->get_name() ] = *assert;
    278305                                        } // if
     
    283310                DeclarationWithType *Pass1::mutate( FunctionDecl *functionDecl ) {
    284311                        // if this is a polymorphic assignment function, put it in the map for this scope
    285                         if ( ReferenceToType *refType = isAssignment( functionDecl ) ) {
    286                                 if ( ! dynamic_cast< TypeInstType* >( refType ) ) {
    287                                         scopedAssignOps.insert( refType->get_name(), functionDecl );
     312                        if ( Type *assignedType = isAssignment( functionDecl ) ) {
     313                                if ( ! dynamic_cast< TypeInstType* >( assignedType ) ) {
     314                                        scopedAssignOps.insert( assignedType, functionDecl );
    288315                                }
    289316                        }
     
    934961                        TyVarMap exprTyVars;
    935962                        makeTyVarMap( function, exprTyVars );
    936                         ReferenceToType *polyRetType = 0;
    937 
    938                         if ( polyRetType = isPolyRet( function ) ) {
     963                        ReferenceToType *polyRetType = isPolyRet( function );
     964
     965                        if ( polyRetType ) {
    939966                                ret = addPolyRetParam( appExpr, function, polyRetType, arg );
    940967                        } else if ( needsAdapter( function, scopeTyVars ) ) {
     
    10421069                                } else if ( ReferenceToType *refType = dynamic_cast< ReferenceToType *>( retval->get_type() ) ) {
    10431070                                        // find assignment operator for generic type
    1044                                         ScopedMap< std::string, DeclarationWithType *>::const_iterator assignIter = scopedAssignOps.find( refType->get_name() );
    1045                                         if ( assignIter == scopedAssignOps.end() ) {
     1071                                        DeclarationWithType *functionDecl = scopedAssignOps.find( refType );
     1072                                        if ( ! functionDecl ) {
    10461073                                                throw SemanticError( "Attempt to return dtype or ftype generic object in ", returnStmt->get_expr() );
    10471074                                        }
    10481075
    10491076                                        // wrap it up in an application expression
    1050                                         DeclarationWithType *functionDecl = assignIter->second;
    10511077                                        assignExpr = new ApplicationExpr( wrapFunctionDecl( functionDecl ) );
    10521078                                        assignExpr->set_env( env->clone() );
     
    10631089                                                assert( ! asserts.empty() && "Type param needs assignment operator assertion" );
    10641090                                                DeclarationWithType *actualDecl = asserts.front();
    1065                                                 ReferenceToType *actualType = isAssignment( actualDecl );
     1091                                                TypeInstType *actualType = isTypeInstAssignment( actualDecl );
    10661092                                                assert( actualType && "First assertion of type with assertions should be assignment operator" );
    10671093                                                TypeExpr *formalTypeExpr = dynamic_cast< TypeExpr* >( *tyIt );
     
    10771103                                                        }
    10781104                                                        assertAssign = assertAssignIt->second;
    1079                                                         //assignExpr->get_env()->add( formalTypeInstType->get_name(), actualType );
    1080                                                 } else if ( ReferenceToType *formalReferenceType = dynamic_cast< ReferenceToType* >( formalType ) )  {
    1081                                                         ScopedMap< std::string, DeclarationWithType *>::const_iterator assertAssignIt = scopedAssignOps.find( formalReferenceType->get_name() );
    1082                                                         if ( assertAssignIt == scopedAssignOps.end() ) {
    1083                                                                 throw SemanticError( "No assignment operation found for ", formalReferenceType );
     1105                                                } else {
     1106                                                        assertAssign = scopedAssignOps.find( formalType );
     1107                                                        if ( ! assertAssign ) {
     1108                                                                throw SemanticError( "No assignment operation found for ", formalType );
    10841109                                                        }
    1085                                                         assertAssign = assertAssignIt->second;
    1086                                                 } else assert( false && "returning polymorphic types with non struct/polymorphic parameters not yet supported" );
     1110                                                }
    10871111                                               
    10881112
     
    14241448                        assert( newMemberExpr );
    14251449
    1426                         // wrap pointer members in appropriate cast
    1427                         if ( dynamic_cast< PointerType* >( memberExpr->get_member()->get_type() ) ) {
    1428                                 CastExpr *ptrCastExpr = new CastExpr( newMemberExpr, new PointerType( Type::Qualifiers(), new PointerType( Type::Qualifiers(), new VoidType( Type::Qualifiers() ) ) ) );
     1450                        Type *memberType = memberExpr->get_member()->get_type();
     1451                        if ( ! isPolyType( memberType, scopeTyVars ) ) {
     1452                                // Not all members of a polymorphic type are themselves of polymorphic type; in this case the member expression should be wrapped and dereferenced to form an lvalue
     1453                                CastExpr *ptrCastExpr = new CastExpr( newMemberExpr, new PointerType( Type::Qualifiers(), memberType->clone() ) );
    14291454                                UntypedExpr *derefExpr = new UntypedExpr( new NameExpr( "*?" ) );
    14301455                                derefExpr->get_args().push_back( ptrCastExpr );
Note: See TracChangeset for help on using the changeset viewer.