Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/GenPoly/Box.cc

    rc2ad3c9 r10a7775  
    197197                        void addInferredParams( ApplicationExpr *appExpr, FunctionType *functionType, std::list< Expression *>::iterator &arg, const TyVarMap &tyVars );
    198198                        /// Stores assignment operators from assertion list in local map of assignment operations
    199                         void findTypeOps( const std::list< TypeDecl *> &forall );
     199                        void findAssignOps( const std::list< TypeDecl *> &forall );
    200200                        void passAdapters( ApplicationExpr *appExpr, FunctionType *functionType, const TyVarMap &exprTyVars );
    201201                        FunctionDecl *makeAdapter( FunctionType *adaptee, FunctionType *realType, const std::string &mangleName, const TyVarMap &tyVars );
     
    205205                        ObjectDecl *makeTemporary( Type *type );
    206206
    207                         ScopedMap< std::string, DeclarationWithType* > assignOps;    ///< Currently known type variable assignment operators
    208                         ScopedMap< std::string, DeclarationWithType* > ctorOps;      ///< Currently known type variable constructors
    209                         ScopedMap< std::string, DeclarationWithType* > copyOps;      ///< Currently known type variable copy constructors
    210                         ScopedMap< std::string, DeclarationWithType* > dtorOps;      ///< Currently known type variable destructors
     207                        ScopedMap< std::string, DeclarationWithType *> assignOps;    ///< Currently known type variable assignment operators
    211208                        ResolvExpr::TypeMap< DeclarationWithType > scopedAssignOps;  ///< Currently known assignment operators
    212                         ResolvExpr::TypeMap< DeclarationWithType > scopedCtorOps;    ///< Currently known assignment operators
    213                         ResolvExpr::TypeMap< DeclarationWithType > scopedCopyOps;    ///< Currently known assignment operators
    214                         ResolvExpr::TypeMap< DeclarationWithType > scopedDtorOps;    ///< Currently known assignment operators
    215209                        ScopedMap< std::string, DeclarationWithType* > adapters;     ///< Set of adapter functions in the current scope
    216210
     
    606600                Pass1::Pass1() : useRetval( false ), tempNamer( "_temp" ) {}
    607601
    608                 /// Returns T if the given declaration is a function with parameter (T*) for some TypeInstType T, NULL otherwise
    609                 TypeInstType *isTypeInstPtrFn( DeclarationWithType *decl ) {
    610                         if ( FunctionType *funType = getFunctionType( decl->get_type() ) ) {
    611                                 if ( funType->get_parameters().size() == 1 ) {
    612                                         if ( PointerType *pointer = dynamic_cast< PointerType *>( funType->get_parameters().front()->get_type() ) ) {
    613                                                 if ( TypeInstType *refType = dynamic_cast< TypeInstType *>( pointer->get_base() ) ) {
    614                                                         return refType;
    615                                                 } // if
    616                                         } // if
    617                                 } // if
    618                         } // if
    619                         return 0;
    620                 }
    621                
    622                 /// Returns T if the given declaration is a function with parameters (T*, T) for some TypeInstType T, NULL otherwise
    623                 TypeInstType *isTypeInstPtrValFn( DeclarationWithType *decl ) {
    624                         if ( FunctionType *funType = getFunctionType( decl->get_type() ) ) {
    625                                 if ( funType->get_parameters().size() == 2 ) {
    626                                         if ( PointerType *pointer = dynamic_cast< PointerType *>( funType->get_parameters().front()->get_type() ) ) {
    627                                                 if ( TypeInstType *refType = dynamic_cast< TypeInstType *>( pointer->get_base() ) ) {
    628                                                         if ( TypeInstType *refType2 = dynamic_cast< TypeInstType *>( funType->get_parameters().back()->get_type() ) ) {
    629                                                                 if ( refType->get_name() == refType2->get_name() ) {
    630                                                                         return refType;
     602                /// Returns T if the given declaration is (*?=?)(T *, T) for some TypeInstType T (return not checked, but maybe should be), NULL otherwise
     603                TypeInstType *isTypeInstAssignment( DeclarationWithType *decl ) {
     604                        if ( decl->get_name() == "?=?" ) {
     605                                if ( FunctionType *funType = getFunctionType( decl->get_type() ) ) {
     606                                        if ( funType->get_parameters().size() == 2 ) {
     607                                                if ( PointerType *pointer = dynamic_cast< PointerType *>( funType->get_parameters().front()->get_type() ) ) {
     608                                                        if ( TypeInstType *refType = dynamic_cast< TypeInstType *>( pointer->get_base() ) ) {
     609                                                                if ( TypeInstType *refType2 = dynamic_cast< TypeInstType *>( funType->get_parameters().back()->get_type() ) ) {
     610                                                                        if ( refType->get_name() == refType2->get_name() ) {
     611                                                                                return refType;
     612                                                                        } // if
    631613                                                                } // if
    632614                                                        } // if
     
    637619                        return 0;
    638620                }
    639                
    640                 /// Returns T if the given declaration is (*?=?)(T *, T) for some TypeInstType T (return not checked, but maybe should be), NULL otherwise
    641                 TypeInstType *isTypeInstAssignment( DeclarationWithType *decl ) {
    642                         return decl->get_name() == "?=?" ? isTypeInstPtrValFn( decl ) : 0;
    643                 }
    644 
    645                 /// Returns T if the given declaration is (*?{})(T *) for some TypeInstType T (return not checked, but maybe should be), NULL otherwise
    646                 TypeInstType *isTypeInstCtor( DeclarationWithType *decl ) {
    647                         return decl->get_name() == "?{}" ? isTypeInstPtrFn( decl ) : 0;
    648                 }
    649 
    650                 /// Returns T if the given declaration is (*?{})(T *, T) for some TypeInstType T (return not checked, but maybe should be), NULL otherwise
    651                 TypeInstType *isTypeInstCopy( DeclarationWithType *decl ) {
    652                         return decl->get_name() == "?{}" ? isTypeInstPtrValFn( decl ) : 0;
    653                 }
    654 
    655                 /// Returns T if the given declaration is (*^?{})(T *) for some TypeInstType T (return not checked, but maybe should be), NULL otherwise
    656                 TypeInstType *isTypeInstDtor( DeclarationWithType *decl ) {
    657                         return decl->get_name() == "^?{}" ? isTypeInstPtrFn( decl ) : 0;
    658                 }
    659 
    660                 /// Returns T if the given declaration is a function with parameters (T*, T) for some type T, where neither parameter is cv-qualified,
    661                 /// NULL otherwise
    662                 Type *isNoCvPtrFn( DeclarationWithType *decl ) {
    663                         if ( FunctionType *funType = getFunctionType( decl->get_type() ) ) {
    664                                 if ( funType->get_parameters().size() == 1 ) {
    665                                         Type::Qualifiers defaultQualifiers;
    666                                         Type *paramType = funType->get_parameters().front()->get_type();
    667                                         if ( paramType->get_qualifiers() != defaultQualifiers ) return 0;
    668 
    669                                         if ( PointerType *pointerType = dynamic_cast< PointerType* >( paramType ) ) {
    670                                                 Type *baseType = pointerType->get_base();
    671                                                 if ( baseType->get_qualifiers() == defaultQualifiers ) {
    672                                                         return baseType;
     621
     622                /// returns T if the given declaration is: (*?=?)(T *, T) for some type T (return not checked, but maybe should be), NULL otherwise
     623                /// Only picks assignments where neither parameter is cv-qualified
     624                Type *isAssignment( DeclarationWithType *decl ) {
     625                        if ( decl->get_name() == "?=?" ) {
     626                                if ( FunctionType *funType = getFunctionType( decl->get_type() ) ) {
     627                                        if ( funType->get_parameters().size() == 2 ) {
     628                                                Type::Qualifiers defaultQualifiers;
     629                                                Type *paramType1 = funType->get_parameters().front()->get_type();
     630                                                if ( paramType1->get_qualifiers() != defaultQualifiers ) return 0;
     631                                                Type *paramType2 = funType->get_parameters().back()->get_type();
     632                                                if ( paramType2->get_qualifiers() != defaultQualifiers ) return 0;
     633
     634                                                if ( PointerType *pointerType = dynamic_cast< PointerType* >( paramType1 ) ) {
     635                                                        Type *baseType1 = pointerType->get_base();
     636                                                        if ( baseType1->get_qualifiers() != defaultQualifiers ) return 0;
     637                                                        SymTab::Indexer dummy;
     638                                                        if ( ResolvExpr::typesCompatible( baseType1, paramType2, dummy ) ) {
     639                                                                return baseType1;
     640                                                        } // if
    673641                                                } // if
    674642                                        } // if
     
    677645                        return 0;
    678646                }
    679                
    680                 /// Returns T if the given declaration is a function with parameters (T*, T) for some type T, where neither parameter is cv-qualified,
    681                 /// NULL otherwise
    682                 Type *isNoCvPtrValFn( DeclarationWithType *decl ) {
    683                         if ( FunctionType *funType = getFunctionType( decl->get_type() ) ) {
    684                                 if ( funType->get_parameters().size() == 2 ) {
    685                                         Type::Qualifiers defaultQualifiers;
    686                                         Type *paramType1 = funType->get_parameters().front()->get_type();
    687                                         if ( paramType1->get_qualifiers() != defaultQualifiers ) return 0;
    688                                         Type *paramType2 = funType->get_parameters().back()->get_type();
    689                                         if ( paramType2->get_qualifiers() != defaultQualifiers ) return 0;
    690 
    691                                         if ( PointerType *pointerType = dynamic_cast< PointerType* >( paramType1 ) ) {
    692                                                 Type *baseType1 = pointerType->get_base();
    693                                                 if ( baseType1->get_qualifiers() != defaultQualifiers ) return 0;
    694                                                 SymTab::Indexer dummy;
    695                                                 if ( ResolvExpr::typesCompatible( baseType1, paramType2, dummy ) ) {
    696                                                         return baseType1;
    697                                                 } // if
    698                                         } // if
    699                                 } // if
    700                         } // if
    701                         return 0;
    702                 }
    703 
    704                 /// returns T if the given declaration is: (*?=?)(T *, T) for some type T (return not checked, but maybe should be), NULL otherwise
    705                 /// Only picks assignments where neither parameter is cv-qualified
    706                 Type *isAssignment( DeclarationWithType *decl ) {
    707                         return decl->get_name() == "?=?" ? isNoCvPtrValFn( decl ) : 0;
    708                 }
    709 
    710                 /// returns T if the given declaration is: (*?{})(T *) for some type T, NULL otherwise
    711                 /// Only picks ctors where the parameter is not cv-qualified
    712                 Type *isCtor( DeclarationWithType *decl ) {
    713                         return decl->get_name() == "?{}" ? isNoCvPtrFn( decl ) : 0;
    714                 }
    715 
    716                 /// returns T if the given declaration is: (*?{})(T *, T) for some type T (return not checked, but maybe should be), NULL otherwise
    717                 /// Only picks copy constructors where neither parameter is cv-qualified
    718                 Type *isCopy( DeclarationWithType *decl ) {
    719                         return decl->get_name() == "?{}" ? isNoCvPtrValFn( decl ) : 0;
    720                 }
    721 
    722                 /// returns T if the given declaration is: (*?{})(T *) for some type T, NULL otherwise
    723                 /// Only picks ctors where the parameter is not cv-qualified
    724                 Type *isDtor( DeclarationWithType *decl ) {
    725                         return decl->get_name() == "^?{}" ? isNoCvPtrFn( decl ) : 0;
    726                 }
    727 
    728                 void Pass1::findTypeOps( const std::list< TypeDecl *> &forall ) {
     647
     648                void Pass1::findAssignOps( const std::list< TypeDecl *> &forall ) {
    729649                        // what if a nested function uses an assignment operator?
    730650                        // assignOps.clear();
     
    734654                                        if ( TypeInstType *typeInst = isTypeInstAssignment( *assert ) ) {
    735655                                                assignOps[ typeInst->get_name() ] = *assert;
    736                                         } else if ( TypeInstType *typeInst = isTypeInstCtor( *assert ) ) {
    737                                                 ctorOps[ typeInst->get_name() ] = *assert;
    738                                         } else if ( TypeInstType *typeInst = isTypeInstCopy( *assert ) ) {
    739                                                 copyOps[ typeInst->get_name() ] = *assert;
    740                                         } else if ( TypeInstType *typeInst = isTypeInstDtor( *assert ) ) {
    741                                                 dtorOps[ typeInst->get_name() ] = *assert;
    742656                                        } // if
    743657                                } // for
     
    747661                DeclarationWithType *Pass1::mutate( FunctionDecl *functionDecl ) {
    748662                        // if this is a assignment function, put it in the map for this scope
    749                         if ( Type *paramType = isAssignment( functionDecl ) ) {
    750                                 if ( ! dynamic_cast< TypeInstType* >( paramType ) ) {
    751                                         scopedAssignOps.insert( paramType, functionDecl );
    752                                 }
    753                         } else if ( Type *paramType = isCtor( functionDecl ) ) {
    754                                 if ( ! dynamic_cast< TypeInstType* >( paramType ) ) {
    755                                         scopedCtorOps.insert( paramType, functionDecl );
    756                                 }
    757                         } else if ( Type *paramType = isCopy( functionDecl ) ) {
    758                                 if ( ! dynamic_cast< TypeInstType* >( paramType ) ) {
    759                                         scopedCopyOps.insert( paramType, functionDecl );
    760                                 }
    761                         } else if ( Type *paramType = isDtor( functionDecl ) ) {
    762                                 if ( ! dynamic_cast< TypeInstType* >( paramType ) ) {
    763                                         scopedDtorOps.insert( paramType, functionDecl );
     663                        if ( Type *assignedType = isAssignment( functionDecl ) ) {
     664                                if ( ! dynamic_cast< TypeInstType* >( assignedType ) ) {
     665                                        scopedAssignOps.insert( assignedType, functionDecl );
    764666                                }
    765667                        }
     
    769671                                scopeTyVars.beginScope();
    770672                                assignOps.beginScope();
    771                                 ctorOps.beginScope();
    772                                 copyOps.beginScope();
    773                                 dtorOps.beginScope();
    774                                
    775673                                DeclarationWithType *oldRetval = retval;
    776674                                bool oldUseRetval = useRetval;
     
    790688                                FunctionType *functionType = functionDecl->get_functionType();
    791689                                makeTyVarMap( functionDecl->get_functionType(), scopeTyVars );
    792                                 findTypeOps( functionDecl->get_functionType()->get_forall() );
     690                                findAssignOps( functionDecl->get_functionType()->get_forall() );
    793691
    794692                                std::list< DeclarationWithType *> &paramList = functionType->get_parameters();
     
    815713                                scopeTyVars.endScope();
    816714                                assignOps.endScope();
    817                                 ctorOps.endScope();
    818                                 copyOps.endScope();
    819                                 dtorOps.endScope();
    820715                                retval = oldRetval;
    821716                                useRetval = oldUseRetval;
     
    14771372                }
    14781373
    1479                 /// Finds the operation declaration for a given type in one of the two maps
    1480                 DeclarationWithType* findOpForType( Type *formalType, const ScopedMap< std::string, DeclarationWithType* >& ops, ResolvExpr::TypeMap< DeclarationWithType >& scopedOps ) {
    1481                         if ( TypeInstType *formalTypeInstType = dynamic_cast< TypeInstType* >( formalType ) ) {
    1482                                 ScopedMap< std::string, DeclarationWithType *>::const_iterator opIt = ops.find( formalTypeInstType->get_name() );
    1483                                 return opIt == ops.end() ? 0 : opIt->second;
    1484                         } else {
    1485                                 return scopedOps.find( formalType );
    1486                         }
    1487                 }
    1488 
    1489                 /// Adds an assertion parameter to the application expression for the actual assertion declaration valued with the assert op
    1490                 void addAssertionFor( ApplicationExpr *appExpr, DeclarationWithType *actualDecl, DeclarationWithType *assertOp ) {
    1491                         appExpr->get_inferParams()[ actualDecl->get_uniqueId() ]
    1492                                         = ParamEntry( assertOp->get_uniqueId(), assertOp->get_type()->clone(), actualDecl->get_type()->clone(), wrapFunctionDecl( assertOp ) );
    1493                 }
    1494                
    14951374                Statement * Pass1::mutate( ReturnStmt *returnStmt ) {
    14961375                        if ( retval && returnStmt->get_expr() ) {
     
    15391418                                                assignExpr->get_env()->add( (*forallIt)->get_name(), formalType );
    15401419
    1541                                                 // skip non-otype parameters (ftype/dtype)
     1420                                                // skip types with no assign op (ftype/dtype)
    15421421                                                if ( (*forallIt)->get_kind() != TypeDecl::Any ) continue;
    15431422
    1544                                                 // find otype operators for formal type
    1545                                                 DeclarationWithType *assertAssign = findOpForType( formalType, assignOps, scopedAssignOps );
    1546                                                 if ( ! assertAssign ) throw SemanticError( "No assignment operation found for ", formalType );
    1547 
    1548                                                 DeclarationWithType *assertCtor = findOpForType( formalType, ctorOps, scopedCtorOps );
    1549                                                 if ( ! assertCtor ) throw SemanticError( "No default constructor found for ", formalType );
    1550 
    1551                                                 DeclarationWithType *assertCopy = findOpForType( formalType, copyOps, scopedCopyOps );
    1552                                                 if ( ! assertCopy ) throw SemanticError( "No copy constructor found for ", formalType );
    1553 
    1554                                                 DeclarationWithType *assertDtor = findOpForType( formalType, dtorOps, scopedDtorOps );
    1555                                                 if ( ! assertDtor ) throw SemanticError( "No destructor found for ", formalType );
    1556                                                
    1557                                                 // add inferred parameters for otype operators to assignment expression
    1558                                                 // NOTE: Code here assumes that first four assertions are assign op, ctor, copy ctor, dtor, in that order
     1423                                                // find assignment operator for formal type
     1424                                                DeclarationWithType *assertAssign = 0;
     1425                                                if ( TypeInstType *formalTypeInstType = dynamic_cast< TypeInstType* >( formalType ) ) {
     1426                                                        ScopedMap< std::string, DeclarationWithType *>::const_iterator assertAssignIt = assignOps.find( formalTypeInstType->get_name() );
     1427                                                        if ( assertAssignIt == assignOps.end() ) {
     1428                                                                throw SemanticError( "No assignment operation found for ", formalTypeInstType );
     1429                                                        }
     1430                                                        assertAssign = assertAssignIt->second;
     1431                                                } else {
     1432                                                        assertAssign = scopedAssignOps.find( formalType );
     1433                                                        if ( ! assertAssign ) {
     1434                                                                throw SemanticError( "No assignment operation found for ", formalType );
     1435                                                        }
     1436                                                }
     1437
     1438                                                // add inferred parameter for field assignment operator to assignment expression
    15591439                                                std::list< DeclarationWithType* > &asserts = (*forallIt)->get_assertions();
    1560                                                 assert( asserts.size() >= 4 && "Type param needs otype operator assertions" );
    1561 
    1562                                                 std::list< DeclarationWithType* >::iterator actualIt = asserts.begin();
    1563                                                 addAssertionFor( assignExpr, *actualIt, assertAssign );
    1564                                                 ++actualIt;
    1565                                                 addAssertionFor( assignExpr, *actualIt, assertCtor );
    1566                                                 ++actualIt;
    1567                                                 addAssertionFor( assignExpr, *actualIt, assertCopy );
    1568                                                 ++actualIt;
    1569                                                 addAssertionFor( assignExpr, *actualIt, assertDtor );
    1570                                                
    1571                                                 //DeclarationWithType *actualDecl = asserts.front();
    1572                                                 //assignExpr->get_inferParams()[ actualDecl->get_uniqueId() ]
    1573                                                 //      = ParamEntry( assertAssign->get_uniqueId(), assertAssign->get_type()->clone(), actualDecl->get_type()->clone(), wrapFunctionDecl( assertAssign ) );
     1440                                                assert( ! asserts.empty() && "Type param needs assignment operator assertion" );
     1441                                                DeclarationWithType *actualDecl = asserts.front();
     1442                                                assignExpr->get_inferParams()[ actualDecl->get_uniqueId() ]
     1443                                                        = ParamEntry( assertAssign->get_uniqueId(), assertAssign->get_type()->clone(), actualDecl->get_type()->clone(), wrapFunctionDecl( assertAssign ) );
    15741444                                        }
    15751445                                }
     
    16171487                        adapters.beginScope();
    16181488                        scopedAssignOps.beginScope();
    1619                         scopedCtorOps.beginScope();
    1620                         scopedCopyOps.beginScope();
    1621                         scopedDtorOps.beginScope();
    16221489                }
    16231490
     
    16251492                        adapters.endScope();
    16261493                        scopedAssignOps.endScope();
    1627                         scopedCtorOps.endScope();
    1628                         scopedCopyOps.endScope();
    1629                         scopedDtorOps.endScope();
    16301494                }
    16311495
     
    21802044
    21812045                bool PolyGenericCalculator::findGeneric( Type *ty ) {
    2182                         ty = replaceTypeInst( ty, env );
    2183                        
    21842046                        if ( TypeInstType *typeInst = dynamic_cast< TypeInstType* >( ty ) ) {
     2047                                // duplicate logic from isPolyType()
     2048                                if ( env ) {
     2049                                        if ( Type *newType = env->lookup( typeInst->get_name() ) ) {
     2050                                                return findGeneric( newType );
     2051                                        } // if
     2052                                } // if
    21852053                                if ( scopeTyVars.find( typeInst->get_name() ) != scopeTyVars.end() ) {
    21862054                                        // NOTE assumes here that getting put in the scopeTyVars included having the layout variables set
Note: See TracChangeset for help on using the changeset viewer.