Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/GenPoly/Box.cc

    rc2ad3c9 raa19ccf  
    99// Author           : Richard C. Bilson
    1010// Created On       : Mon May 18 07:44:20 2015
    11 // Last Modified By : Rob Schluntz
    12 // Last Modified On : Fri May 13 14:51:21 2016
    13 // Update Count     : 295
     11// Last Modified By : Peter A. Buhr
     12// Last Modified On : Fri Feb  5 16:45:07 2016
     13// Update Count     : 286
    1414//
    1515
     
    133133                        Value *lookup( Key *key, const std::list< TypeExpr* >& params ) const {
    134134                                TypeList typeList( params );
    135 
     135                               
    136136                                // scan scopes for matches to the key
    137137                                for ( typename InnerMap::const_iterator insts = instantiations.find( key ); insts != instantiations.end(); insts = instantiations.findNext( insts, key ) ) {
     
    160160                        virtual Declaration *mutate( UnionDecl *unionDecl );
    161161                };
    162 
     162               
    163163                /// Replaces polymorphic return types with out-parameters, replaces calls to polymorphic functions with adapter calls as needed, and adds appropriate type variables to the function call
    164164                class Pass1 : public PolyMutator {
     
    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
    216 
     210                       
    217211                        DeclarationWithType *retval;
    218212                        bool useRetval;
     
    232226                        virtual Type *mutate( PointerType *pointerType );
    233227                        virtual Type *mutate( FunctionType *funcType );
    234 
     228                       
    235229                  private:
    236230                        void addAdapters( FunctionType *functionType );
     
    303297                        /// Exits the type-variable scope
    304298                        void endTypeScope();
    305 
     299                       
    306300                        ScopedSet< std::string > knownLayouts;          ///< Set of generic type layouts known in the current scope, indexed by sizeofName
    307301                        ScopedSet< std::string > knownOffsets;          ///< Set of non-generic types for which the offset array exists in the current scope, indexed by offsetofName
     
    357351                PolyGenericCalculator polyCalculator;
    358352                Pass3 pass3;
    359 
     353               
    360354                layoutBuilder.mutateDeclarationList( translationUnit );
    361355                mutateTranslationUnit/*All*/( translationUnit, pass1 );
     
    376370                return functionDecl;
    377371        }
    378 
     372       
    379373        /// Get a list of type declarations that will affect a layout function
    380374        std::list< TypeDecl* > takeOtypeOnly( std::list< TypeDecl* > &decls ) {
     
    386380                        }
    387381                }
    388 
     382               
    389383                return otypeDecls;
    390384        }
     
    393387        void addOtypeParams( FunctionType *layoutFnType, std::list< TypeDecl* > &otypeParams ) {
    394388                BasicType sizeAlignType( Type::Qualifiers(), BasicType::LongUnsignedInt );
    395 
     389               
    396390                for ( std::list< TypeDecl* >::const_iterator param = otypeParams.begin(); param != otypeParams.end(); ++param ) {
    397391                        TypeInstType paramType( Type::Qualifiers(), (*param)->get_name(), *param );
     
    450444                return makeCond( ifCond, ifExpr );
    451445        }
    452 
     446       
    453447        /// adds an expression to a compound statement
    454448        void addExpr( CompoundStmt *stmts, Expression *expr ) {
     
    460454                stmts->get_kids().push_back( stmt );
    461455        }
    462 
     456       
    463457        Declaration *LayoutFunctionBuilder::mutate( StructDecl *structDecl ) {
    464458                // do not generate layout function for "empty" tag structs
     
    473467                BasicType *sizeAlignType = new BasicType( Type::Qualifiers(), BasicType::LongUnsignedInt );
    474468                PointerType *sizeAlignOutType = new PointerType( Type::Qualifiers(), sizeAlignType );
    475 
     469               
    476470                ObjectDecl *sizeParam = new ObjectDecl( sizeofName( structDecl->get_name() ), DeclarationNode::NoStorageClass, LinkageSpec::Cforall, 0, sizeAlignOutType, 0 );
    477471                layoutFnType->get_parameters().push_back( sizeParam );
     
    503497                                addStmt( layoutDecl->get_statements(), makeAlignTo( derefVar( sizeParam ), new AlignofExpr( memberType->clone() ) ) );
    504498                        }
    505 
     499                       
    506500                        // place current size in the current offset index
    507                         addExpr( layoutDecl->get_statements(), makeOp( "?=?", makeOp( "?[?]", new VariableExpr( offsetParam ), new ConstantExpr( Constant::from_ulong( n_members ) ) ),
     501                        addExpr( layoutDecl->get_statements(), makeOp( "?=?", makeOp( "?[?]", new VariableExpr( offsetParam ), new ConstantExpr( Constant::from( n_members ) ) ),
    508502                                                                              derefVar( sizeParam ) ) );
    509503                        ++n_members;
     
    511505                        // add member size to current size
    512506                        addExpr( layoutDecl->get_statements(), makeOp( "?+=?", derefVar( sizeParam ), new SizeofExpr( memberType->clone() ) ) );
    513 
     507                       
    514508                        // take max of member alignment and global alignment
    515509                        addStmt( layoutDecl->get_statements(), makeAssignMax( derefVar( alignParam ), new AlignofExpr( memberType->clone() ) ) );
     
    521515                return structDecl;
    522516        }
    523 
     517       
    524518        Declaration *LayoutFunctionBuilder::mutate( UnionDecl *unionDecl ) {
    525519                // do not generate layout function for "empty" tag unions
    526520                if ( unionDecl->get_members().empty() ) return unionDecl;
    527 
     521               
    528522                // get parameters that can change layout, exiting early if none
    529523                std::list< TypeDecl* > otypeParams = takeOtypeOnly( unionDecl->get_parameters() );
     
    534528                BasicType *sizeAlignType = new BasicType( Type::Qualifiers(), BasicType::LongUnsignedInt );
    535529                PointerType *sizeAlignOutType = new PointerType( Type::Qualifiers(), sizeAlignType );
    536 
     530               
    537531                ObjectDecl *sizeParam = new ObjectDecl( sizeofName( unionDecl->get_name() ), DeclarationNode::NoStorageClass, LinkageSpec::Cforall, 0, sizeAlignOutType, 0 );
    538532                layoutFnType->get_parameters().push_back( sizeParam );
     
    551545                        assert( dwt );
    552546                        Type *memberType = dwt->get_type();
    553 
     547                       
    554548                        // take max member size and global size
    555549                        addStmt( layoutDecl->get_statements(), makeAssignMax( derefVar( sizeParam ), new SizeofExpr( memberType->clone() ) ) );
    556 
     550                       
    557551                        // take max of member alignment and global alignment
    558552                        addStmt( layoutDecl->get_statements(), makeAssignMax( derefVar( alignParam ), new AlignofExpr( memberType->clone() ) ) );
     
    564558                return unionDecl;
    565559        }
    566 
     560       
    567561        ////////////////////////////////////////// Pass1 ////////////////////////////////////////////////////
    568562
     
    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
     
    638620                }
    639621               
    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;
     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;
     
    889784                                                arg++;
    890785                                        } else {
    891                                                 /// xxx - should this be an assertion?
    892                                                 throw SemanticError( "unbound type variable: " + tyParm->first + " in application ", appExpr );
     786                                                throw SemanticError( "unbound type variable in application ", appExpr );
    893787                                        } // if
    894788                                } // if
     
    909803                                passArgTypeVars( appExpr, polyRetType, concRetType, arg, exprTyVars, seenTypes );
    910804                        }
    911 
     805                       
    912806                        // add type information args for presently unseen types in parameter list
    913807                        for ( ; fnParm != funcType->get_parameters().end() && fnArg != appExpr->get_args().end(); ++fnParm, ++fnArg ) {
     
    988882                        assert( env );
    989883                        Type *concrete = replaceWithConcrete( appExpr, polyType );
    990                         // add out-parameter for return value
     884                        // add out-parameter for return value   
    991885                        return addRetParam( appExpr, function, concrete, arg );
    992886                }
     
    1016910                                } else if ( arg->get_results().front()->get_isLvalue() ) {
    1017911                                        // VariableExpr and MemberExpr are lvalues; need to check this isn't coming from the second arg of a comma expression though (not an lvalue)
    1018                                         // xxx - need to test that this code is still reachable
    1019912                                        if ( CommaExpr *commaArg = dynamic_cast< CommaExpr* >( arg ) ) {
    1020913                                                commaArg->set_arg2( new AddressExpr( commaArg->get_arg2() ) );
     
    11421035                        std::list< DeclarationWithType *>::iterator param = adapterType->get_parameters().begin();
    11431036                        std::list< DeclarationWithType *>::iterator realParam = adaptee->get_parameters().begin();
    1144                         param++;                // skip adaptee parameter in the adapter type
     1037                        param++;                // skip adaptee parameter
    11451038                        if ( realType->get_returnVals().empty() ) {
    1146                                 // void return
    11471039                                addAdapterParams( adapteeApp, arg, param, adapterType->get_parameters().end(), realParam, tyVars );
    11481040                                bodyStmt = new ExprStmt( noLabels, adapteeApp );
    11491041                        } else if ( isPolyType( adaptee->get_returnVals().front()->get_type(), tyVars ) ) {
    1150                                 // return type T
    11511042                                if ( (*param)->get_name() == "" ) {
    11521043                                        (*param)->set_name( "_ret" );
     
    14001291                        } else if ( needsAdapter( function, scopeTyVars ) ) {
    14011292                                // std::cerr << "needs adapter: ";
    1402                                 // printTyVarMap( std::cerr, scopeTyVars );
    1403                                 // std::cerr << *env << std::endl;
     1293                                // for ( TyVarMap::iterator i = scopeTyVars.begin(); i != scopeTyVars.end(); ++i ) {
     1294                                //      std::cerr << i->first << " ";
     1295                                // }
     1296                                // std::cerr << "\n";
    14041297                                // change the application so it calls the adapter rather than the passed function
    14051298                                ret = applyAdapter( appExpr, function, arg, scopeTyVars );
     
    14521345                                } // if
    14531346                        } // if
    1454                         // isPolyType check needs to happen before mutating addrExpr arg, so pull it forward
    1455                         // out of the if condition.
    1456                         bool polytype = isPolyType( addrExpr->get_arg()->get_results().front(), scopeTyVars, env );
    14571347                        addrExpr->set_arg( mutateExpression( addrExpr->get_arg() ) );
    1458                         if ( polytype || needs ) {
     1348                        if ( isPolyType( addrExpr->get_arg()->get_results().front(), scopeTyVars, env ) || needs ) {
    14591349                                Expression *ret = addrExpr->get_arg();
    14601350                                delete ret->get_results().front();
     
    14751365                        functionObj->set_mangleName( functionDecl->get_mangleName() );
    14761366                        return new VariableExpr( functionObj );
    1477                 }
    1478 
    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 ) );
    14931367                }
    14941368               
     
    15391413                                                assignExpr->get_env()->add( (*forallIt)->get_name(), formalType );
    15401414
    1541                                                 // skip non-otype parameters (ftype/dtype)
     1415                                                // skip types with no assign op (ftype/dtype)
    15421416                                                if ( (*forallIt)->get_kind() != TypeDecl::Any ) continue;
    15431417
    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
     1418                                                // find assignment operator for formal type
     1419                                                DeclarationWithType *assertAssign = 0;
     1420                                                if ( TypeInstType *formalTypeInstType = dynamic_cast< TypeInstType* >( formalType ) ) {
     1421                                                        ScopedMap< std::string, DeclarationWithType *>::const_iterator assertAssignIt = assignOps.find( formalTypeInstType->get_name() );
     1422                                                        if ( assertAssignIt == assignOps.end() ) {
     1423                                                                throw SemanticError( "No assignment operation found for ", formalTypeInstType );
     1424                                                        }
     1425                                                        assertAssign = assertAssignIt->second;
     1426                                                } else {
     1427                                                        assertAssign = scopedAssignOps.find( formalType );
     1428                                                        if ( ! assertAssign ) {
     1429                                                                throw SemanticError( "No assignment operation found for ", formalType );
     1430                                                        }
     1431                                                }
     1432
     1433                                                // add inferred parameter for field assignment operator to assignment expression
    15591434                                                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 ) );
     1435                                                assert( ! asserts.empty() && "Type param needs assignment operator assertion" );
     1436                                                DeclarationWithType *actualDecl = asserts.front();
     1437                                                assignExpr->get_inferParams()[ actualDecl->get_uniqueId() ]
     1438                                                        = ParamEntry( assertAssign->get_uniqueId(), assertAssign->get_type()->clone(), actualDecl->get_type()->clone(), wrapFunctionDecl( assertAssign ) );
    15741439                                        }
    15751440                                }
     
    16171482                        adapters.beginScope();
    16181483                        scopedAssignOps.beginScope();
    1619                         scopedCtorOps.beginScope();
    1620                         scopedCopyOps.beginScope();
    1621                         scopedDtorOps.beginScope();
    16221484                }
    16231485
     
    16251487                        adapters.endScope();
    16261488                        scopedAssignOps.endScope();
    1627                         scopedCtorOps.endScope();
    1628                         scopedCopyOps.endScope();
    1629                         scopedDtorOps.endScope();
    16301489                }
    16311490
     
    20271886                                }
    20281887                        }
    2029 
     1888                       
    20301889                        Type *ret = Mutator::mutate( funcType );
    20311890
     
    20461905
    20471906                                        std::list<Expression*> designators;
    2048                                         objectDecl->set_init( new SingleInit( alloc, designators, false ) ); // not constructed
     1907                                        objectDecl->set_init( new SingleInit( alloc, designators ) );
    20491908                                }
    20501909                        }
     
    20831942                                UntypedExpr *derefExpr = new UntypedExpr( new NameExpr( "*?" ) );
    20841943                                derefExpr->get_args().push_back( derefdVar );
    2085                                 // xxx - should set results on derefExpr
    20861944                                derefdVar = derefExpr;
    20871945                        }
    20881946                        return derefdVar;
    20891947                }
    2090 
     1948               
    20911949                Expression *PolyGenericCalculator::mutate( MemberExpr *memberExpr ) {
    20921950                        // mutate, exiting early if no longer MemberExpr
     
    21802038
    21812039                bool PolyGenericCalculator::findGeneric( Type *ty ) {
    2182                         ty = replaceTypeInst( ty, env );
    2183                        
    21842040                        if ( TypeInstType *typeInst = dynamic_cast< TypeInstType* >( ty ) ) {
     2041                                // duplicate logic from isPolyType()
     2042                                if ( env ) {
     2043                                        if ( Type *newType = env->lookup( typeInst->get_name() ) ) {
     2044                                                return findGeneric( newType );
     2045                                        } // if
     2046                                } // if
    21852047                                if ( scopeTyVars.find( typeInst->get_name() ) != scopeTyVars.end() ) {
    21862048                                        // NOTE assumes here that getting put in the scopeTyVars included having the layout variables set
     
    22042066                                if ( n_members == 0 ) {
    22052067                                        // all empty structs have the same layout - size 1, align 1
    2206                                         makeVar( sizeofName( typeName ), layoutType, new SingleInit( new ConstantExpr( Constant::from_ulong( (unsigned long)1 ) ) ) );
    2207                                         makeVar( alignofName( typeName ), layoutType->clone(), new SingleInit( new ConstantExpr( Constant::from_ulong( (unsigned long)1 ) ) ) );
     2068                                        makeVar( sizeofName( typeName ), layoutType, new SingleInit( new ConstantExpr( Constant::from( (unsigned long)1 ) ) ) );
     2069                                        makeVar( alignofName( typeName ), layoutType->clone(), new SingleInit( new ConstantExpr( Constant::from( (unsigned long)1 ) ) ) );
    22082070                                        // NOTE zero-length arrays are forbidden in C, so empty structs have no offsetof array
    22092071                                } else {
    22102072                                        ObjectDecl *sizeVar = makeVar( sizeofName( typeName ), layoutType );
    22112073                                        ObjectDecl *alignVar = makeVar( alignofName( typeName ), layoutType->clone() );
    2212                                         ObjectDecl *offsetVar = makeVar( offsetofName( typeName ), new ArrayType( Type::Qualifiers(), layoutType->clone(), new ConstantExpr( Constant::from_int( n_members ) ), false, false ) );
     2074                                        ObjectDecl *offsetVar = makeVar( offsetofName( typeName ), new ArrayType( Type::Qualifiers(), layoutType->clone(), new ConstantExpr( Constant::from( n_members ) ), false, false ) );
    22132075
    22142076                                        // generate call to layout function
     
    22822144                        Type *ty = offsetofExpr->get_type();
    22832145                        if ( ! findGeneric( ty ) ) return offsetofExpr;
    2284 
     2146                       
    22852147                        if ( StructInstType *structType = dynamic_cast< StructInstType* >( ty ) ) {
    22862148                                // replace offsetof expression by index into offset array
     
    23292191
    23302192                                        // build the offset array and replace the pack with a reference to it
    2331                                         ObjectDecl *offsetArray = makeVar( offsetName, new ArrayType( Type::Qualifiers(), offsetType, new ConstantExpr( Constant::from_ulong( baseMembers.size() ) ), false, false ),
     2193                                        ObjectDecl *offsetArray = makeVar( offsetName, new ArrayType( Type::Qualifiers(), offsetType, new ConstantExpr( Constant::from( baseMembers.size() ) ), false, false ),
    23322194                                                        new ListInit( inits ) );
    23332195                                        ret = new VariableExpr( offsetArray );
Note: See TracChangeset for help on using the changeset viewer.