Ignore:
Timestamp:
Nov 14, 2022, 11:52:44 AM (3 years ago)
Author:
caparson <caparson@…>
Branches:
ADT, ast-experimental, master
Children:
7d9598d8
Parents:
b77f0e1 (diff), 19a8c40 (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the (diff) links above to see all the changes relative to each parent.
Message:

Merge branch 'master' of plg.uwaterloo.ca:software/cfa/cfa-cc

File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/GenPoly/Box.cc

    rb77f0e1 r63be3387  
    5858namespace GenPoly {
    5959        namespace {
    60                 FunctionType *makeAdapterType( FunctionType *adaptee, const TyVarMap &tyVars );
     60                FunctionType *makeAdapterType( FunctionType const *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;
    7270                public:
    73                         void previsit( FunctionDecl *functionDecl );
    7471                        void previsit( StructDecl *structDecl );
    7572                        void previsit( UnionDecl *unionDecl );
     
    10097                        void passArgTypeVars( ApplicationExpr *appExpr, Type *parmType, Type *argBaseType, std::list< Expression *>::iterator &arg, const TyVarMap &exprTyVars, std::set< std::string > &seenTypes );
    10198                        /// passes extra type parameters into a polymorphic function application
    102                         void passTypeVars( ApplicationExpr *appExpr, Type *polyRetType, std::list< Expression *>::iterator &arg, const TyVarMap &exprTyVars );
     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 );
    103102                        /// wraps a function application with a new temporary for the out-parameter return value
    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 );
     103                        /// The new out-parameter is the new first parameter.
     104                        Expression *addRetParam( ApplicationExpr *appExpr, Type *retType );
    110105                        /// wraps a function application returning a polymorphic type with a new temporary for the out-parameter return value
    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 );
     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 );
    116121                        /// Stores assignment operators from assertion list in local map of assignment operations
    117122                        void passAdapters( ApplicationExpr *appExpr, FunctionType *functionType, const TyVarMap &exprTyVars );
    118                         FunctionDecl *makeAdapter( FunctionType *adaptee, FunctionType *realType, const std::string &mangleName, const TyVarMap &tyVars );
     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 );
    119127                        /// Replaces intrinsic operator functions with their arithmetic desugaring
    120128                        Expression *handleIntrinsics( ApplicationExpr *appExpr );
     
    182190                        ObjectDecl *makeVar( const std::string &name, Type *type, Initializer *init = 0 );
    183191                        /// returns true if the type has a dynamic layout; such a layout will be stored in appropriately-named local variables when the function returns
    184                         bool findGeneric( Type *ty );
     192                        bool findGeneric( Type const *ty );
    185193                        /// adds type parameters to the layout call; will generate the appropriate parameters if needed
    186194                        void addOtypeParamsToLayoutCall( UntypedExpr *layoutCall, const std::list< Type* > &otypeParams );
     
    221229        } // anonymous namespace
    222230
    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 
    249231        void box( std::list< Declaration *>& translationUnit ) {
    250232                PassVisitor<LayoutFunctionBuilder> layoutBuilder;
     
    263245        ////////////////////////////////// LayoutFunctionBuilder ////////////////////////////////////////////
    264246
    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 
    273247        /// Get a list of type declarations that will affect a layout function
    274248        std::list< TypeDecl* > takeOtypeOnly( std::list< TypeDecl* > &decls ) {
    275249                std::list< TypeDecl * > otypeDecls;
    276250
    277                 for ( std::list< TypeDecl* >::const_iterator decl = decls.begin(); decl != decls.end(); ++decl ) {
    278                         if ( (*decl)->isComplete() ) {
    279                                 otypeDecls.push_back( *decl );
     251                for ( TypeDecl * const decl : decls ) {
     252                        if ( decl->isComplete() ) {
     253                                otypeDecls.push_back( decl );
    280254                        }
    281255                }
     
    288262                BasicType sizeAlignType( Type::Qualifiers(), BasicType::LongUnsignedInt );
    289263
    290                 for ( std::list< TypeDecl* >::const_iterator param = otypeParams.begin(); param != otypeParams.end(); ++param ) {
    291                         TypeInstType paramType( Type::Qualifiers(), (*param)->get_name(), *param );
     264                for ( TypeDecl * const param : otypeParams ) {
     265                        TypeInstType paramType( Type::Qualifiers(), param->get_name(), param );
    292266                        std::string paramName = mangleType( &paramType );
    293267                        layoutFnType->get_parameters().push_back( new ObjectDecl( sizeofName( paramName ), Type::StorageClasses(), LinkageSpec::Cforall, 0, sizeAlignType.clone(), 0 ) );
     
    297271
    298272        /// Builds a layout function declaration
    299         FunctionDecl *buildLayoutFunctionDecl( AggregateDecl *typeDecl, unsigned int functionNesting, FunctionType *layoutFnType ) {
     273        FunctionDecl *buildLayoutFunctionDecl( AggregateDecl *typeDecl, bool isInFunction, FunctionType *layoutFnType ) {
    300274                // Routines at global scope marked "static" to prevent multiple definitions is separate translation units
    301275                // because each unit generates copies of the default routines for each aggregate.
    302276                FunctionDecl *layoutDecl = new FunctionDecl( layoutofName( typeDecl ),
    303                                                                                                          functionNesting > 0 ? Type::StorageClasses() : Type::StorageClasses( Type::Static ),
     277                                                                                                         isInFunction ? Type::StorageClasses() : Type::StorageClasses( Type::Static ),
    304278                                                                                                         LinkageSpec::AutoGen, layoutFnType, new CompoundStmt(),
    305279                                                                                                         std::list< Attribute * >(), Type::FuncSpecifiers( Type::Inline ) );
    306280                layoutDecl->fixUniqueId();
    307281                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;
    315282        }
    316283
     
    380347
    381348                // build function decl
    382                 FunctionDecl *layoutDecl = buildLayoutFunctionDecl( structDecl, functionNesting, layoutFnType );
     349                FunctionDecl *layoutDecl = buildLayoutFunctionDecl( structDecl, isInFunction(), layoutFnType );
    383350
    384351                // calculate struct layout in function body
     
    387354                addExpr( layoutDecl->get_statements(), makeOp( "?=?", derefVar( sizeParam ), new ConstantExpr( Constant::from_ulong( 0 ) ) ) );
    388355                addExpr( layoutDecl->get_statements(), makeOp( "?=?", derefVar( alignParam ), new ConstantExpr( Constant::from_ulong( 1 ) ) ) );
    389                 unsigned long n_members = 0;
    390                 bool firstMember = true;
    391                 for ( Declaration* member : structDecl->get_members() ) {
    392                         DeclarationWithType *dwt = dynamic_cast< DeclarationWithType * >( member );
     356                for ( auto index_member : enumerate( structDecl->members ) ) {
     357                        DeclarationWithType *dwt = dynamic_cast< DeclarationWithType * >( index_member.val );
    393358                        assert( dwt );
    394359                        Type *memberType = dwt->get_type();
    395360
    396                         if ( firstMember ) {
    397                                 firstMember = false;
    398                         } else {
     361                        if ( 0 < index_member.idx ) {
    399362                                // make sure all members after the first (automatically aligned at 0) are properly padded for alignment
    400363                                addStmt( layoutDecl->get_statements(), makeAlignTo( derefVar( sizeParam ), new AlignofExpr( memberType->clone() ) ) );
     
    402365
    403366                        // place current size in the current offset index
    404                         addExpr( layoutDecl->get_statements(), makeOp( "?=?", makeOp( "?[?]", new VariableExpr( offsetParam ), new ConstantExpr( Constant::from_ulong( n_members ) ) ),
     367                        addExpr( layoutDecl->get_statements(), makeOp( "?=?", makeOp( "?[?]", new VariableExpr( offsetParam ), new ConstantExpr( Constant::from_ulong( index_member.idx ) ) ),
    405368                                                                              derefVar( sizeParam ) ) );
    406                         ++n_members;
    407369
    408370                        // add member size to current size
     
    439401
    440402                // build function decl
    441                 FunctionDecl *layoutDecl = buildLayoutFunctionDecl( unionDecl, functionNesting, layoutFnType );
     403                FunctionDecl *layoutDecl = buildLayoutFunctionDecl( unionDecl, isInFunction(), layoutFnType );
    442404
    443405                // calculate union layout in function body
    444406                addExpr( layoutDecl->get_statements(), makeOp( "?=?", derefVar( sizeParam ), new ConstantExpr( Constant::from_ulong( 1 ) ) ) );
    445407                addExpr( layoutDecl->get_statements(), makeOp( "?=?", derefVar( alignParam ), new ConstantExpr( Constant::from_ulong( 1 ) ) ) );
    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 );
     408                for ( Declaration * const member : unionDecl->members ) {
     409                        DeclarationWithType *dwt = dynamic_cast< DeclarationWithType * >( member );
    448410                        assert( dwt );
    449411                        Type *memberType = dwt->get_type();
     
    464426
    465427        namespace {
    466                 std::string makePolyMonoSuffix( FunctionType * function, const TyVarMap &tyVars ) {
     428                std::string makePolyMonoSuffix( FunctionType const * function, const TyVarMap &tyVars ) {
    467429                        std::stringstream name;
    468430
     
    473435                        // to take those polymorphic types as pointers. Therefore, there can be two different functions
    474436                        // with the same mangled name, so we need to further mangle the names.
    475                         for ( std::list< DeclarationWithType *>::iterator retval = function->get_returnVals().begin(); retval != function->get_returnVals().end(); ++retval ) {
    476                                 if ( isPolyType( (*retval)->get_type(), tyVars ) ) {
     437                        for ( DeclarationWithType const * const ret : function->returnVals ) {
     438                                if ( isPolyType( ret->get_type(), tyVars ) ) {
    477439                                        name << "P";
    478440                                } else {
     
    481443                        }
    482444                        name << "_";
    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 ) ) {
     445                        for ( DeclarationWithType const * const arg : function->parameters ) {
     446                                if ( isPolyType( arg->get_type(), tyVars ) ) {
    486447                                        name << "P";
    487448                                } else {
     
    492453                }
    493454
    494                 std::string mangleAdapterName( FunctionType * function, const TyVarMap &tyVars ) {
     455                std::string mangleAdapterName( FunctionType const * function, const TyVarMap &tyVars ) {
    495456                        return SymTab::Mangler::mangle( function ) + makePolyMonoSuffix( function, tyVars );
    496457                }
     
    499460                        return "_adapter" + mangleName;
    500461                }
     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 );
    501466
    502467                Pass1::Pass1() : tempNamer( "_temp" ) {}
     
    524489
    525490                                std::list< DeclarationWithType *> &paramList = functionType->parameters;
    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 );
     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 );
    530495                                        } // for
    531496                                } // for
    532                                 for ( std::list< DeclarationWithType *>::iterator arg = paramList.begin(); arg != paramList.end(); ++arg ) {
    533                                         findFunction( (*arg)->get_type(), functions, scopeTyVars, needsAdapter );
     497                                for ( DeclarationWithType * const arg : paramList ) {
     498                                        findFunction( arg->get_type(), functions, scopeTyVars, needsAdapter );
    534499                                } // for
    535500
    536                                 for ( std::list< FunctionType *>::iterator funType = functions.begin(); funType != functions.end(); ++funType ) {
    537                                         std::string mangleName = mangleAdapterName( *funType, scopeTyVars );
     501                                for ( FunctionType const * const funType : functions ) {
     502                                        std::string mangleName = mangleAdapterName( funType, scopeTyVars );
    538503                                        if ( adapters.find( mangleName ) == adapters.end() ) {
    539504                                                std::string adapterName = makeAdapterName( mangleName );
    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 ) ) );
     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 ) ) );
    541506                                        } // if
    542507                                } // for
     
    593558                }
    594559
    595                 void Pass1::passTypeVars( ApplicationExpr *appExpr, Type *polyRetType, std::list< Expression *>::iterator &arg, const TyVarMap &exprTyVars ) {
     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();
    596563                        // pass size/align for type variables
    597                         for ( TyVarMap::const_iterator tyParm = exprTyVars.begin(); tyParm != exprTyVars.end(); ++tyParm ) {
     564                        for ( std::pair<std::string, TypeDecl::Data> const & tyParam : exprTyVars ) {
    598565                                ResolvExpr::EqvClass eqvClass;
    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
     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++;
    611576                                } // if
    612577                        } // for
    613578
    614579                        // add size/align for generic types to parameter list
    615                         if ( ! appExpr->get_function()->result ) return;
     580                        if ( ! appExpr->get_function()->result ) return arg;
    616581                        FunctionType *funcType = getFunctionType( appExpr->get_function()->get_result() );
    617582                        assert( funcType );
    618583
     584                        // These iterators don't advance in unison.
    619585                        std::list< DeclarationWithType* >::const_iterator fnParm = funcType->get_parameters().begin();
    620586                        std::list< Expression* >::const_iterator fnArg = arg;
     
    623589                        // a polymorphic return type may need to be added to the argument list
    624590                        if ( polyRetType ) {
    625                                 Type *concRetType = replaceWithConcrete( appExpr, polyRetType );
     591                                Type *concRetType = replaceWithConcrete( polyRetType, env );
    626592                                passArgTypeVars( appExpr, polyRetType, concRetType, arg, exprTyVars, seenTypes );
    627593                                ++fnArg; // skip the return parameter in the argument list
     
    634600                                passArgTypeVars( appExpr, (*fnParm)->get_type(), argType, arg, exprTyVars, seenTypes );
    635601                        }
     602                        return arg;
    636603                }
    637604
     
    642609                }
    643610
    644                 Expression *Pass1::addRetParam( ApplicationExpr *appExpr, Type *retType, std::list< Expression *>::iterator &arg ) {
     611                Expression *Pass1::addRetParam( ApplicationExpr *appExpr, Type *retType ) {
    645612                        // Create temporary to hold return value of polymorphic function and produce that temporary as a result
    646613                        // using a comma expression.
     
    662629                                paramExpr = new AddressExpr( paramExpr );
    663630                        } // if
    664                         arg = appExpr->args.insert( arg, paramExpr ); // add argument to function call
    665                         arg++;
     631                        // Add argument to function call.
     632                        appExpr->args.push_front( paramExpr );
    666633                        // Build a comma expression to call the function and emulate a normal return.
    667634                        CommaExpr *commaExpr = new CommaExpr( appExpr, retExpr );
     
    671638                }
    672639
    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 );
     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 );
    676644                                assertf(paramType, "Aggregate parameters should be type expressions");
    677                                 paramType->set_type( replaceWithConcrete( appExpr, paramType->get_type(), false ) );
    678                         }
    679                 }
    680 
    681                 Type *Pass1::replaceWithConcrete( ApplicationExpr *appExpr, Type *type, bool doClone ) {
     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 );
    682652                        if ( TypeInstType *typeInst = dynamic_cast< TypeInstType * >( type ) ) {
    683653                                Type *concrete = env->lookup( typeInst->get_name() );
     
    690660                                        structType = structType->clone();
    691661                                }
    692                                 replaceParametersWithConcrete( appExpr, structType->get_parameters() );
     662                                replaceParametersWithConcrete( structType->get_parameters(), env );
    693663                                return structType;
    694664                        } else if ( UnionInstType *unionType = dynamic_cast< UnionInstType* >( type ) ) {
     
    696666                                        unionType = unionType->clone();
    697667                                }
    698                                 replaceParametersWithConcrete( appExpr, unionType->get_parameters() );
     668                                replaceParametersWithConcrete( unionType->get_parameters(), env );
    699669                                return unionType;
    700670                        }
     
    702672                }
    703673
    704                 Expression *Pass1::addDynRetParam( ApplicationExpr *appExpr, Type *dynType, std::list< Expression *>::iterator &arg ) {
    705                         assert( env );
    706                         Type *concrete = replaceWithConcrete( appExpr, dynType );
     674                Expression *Pass1::addDynRetParam( ApplicationExpr *appExpr, Type *dynType ) {
     675                        Type *concrete = replaceWithConcrete( dynType, env );
    707676                        // add out-parameter for return value
    708                         return addRetParam( appExpr, concrete, arg );
    709                 }
    710 
    711                 Expression *Pass1::applyAdapter( ApplicationExpr *appExpr, FunctionType *function, std::list< Expression *>::iterator &arg, const TyVarMap &tyVars ) {
     677                        return addRetParam( appExpr, concrete );
     678                }
     679
     680                Expression *Pass1::applyAdapter( ApplicationExpr *appExpr, FunctionType *function ) {
    712681                        Expression *ret = appExpr;
    713682//                      if ( ! function->get_returnVals().empty() && isPolyType( function->get_returnVals().front()->get_type(), tyVars ) ) {
    714                         if ( isDynRet( function, tyVars ) ) {
    715                                 ret = addRetParam( appExpr, function->returnVals.front()->get_type(), arg );
     683                        if ( isDynRet( function, scopeTyVars ) ) {
     684                                ret = addRetParam( appExpr, function->returnVals.front()->get_type() );
    716685                        } // if
    717                         std::string mangleName = mangleAdapterName( function, tyVars );
     686                        std::string mangleName = mangleAdapterName( function, scopeTyVars );
    718687                        std::string adapterName = makeAdapterName( mangleName );
    719688
     
    724693
    725694                        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
    758695                }
    759696
     
    791728                }
    792729
    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 );
     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;
    798770                        } // for
    799771                }
    800772
    801                 void Pass1::addInferredParams( ApplicationExpr *appExpr, FunctionType *functionType, std::list< Expression *>::iterator &arg, const TyVarMap &tyVars ) {
     773                void Pass1::addInferredParams( ApplicationExpr *appExpr, std::list< Expression *>::iterator arg, FunctionType *functionType, const TyVarMap &tyVars ) {
    802774                        std::list< Expression *>::iterator cur = arg;
    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() );
     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() );
    807779                                        Expression *newExpr = inferParam->second.expr->clone();
    808                                         addCast( newExpr, (*assert)->get_type(), tyVars );
    809                                         boxParam( (*assert)->get_type(), newExpr, tyVars );
     780                                        boxParam( newExpr, assert->get_type(), tyVars );
    810781                                        appExpr->get_args().insert( cur, newExpr );
    811782                                } // for
     
    824795                }
    825796
    826                 FunctionType *makeAdapterType( FunctionType *adaptee, const TyVarMap &tyVars ) {
     797                FunctionType *makeAdapterType( FunctionType const *adaptee, const TyVarMap &tyVars ) {
    827798                        // actually make the adapter type
    828799                        FunctionType *adapter = adaptee->clone();
     
    834805                }
    835806
    836                 Expression *makeAdapterArg( DeclarationWithType *param, DeclarationWithType *arg, DeclarationWithType *realParam, const TyVarMap &tyVars ) {
     807                Expression *makeAdapterArg(
     808                                DeclarationWithType *param,
     809                                DeclarationWithType const *arg,
     810                                DeclarationWithType const *realParam,
     811                                const TyVarMap &tyVars ) {
    837812                        assert( param );
    838813                        assert( arg );
    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
     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;
    846820                        } // if
    847821                        return new VariableExpr( param );
    848822                }
    849823
    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 ) {
     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 ) {
    851831                        UniqueName paramNamer( "_p" );
    852832                        for ( ; param != paramEnd; ++param, ++arg, ++realParam ) {
     
    859839                }
    860840
    861                 FunctionDecl *Pass1::makeAdapter( FunctionType *adaptee, FunctionType *realType, const std::string &mangleName, const TyVarMap &tyVars ) {
     841                FunctionDecl *Pass1::makeAdapter( FunctionType const *adaptee, FunctionType *realType, const std::string &mangleName, const TyVarMap &tyVars ) {
    862842                        FunctionType *adapterType = makeAdapterType( adaptee, tyVars );
    863843                        adapterType = ScrubTyVars::scrub( adapterType, tyVars );
     
    876856                        Statement *bodyStmt;
    877857
    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 ) );
     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 ) );
    889867                                } // for
    890868                        } // for
    891869
    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();
     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();
    895873                        param++;                // skip adaptee parameter in the adapter type
    896874                        if ( realType->get_returnVals().empty() ) {
     
    898876                                addAdapterParams( adapteeApp, arg, param, adapterType->get_parameters().end(), realParam, tyVars );
    899877                                bodyStmt = new ExprStmt( adapteeApp );
    900                         } else if ( isDynType( adaptee->get_returnVals().front()->get_type(), tyVars ) ) {
     878                        } else if ( isDynType( adaptee->returnVals.front()->get_type(), tyVars ) ) {
    901879                                // return type T
    902880                                if ( (*param)->get_name() == "" ) {
     
    923901                void Pass1::passAdapters( ApplicationExpr * appExpr, FunctionType * functionType, const TyVarMap & exprTyVars ) {
    924902                        // collect a list of function types passed as parameters or implicit parameters (assertions)
    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 );
     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 );
    930907                                } // for
    931908                        } // for
    932                         for ( std::list< DeclarationWithType *>::iterator arg = paramList.begin(); arg != paramList.end(); ++arg ) {
    933                                 findFunction( (*arg)->get_type(), functions, exprTyVars, needsAdapter );
     909                        for ( DeclarationWithType * const arg : functionType->get_parameters() ) {
     910                                findFunction( arg->get_type(), functions, exprTyVars, needsAdapter );
    934911                        } // for
    935912
     
    938915                        std::set< std::string > adaptersDone;
    939916
    940                         for ( std::list< FunctionType *>::iterator funType = functions.begin(); funType != functions.end(); ++funType ) {
    941                                 FunctionType *originalFunction = (*funType)->clone();
    942                                 FunctionType *realFunction = (*funType)->clone();
     917                        for ( FunctionType const * const funType : functions ) {
     918                                FunctionType *originalFunction = funType->clone();
     919                                FunctionType *realFunction = funType->clone();
    943920                                std::string mangleName = SymTab::Mangler::mangle( realFunction );
    944921
     
    958935                                        if ( adapter == adapters.end() ) {
    959936                                                // adapter has not been created yet in the current scope, so define it
    960                                                 FunctionDecl *newAdapter = makeAdapter( *funType, realFunction, mangleName, exprTyVars );
     937                                                FunctionDecl *newAdapter = makeAdapter( funType, realFunction, mangleName, exprTyVars );
    961938                                                std::pair< AdapterIter, bool > answer = adapters.insert( std::pair< std::string, DeclarationWithType *>( mangleName, newAdapter ) );
    962939                                                adapter = answer.first;
     
    972949
    973950                Expression *makeIncrDecrExpr( ApplicationExpr *appExpr, Type *polyType, bool isIncr ) {
    974                         NameExpr *opExpr;
    975                         if ( isIncr ) {
    976                                 opExpr = new NameExpr( "?+=?" );
    977                         } else {
    978                                 opExpr = new NameExpr( "?-=?" );
    979                         } // if
     951                        NameExpr *opExpr = new NameExpr( ( isIncr ) ? "?+=?" : "?-=?" );
    980952                        UntypedExpr *addAssign = new UntypedExpr( opExpr );
    981953                        if ( AddressExpr *address = dynamic_cast< AddressExpr *>( appExpr->get_args().front() ) ) {
     
    11201092                Expression *Pass1::postmutate( ApplicationExpr *appExpr ) {
    11211093                        // std::cerr << "mutate appExpr: " << InitTweak::getFunctionName( appExpr ) << std::endl;
    1122                         // for ( TyVarMap::iterator i = scopeTyVars.begin(); i != scopeTyVars.end(); ++i ) {
    1123                         //      std::cerr << i->first << " ";
     1094                        // for ( auto tyVar : scopeTyVars ) {
     1095                        //      std::cerr << tyVar.first << " ";
    11241096                        // }
    11251097                        // std::cerr << "\n";
     
    11341106
    11351107                        Expression *ret = appExpr;
    1136 
    1137                         std::list< Expression *>::iterator arg = appExpr->get_args().begin();
    11381108                        std::list< Expression *>::iterator paramBegin = appExpr->get_args().begin();
    11391109
     
    11561126                                // std::cerr << "dynRetType: " << dynRetType << std::endl;
    11571127                                Type *concRetType = appExpr->get_result()->isVoid() ? nullptr : appExpr->get_result();
    1158                                 ret = addDynRetParam( appExpr, concRetType, arg ); // xxx - used to use dynRetType instead of concRetType
     1128                                ret = addDynRetParam( appExpr, concRetType ); // xxx - used to use dynRetType instead of concRetType
    11591129                        } else if ( needsAdapter( function, scopeTyVars ) && ! needsAdapter( function, exprTyVars) ) { // xxx - exprTyVars is used above...?
    11601130                                // 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.
     
    11641134                                // std::cerr << *env << std::endl;
    11651135                                // change the application so it calls the adapter rather than the passed function
    1166                                 ret = applyAdapter( appExpr, function, arg, scopeTyVars );
     1136                                ret = applyAdapter( appExpr, function );
    11671137                        } // if
    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 );
     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
    11771147                        passAdapters( appExpr, function, exprTyVars );
    11781148
     
    11801150                }
    11811151
    1182                 Expression * Pass1::postmutate( UntypedExpr *expr ) {
     1152                bool isPolyDeref( UntypedExpr const * expr, TyVarMap const & scopeTyVars, TypeSubstitution const * env ) {
    11831153                        if ( expr->result && isPolyType( expr->result, scopeTyVars, env ) ) {
    1184                                 if ( NameExpr *name = dynamic_cast< NameExpr *>( expr->function ) ) {
     1154                                if ( auto name = dynamic_cast<NameExpr const *>( expr->function ) ) {
    11851155                                        if ( name->name == "*?" ) {
    1186                                                 Expression *ret = expr->args.front();
    1187                                                 expr->args.clear();
    1188                                                 delete expr;
    1189                                                 return ret;
     1156                                                return true;
    11901157                                        } // if
    11911158                                } // if
    11921159                        } // 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                        }
    11931170                        return expr;
    11941171                }
     
    12001177                        bool needs = false;
    12011178                        if ( UntypedExpr *expr = dynamic_cast< UntypedExpr *>( addrExpr->arg ) ) {
    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
     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 );
    12121185                                        } // if
    12131186                                } // if
     
    12601233                void Pass2::addAdapters( FunctionType *functionType ) {
    12611234                        std::list< DeclarationWithType *> &paramList = functionType->parameters;
    1262                         std::list< FunctionType *> functions;
    1263                         for ( std::list< DeclarationWithType *>::iterator arg = paramList.begin(); arg != paramList.end(); ++arg ) {
    1264                                 Type *orig = (*arg)->get_type();
     1235                        std::list< FunctionType const *> functions;
     1236                        for ( DeclarationWithType * const arg : functionType->parameters ) {
     1237                                Type *orig = arg->get_type();
    12651238                                findAndReplaceFunction( orig, functions, scopeTyVars, needsAdapter );
    1266                                 (*arg)->set_type( orig );
     1239                                arg->set_type( orig );
    12671240                        }
    12681241                        std::set< std::string > adaptersDone;
    1269                         for ( std::list< FunctionType *>::iterator funType = functions.begin(); funType != functions.end(); ++funType ) {
    1270                                 std::string mangleName = mangleAdapterName( *funType, scopeTyVars );
     1242                        for ( FunctionType const * const funType : functions ) {
     1243                                std::string mangleName = mangleAdapterName( funType, scopeTyVars );
    12711244                                if ( adaptersDone.find( mangleName ) == adaptersDone.end() ) {
    12721245                                        std::string adapterName = makeAdapterName( mangleName );
    12731246                                        // adapter may not be used in body, pass along with unused attribute.
    1274                                         paramList.push_front( new ObjectDecl( adapterName, Type::StorageClasses(), LinkageSpec::C, 0, new PointerType( Type::Qualifiers(), makeAdapterType( *funType, scopeTyVars ) ), 0, { new Attribute( "unused" ) } ) );
     1247                                        paramList.push_front( new ObjectDecl( adapterName, Type::StorageClasses(), LinkageSpec::C, 0, new PointerType( Type::Qualifiers(), makeAdapterType( funType, scopeTyVars ) ), 0, { new Attribute( "unused" ) } ) );
    12751248                                        adaptersDone.insert( adaptersDone.begin(), mangleName );
    12761249                                }
     
    13491322                        ObjectDecl newPtr( "", Type::StorageClasses(), LinkageSpec::C, 0,
    13501323                                           new PointerType( Type::Qualifiers(), new BasicType( Type::Qualifiers(), BasicType::LongUnsignedInt ) ), 0 );
    1351                         for ( Type::ForallList::const_iterator tyParm = funcType->get_forall().begin(); tyParm != funcType->get_forall().end(); ++tyParm ) {
     1324                        for ( TypeDecl * const tyParam : funcType->get_forall() ) {
    13521325                                ObjectDecl *sizeParm, *alignParm;
    13531326                                // add all size and alignment parameters to parameter list
    1354                                 if ( (*tyParm)->isComplete() ) {
    1355                                         TypeInstType parmType( Type::Qualifiers(), (*tyParm)->get_name(), *tyParm );
     1327                                if ( tyParam->isComplete() ) {
     1328                                        TypeInstType parmType( Type::Qualifiers(), tyParam->get_name(), tyParam );
    13561329                                        std::string parmName = mangleType( &parmType );
    13571330
     
    13671340                                }
    13681341                                // move all assertions into parameter list
    1369                                 for ( std::list< DeclarationWithType *>::iterator assert = (*tyParm)->get_assertions().begin(); assert != (*tyParm)->get_assertions().end(); ++assert ) {
     1342                                for ( DeclarationWithType * const assert : tyParam->get_assertions() ) {
    13701343                                        // assertion parameters may not be used in body, pass along with unused attribute.
    1371                                         (*assert)->get_attributes().push_back( new Attribute( "unused" ) );
    1372                                         inferredParams.push_back( *assert );
    1373                                 }
    1374                                 (*tyParm)->get_assertions().clear();
     1344                                        assert->get_attributes().push_back( new Attribute( "unused" ) );
     1345                                        inferredParams.push_back( assert );
     1346                                }
     1347                                tyParam->get_assertions().clear();
    13751348                        }
    13761349
    13771350                        // add size/align for generic parameter types to parameter list
    13781351                        std::set< std::string > seenTypes; // sizeofName for generic types we've seen
    1379                         for ( std::list< DeclarationWithType* >::const_iterator fnParm = last; fnParm != funcType->get_parameters().end(); ++fnParm ) {
    1380                                 Type *polyType = isPolyType( (*fnParm)->get_type(), scopeTyVars );
     1352                        for ( DeclarationWithType * const fnParam : funcType->get_parameters() ) {
     1353                                Type *polyType = isPolyType( fnParam->get_type(), scopeTyVars );
    13811354                                if ( polyType && ! dynamic_cast< TypeInstType* >( polyType ) ) {
    13821355                                        std::string typeName = mangleType( polyType );
     
    14821455
    14831456                        if(!expect_func_type) {
    1484                                 GuardAction( [this]() {
    1485                                         knownLayouts.endScope();
    1486                                         knownOffsets.endScope();
    1487                                 });
    14881457                                // If this is the first function type we see
    14891458                                // Then it's the type of the declaration and we care about it
    1490                                 knownLayouts.beginScope();
    1491                                 knownOffsets.beginScope();
     1459                                GuardScope( *this );
    14921460                        }
    14931461
     
    14971465
    14981466                        // make sure that any type information passed into the function is accounted for
    1499                         for ( std::list< DeclarationWithType* >::const_iterator fnParm = funcType->get_parameters().begin(); fnParm != funcType->get_parameters().end(); ++fnParm ) {
     1467                        for ( DeclarationWithType * const fnParam : funcType->get_parameters() ) {
    15001468                                // condition here duplicates that in Pass2::mutate( FunctionType* )
    1501                                 Type *polyType = isPolyType( (*fnParm)->get_type(), scopeTyVars );
     1469                                Type *polyType = isPolyType( fnParam->get_type(), scopeTyVars );
    15021470                                if ( polyType && ! dynamic_cast< TypeInstType* >( polyType ) ) {
    15031471                                        knownLayouts.insert( mangleType( polyType ) );
     
    15071475
    15081476                /// converts polymorphic type T into a suitable monomorphic representation, currently: __attribute__((aligned(8)) char[size_T]
    1509                 Type * polyToMonoType( Type * declType ) {
     1477                Type * polyToMonoType( Type const * declType ) {
    15101478                        Type * charType = new BasicType( Type::Qualifiers(), BasicType::Kind::Char);
    15111479                        Expression * size = new NameExpr( sizeofName( mangleType(declType) ) );
     
    15721540                /// Finds the member in the base list that matches the given declaration; returns its index, or -1 if not present
    15731541                long findMember( DeclarationWithType *memberDecl, std::list< Declaration* > &baseDecls ) {
    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() )
     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() )
    15771546                                        continue;
    15781547
    15791548                                if ( memberDecl->get_name().empty() ) {
    15801549                                        // plan-9 field: match on unique_id
    1581                                         if ( memberDecl->get_uniqueId() == (*decl)->get_uniqueId() )
     1550                                        if ( memberDecl->get_uniqueId() == decl->get_uniqueId() )
    15821551                                                return i;
    15831552                                        else
     
    15851554                                }
    15861555
    1587                                 DeclarationWithType *declWithType = strict_dynamic_cast< DeclarationWithType* >( *decl );
     1556                                DeclarationWithType *declWithType = strict_dynamic_cast< DeclarationWithType* >( decl );
    15881557
    15891558                                if ( memberDecl->get_mangleName().empty() || declWithType->get_mangleName().empty() ) {
     
    16031572
    16041573                /// Returns an index expression into the offset array for a type
    1605                 Expression *makeOffsetIndex( Type *objectType, long i ) {
     1574                Expression *makeOffsetIndex( Type const *objectType, long i ) {
    16061575                        ConstantExpr *fieldIndex = new ConstantExpr( Constant::from_ulong( i ) );
    16071576                        UntypedExpr *fieldOffset = new UntypedExpr( new NameExpr( "?[?]" ) );
     
    16961665
    16971666                void PolyGenericCalculator::addOtypeParamsToLayoutCall( UntypedExpr *layoutCall, const std::list< Type* > &otypeParams ) {
    1698                         for ( std::list< Type* >::const_iterator param = otypeParams.begin(); param != otypeParams.end(); ++param ) {
    1699                                 if ( findGeneric( *param ) ) {
     1667                        for ( Type * const param : otypeParams ) {
     1668                                if ( findGeneric( param ) ) {
    17001669                                        // push size/align vars for a generic parameter back
    1701                                         std::string paramName = mangleType( *param );
     1670                                        std::string paramName = mangleType( param );
    17021671                                        layoutCall->get_args().push_back( new NameExpr( sizeofName( paramName ) ) );
    17031672                                        layoutCall->get_args().push_back( new NameExpr( alignofName( paramName ) ) );
    17041673                                } else {
    1705                                         layoutCall->get_args().push_back( new SizeofExpr( (*param)->clone() ) );
    1706                                         layoutCall->get_args().push_back( new AlignofExpr( (*param)->clone() ) );
     1674                                        layoutCall->get_args().push_back( new SizeofExpr( param->clone() ) );
     1675                                        layoutCall->get_args().push_back( new AlignofExpr( param->clone() ) );
    17071676                                }
    17081677                        }
     
    17101679
    17111680                /// returns true if any of the otype parameters have a dynamic layout and puts all otype parameters in the output list
    1712                 bool findGenericParams( std::list< TypeDecl* > &baseParams, std::list< Expression* > &typeParams, std::list< Type* > &out ) {
     1681                bool findGenericParams( std::list< TypeDecl* > const &baseParams, std::list< Expression* > const &typeParams, std::list< Type* > &out ) {
    17131682                        bool hasDynamicLayout = false;
    17141683
    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 ) {
     1684                        for ( auto paramPair : group_iterate( baseParams, typeParams ) ) {
     1685                                TypeDecl * baseParam = std::get<0>( paramPair );
     1686                                Expression * typeParam = std::get<1>( paramPair );
    17181687                                // skip non-otype parameters
    1719                                 if ( ! (*baseParam)->isComplete() ) continue;
    1720                                 TypeExpr *typeExpr = dynamic_cast< TypeExpr* >( *typeParam );
     1688                                if ( ! baseParam->isComplete() ) continue;
     1689                                TypeExpr *typeExpr = dynamic_cast< TypeExpr* >( typeParam );
    17211690                                assert( typeExpr && "all otype parameters should be type expressions" );
    17221691
     
    17251694                                if ( isPolyType( type ) ) hasDynamicLayout = true;
    17261695                        }
    1727                         assert( baseParam == baseParams.end() && typeParam == typeParams.end() );
    17281696
    17291697                        return hasDynamicLayout;
    17301698                }
    17311699
    1732                 bool PolyGenericCalculator::findGeneric( Type *ty ) {
     1700                bool PolyGenericCalculator::findGeneric( Type const *ty ) {
    17331701                        ty = replaceTypeInst( ty, env );
    17341702
    1735                         if ( TypeInstType *typeInst = dynamic_cast< TypeInstType* >( ty ) ) {
     1703                        if ( auto typeInst = dynamic_cast< TypeInstType const * >( ty ) ) {
    17361704                                if ( scopeTyVars.find( typeInst->get_name() ) != scopeTyVars.end() ) {
    17371705                                        // NOTE assumes here that getting put in the scopeTyVars included having the layout variables set
     
    17391707                                }
    17401708                                return false;
    1741                         } else if ( StructInstType *structTy = dynamic_cast< StructInstType* >( ty ) ) {
     1709                        } else if ( auto structTy = dynamic_cast< StructInstType const * >( ty ) ) {
    17421710                                // check if this type already has a layout generated for it
    17431711                                std::string typeName = mangleType( ty );
     
    17461714                                // check if any of the type parameters have dynamic layout; if none do, this type is (or will be) monomorphized
    17471715                                std::list< Type* > otypeParams;
    1748                                 if ( ! findGenericParams( *structTy->get_baseParameters(), structTy->get_parameters(), otypeParams ) ) return false;
     1716                                if ( ! findGenericParams( *structTy->get_baseParameters(), structTy->parameters, otypeParams ) ) return false;
    17491717
    17501718                                // insert local variables for layout and generate call to layout function
     
    17761744
    17771745                                return true;
    1778                         } else if ( UnionInstType *unionTy = dynamic_cast< UnionInstType* >( ty ) ) {
     1746                        } else if ( auto unionTy = dynamic_cast< UnionInstType const * >( ty ) ) {
    17791747                                // check if this type already has a layout generated for it
    17801748                                std::string typeName = mangleType( ty );
     
    17831751                                // check if any of the type parameters have dynamic layout; if none do, this type is (or will be) monomorphized
    17841752                                std::list< Type* > otypeParams;
    1785                                 if ( ! findGenericParams( *unionTy->get_baseParameters(), unionTy->get_parameters(), otypeParams ) ) return false;
     1753                                if ( ! findGenericParams( *unionTy->get_baseParameters(), unionTy->parameters, otypeParams ) ) return false;
    17861754
    17871755                                // insert local variables for layout and generate call to layout function
     
    18811849                                        // build initializer list for offset array
    18821850                                        std::list< Initializer* > inits;
    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                                                 }
     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 ) ) );
    18891855                                        }
    18901856
     
    19651931// compile-command: "make install" //
    19661932// End: //
     1933
Note: See TracChangeset for help on using the changeset viewer.