Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/GenPoly/Box.cc

    r271a5d3 r8c91088  
    5858namespace GenPoly {
    5959        namespace {
    60                 FunctionType *makeAdapterType( FunctionType const *adaptee, const TyVarMap &tyVars );
     60                FunctionType *makeAdapterType( FunctionType *adaptee, const TyVarMap &tyVars );
    6161
    6262                class BoxPass {
     
    6868                /// Adds layout-generation functions to polymorphic types.
    6969                class LayoutFunctionBuilder final : public WithDeclsToAdd, public WithVisitorRef<LayoutFunctionBuilder>, public WithShortCircuiting {
     70                        // Current level of nested functions:
     71                        unsigned int functionNesting = 0;
    7072                public:
     73                        void previsit( FunctionDecl *functionDecl );
    7174                        void previsit( StructDecl *structDecl );
    7275                        void previsit( UnionDecl *unionDecl );
     
    97100                        void passArgTypeVars( ApplicationExpr *appExpr, Type *parmType, Type *argBaseType, std::list< Expression *>::iterator &arg, const TyVarMap &exprTyVars, std::set< std::string > &seenTypes );
    98101                        /// passes extra type parameters into a polymorphic function application
    99                         /// Returns an iterator to the first argument after the added
    100                         /// arguments, which are added at the beginning.
    101                         std::list< Expression *>::iterator passTypeVars( ApplicationExpr *appExpr, Type *polyRetType, const TyVarMap &exprTyVars );
     102                        void passTypeVars( ApplicationExpr *appExpr, Type *polyRetType, std::list< Expression *>::iterator &arg, const TyVarMap &exprTyVars );
    102103                        /// wraps a function application with a new temporary for the out-parameter return value
    103                         /// The new out-parameter is the new first parameter.
    104                         Expression *addRetParam( ApplicationExpr *appExpr, Type *retType );
     104                        Expression *addRetParam( ApplicationExpr *appExpr, Type *retType, std::list< Expression *>::iterator &arg );
     105                        /// Replaces all the type parameters of a generic type with their concrete equivalents under the current environment
     106                        void replaceParametersWithConcrete( ApplicationExpr *appExpr, std::list< Expression* >& params );
     107                        /// Replaces a polymorphic type with its concrete equivalant under the current environment (returns itself if concrete).
     108                        /// If `doClone` is set to false, will not clone interior types
     109                        Type *replaceWithConcrete( ApplicationExpr *appExpr, Type *type, bool doClone = true );
    105110                        /// wraps a function application returning a polymorphic type with a new temporary for the out-parameter return value
    106                         Expression *addDynRetParam( ApplicationExpr *appExpr, Type *polyType );
    107                         /// Converts a function call into a call of the adapter with the
    108                         /// original function as the first argument (all other arguments
    109                         /// are pushed back). May adjust return value.
    110                         Expression *applyAdapter( ApplicationExpr *appExpr, FunctionType *function );
    111                         /// Modifies the `arg`, replacing it with a boxed expression
    112                         /// that matches `formal` under the current TyVarMap.
    113                         void boxParam( Expression *&arg, Type *formal, const TyVarMap &exprTyVars );
    114                         /// Box an argument of `appExpr` for each parameter in `function`
    115                         /// starting at `arg`.
    116                         /// `exprTyVars` is the function's type variables.
    117                         void boxParams( ApplicationExpr *appExpr, std::list< Expression *>::iterator arg, FunctionType *function, const TyVarMap &exprTyVars );
    118                         /// Boxes each assertion and inserts them into `appExpr` at
    119                         /// `arg`. `exprTyVars` is the function's type variables.
    120                         void addInferredParams( ApplicationExpr *appExpr, std::list< Expression *>::iterator arg, FunctionType *functionType, const TyVarMap &tyVars );
     111                        Expression *addDynRetParam( ApplicationExpr *appExpr, Type *polyType, std::list< Expression *>::iterator &arg );
     112                        Expression *applyAdapter( ApplicationExpr *appExpr, FunctionType *function, std::list< Expression *>::iterator &arg, const TyVarMap &exprTyVars );
     113                        void boxParam( Type *formal, Expression *&arg, const TyVarMap &exprTyVars );
     114                        void boxParams( ApplicationExpr *appExpr, FunctionType *function, std::list< Expression *>::iterator &arg, const TyVarMap &exprTyVars );
     115                        void addInferredParams( ApplicationExpr *appExpr, FunctionType *functionType, std::list< Expression *>::iterator &arg, const TyVarMap &tyVars );
    121116                        /// Stores assignment operators from assertion list in local map of assignment operations
    122117                        void passAdapters( ApplicationExpr *appExpr, FunctionType *functionType, const TyVarMap &exprTyVars );
    123                         /// Creates an adapter definition from `adaptee` to `realType`, using
    124                         /// `mangleName` as the base name for the adapter. `tyVars` is the map of
    125                         /// type variables for the function type of the adapted expression.
    126                         FunctionDecl *makeAdapter( FunctionType const *adaptee, FunctionType *realType, const std::string &mangleName, const TyVarMap &tyVars );
     118                        FunctionDecl *makeAdapter( FunctionType *adaptee, FunctionType *realType, const std::string &mangleName, const TyVarMap &tyVars );
    127119                        /// Replaces intrinsic operator functions with their arithmetic desugaring
    128120                        Expression *handleIntrinsics( ApplicationExpr *appExpr );
     
    190182                        ObjectDecl *makeVar( const std::string &name, Type *type, Initializer *init = 0 );
    191183                        /// returns true if the type has a dynamic layout; such a layout will be stored in appropriately-named local variables when the function returns
    192                         bool findGeneric( Type const *ty );
     184                        bool findGeneric( Type *ty );
    193185                        /// adds type parameters to the layout call; will generate the appropriate parameters if needed
    194186                        void addOtypeParamsToLayoutCall( UntypedExpr *layoutCall, const std::list< Type* > &otypeParams );
     
    229221        } // anonymous namespace
    230222
     223        /// version of mutateAll with special handling for translation unit so you can check the end of the prelude when debugging
     224        template< typename MutatorType >
     225        inline void mutateTranslationUnit( std::list< Declaration* > &translationUnit, MutatorType &mutator ) {
     226                bool seenIntrinsic = false;
     227                SemanticErrorException errors;
     228                for ( typename std::list< Declaration* >::iterator i = translationUnit.begin(); i != translationUnit.end(); ++i ) {
     229                        try {
     230                                if ( *i ) {
     231                                        if ( (*i)->get_linkage() == LinkageSpec::Intrinsic ) {
     232                                                seenIntrinsic = true;
     233                                        } else if ( seenIntrinsic ) {
     234                                                seenIntrinsic = false; // break on this line when debugging for end of prelude
     235                                        }
     236
     237                                        *i = dynamic_cast< Declaration* >( (*i)->acceptMutator( mutator ) );
     238                                        assert( *i );
     239                                } // if
     240                        } catch( SemanticErrorException &e ) {
     241                                errors.append( e );
     242                        } // try
     243                } // for
     244                if ( ! errors.isEmpty() ) {
     245                        throw errors;
     246                } // if
     247        }
     248
    231249        void box( std::list< Declaration *>& translationUnit ) {
    232250                PassVisitor<LayoutFunctionBuilder> layoutBuilder;
     
    245263        ////////////////////////////////// LayoutFunctionBuilder ////////////////////////////////////////////
    246264
     265        void LayoutFunctionBuilder::previsit( FunctionDecl *functionDecl ) {
     266                visit_children = false;
     267                maybeAccept( functionDecl->get_functionType(), *visitor );
     268                ++functionNesting;
     269                maybeAccept( functionDecl->get_statements(), *visitor );
     270                --functionNesting;
     271        }
     272
    247273        /// Get a list of type declarations that will affect a layout function
    248274        std::list< TypeDecl* > takeOtypeOnly( std::list< TypeDecl* > &decls ) {
    249275                std::list< TypeDecl * > otypeDecls;
    250276
    251                 for ( TypeDecl * const decl : decls ) {
    252                         if ( decl->isComplete() ) {
    253                                 otypeDecls.push_back( decl );
     277                for ( std::list< TypeDecl* >::const_iterator decl = decls.begin(); decl != decls.end(); ++decl ) {
     278                        if ( (*decl)->isComplete() ) {
     279                                otypeDecls.push_back( *decl );
    254280                        }
    255281                }
     
    262288                BasicType sizeAlignType( Type::Qualifiers(), BasicType::LongUnsignedInt );
    263289
    264                 for ( TypeDecl * const param : otypeParams ) {
    265                         TypeInstType paramType( Type::Qualifiers(), param->get_name(), param );
     290                for ( std::list< TypeDecl* >::const_iterator param = otypeParams.begin(); param != otypeParams.end(); ++param ) {
     291                        TypeInstType paramType( Type::Qualifiers(), (*param)->get_name(), *param );
    266292                        std::string paramName = mangleType( &paramType );
    267293                        layoutFnType->get_parameters().push_back( new ObjectDecl( sizeofName( paramName ), Type::StorageClasses(), LinkageSpec::Cforall, 0, sizeAlignType.clone(), 0 ) );
     
    271297
    272298        /// Builds a layout function declaration
    273         FunctionDecl *buildLayoutFunctionDecl( AggregateDecl *typeDecl, bool isInFunction, FunctionType *layoutFnType ) {
     299        FunctionDecl *buildLayoutFunctionDecl( AggregateDecl *typeDecl, unsigned int functionNesting, FunctionType *layoutFnType ) {
    274300                // Routines at global scope marked "static" to prevent multiple definitions is separate translation units
    275301                // because each unit generates copies of the default routines for each aggregate.
    276302                FunctionDecl *layoutDecl = new FunctionDecl( layoutofName( typeDecl ),
    277                                                                                                          isInFunction ? Type::StorageClasses() : Type::StorageClasses( Type::Static ),
     303                                                                                                         functionNesting > 0 ? Type::StorageClasses() : Type::StorageClasses( Type::Static ),
    278304                                                                                                         LinkageSpec::AutoGen, layoutFnType, new CompoundStmt(),
    279305                                                                                                         std::list< Attribute * >(), Type::FuncSpecifiers( Type::Inline ) );
    280306                layoutDecl->fixUniqueId();
    281307                return layoutDecl;
     308        }
     309
     310        /// Makes a unary operation
     311        Expression *makeOp( const std::string &name, Expression *arg ) {
     312                UntypedExpr *expr = new UntypedExpr( new NameExpr( name ) );
     313                expr->args.push_back( arg );
     314                return expr;
    282315        }
    283316
     
    347380
    348381                // build function decl
    349                 FunctionDecl *layoutDecl = buildLayoutFunctionDecl( structDecl, isInFunction(), layoutFnType );
     382                FunctionDecl *layoutDecl = buildLayoutFunctionDecl( structDecl, functionNesting, layoutFnType );
    350383
    351384                // calculate struct layout in function body
     
    354387                addExpr( layoutDecl->get_statements(), makeOp( "?=?", derefVar( sizeParam ), new ConstantExpr( Constant::from_ulong( 0 ) ) ) );
    355388                addExpr( layoutDecl->get_statements(), makeOp( "?=?", derefVar( alignParam ), new ConstantExpr( Constant::from_ulong( 1 ) ) ) );
    356                 for ( auto index_member : enumerate( structDecl->members ) ) {
    357                         DeclarationWithType *dwt = dynamic_cast< DeclarationWithType * >( index_member.val );
     389                unsigned long n_members = 0;
     390                bool firstMember = true;
     391                for ( Declaration* member : structDecl->get_members() ) {
     392                        DeclarationWithType *dwt = dynamic_cast< DeclarationWithType * >( member );
    358393                        assert( dwt );
    359394                        Type *memberType = dwt->get_type();
    360395
    361                         if ( 0 < index_member.idx ) {
     396                        if ( firstMember ) {
     397                                firstMember = false;
     398                        } else {
    362399                                // make sure all members after the first (automatically aligned at 0) are properly padded for alignment
    363400                                addStmt( layoutDecl->get_statements(), makeAlignTo( derefVar( sizeParam ), new AlignofExpr( memberType->clone() ) ) );
     
    365402
    366403                        // place current size in the current offset index
    367                         addExpr( layoutDecl->get_statements(), makeOp( "?=?", makeOp( "?[?]", new VariableExpr( offsetParam ), new ConstantExpr( Constant::from_ulong( index_member.idx ) ) ),
     404                        addExpr( layoutDecl->get_statements(), makeOp( "?=?", makeOp( "?[?]", new VariableExpr( offsetParam ), new ConstantExpr( Constant::from_ulong( n_members ) ) ),
    368405                                                                              derefVar( sizeParam ) ) );
     406                        ++n_members;
    369407
    370408                        // add member size to current size
     
    401439
    402440                // build function decl
    403                 FunctionDecl *layoutDecl = buildLayoutFunctionDecl( unionDecl, isInFunction(), layoutFnType );
     441                FunctionDecl *layoutDecl = buildLayoutFunctionDecl( unionDecl, functionNesting, layoutFnType );
    404442
    405443                // calculate union layout in function body
    406444                addExpr( layoutDecl->get_statements(), makeOp( "?=?", derefVar( sizeParam ), new ConstantExpr( Constant::from_ulong( 1 ) ) ) );
    407445                addExpr( layoutDecl->get_statements(), makeOp( "?=?", derefVar( alignParam ), new ConstantExpr( Constant::from_ulong( 1 ) ) ) );
    408                 for ( Declaration * const member : unionDecl->members ) {
    409                         DeclarationWithType *dwt = dynamic_cast< DeclarationWithType * >( member );
     446                for ( std::list< Declaration* >::const_iterator member = unionDecl->get_members().begin(); member != unionDecl->get_members().end(); ++member ) {
     447                        DeclarationWithType *dwt = dynamic_cast< DeclarationWithType * >( *member );
    410448                        assert( dwt );
    411449                        Type *memberType = dwt->get_type();
     
    426464
    427465        namespace {
    428                 std::string makePolyMonoSuffix( FunctionType const * function, const TyVarMap &tyVars ) {
     466                std::string makePolyMonoSuffix( FunctionType * function, const TyVarMap &tyVars ) {
    429467                        std::stringstream name;
    430468
     
    435473                        // to take those polymorphic types as pointers. Therefore, there can be two different functions
    436474                        // with the same mangled name, so we need to further mangle the names.
    437                         for ( DeclarationWithType const * const ret : function->returnVals ) {
    438                                 if ( isPolyType( ret->get_type(), tyVars ) ) {
     475                        for ( std::list< DeclarationWithType *>::iterator retval = function->get_returnVals().begin(); retval != function->get_returnVals().end(); ++retval ) {
     476                                if ( isPolyType( (*retval)->get_type(), tyVars ) ) {
    439477                                        name << "P";
    440478                                } else {
     
    443481                        }
    444482                        name << "_";
    445                         for ( DeclarationWithType const * const arg : function->parameters ) {
    446                                 if ( isPolyType( arg->get_type(), tyVars ) ) {
     483                        std::list< DeclarationWithType *> &paramList = function->get_parameters();
     484                        for ( std::list< DeclarationWithType *>::iterator arg = paramList.begin(); arg != paramList.end(); ++arg ) {
     485                                if ( isPolyType( (*arg)->get_type(), tyVars ) ) {
    447486                                        name << "P";
    448487                                } else {
     
    453492                }
    454493
    455                 std::string mangleAdapterName( FunctionType const * function, const TyVarMap &tyVars ) {
     494                std::string mangleAdapterName( FunctionType * function, const TyVarMap &tyVars ) {
    456495                        return SymTab::Mangler::mangle( function ) + makePolyMonoSuffix( function, tyVars );
    457496                }
     
    460499                        return "_adapter" + mangleName;
    461500                }
    462 
    463                 /// Replaces a polymorphic type with its concrete equivalant under the current environment (returns itself if concrete).
    464                 /// If `doClone` is set to false, will not clone interior types
    465                 Type *replaceWithConcrete( Type *type, TypeSubstitution const * env, bool doClone = true );
    466501
    467502                Pass1::Pass1() : tempNamer( "_temp" ) {}
     
    489524
    490525                                std::list< DeclarationWithType *> &paramList = functionType->parameters;
    491                                 std::list< FunctionType const *> functions;
    492                                 for ( TypeDecl * const tyVar : functionType->forall ) {
    493                                         for ( DeclarationWithType * const assert : tyVar->assertions ) {
    494                                                 findFunction( assert->get_type(), functions, scopeTyVars, needsAdapter );
     526                                std::list< FunctionType *> functions;
     527                                for ( Type::ForallList::iterator tyVar = functionType->forall.begin(); tyVar != functionType->forall.end(); ++tyVar ) {
     528                                        for ( std::list< DeclarationWithType *>::iterator assert = (*tyVar)->assertions.begin(); assert != (*tyVar)->assertions.end(); ++assert ) {
     529                                                findFunction( (*assert)->get_type(), functions, scopeTyVars, needsAdapter );
    495530                                        } // for
    496531                                } // for
    497                                 for ( DeclarationWithType * const arg : paramList ) {
    498                                         findFunction( arg->get_type(), functions, scopeTyVars, needsAdapter );
     532                                for ( std::list< DeclarationWithType *>::iterator arg = paramList.begin(); arg != paramList.end(); ++arg ) {
     533                                        findFunction( (*arg)->get_type(), functions, scopeTyVars, needsAdapter );
    499534                                } // for
    500535
    501                                 for ( FunctionType const * const funType : functions ) {
    502                                         std::string mangleName = mangleAdapterName( funType, scopeTyVars );
     536                                for ( std::list< FunctionType *>::iterator funType = functions.begin(); funType != functions.end(); ++funType ) {
     537                                        std::string mangleName = mangleAdapterName( *funType, scopeTyVars );
    503538                                        if ( adapters.find( mangleName ) == adapters.end() ) {
    504539                                                std::string adapterName = makeAdapterName( mangleName );
    505                                                 adapters.insert( std::pair< std::string, DeclarationWithType *>( mangleName, new ObjectDecl( adapterName, Type::StorageClasses(), LinkageSpec::C, nullptr, new PointerType( Type::Qualifiers(), makeAdapterType( funType, scopeTyVars ) ), nullptr ) ) );
     540                                                adapters.insert( std::pair< std::string, DeclarationWithType *>( mangleName, new ObjectDecl( adapterName, Type::StorageClasses(), LinkageSpec::C, nullptr, new PointerType( Type::Qualifiers(), makeAdapterType( *funType, scopeTyVars ) ), nullptr ) ) );
    506541                                        } // if
    507542                                } // for
     
    558593                }
    559594
    560                 std::list< Expression *>::iterator Pass1::passTypeVars( ApplicationExpr *appExpr, Type *polyRetType, const TyVarMap &exprTyVars ) {
    561                         assert( env );
    562                         std::list< Expression *>::iterator arg = appExpr->args.begin();
     595                void Pass1::passTypeVars( ApplicationExpr *appExpr, Type *polyRetType, std::list< Expression *>::iterator &arg, const TyVarMap &exprTyVars ) {
    563596                        // pass size/align for type variables
    564                         for ( std::pair<std::string, TypeDecl::Data> const & tyParam : exprTyVars ) {
     597                        for ( TyVarMap::const_iterator tyParm = exprTyVars.begin(); tyParm != exprTyVars.end(); ++tyParm ) {
    565598                                ResolvExpr::EqvClass eqvClass;
    566                                 if ( tyParam.second.isComplete ) {
    567                                         Type *concrete = env->lookup( tyParam.first );
    568                                         // If there is an unbound type variable, it should have detected already.
    569                                         assertf( concrete, "Unbound type variable: %s in: %s",
    570                                                 toCString( tyParam.first ), toCString( *env ) );
    571 
    572                                         arg = appExpr->get_args().insert( arg, new SizeofExpr( concrete->clone() ) );
    573                                         arg++;
    574                                         arg = appExpr->get_args().insert( arg, new AlignofExpr( concrete->clone() ) );
    575                                         arg++;
     599                                assert( env );
     600                                if ( tyParm->second.isComplete ) {
     601                                        Type *concrete = env->lookup( tyParm->first );
     602                                        if ( concrete ) {
     603                                                arg = appExpr->get_args().insert( arg, new SizeofExpr( concrete->clone() ) );
     604                                                arg++;
     605                                                arg = appExpr->get_args().insert( arg, new AlignofExpr( concrete->clone() ) );
     606                                                arg++;
     607                                        } else {
     608                                                // xxx - should this be an assertion?
     609                                                SemanticError( appExpr, toString( *env, "\nunbound type variable: ", tyParm->first, " in application " ) );
     610                                        } // if
    576611                                } // if
    577612                        } // for
    578613
    579614                        // add size/align for generic types to parameter list
    580                         if ( ! appExpr->get_function()->result ) return arg;
     615                        if ( ! appExpr->get_function()->result ) return;
    581616                        FunctionType *funcType = getFunctionType( appExpr->get_function()->get_result() );
    582617                        assert( funcType );
    583618
    584                         // These iterators don't advance in unison.
    585619                        std::list< DeclarationWithType* >::const_iterator fnParm = funcType->get_parameters().begin();
    586620                        std::list< Expression* >::const_iterator fnArg = arg;
     
    589623                        // a polymorphic return type may need to be added to the argument list
    590624                        if ( polyRetType ) {
    591                                 Type *concRetType = replaceWithConcrete( polyRetType, env );
     625                                Type *concRetType = replaceWithConcrete( appExpr, polyRetType );
    592626                                passArgTypeVars( appExpr, polyRetType, concRetType, arg, exprTyVars, seenTypes );
    593627                                ++fnArg; // skip the return parameter in the argument list
     
    600634                                passArgTypeVars( appExpr, (*fnParm)->get_type(), argType, arg, exprTyVars, seenTypes );
    601635                        }
    602                         return arg;
    603636                }
    604637
     
    609642                }
    610643
    611                 Expression *Pass1::addRetParam( ApplicationExpr *appExpr, Type *retType ) {
     644                Expression *Pass1::addRetParam( ApplicationExpr *appExpr, Type *retType, std::list< Expression *>::iterator &arg ) {
    612645                        // Create temporary to hold return value of polymorphic function and produce that temporary as a result
    613646                        // using a comma expression.
     
    629662                                paramExpr = new AddressExpr( paramExpr );
    630663                        } // if
    631                         // Add argument to function call.
    632                         appExpr->args.push_front( paramExpr );
     664                        arg = appExpr->args.insert( arg, paramExpr ); // add argument to function call
     665                        arg++;
    633666                        // Build a comma expression to call the function and emulate a normal return.
    634667                        CommaExpr *commaExpr = new CommaExpr( appExpr, retExpr );
     
    638671                }
    639672
    640                 /// Replaces all the type parameters of a generic type with their concrete equivalents under the current environment
    641                 void replaceParametersWithConcrete( std::list< Expression* >& params, TypeSubstitution const * env ) {
    642                         for ( Expression * const param : params ) {
    643                                 TypeExpr *paramType = dynamic_cast< TypeExpr* >( param );
     673                void Pass1::replaceParametersWithConcrete( ApplicationExpr *appExpr, std::list< Expression* >& params ) {
     674                        for ( std::list< Expression* >::iterator param = params.begin(); param != params.end(); ++param ) {
     675                                TypeExpr *paramType = dynamic_cast< TypeExpr* >( *param );
    644676                                assertf(paramType, "Aggregate parameters should be type expressions");
    645                                 paramType->set_type( replaceWithConcrete( paramType->get_type(), env, false ) );
    646                         }
    647                 }
    648 
    649                 // See forward definition.
    650                 Type *replaceWithConcrete( Type *type, TypeSubstitution const * env, bool doClone ) {
    651                         assert( env );
     677                                paramType->set_type( replaceWithConcrete( appExpr, paramType->get_type(), false ) );
     678                        }
     679                }
     680
     681                Type *Pass1::replaceWithConcrete( ApplicationExpr *appExpr, Type *type, bool doClone ) {
    652682                        if ( TypeInstType *typeInst = dynamic_cast< TypeInstType * >( type ) ) {
    653683                                Type *concrete = env->lookup( typeInst->get_name() );
     
    660690                                        structType = structType->clone();
    661691                                }
    662                                 replaceParametersWithConcrete( structType->get_parameters(), env );
     692                                replaceParametersWithConcrete( appExpr, structType->get_parameters() );
    663693                                return structType;
    664694                        } else if ( UnionInstType *unionType = dynamic_cast< UnionInstType* >( type ) ) {
     
    666696                                        unionType = unionType->clone();
    667697                                }
    668                                 replaceParametersWithConcrete( unionType->get_parameters(), env );
     698                                replaceParametersWithConcrete( appExpr, unionType->get_parameters() );
    669699                                return unionType;
    670700                        }
     
    672702                }
    673703
    674                 Expression *Pass1::addDynRetParam( ApplicationExpr *appExpr, Type *dynType ) {
    675                         Type *concrete = replaceWithConcrete( dynType, env );
     704                Expression *Pass1::addDynRetParam( ApplicationExpr *appExpr, Type *dynType, std::list< Expression *>::iterator &arg ) {
     705                        assert( env );
     706                        Type *concrete = replaceWithConcrete( appExpr, dynType );
    676707                        // add out-parameter for return value
    677                         return addRetParam( appExpr, concrete );
    678                 }
    679 
    680                 Expression *Pass1::applyAdapter( ApplicationExpr *appExpr, FunctionType *function ) {
     708                        return addRetParam( appExpr, concrete, arg );
     709                }
     710
     711                Expression *Pass1::applyAdapter( ApplicationExpr *appExpr, FunctionType *function, std::list< Expression *>::iterator &arg, const TyVarMap &tyVars ) {
    681712                        Expression *ret = appExpr;
    682713//                      if ( ! function->get_returnVals().empty() && isPolyType( function->get_returnVals().front()->get_type(), tyVars ) ) {
    683                         if ( isDynRet( function, scopeTyVars ) ) {
    684                                 ret = addRetParam( appExpr, function->returnVals.front()->get_type() );
     714                        if ( isDynRet( function, tyVars ) ) {
     715                                ret = addRetParam( appExpr, function->returnVals.front()->get_type(), arg );
    685716                        } // if
    686                         std::string mangleName = mangleAdapterName( function, scopeTyVars );
     717                        std::string mangleName = mangleAdapterName( function, tyVars );
    687718                        std::string adapterName = makeAdapterName( mangleName );
    688719
     
    693724
    694725                        return ret;
     726                }
     727
     728                void Pass1::boxParam( Type *param, Expression *&arg, const TyVarMap &exprTyVars ) {
     729                        assertf( arg->result, "arg does not have result: %s", toString( arg ).c_str() );
     730                        if ( ! needsBoxing( param, arg->result, exprTyVars, env ) ) return;
     731
     732                        if ( arg->get_lvalue() ) {
     733                                // argument expression may be CFA lvalue, but not C lvalue -- apply generalizedLvalue transformations.
     734                                // if ( VariableExpr * varExpr = dynamic_cast< VariableExpr * >( arg ) ) {
     735                                //      if ( dynamic_cast<ArrayType *>( varExpr->var->get_type() ) ){
     736                                //              // temporary hack - don't box arrays, because &arr is not the same as &arr[0]
     737                                //              return;
     738                                //      }
     739                                // }
     740                                arg =  generalizedLvalue( new AddressExpr( arg ) );
     741                                if ( ! ResolvExpr::typesCompatible( param, arg->get_result(), SymTab::Indexer() ) ) {
     742                                        // silence warnings by casting boxed parameters when the actual type does not match up with the formal type.
     743                                        arg = new CastExpr( arg, param->clone() );
     744                                }
     745                        } else {
     746                                // use type computed in unification to declare boxed variables
     747                                Type * newType = param->clone();
     748                                if ( env ) env->apply( newType );
     749                                ObjectDecl *newObj = ObjectDecl::newObject( tempNamer.newName(), newType, nullptr );
     750                                newObj->get_type()->get_qualifiers() = Type::Qualifiers(); // TODO: is this right???
     751                                stmtsToAddBefore.push_back( new DeclStmt( newObj ) );
     752                                UntypedExpr *assign = new UntypedExpr( new NameExpr( "?=?" ) ); // TODO: why doesn't this just use initialization syntax?
     753                                assign->get_args().push_back( new VariableExpr( newObj ) );
     754                                assign->get_args().push_back( arg );
     755                                stmtsToAddBefore.push_back( new ExprStmt( assign ) );
     756                                arg = new AddressExpr( new VariableExpr( newObj ) );
     757                        } // if
    695758                }
    696759
     
    728791                }
    729792
    730                 void Pass1::boxParam( Expression *&arg, Type *param, const TyVarMap &exprTyVars ) {
    731                         assertf( arg->result, "arg does not have result: %s", toString( arg ).c_str() );
    732                         addCast( arg, param, exprTyVars );
    733                         if ( ! needsBoxing( param, arg->result, exprTyVars, env ) ) return;
    734 
    735                         if ( arg->get_lvalue() ) {
    736                                 // argument expression may be CFA lvalue, but not C lvalue -- apply generalizedLvalue transformations.
    737                                 // if ( VariableExpr * varExpr = dynamic_cast< VariableExpr * >( arg ) ) {
    738                                 //      if ( dynamic_cast<ArrayType *>( varExpr->var->get_type() ) ){
    739                                 //              // temporary hack - don't box arrays, because &arr is not the same as &arr[0]
    740                                 //              return;
    741                                 //      }
    742                                 // }
    743                                 arg = generalizedLvalue( new AddressExpr( arg ) );
    744                                 if ( ! ResolvExpr::typesCompatible( param, arg->get_result(), SymTab::Indexer() ) ) {
    745                                         // silence warnings by casting boxed parameters when the actual type does not match up with the formal type.
    746                                         arg = new CastExpr( arg, param->clone() );
    747                                 }
    748                         } else {
    749                                 // use type computed in unification to declare boxed variables
    750                                 Type * newType = param->clone();
    751                                 if ( env ) env->apply( newType );
    752                                 ObjectDecl *newObj = makeTemporary( newType );
    753                                 // TODO: is this right??? (Why wouldn't it be?)
    754                                 newObj->get_type()->get_qualifiers() = Type::Qualifiers();
    755                                 // TODO: why doesn't this just use initialization syntax?
    756                                 // (Possibly to ensure code is run at the right time.)
    757                                 UntypedExpr *assign = new UntypedExpr( new NameExpr( "?=?" ) );
    758                                 assign->get_args().push_back( new VariableExpr( newObj ) );
    759                                 assign->get_args().push_back( arg );
    760                                 stmtsToAddBefore.push_back( new ExprStmt( assign ) );
    761                                 arg = new AddressExpr( new VariableExpr( newObj ) );
    762                         } // if
    763                 }
    764 
    765                 void Pass1::boxParams( ApplicationExpr *appExpr, std::list< Expression *>::iterator arg, FunctionType *function, const TyVarMap &exprTyVars ) {
    766                         for ( DeclarationWithType * param : function->parameters ) {
    767                                 assertf( arg != appExpr->args.end(), "boxParams: missing argument for param %s to %s in %s", toString( param ).c_str(), toString( function ).c_str(), toString( appExpr ).c_str() );
    768                                 boxParam( *arg, param->get_type(), exprTyVars );
    769                                 ++arg;
     793                void Pass1::boxParams( ApplicationExpr *appExpr, FunctionType *function, std::list< Expression *>::iterator &arg, const TyVarMap &exprTyVars ) {
     794                        for ( std::list< DeclarationWithType *>::const_iterator param = function->get_parameters().begin(); param != function->parameters.end(); ++param, ++arg ) {
     795                                assertf( arg != appExpr->args.end(), "boxParams: missing argument for param %s to %s in %s", toString( *param ).c_str(), toString( function ).c_str(), toString( appExpr ).c_str() );
     796                                addCast( *arg, (*param)->get_type(), exprTyVars );
     797                                boxParam( (*param)->get_type(), *arg, exprTyVars );
    770798                        } // for
    771799                }
    772800
    773                 void Pass1::addInferredParams( ApplicationExpr *appExpr, std::list< Expression *>::iterator arg, FunctionType *functionType, const TyVarMap &tyVars ) {
     801                void Pass1::addInferredParams( ApplicationExpr *appExpr, FunctionType *functionType, std::list< Expression *>::iterator &arg, const TyVarMap &tyVars ) {
    774802                        std::list< Expression *>::iterator cur = arg;
    775                         for ( TypeDecl * const tyVar : functionType->forall ) {
    776                                 for ( DeclarationWithType * const assert : tyVar->assertions ) {
    777                                         InferredParams::const_iterator inferParam = appExpr->inferParams.find( assert->get_uniqueId() );
    778                                         assertf( inferParam != appExpr->inferParams.end(), "addInferredParams missing inferred parameter: %s in: %s", toString( assert ).c_str(), toString( appExpr ).c_str() );
     803                        for ( Type::ForallList::iterator tyVar = functionType->get_forall().begin(); tyVar != functionType->get_forall().end(); ++tyVar ) {
     804                                for ( std::list< DeclarationWithType *>::iterator assert = (*tyVar)->assertions.begin(); assert != (*tyVar)->assertions.end(); ++assert ) {
     805                                        InferredParams::const_iterator inferParam = appExpr->inferParams.find( (*assert)->get_uniqueId() );
     806                                        assertf( inferParam != appExpr->inferParams.end(), "addInferredParams missing inferred parameter: %s in: %s", toString( *assert ).c_str(), toString( appExpr ).c_str() );
    779807                                        Expression *newExpr = inferParam->second.expr->clone();
    780                                         boxParam( newExpr, assert->get_type(), tyVars );
     808                                        addCast( newExpr, (*assert)->get_type(), tyVars );
     809                                        boxParam( (*assert)->get_type(), newExpr, tyVars );
    781810                                        appExpr->get_args().insert( cur, newExpr );
    782811                                } // for
     
    795824                }
    796825
    797                 FunctionType *makeAdapterType( FunctionType const *adaptee, const TyVarMap &tyVars ) {
     826                FunctionType *makeAdapterType( FunctionType *adaptee, const TyVarMap &tyVars ) {
    798827                        // actually make the adapter type
    799828                        FunctionType *adapter = adaptee->clone();
     
    805834                }
    806835
    807                 Expression *makeAdapterArg(
    808                                 DeclarationWithType *param,
    809                                 DeclarationWithType const *arg,
    810                                 DeclarationWithType const *realParam,
    811                                 const TyVarMap &tyVars ) {
     836                Expression *makeAdapterArg( DeclarationWithType *param, DeclarationWithType *arg, DeclarationWithType *realParam, const TyVarMap &tyVars ) {
    812837                        assert( param );
    813838                        assert( arg );
    814                         if ( isPolyType( realParam->get_type(), tyVars )
    815                                         && ! isPolyType( arg->get_type() ) ) {
    816                                 UntypedExpr *deref = new UntypedExpr( new NameExpr( "*?" ) );
    817                                 deref->args.push_back( new CastExpr( new VariableExpr( param ), new PointerType( Type::Qualifiers(), arg->get_type()->clone() ) ) );
    818                                 deref->result = arg->get_type()->clone();
    819                                 return deref;
     839                        if ( isPolyType( realParam->get_type(), tyVars ) ) {
     840                                if ( ! isPolyType( arg->get_type() ) ) {
     841                                        UntypedExpr *deref = new UntypedExpr( new NameExpr( "*?" ) );
     842                                        deref->args.push_back( new CastExpr( new VariableExpr( param ), new PointerType( Type::Qualifiers(), arg->get_type()->clone() ) ) );
     843                                        deref->result = arg->get_type()->clone();
     844                                        return deref;
     845                                } // if
    820846                        } // if
    821847                        return new VariableExpr( param );
    822848                }
    823849
    824                 void addAdapterParams(
    825                                 ApplicationExpr *adapteeApp,
    826                                 std::list< DeclarationWithType *>::const_iterator arg,
    827                                 std::list< DeclarationWithType *>::const_iterator param,
    828                                 std::list< DeclarationWithType *>::const_iterator paramEnd,
    829                                 std::list< DeclarationWithType *>::const_iterator realParam,
    830                                 const TyVarMap &tyVars ) {
     850                void addAdapterParams( ApplicationExpr *adapteeApp, std::list< DeclarationWithType *>::iterator arg, std::list< DeclarationWithType *>::iterator param, std::list< DeclarationWithType *>::iterator paramEnd, std::list< DeclarationWithType *>::iterator realParam, const TyVarMap &tyVars ) {
    831851                        UniqueName paramNamer( "_p" );
    832852                        for ( ; param != paramEnd; ++param, ++arg, ++realParam ) {
     
    839859                }
    840860
    841                 FunctionDecl *Pass1::makeAdapter( FunctionType const *adaptee, FunctionType *realType, const std::string &mangleName, const TyVarMap &tyVars ) {
     861                FunctionDecl *Pass1::makeAdapter( FunctionType *adaptee, FunctionType *realType, const std::string &mangleName, const TyVarMap &tyVars ) {
    842862                        FunctionType *adapterType = makeAdapterType( adaptee, tyVars );
    843863                        adapterType = ScrubTyVars::scrub( adapterType, tyVars );
     
    856876                        Statement *bodyStmt;
    857877
    858                         for ( auto tys : group_iterate( realType->forall, adapterType->forall, adaptee->forall ) ) {
    859                                 TypeDecl * tyArg = std::get<0>( tys );
    860                                 TypeDecl * tyParam = std::get<1>( tys );
    861                                 TypeDecl * realTyParam = std::get<2>( tys );
    862                                 for ( auto asserts : group_iterate( tyArg->assertions, tyParam->assertions, realTyParam->assertions ) ) {
    863                                         DeclarationWithType * assertArg = std::get<0>( asserts );
    864                                         DeclarationWithType * assertParam = std::get<1>( asserts );
    865                                         DeclarationWithType * realAssertParam = std::get<2>( asserts );
    866                                         adapteeApp->args.push_back( makeAdapterArg( assertParam, assertArg, realAssertParam, tyVars ) );
     878                        Type::ForallList::iterator tyArg = realType->get_forall().begin();
     879                        Type::ForallList::iterator tyParam = adapterType->get_forall().begin();
     880                        Type::ForallList::iterator realTyParam = adaptee->get_forall().begin();
     881                        for ( ; tyParam != adapterType->get_forall().end(); ++tyArg, ++tyParam, ++realTyParam ) {
     882                                assert( tyArg != realType->get_forall().end() );
     883                                std::list< DeclarationWithType *>::iterator assertArg = (*tyArg)->get_assertions().begin();
     884                                std::list< DeclarationWithType *>::iterator assertParam = (*tyParam)->get_assertions().begin();
     885                                std::list< DeclarationWithType *>::iterator realAssertParam = (*realTyParam)->get_assertions().begin();
     886                                for ( ; assertParam != (*tyParam)->get_assertions().end(); ++assertArg, ++assertParam, ++realAssertParam ) {
     887                                        assert( assertArg != (*tyArg)->get_assertions().end() );
     888                                        adapteeApp->get_args().push_back( makeAdapterArg( *assertParam, *assertArg, *realAssertParam, tyVars ) );
    867889                                } // for
    868890                        } // for
    869891
    870                         std::list< DeclarationWithType *>::const_iterator arg = realType->parameters.begin();
    871                         std::list< DeclarationWithType *>::const_iterator param = adapterType->parameters.begin();
    872                         std::list< DeclarationWithType *>::const_iterator realParam = adaptee->parameters.begin();
     892                        std::list< DeclarationWithType *>::iterator arg = realType->get_parameters().begin();
     893                        std::list< DeclarationWithType *>::iterator param = adapterType->get_parameters().begin();
     894                        std::list< DeclarationWithType *>::iterator realParam = adaptee->get_parameters().begin();
    873895                        param++;                // skip adaptee parameter in the adapter type
    874896                        if ( realType->get_returnVals().empty() ) {
     
    876898                                addAdapterParams( adapteeApp, arg, param, adapterType->get_parameters().end(), realParam, tyVars );
    877899                                bodyStmt = new ExprStmt( adapteeApp );
    878                         } else if ( isDynType( adaptee->returnVals.front()->get_type(), tyVars ) ) {
     900                        } else if ( isDynType( adaptee->get_returnVals().front()->get_type(), tyVars ) ) {
    879901                                // return type T
    880902                                if ( (*param)->get_name() == "" ) {
     
    901923                void Pass1::passAdapters( ApplicationExpr * appExpr, FunctionType * functionType, const TyVarMap & exprTyVars ) {
    902924                        // collect a list of function types passed as parameters or implicit parameters (assertions)
    903                         std::list<FunctionType const *> functions;
    904                         for ( TypeDecl * const tyVar : functionType->get_forall() ) {
    905                                 for ( DeclarationWithType * const assert : tyVar->get_assertions() ) {
    906                                         findFunction( assert->get_type(), functions, exprTyVars, needsAdapter );
     925                        std::list< DeclarationWithType *> &paramList = functionType->get_parameters();
     926                        std::list< FunctionType *> functions;
     927                        for ( Type::ForallList::iterator tyVar = functionType->get_forall().begin(); tyVar != functionType->get_forall().end(); ++tyVar ) {
     928                                for ( std::list< DeclarationWithType *>::iterator assert = (*tyVar)->get_assertions().begin(); assert != (*tyVar)->get_assertions().end(); ++assert ) {
     929                                        findFunction( (*assert)->get_type(), functions, exprTyVars, needsAdapter );
    907930                                } // for
    908931                        } // for
    909                         for ( DeclarationWithType * const arg : functionType->get_parameters() ) {
    910                                 findFunction( arg->get_type(), functions, exprTyVars, needsAdapter );
     932                        for ( std::list< DeclarationWithType *>::iterator arg = paramList.begin(); arg != paramList.end(); ++arg ) {
     933                                findFunction( (*arg)->get_type(), functions, exprTyVars, needsAdapter );
    911934                        } // for
    912935
     
    915938                        std::set< std::string > adaptersDone;
    916939
    917                         for ( FunctionType const * const funType : functions ) {
    918                                 FunctionType *originalFunction = funType->clone();
    919                                 FunctionType *realFunction = funType->clone();
     940                        for ( std::list< FunctionType *>::iterator funType = functions.begin(); funType != functions.end(); ++funType ) {
     941                                FunctionType *originalFunction = (*funType)->clone();
     942                                FunctionType *realFunction = (*funType)->clone();
    920943                                std::string mangleName = SymTab::Mangler::mangle( realFunction );
    921944
     
    935958                                        if ( adapter == adapters.end() ) {
    936959                                                // adapter has not been created yet in the current scope, so define it
    937                                                 FunctionDecl *newAdapter = makeAdapter( funType, realFunction, mangleName, exprTyVars );
     960                                                FunctionDecl *newAdapter = makeAdapter( *funType, realFunction, mangleName, exprTyVars );
    938961                                                std::pair< AdapterIter, bool > answer = adapters.insert( std::pair< std::string, DeclarationWithType *>( mangleName, newAdapter ) );
    939962                                                adapter = answer.first;
     
    949972
    950973                Expression *makeIncrDecrExpr( ApplicationExpr *appExpr, Type *polyType, bool isIncr ) {
    951                         NameExpr *opExpr = new NameExpr( ( isIncr ) ? "?+=?" : "?-=?" );
     974                        NameExpr *opExpr;
     975                        if ( isIncr ) {
     976                                opExpr = new NameExpr( "?+=?" );
     977                        } else {
     978                                opExpr = new NameExpr( "?-=?" );
     979                        } // if
    952980                        UntypedExpr *addAssign = new UntypedExpr( opExpr );
    953981                        if ( AddressExpr *address = dynamic_cast< AddressExpr *>( appExpr->get_args().front() ) ) {
     
    10921120                Expression *Pass1::postmutate( ApplicationExpr *appExpr ) {
    10931121                        // std::cerr << "mutate appExpr: " << InitTweak::getFunctionName( appExpr ) << std::endl;
    1094                         // for ( auto tyVar : scopeTyVars ) {
    1095                         //      std::cerr << tyVar.first << " ";
     1122                        // for ( TyVarMap::iterator i = scopeTyVars.begin(); i != scopeTyVars.end(); ++i ) {
     1123                        //      std::cerr << i->first << " ";
    10961124                        // }
    10971125                        // std::cerr << "\n";
     
    11061134
    11071135                        Expression *ret = appExpr;
     1136
     1137                        std::list< Expression *>::iterator arg = appExpr->get_args().begin();
    11081138                        std::list< Expression *>::iterator paramBegin = appExpr->get_args().begin();
    11091139
     
    11261156                                // std::cerr << "dynRetType: " << dynRetType << std::endl;
    11271157                                Type *concRetType = appExpr->get_result()->isVoid() ? nullptr : appExpr->get_result();
    1128                                 ret = addDynRetParam( appExpr, concRetType ); // xxx - used to use dynRetType instead of concRetType
     1158                                ret = addDynRetParam( appExpr, concRetType, arg ); // xxx - used to use dynRetType instead of concRetType
    11291159                        } else if ( needsAdapter( function, scopeTyVars ) && ! needsAdapter( function, exprTyVars) ) { // xxx - exprTyVars is used above...?
    11301160                                // xxx - the ! needsAdapter check may be incorrect. It seems there is some situation where an adapter is applied where it shouldn't be, and this fixes it for some cases. More investigation is needed.
     
    11341164                                // std::cerr << *env << std::endl;
    11351165                                // change the application so it calls the adapter rather than the passed function
    1136                                 ret = applyAdapter( appExpr, function );
     1166                                ret = applyAdapter( appExpr, function, arg, scopeTyVars );
    11371167                        } // if
    1138 
    1139                         Type *concRetType = replaceWithConcrete( dynRetType, env );
    1140                         std::list< Expression *>::iterator arg =
    1141                                 passTypeVars( appExpr, concRetType, exprTyVars ); // xxx - used to use dynRetType instead of concRetType; this changed so that the correct type paramaters are passed for return types (it should be the concrete type's parameters, not the formal type's)
    1142                         addInferredParams( appExpr, arg, function, exprTyVars );
    1143 
    1144                         // This needs to point at the original first argument.
    1145                         boxParams( appExpr, paramBegin, function, exprTyVars );
    1146 
     1168                        arg = appExpr->get_args().begin();
     1169
     1170                        Type *concRetType = replaceWithConcrete( appExpr, dynRetType );
     1171                        passTypeVars( appExpr, concRetType, arg, exprTyVars ); // xxx - used to use dynRetType instead of concRetType; this changed so that the correct type paramaters are passed for return types (it should be the concrete type's parameters, not the formal type's)
     1172                        addInferredParams( appExpr, function, arg, exprTyVars );
     1173
     1174                        arg = paramBegin;
     1175
     1176                        boxParams( appExpr, function, arg, exprTyVars );
    11471177                        passAdapters( appExpr, function, exprTyVars );
    11481178
     
    11501180                }
    11511181
    1152                 bool isPolyDeref( UntypedExpr const * expr, TyVarMap const & scopeTyVars, TypeSubstitution const * env ) {
     1182                Expression * Pass1::postmutate( UntypedExpr *expr ) {
    11531183                        if ( expr->result && isPolyType( expr->result, scopeTyVars, env ) ) {
    1154                                 if ( auto name = dynamic_cast<NameExpr const *>( expr->function ) ) {
     1184                                if ( NameExpr *name = dynamic_cast< NameExpr *>( expr->function ) ) {
    11551185                                        if ( name->name == "*?" ) {
    1156                                                 return true;
     1186                                                Expression *ret = expr->args.front();
     1187                                                expr->args.clear();
     1188                                                delete expr;
     1189                                                return ret;
    11571190                                        } // if
    11581191                                } // if
    11591192                        } // if
    1160                         return false;
    1161                 }
    1162 
    1163                 Expression * Pass1::postmutate( UntypedExpr *expr ) {
    1164                         if ( isPolyDeref( expr, scopeTyVars, env ) ) {
    1165                                 Expression *ret = expr->args.front();
    1166                                 expr->args.clear();
    1167                                 delete expr;
    1168                                 return ret;
    1169                         }
    11701193                        return expr;
    11711194                }
     
    11771200                        bool needs = false;
    11781201                        if ( UntypedExpr *expr = dynamic_cast< UntypedExpr *>( addrExpr->arg ) ) {
    1179                                 if ( isPolyDeref( expr, scopeTyVars, env ) ) {
    1180                                         if ( ApplicationExpr * appExpr = dynamic_cast< ApplicationExpr * >( expr->args.front() ) ) {
    1181                                                 assert( appExpr->function->result );
    1182                                                 FunctionType *function = getFunctionType( appExpr->function->result );
    1183                                                 assert( function );
    1184                                                 needs = needsAdapter( function, scopeTyVars );
     1202                                if ( expr->result && isPolyType( expr->result, scopeTyVars, env ) ) {
     1203                                        if ( NameExpr *name = dynamic_cast< NameExpr *>( expr->function ) ) {
     1204                                                if ( name->name == "*?" ) {
     1205                                                        if ( ApplicationExpr * appExpr = dynamic_cast< ApplicationExpr * >( expr->args.front() ) ) {
     1206                                                                assert( appExpr->function->result );
     1207                                                                FunctionType *function = getFunctionType( appExpr->function->result );
     1208                                                                assert( function );
     1209                                                                needs = needsAdapter( function, scopeTyVars );
     1210                                                        } // if
     1211                                                } // if
    11851212                                        } // if
    11861213                                } // if
     
    12331260                void Pass2::addAdapters( FunctionType *functionType ) {
    12341261                        std::list< DeclarationWithType *> &paramList = functionType->parameters;
    1235                         std::list< FunctionType const *> functions;
    1236                         for ( DeclarationWithType * const arg : functionType->parameters ) {
    1237                                 Type *orig = arg->get_type();
     1262                        std::list< FunctionType *> functions;
     1263                        for ( std::list< DeclarationWithType *>::iterator arg = paramList.begin(); arg != paramList.end(); ++arg ) {
     1264                                Type *orig = (*arg)->get_type();
    12381265                                findAndReplaceFunction( orig, functions, scopeTyVars, needsAdapter );
    1239                                 arg->set_type( orig );
     1266                                (*arg)->set_type( orig );
    12401267                        }
    12411268                        std::set< std::string > adaptersDone;
    1242                         for ( FunctionType const * const funType : functions ) {
    1243                                 std::string mangleName = mangleAdapterName( funType, scopeTyVars );
     1269                        for ( std::list< FunctionType *>::iterator funType = functions.begin(); funType != functions.end(); ++funType ) {
     1270                                std::string mangleName = mangleAdapterName( *funType, scopeTyVars );
    12441271                                if ( adaptersDone.find( mangleName ) == adaptersDone.end() ) {
    12451272                                        std::string adapterName = makeAdapterName( mangleName );
    12461273                                        // adapter may not be used in body, pass along with unused attribute.
    1247                                         paramList.push_front( new ObjectDecl( adapterName, Type::StorageClasses(), LinkageSpec::C, 0, new PointerType( Type::Qualifiers(), makeAdapterType( funType, scopeTyVars ) ), 0, { new Attribute( "unused" ) } ) );
     1274                                        paramList.push_front( new ObjectDecl( adapterName, Type::StorageClasses(), LinkageSpec::C, 0, new PointerType( Type::Qualifiers(), makeAdapterType( *funType, scopeTyVars ) ), 0, { new Attribute( "unused" ) } ) );
    12481275                                        adaptersDone.insert( adaptersDone.begin(), mangleName );
    12491276                                }
     
    13221349                        ObjectDecl newPtr( "", Type::StorageClasses(), LinkageSpec::C, 0,
    13231350                                           new PointerType( Type::Qualifiers(), new BasicType( Type::Qualifiers(), BasicType::LongUnsignedInt ) ), 0 );
    1324                         for ( TypeDecl * const tyParam : funcType->get_forall() ) {
     1351                        for ( Type::ForallList::const_iterator tyParm = funcType->get_forall().begin(); tyParm != funcType->get_forall().end(); ++tyParm ) {
    13251352                                ObjectDecl *sizeParm, *alignParm;
    13261353                                // add all size and alignment parameters to parameter list
    1327                                 if ( tyParam->isComplete() ) {
    1328                                         TypeInstType parmType( Type::Qualifiers(), tyParam->get_name(), tyParam );
     1354                                if ( (*tyParm)->isComplete() ) {
     1355                                        TypeInstType parmType( Type::Qualifiers(), (*tyParm)->get_name(), *tyParm );
    13291356                                        std::string parmName = mangleType( &parmType );
    13301357
     
    13401367                                }
    13411368                                // move all assertions into parameter list
    1342                                 for ( DeclarationWithType * const assert : tyParam->get_assertions() ) {
     1369                                for ( std::list< DeclarationWithType *>::iterator assert = (*tyParm)->get_assertions().begin(); assert != (*tyParm)->get_assertions().end(); ++assert ) {
    13431370                                        // assertion parameters may not be used in body, pass along with unused attribute.
    1344                                         assert->get_attributes().push_back( new Attribute( "unused" ) );
    1345                                         inferredParams.push_back( assert );
    1346                                 }
    1347                                 tyParam->get_assertions().clear();
     1371                                        (*assert)->get_attributes().push_back( new Attribute( "unused" ) );
     1372                                        inferredParams.push_back( *assert );
     1373                                }
     1374                                (*tyParm)->get_assertions().clear();
    13481375                        }
    13491376
    13501377                        // add size/align for generic parameter types to parameter list
    13511378                        std::set< std::string > seenTypes; // sizeofName for generic types we've seen
    1352                         for ( DeclarationWithType * const fnParam : funcType->get_parameters() ) {
    1353                                 Type *polyType = isPolyType( fnParam->get_type(), scopeTyVars );
     1379                        for ( std::list< DeclarationWithType* >::const_iterator fnParm = last; fnParm != funcType->get_parameters().end(); ++fnParm ) {
     1380                                Type *polyType = isPolyType( (*fnParm)->get_type(), scopeTyVars );
    13541381                                if ( polyType && ! dynamic_cast< TypeInstType* >( polyType ) ) {
    13551382                                        std::string typeName = mangleType( polyType );
     
    14551482
    14561483                        if(!expect_func_type) {
     1484                                GuardAction( [this]() {
     1485                                        knownLayouts.endScope();
     1486                                        knownOffsets.endScope();
     1487                                });
    14571488                                // If this is the first function type we see
    14581489                                // Then it's the type of the declaration and we care about it
    1459                                 GuardScope( *this );
     1490                                knownLayouts.beginScope();
     1491                                knownOffsets.beginScope();
    14601492                        }
    14611493
     
    14651497
    14661498                        // make sure that any type information passed into the function is accounted for
    1467                         for ( DeclarationWithType * const fnParam : funcType->get_parameters() ) {
     1499                        for ( std::list< DeclarationWithType* >::const_iterator fnParm = funcType->get_parameters().begin(); fnParm != funcType->get_parameters().end(); ++fnParm ) {
    14681500                                // condition here duplicates that in Pass2::mutate( FunctionType* )
    1469                                 Type *polyType = isPolyType( fnParam->get_type(), scopeTyVars );
     1501                                Type *polyType = isPolyType( (*fnParm)->get_type(), scopeTyVars );
    14701502                                if ( polyType && ! dynamic_cast< TypeInstType* >( polyType ) ) {
    14711503                                        knownLayouts.insert( mangleType( polyType ) );
     
    14751507
    14761508                /// converts polymorphic type T into a suitable monomorphic representation, currently: __attribute__((aligned(8)) char[size_T]
    1477                 Type * polyToMonoType( Type const * declType ) {
     1509                Type * polyToMonoType( Type * declType ) {
    14781510                        Type * charType = new BasicType( Type::Qualifiers(), BasicType::Kind::Char);
    14791511                        Expression * size = new NameExpr( sizeofName( mangleType(declType) ) );
     
    15401572                /// Finds the member in the base list that matches the given declaration; returns its index, or -1 if not present
    15411573                long findMember( DeclarationWithType *memberDecl, std::list< Declaration* > &baseDecls ) {
    1542                         for ( auto pair : enumerate( baseDecls ) ) {
    1543                                 Declaration * decl = pair.val;
    1544                                 size_t i = pair.idx;
    1545                                 if ( memberDecl->get_name() != decl->get_name() )
     1574                        long i = 0;
     1575                        for(std::list< Declaration* >::const_iterator decl = baseDecls.begin(); decl != baseDecls.end(); ++decl, ++i ) {
     1576                                if ( memberDecl->get_name() != (*decl)->get_name() )
    15461577                                        continue;
    15471578
    15481579                                if ( memberDecl->get_name().empty() ) {
    15491580                                        // plan-9 field: match on unique_id
    1550                                         if ( memberDecl->get_uniqueId() == decl->get_uniqueId() )
     1581                                        if ( memberDecl->get_uniqueId() == (*decl)->get_uniqueId() )
    15511582                                                return i;
    15521583                                        else
     
    15541585                                }
    15551586
    1556                                 DeclarationWithType *declWithType = strict_dynamic_cast< DeclarationWithType* >( decl );
     1587                                DeclarationWithType *declWithType = strict_dynamic_cast< DeclarationWithType* >( *decl );
    15571588
    15581589                                if ( memberDecl->get_mangleName().empty() || declWithType->get_mangleName().empty() ) {
     
    15721603
    15731604                /// Returns an index expression into the offset array for a type
    1574                 Expression *makeOffsetIndex( Type const *objectType, long i ) {
     1605                Expression *makeOffsetIndex( Type *objectType, long i ) {
    15751606                        ConstantExpr *fieldIndex = new ConstantExpr( Constant::from_ulong( i ) );
    15761607                        UntypedExpr *fieldOffset = new UntypedExpr( new NameExpr( "?[?]" ) );
     
    16651696
    16661697                void PolyGenericCalculator::addOtypeParamsToLayoutCall( UntypedExpr *layoutCall, const std::list< Type* > &otypeParams ) {
    1667                         for ( Type * const param : otypeParams ) {
    1668                                 if ( findGeneric( param ) ) {
     1698                        for ( std::list< Type* >::const_iterator param = otypeParams.begin(); param != otypeParams.end(); ++param ) {
     1699                                if ( findGeneric( *param ) ) {
    16691700                                        // push size/align vars for a generic parameter back
    1670                                         std::string paramName = mangleType( param );
     1701                                        std::string paramName = mangleType( *param );
    16711702                                        layoutCall->get_args().push_back( new NameExpr( sizeofName( paramName ) ) );
    16721703                                        layoutCall->get_args().push_back( new NameExpr( alignofName( paramName ) ) );
    16731704                                } else {
    1674                                         layoutCall->get_args().push_back( new SizeofExpr( param->clone() ) );
    1675                                         layoutCall->get_args().push_back( new AlignofExpr( param->clone() ) );
     1705                                        layoutCall->get_args().push_back( new SizeofExpr( (*param)->clone() ) );
     1706                                        layoutCall->get_args().push_back( new AlignofExpr( (*param)->clone() ) );
    16761707                                }
    16771708                        }
     
    16791710
    16801711                /// returns true if any of the otype parameters have a dynamic layout and puts all otype parameters in the output list
    1681                 bool findGenericParams( std::list< TypeDecl* > const &baseParams, std::list< Expression* > const &typeParams, std::list< Type* > &out ) {
     1712                bool findGenericParams( std::list< TypeDecl* > &baseParams, std::list< Expression* > &typeParams, std::list< Type* > &out ) {
    16821713                        bool hasDynamicLayout = false;
    16831714
    1684                         for ( auto paramPair : group_iterate( baseParams, typeParams ) ) {
    1685                                 TypeDecl * baseParam = std::get<0>( paramPair );
    1686                                 Expression * typeParam = std::get<1>( paramPair );
     1715                        std::list< TypeDecl* >::const_iterator baseParam = baseParams.begin();
     1716                        std::list< Expression* >::const_iterator typeParam = typeParams.begin();
     1717                        for ( ; baseParam != baseParams.end() && typeParam != typeParams.end(); ++baseParam, ++typeParam ) {
    16871718                                // skip non-otype parameters
    1688                                 if ( ! baseParam->isComplete() ) continue;
    1689                                 TypeExpr *typeExpr = dynamic_cast< TypeExpr* >( typeParam );
     1719                                if ( ! (*baseParam)->isComplete() ) continue;
     1720                                TypeExpr *typeExpr = dynamic_cast< TypeExpr* >( *typeParam );
    16901721                                assert( typeExpr && "all otype parameters should be type expressions" );
    16911722
     
    16941725                                if ( isPolyType( type ) ) hasDynamicLayout = true;
    16951726                        }
     1727                        assert( baseParam == baseParams.end() && typeParam == typeParams.end() );
    16961728
    16971729                        return hasDynamicLayout;
    16981730                }
    16991731
    1700                 bool PolyGenericCalculator::findGeneric( Type const *ty ) {
     1732                bool PolyGenericCalculator::findGeneric( Type *ty ) {
    17011733                        ty = replaceTypeInst( ty, env );
    17021734
    1703                         if ( auto typeInst = dynamic_cast< TypeInstType const * >( ty ) ) {
     1735                        if ( TypeInstType *typeInst = dynamic_cast< TypeInstType* >( ty ) ) {
    17041736                                if ( scopeTyVars.find( typeInst->get_name() ) != scopeTyVars.end() ) {
    17051737                                        // NOTE assumes here that getting put in the scopeTyVars included having the layout variables set
     
    17071739                                }
    17081740                                return false;
    1709                         } else if ( auto structTy = dynamic_cast< StructInstType const * >( ty ) ) {
     1741                        } else if ( StructInstType *structTy = dynamic_cast< StructInstType* >( ty ) ) {
    17101742                                // check if this type already has a layout generated for it
    17111743                                std::string typeName = mangleType( ty );
     
    17141746                                // check if any of the type parameters have dynamic layout; if none do, this type is (or will be) monomorphized
    17151747                                std::list< Type* > otypeParams;
    1716                                 if ( ! findGenericParams( *structTy->get_baseParameters(), structTy->parameters, otypeParams ) ) return false;
     1748                                if ( ! findGenericParams( *structTy->get_baseParameters(), structTy->get_parameters(), otypeParams ) ) return false;
    17171749
    17181750                                // insert local variables for layout and generate call to layout function
     
    17441776
    17451777                                return true;
    1746                         } else if ( auto unionTy = dynamic_cast< UnionInstType const * >( ty ) ) {
     1778                        } else if ( UnionInstType *unionTy = dynamic_cast< UnionInstType* >( ty ) ) {
    17471779                                // check if this type already has a layout generated for it
    17481780                                std::string typeName = mangleType( ty );
     
    17511783                                // check if any of the type parameters have dynamic layout; if none do, this type is (or will be) monomorphized
    17521784                                std::list< Type* > otypeParams;
    1753                                 if ( ! findGenericParams( *unionTy->get_baseParameters(), unionTy->parameters, otypeParams ) ) return false;
     1785                                if ( ! findGenericParams( *unionTy->get_baseParameters(), unionTy->get_parameters(), otypeParams ) ) return false;
    17541786
    17551787                                // insert local variables for layout and generate call to layout function
     
    18491881                                        // build initializer list for offset array
    18501882                                        std::list< Initializer* > inits;
    1851                                         for ( Declaration * const member : baseMembers ) {
    1852                                                 DeclarationWithType *memberDecl = dynamic_cast< DeclarationWithType* >( member );
    1853                                                 assertf( memberDecl, "Requesting offset of Non-DWT member: %s", toString( member ).c_str() );
    1854                                                 inits.push_back( new SingleInit( new OffsetofExpr( ty->clone(), memberDecl ) ) );
     1883                                        for ( std::list< Declaration* >::const_iterator member = baseMembers.begin(); member != baseMembers.end(); ++member ) {
     1884                                                if ( DeclarationWithType *memberDecl = dynamic_cast< DeclarationWithType* >( *member ) ) {
     1885                                                        inits.push_back( new SingleInit( new OffsetofExpr( ty->clone(), memberDecl ) ) );
     1886                                                } else {
     1887                                                        assertf( false, "Requesting offset of Non-DWT member: %s", toString( *member ).c_str() );
     1888                                                }
    18551889                                        }
    18561890
     
    19311965// compile-command: "make install" //
    19321966// End: //
    1933 
Note: See TracChangeset for help on using the changeset viewer.