Changeset c14cff1 for src/GenPoly


Ignore:
Timestamp:
Feb 25, 2016, 5:16:15 PM (9 years ago)
Author:
Rob Schluntz <rschlunt@…>
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, with_gc
Children:
071a31a
Parents:
a9a259c (diff), ac1ed49 (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the (diff) links above to see all the changes relative to each parent.
Message:

Merge branch 'master' into ctor

File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/GenPoly/Box.cc

    ra9a259c rc14cff1  
    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                        }
     
    935962                        TyVarMap exprTyVars;
    936963                        makeTyVarMap( function, exprTyVars );
    937                         ReferenceToType *polyRetType = 0;
    938 
    939                         if ( polyRetType = isPolyRet( function ) ) {
     964                        ReferenceToType *polyRetType = isPolyRet( function );
     965
     966                        if ( polyRetType ) {
    940967                                ret = addPolyRetParam( appExpr, function, polyRetType, arg );
    941968                        } else if ( needsAdapter( function, scopeTyVars ) ) {
     
    10431070                                } else if ( ReferenceToType *refType = dynamic_cast< ReferenceToType *>( retval->get_type() ) ) {
    10441071                                        // find assignment operator for generic type
    1045                                         ScopedMap< std::string, DeclarationWithType *>::const_iterator assignIter = scopedAssignOps.find( refType->get_name() );
    1046                                         if ( assignIter == scopedAssignOps.end() ) {
     1072                                        DeclarationWithType *functionDecl = scopedAssignOps.find( refType );
     1073                                        if ( ! functionDecl ) {
    10471074                                                throw SemanticError( "Attempt to return dtype or ftype generic object in ", returnStmt->get_expr() );
    10481075                                        }
    10491076
    10501077                                        // wrap it up in an application expression
    1051                                         DeclarationWithType *functionDecl = assignIter->second;
    10521078                                        assignExpr = new ApplicationExpr( wrapFunctionDecl( functionDecl ) );
    10531079                                        assignExpr->set_env( env->clone() );
     
    10641090                                                assert( ! asserts.empty() && "Type param needs assignment operator assertion" );
    10651091                                                DeclarationWithType *actualDecl = asserts.front();
    1066                                                 ReferenceToType *actualType = isAssignment( actualDecl );
     1092                                                TypeInstType *actualType = isTypeInstAssignment( actualDecl );
    10671093                                                assert( actualType && "First assertion of type with assertions should be assignment operator" );
    10681094                                                TypeExpr *formalTypeExpr = dynamic_cast< TypeExpr* >( *tyIt );
     
    10781104                                                        }
    10791105                                                        assertAssign = assertAssignIt->second;
    1080                                                         //assignExpr->get_env()->add( formalTypeInstType->get_name(), actualType );
    1081                                                 } else if ( ReferenceToType *formalReferenceType = dynamic_cast< ReferenceToType* >( formalType ) )  {
    1082                                                         ScopedMap< std::string, DeclarationWithType *>::const_iterator assertAssignIt = scopedAssignOps.find( formalReferenceType->get_name() );
    1083                                                         if ( assertAssignIt == scopedAssignOps.end() ) {
    1084                                                                 throw SemanticError( "No assignment operation found for ", formalReferenceType );
     1106                                                } else {
     1107                                                        assertAssign = scopedAssignOps.find( formalType );
     1108                                                        if ( ! assertAssign ) {
     1109                                                                throw SemanticError( "No assignment operation found for ", formalType );
    10851110                                                        }
    1086                                                         assertAssign = assertAssignIt->second;
    1087                                                 } else assert( false && "returning polymorphic types with non struct/polymorphic parameters not yet supported" );
     1111                                                }
    10881112                                               
    10891113
     
    14251449                        assert( newMemberExpr );
    14261450
    1427                         // wrap pointer members in appropriate cast
    1428                         if ( dynamic_cast< PointerType* >( memberExpr->get_member()->get_type() ) ) {
    1429                                 CastExpr *ptrCastExpr = new CastExpr( newMemberExpr, new PointerType( Type::Qualifiers(), new PointerType( Type::Qualifiers(), new VoidType( Type::Qualifiers() ) ) ) );
     1451                        Type *memberType = memberExpr->get_member()->get_type();
     1452                        if ( ! isPolyType( memberType, scopeTyVars ) ) {
     1453                                // 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
     1454                                CastExpr *ptrCastExpr = new CastExpr( newMemberExpr, new PointerType( Type::Qualifiers(), memberType->clone() ) );
    14301455                                UntypedExpr *derefExpr = new UntypedExpr( new NameExpr( "*?" ) );
    14311456                                derefExpr->get_args().push_back( ptrCastExpr );
Note: See TracChangeset for help on using the changeset viewer.