Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/GenPoly/Box.cc

    raa19ccf rc2ad3c9  
    99// Author           : Richard C. Bilson
    1010// Created On       : Mon May 18 07:44:20 2015
    11 // Last Modified By : Peter A. Buhr
    12 // Last Modified On : Fri Feb  5 16:45:07 2016
    13 // Update Count     : 286
     11// Last Modified By : Rob Schluntz
     12// Last Modified On : Fri May 13 14:51:21 2016
     13// Update Count     : 295
    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 findAssignOps( const std::list< TypeDecl *> &forall );
     199                        void findTypeOps( 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
     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
    208211                        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
    209215                        ScopedMap< std::string, DeclarationWithType* > adapters;     ///< Set of adapter functions in the current scope
    210                        
     216
    211217                        DeclarationWithType *retval;
    212218                        bool useRetval;
     
    226232                        virtual Type *mutate( PointerType *pointerType );
    227233                        virtual Type *mutate( FunctionType *funcType );
    228                        
     234
    229235                  private:
    230236                        void addAdapters( FunctionType *functionType );
     
    297303                        /// Exits the type-variable scope
    298304                        void endTypeScope();
    299                        
     305
    300306                        ScopedSet< std::string > knownLayouts;          ///< Set of generic type layouts known in the current scope, indexed by sizeofName
    301307                        ScopedSet< std::string > knownOffsets;          ///< Set of non-generic types for which the offset array exists in the current scope, indexed by offsetofName
     
    351357                PolyGenericCalculator polyCalculator;
    352358                Pass3 pass3;
    353                
     359
    354360                layoutBuilder.mutateDeclarationList( translationUnit );
    355361                mutateTranslationUnit/*All*/( translationUnit, pass1 );
     
    370376                return functionDecl;
    371377        }
    372        
     378
    373379        /// Get a list of type declarations that will affect a layout function
    374380        std::list< TypeDecl* > takeOtypeOnly( std::list< TypeDecl* > &decls ) {
     
    380386                        }
    381387                }
    382                
     388
    383389                return otypeDecls;
    384390        }
     
    387393        void addOtypeParams( FunctionType *layoutFnType, std::list< TypeDecl* > &otypeParams ) {
    388394                BasicType sizeAlignType( Type::Qualifiers(), BasicType::LongUnsignedInt );
    389                
     395
    390396                for ( std::list< TypeDecl* >::const_iterator param = otypeParams.begin(); param != otypeParams.end(); ++param ) {
    391397                        TypeInstType paramType( Type::Qualifiers(), (*param)->get_name(), *param );
     
    444450                return makeCond( ifCond, ifExpr );
    445451        }
    446        
     452
    447453        /// adds an expression to a compound statement
    448454        void addExpr( CompoundStmt *stmts, Expression *expr ) {
     
    454460                stmts->get_kids().push_back( stmt );
    455461        }
    456        
     462
    457463        Declaration *LayoutFunctionBuilder::mutate( StructDecl *structDecl ) {
    458464                // do not generate layout function for "empty" tag structs
     
    467473                BasicType *sizeAlignType = new BasicType( Type::Qualifiers(), BasicType::LongUnsignedInt );
    468474                PointerType *sizeAlignOutType = new PointerType( Type::Qualifiers(), sizeAlignType );
    469                
     475
    470476                ObjectDecl *sizeParam = new ObjectDecl( sizeofName( structDecl->get_name() ), DeclarationNode::NoStorageClass, LinkageSpec::Cforall, 0, sizeAlignOutType, 0 );
    471477                layoutFnType->get_parameters().push_back( sizeParam );
     
    497503                                addStmt( layoutDecl->get_statements(), makeAlignTo( derefVar( sizeParam ), new AlignofExpr( memberType->clone() ) ) );
    498504                        }
    499                        
     505
    500506                        // place current size in the current offset index
    501                         addExpr( layoutDecl->get_statements(), makeOp( "?=?", makeOp( "?[?]", new VariableExpr( offsetParam ), new ConstantExpr( Constant::from( n_members ) ) ),
     507                        addExpr( layoutDecl->get_statements(), makeOp( "?=?", makeOp( "?[?]", new VariableExpr( offsetParam ), new ConstantExpr( Constant::from_ulong( n_members ) ) ),
    502508                                                                              derefVar( sizeParam ) ) );
    503509                        ++n_members;
     
    505511                        // add member size to current size
    506512                        addExpr( layoutDecl->get_statements(), makeOp( "?+=?", derefVar( sizeParam ), new SizeofExpr( memberType->clone() ) ) );
    507                        
     513
    508514                        // take max of member alignment and global alignment
    509515                        addStmt( layoutDecl->get_statements(), makeAssignMax( derefVar( alignParam ), new AlignofExpr( memberType->clone() ) ) );
     
    515521                return structDecl;
    516522        }
    517        
     523
    518524        Declaration *LayoutFunctionBuilder::mutate( UnionDecl *unionDecl ) {
    519525                // do not generate layout function for "empty" tag unions
    520526                if ( unionDecl->get_members().empty() ) return unionDecl;
    521                
     527
    522528                // get parameters that can change layout, exiting early if none
    523529                std::list< TypeDecl* > otypeParams = takeOtypeOnly( unionDecl->get_parameters() );
     
    528534                BasicType *sizeAlignType = new BasicType( Type::Qualifiers(), BasicType::LongUnsignedInt );
    529535                PointerType *sizeAlignOutType = new PointerType( Type::Qualifiers(), sizeAlignType );
    530                
     536
    531537                ObjectDecl *sizeParam = new ObjectDecl( sizeofName( unionDecl->get_name() ), DeclarationNode::NoStorageClass, LinkageSpec::Cforall, 0, sizeAlignOutType, 0 );
    532538                layoutFnType->get_parameters().push_back( sizeParam );
     
    545551                        assert( dwt );
    546552                        Type *memberType = dwt->get_type();
    547                        
     553
    548554                        // take max member size and global size
    549555                        addStmt( layoutDecl->get_statements(), makeAssignMax( derefVar( sizeParam ), new SizeofExpr( memberType->clone() ) ) );
    550                        
     556
    551557                        // take max of member alignment and global alignment
    552558                        addStmt( layoutDecl->get_statements(), makeAssignMax( derefVar( alignParam ), new AlignofExpr( memberType->clone() ) ) );
     
    558564                return unionDecl;
    559565        }
    560        
     566
    561567        ////////////////////////////////////////// Pass1 ////////////////////////////////////////////////////
    562568
     
    600606                Pass1::Pass1() : useRetval( false ), tempNamer( "_temp" ) {}
    601607
    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
     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;
    613631                                                                } // if
    614632                                                        } // if
     
    620638                }
    621639               
    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
     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;
    641673                                                } // if
    642674                                        } // if
     
    645677                        return 0;
    646678                }
    647 
    648                 void Pass1::findAssignOps( const std::list< TypeDecl *> &forall ) {
     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 ) {
    649729                        // what if a nested function uses an assignment operator?
    650730                        // assignOps.clear();
     
    654734                                        if ( TypeInstType *typeInst = isTypeInstAssignment( *assert ) ) {
    655735                                                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;
    656742                                        } // if
    657743                                } // for
     
    661747                DeclarationWithType *Pass1::mutate( FunctionDecl *functionDecl ) {
    662748                        // if this is a assignment function, put it in the map for this scope
    663                         if ( Type *assignedType = isAssignment( functionDecl ) ) {
    664                                 if ( ! dynamic_cast< TypeInstType* >( assignedType ) ) {
    665                                         scopedAssignOps.insert( assignedType, functionDecl );
     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 );
    666764                                }
    667765                        }
     
    671769                                scopeTyVars.beginScope();
    672770                                assignOps.beginScope();
     771                                ctorOps.beginScope();
     772                                copyOps.beginScope();
     773                                dtorOps.beginScope();
     774                               
    673775                                DeclarationWithType *oldRetval = retval;
    674776                                bool oldUseRetval = useRetval;
     
    688790                                FunctionType *functionType = functionDecl->get_functionType();
    689791                                makeTyVarMap( functionDecl->get_functionType(), scopeTyVars );
    690                                 findAssignOps( functionDecl->get_functionType()->get_forall() );
     792                                findTypeOps( functionDecl->get_functionType()->get_forall() );
    691793
    692794                                std::list< DeclarationWithType *> &paramList = functionType->get_parameters();
     
    713815                                scopeTyVars.endScope();
    714816                                assignOps.endScope();
     817                                ctorOps.endScope();
     818                                copyOps.endScope();
     819                                dtorOps.endScope();
    715820                                retval = oldRetval;
    716821                                useRetval = oldUseRetval;
     
    784889                                                arg++;
    785890                                        } else {
    786                                                 throw SemanticError( "unbound type variable in application ", appExpr );
     891                                                /// xxx - should this be an assertion?
     892                                                throw SemanticError( "unbound type variable: " + tyParm->first + " in application ", appExpr );
    787893                                        } // if
    788894                                } // if
     
    803909                                passArgTypeVars( appExpr, polyRetType, concRetType, arg, exprTyVars, seenTypes );
    804910                        }
    805                        
     911
    806912                        // add type information args for presently unseen types in parameter list
    807913                        for ( ; fnParm != funcType->get_parameters().end() && fnArg != appExpr->get_args().end(); ++fnParm, ++fnArg ) {
     
    882988                        assert( env );
    883989                        Type *concrete = replaceWithConcrete( appExpr, polyType );
    884                         // add out-parameter for return value   
     990                        // add out-parameter for return value
    885991                        return addRetParam( appExpr, function, concrete, arg );
    886992                }
     
    9101016                                } else if ( arg->get_results().front()->get_isLvalue() ) {
    9111017                                        // 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
    9121019                                        if ( CommaExpr *commaArg = dynamic_cast< CommaExpr* >( arg ) ) {
    9131020                                                commaArg->set_arg2( new AddressExpr( commaArg->get_arg2() ) );
     
    10351142                        std::list< DeclarationWithType *>::iterator param = adapterType->get_parameters().begin();
    10361143                        std::list< DeclarationWithType *>::iterator realParam = adaptee->get_parameters().begin();
    1037                         param++;                // skip adaptee parameter
     1144                        param++;                // skip adaptee parameter in the adapter type
    10381145                        if ( realType->get_returnVals().empty() ) {
     1146                                // void return
    10391147                                addAdapterParams( adapteeApp, arg, param, adapterType->get_parameters().end(), realParam, tyVars );
    10401148                                bodyStmt = new ExprStmt( noLabels, adapteeApp );
    10411149                        } else if ( isPolyType( adaptee->get_returnVals().front()->get_type(), tyVars ) ) {
     1150                                // return type T
    10421151                                if ( (*param)->get_name() == "" ) {
    10431152                                        (*param)->set_name( "_ret" );
     
    12911400                        } else if ( needsAdapter( function, scopeTyVars ) ) {
    12921401                                // std::cerr << "needs adapter: ";
    1293                                 // for ( TyVarMap::iterator i = scopeTyVars.begin(); i != scopeTyVars.end(); ++i ) {
    1294                                 //      std::cerr << i->first << " ";
    1295                                 // }
    1296                                 // std::cerr << "\n";
     1402                                // printTyVarMap( std::cerr, scopeTyVars );
     1403                                // std::cerr << *env << std::endl;
    12971404                                // change the application so it calls the adapter rather than the passed function
    12981405                                ret = applyAdapter( appExpr, function, arg, scopeTyVars );
     
    13451452                                } // if
    13461453                        } // 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 );
    13471457                        addrExpr->set_arg( mutateExpression( addrExpr->get_arg() ) );
    1348                         if ( isPolyType( addrExpr->get_arg()->get_results().front(), scopeTyVars, env ) || needs ) {
     1458                        if ( polytype || needs ) {
    13491459                                Expression *ret = addrExpr->get_arg();
    13501460                                delete ret->get_results().front();
     
    13651475                        functionObj->set_mangleName( functionDecl->get_mangleName() );
    13661476                        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 ) );
    13671493                }
    13681494               
     
    14131539                                                assignExpr->get_env()->add( (*forallIt)->get_name(), formalType );
    14141540
    1415                                                 // skip types with no assign op (ftype/dtype)
     1541                                                // skip non-otype parameters (ftype/dtype)
    14161542                                                if ( (*forallIt)->get_kind() != TypeDecl::Any ) continue;
    14171543
    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
     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
    14341559                                                std::list< DeclarationWithType* > &asserts = (*forallIt)->get_assertions();
    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 ) );
     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 ) );
    14391574                                        }
    14401575                                }
     
    14821617                        adapters.beginScope();
    14831618                        scopedAssignOps.beginScope();
     1619                        scopedCtorOps.beginScope();
     1620                        scopedCopyOps.beginScope();
     1621                        scopedDtorOps.beginScope();
    14841622                }
    14851623
     
    14871625                        adapters.endScope();
    14881626                        scopedAssignOps.endScope();
     1627                        scopedCtorOps.endScope();
     1628                        scopedCopyOps.endScope();
     1629                        scopedDtorOps.endScope();
    14891630                }
    14901631
     
    18862027                                }
    18872028                        }
    1888                        
     2029
    18892030                        Type *ret = Mutator::mutate( funcType );
    18902031
     
    19052046
    19062047                                        std::list<Expression*> designators;
    1907                                         objectDecl->set_init( new SingleInit( alloc, designators ) );
     2048                                        objectDecl->set_init( new SingleInit( alloc, designators, false ) ); // not constructed
    19082049                                }
    19092050                        }
     
    19422083                                UntypedExpr *derefExpr = new UntypedExpr( new NameExpr( "*?" ) );
    19432084                                derefExpr->get_args().push_back( derefdVar );
     2085                                // xxx - should set results on derefExpr
    19442086                                derefdVar = derefExpr;
    19452087                        }
    19462088                        return derefdVar;
    19472089                }
    1948                
     2090
    19492091                Expression *PolyGenericCalculator::mutate( MemberExpr *memberExpr ) {
    19502092                        // mutate, exiting early if no longer MemberExpr
     
    20382180
    20392181                bool PolyGenericCalculator::findGeneric( Type *ty ) {
     2182                        ty = replaceTypeInst( ty, env );
     2183                       
    20402184                        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
    20472185                                if ( scopeTyVars.find( typeInst->get_name() ) != scopeTyVars.end() ) {
    20482186                                        // NOTE assumes here that getting put in the scopeTyVars included having the layout variables set
     
    20662204                                if ( n_members == 0 ) {
    20672205                                        // all empty structs have the same layout - size 1, align 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 ) ) ) );
     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 ) ) ) );
    20702208                                        // NOTE zero-length arrays are forbidden in C, so empty structs have no offsetof array
    20712209                                } else {
    20722210                                        ObjectDecl *sizeVar = makeVar( sizeofName( typeName ), layoutType );
    20732211                                        ObjectDecl *alignVar = makeVar( alignofName( typeName ), layoutType->clone() );
    2074                                         ObjectDecl *offsetVar = makeVar( offsetofName( typeName ), new ArrayType( Type::Qualifiers(), layoutType->clone(), new ConstantExpr( Constant::from( n_members ) ), false, false ) );
     2212                                        ObjectDecl *offsetVar = makeVar( offsetofName( typeName ), new ArrayType( Type::Qualifiers(), layoutType->clone(), new ConstantExpr( Constant::from_int( n_members ) ), false, false ) );
    20752213
    20762214                                        // generate call to layout function
     
    21442282                        Type *ty = offsetofExpr->get_type();
    21452283                        if ( ! findGeneric( ty ) ) return offsetofExpr;
    2146                        
     2284
    21472285                        if ( StructInstType *structType = dynamic_cast< StructInstType* >( ty ) ) {
    21482286                                // replace offsetof expression by index into offset array
     
    21912329
    21922330                                        // build the offset array and replace the pack with a reference to it
    2193                                         ObjectDecl *offsetArray = makeVar( offsetName, new ArrayType( Type::Qualifiers(), offsetType, new ConstantExpr( Constant::from( baseMembers.size() ) ), false, false ),
     2331                                        ObjectDecl *offsetArray = makeVar( offsetName, new ArrayType( Type::Qualifiers(), offsetType, new ConstantExpr( Constant::from_ulong( baseMembers.size() ) ), false, false ),
    21942332                                                        new ListInit( inits ) );
    21952333                                        ret = new VariableExpr( offsetArray );
Note: See TracChangeset for help on using the changeset viewer.