Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/GenPoly/Box.cc

    raa19ccf r4067aa8  
    1414//
    1515
    16 #include <algorithm>
    17 #include <iterator>
    18 #include <list>
    19 #include <map>
    2016#include <set>
    2117#include <stack>
    2218#include <string>
    23 #include <utility>
    24 #include <vector>
     19#include <iterator>
     20#include <algorithm>
    2521#include <cassert>
    2622
    2723#include "Box.h"
    28 #include "DeclMutator.h"
     24#include "InstantiateGeneric.h"
    2925#include "PolyMutator.h"
    3026#include "FindFunction.h"
    31 #include "ScopedMap.h"
    32 #include "ScopedSet.h"
    3327#include "ScrubTyVars.h"
    3428
     
    3630
    3731#include "SynTree/Constant.h"
    38 #include "SynTree/Declaration.h"
     32#include "SynTree/Type.h"
    3933#include "SynTree/Expression.h"
    4034#include "SynTree/Initializer.h"
     35#include "SynTree/Statement.h"
    4136#include "SynTree/Mutator.h"
    42 #include "SynTree/Statement.h"
    43 #include "SynTree/Type.h"
    44 #include "SynTree/TypeSubstitution.h"
    4537
    4638#include "ResolvExpr/TypeEnvironment.h"
     
    4840#include "ResolvExpr/typeops.h"
    4941
    50 #include "SymTab/Indexer.h"
    5142#include "SymTab/Mangler.h"
    5243
     
    6354                FunctionType *makeAdapterType( FunctionType *adaptee, const TyVarMap &tyVars );
    6455
    65                 /// Abstracts type equality for a list of parameter types
    66                 struct TypeList {
    67                         TypeList() : params() {}
    68                         TypeList( const std::list< Type* > &_params ) : params() { cloneAll(_params, params); }
    69                         TypeList( std::list< Type* > &&_params ) : params( _params ) {}
    70 
    71                         TypeList( const TypeList &that ) : params() { cloneAll(that.params, params); }
    72                         TypeList( TypeList &&that ) : params( std::move( that.params ) ) {}
    73 
    74                         /// Extracts types from a list of TypeExpr*
    75                         TypeList( const std::list< TypeExpr* >& _params ) : params() {
    76                                 for ( std::list< TypeExpr* >::const_iterator param = _params.begin(); param != _params.end(); ++param ) {
    77                                         params.push_back( (*param)->get_type()->clone() );
    78                                 }
    79                         }
    80 
    81                         TypeList& operator= ( const TypeList &that ) {
    82                                 deleteAll( params );
    83 
    84                                 params.clear();
    85                                 cloneAll( that.params, params );
    86 
    87                                 return *this;
    88                         }
    89 
    90                         TypeList& operator= ( TypeList &&that ) {
    91                                 deleteAll( params );
    92 
    93                                 params = std::move( that.params );
    94 
    95                                 return *this;
    96                         }
    97 
    98                         ~TypeList() { deleteAll( params ); }
    99 
    100                         bool operator== ( const TypeList& that ) const {
    101                                 if ( params.size() != that.params.size() ) return false;
    102 
    103                                 SymTab::Indexer dummy;
    104                                 for ( std::list< Type* >::const_iterator it = params.begin(), jt = that.params.begin(); it != params.end(); ++it, ++jt ) {
    105                                         if ( ! ResolvExpr::typesCompatible( *it, *jt, dummy ) ) return false;
    106                                 }
    107                                 return true;
    108                         }
    109 
    110                         std::list< Type* > params;  ///< Instantiation parameters
    111                 };
    112 
    113                 /// Maps a key and a TypeList to the some value, accounting for scope
    114                 template< typename Key, typename Value >
    115                 class InstantiationMap {
    116                         /// Wraps value for a specific (Key, TypeList) combination
    117                         typedef std::pair< TypeList, Value* > Instantiation;
    118                         /// List of TypeLists paired with their appropriate values
    119                         typedef std::vector< Instantiation > ValueList;
    120                         /// Underlying map type; maps keys to a linear list of corresponding TypeLists and values
    121                         typedef ScopedMap< Key*, ValueList > InnerMap;
    122 
    123                         InnerMap instantiations;  ///< instantiations
    124 
    125                 public:
    126                         /// Starts a new scope
    127                         void beginScope() { instantiations.beginScope(); }
    128 
    129                         /// Ends a scope
    130                         void endScope() { instantiations.endScope(); }
    131 
    132                         /// Gets the value for the (key, typeList) pair, returns NULL on none such.
    133                         Value *lookup( Key *key, const std::list< TypeExpr* >& params ) const {
    134                                 TypeList typeList( params );
    135                                
    136                                 // scan scopes for matches to the key
    137                                 for ( typename InnerMap::const_iterator insts = instantiations.find( key ); insts != instantiations.end(); insts = instantiations.findNext( insts, key ) ) {
    138                                         for ( typename ValueList::const_reverse_iterator inst = insts->second.rbegin(); inst != insts->second.rend(); ++inst ) {
    139                                                 if ( inst->first == typeList ) return inst->second;
    140                                         }
    141                                 }
    142                                 // no matching instantiations found
    143                                 return 0;
    144                         }
    145 
    146                         /// Adds a value for a (key, typeList) pair to the current scope
    147                         void insert( Key *key, const std::list< TypeExpr* > &params, Value *value ) {
    148                                 instantiations[ key ].push_back( Instantiation( TypeList( params ), value ) );
    149                         }
    150                 };
    151 
    152                 /// Adds layout-generation functions to polymorphic types
    153                 class LayoutFunctionBuilder : public DeclMutator {
    154                         unsigned int functionNesting;  // current level of nested functions
    155                 public:
    156                         LayoutFunctionBuilder() : functionNesting( 0 ) {}
    157 
    158                         virtual DeclarationWithType *mutate( FunctionDecl *functionDecl );
    159                         virtual Declaration *mutate( StructDecl *structDecl );
    160                         virtual Declaration *mutate( UnionDecl *unionDecl );
    161                 };
    162                
    16356                /// Replaces polymorphic return types with out-parameters, replaces calls to polymorphic functions with adapter calls as needed, and adds appropriate type variables to the function call
    16457                class Pass1 : public PolyMutator {
     
    17972                        virtual void doEndScope();
    18073                  private:
     74                        /// Makes a new temporary array holding the offsets of the fields of `type`, and returns a new variable expression referencing it
     75                        Expression *makeOffsetArray( StructInstType *type );
    18176                        /// Pass the extra type parameters from polymorphic generic arguments or return types into a function application
    18277                        void passArgTypeVars( ApplicationExpr *appExpr, Type *parmType, Type *argBaseType, std::list< Expression *>::iterator &arg, const TyVarMap &exprTyVars, std::set< std::string > &seenTypes );
     
    205100                        ObjectDecl *makeTemporary( Type *type );
    206101
    207                         ScopedMap< std::string, DeclarationWithType *> assignOps;    ///< Currently known type variable assignment operators
    208                         ResolvExpr::TypeMap< DeclarationWithType > scopedAssignOps;  ///< Currently known assignment operators
    209                         ScopedMap< std::string, DeclarationWithType* > adapters;     ///< Set of adapter functions in the current scope
    210                        
     102                        typedef std::map< std::string, DeclarationWithType *> AdapterMap;
     103                        std::map< std::string, DeclarationWithType *> assignOps;
     104                        ResolvExpr::TypeMap< DeclarationWithType > scopedAssignOps;
     105                        std::stack< AdapterMap > adapters;
    211106                        DeclarationWithType *retval;
    212107                        bool useRetval;
     
    214109                };
    215110
    216                 /// * Moves polymorphic returns in function types to pointer-type parameters
    217                 /// * adds type size and assertion parameters to parameter lists
     111                /// Moves polymorphic returns in function types to pointer-type parameters, adds type size and assertion parameters to parameter lists as well
    218112                class Pass2 : public PolyMutator {
    219113                  public:
     
    226120                        virtual Type *mutate( PointerType *pointerType );
    227121                        virtual Type *mutate( FunctionType *funcType );
    228                        
    229122                  private:
    230123                        void addAdapters( FunctionType *functionType );
     
    233126                };
    234127
    235                 /// Mutator pass that replaces concrete instantiations of generic types with actual struct declarations, scoped appropriately
    236                 class GenericInstantiator : public DeclMutator {
    237                         /// Map of (generic type, parameter list) pairs to concrete type instantiations
    238                         InstantiationMap< AggregateDecl, AggregateDecl > instantiations;
    239                         /// Namer for concrete types
    240                         UniqueName typeNamer;
    241 
    242                 public:
    243                         GenericInstantiator() : DeclMutator(), instantiations(), typeNamer("_conc_") {}
    244 
    245                         virtual Type* mutate( StructInstType *inst );
    246                         virtual Type* mutate( UnionInstType *inst );
    247 
    248         //              virtual Expression* mutate( MemberExpr *memberExpr );
    249 
    250                         virtual void doBeginScope();
    251                         virtual void doEndScope();
    252                 private:
    253                         /// Wrap instantiation lookup for structs
    254                         StructDecl* lookup( StructInstType *inst, const std::list< TypeExpr* > &typeSubs ) { return (StructDecl*)instantiations.lookup( inst->get_baseStruct(), typeSubs ); }
    255                         /// Wrap instantiation lookup for unions
    256                         UnionDecl* lookup( UnionInstType *inst, const std::list< TypeExpr* > &typeSubs ) { return (UnionDecl*)instantiations.lookup( inst->get_baseUnion(), typeSubs ); }
    257                         /// Wrap instantiation insertion for structs
    258                         void insert( StructInstType *inst, const std::list< TypeExpr* > &typeSubs, StructDecl *decl ) { instantiations.insert( inst->get_baseStruct(), typeSubs, decl ); }
    259                         /// Wrap instantiation insertion for unions
    260                         void insert( UnionInstType *inst, const std::list< TypeExpr* > &typeSubs, UnionDecl *decl ) { instantiations.insert( inst->get_baseUnion(), typeSubs, decl ); }
    261                 };
    262 
    263                 /// Replaces member and size/align/offsetof expressions on polymorphic generic types with calculated expressions.
    264                 /// * Replaces member expressions for polymorphic types with calculated add-field-offset-and-dereference
    265                 /// * Calculates polymorphic offsetof expressions from offset array
    266                 /// * Inserts dynamic calculation of polymorphic type layouts where needed
    267                 class PolyGenericCalculator : public PolyMutator {
    268                 public:
     128                /// Replaces member expressions for polymorphic types with calculated add-field-offset-and-dereference;
     129                /// also fixes offsetof expressions.
     130                class MemberExprFixer : public PolyMutator {
     131                  public:
    269132                        template< typename DeclClass >
    270133                        DeclClass *handleDecl( DeclClass *decl, Type *type );
     
    277140                        virtual Type *mutate( FunctionType *funcType );
    278141                        virtual Expression *mutate( MemberExpr *memberExpr );
    279                         virtual Expression *mutate( SizeofExpr *sizeofExpr );
    280                         virtual Expression *mutate( AlignofExpr *alignofExpr );
    281142                        virtual Expression *mutate( OffsetofExpr *offsetofExpr );
    282                         virtual Expression *mutate( OffsetPackExpr *offsetPackExpr );
    283 
    284                         virtual void doBeginScope();
    285                         virtual void doEndScope();
    286 
    287                 private:
    288                         /// Makes a new variable in the current scope with the given name, type & optional initializer
    289                         ObjectDecl *makeVar( const std::string &name, Type *type, Initializer *init = 0 );
    290                         /// returns true if the type has a dynamic layout; such a layout will be stored in appropriately-named local variables when the function returns
    291                         bool findGeneric( Type *ty );
    292                         /// adds type parameters to the layout call; will generate the appropriate parameters if needed
    293                         void addOtypeParamsToLayoutCall( UntypedExpr *layoutCall, const std::list< Type* > &otypeParams );
    294 
    295                         /// Enters a new scope for type-variables, adding the type variables from ty
    296                         void beginTypeScope( Type *ty );
    297                         /// Exits the type-variable scope
    298                         void endTypeScope();
    299                        
    300                         ScopedSet< std::string > knownLayouts;          ///< Set of generic type layouts known in the current scope, indexed by sizeofName
    301                         ScopedSet< std::string > knownOffsets;          ///< Set of non-generic types for which the offset array exists in the current scope, indexed by offsetofName
    302143                };
    303144
     
    318159        } // anonymous namespace
    319160
     161        void printAllNotBuiltin( const std::list< Declaration *>& translationUnit, std::ostream &os ) {
     162                for ( std::list< Declaration *>::const_iterator i = translationUnit.begin(); i != translationUnit.end(); ++i ) {
     163                        if ( ! LinkageSpec::isBuiltin( (*i)->get_linkage() ) ) {
     164                                (*i)->print( os );
     165                                os << std::endl;
     166                        } // if
     167                } // for
     168        }
     169
    320170        /// version of mutateAll with special handling for translation unit so you can check the end of the prelude when debugging
    321171        template< typename MutatorType >
     
    345195
    346196        void box( std::list< Declaration *>& translationUnit ) {
    347                 LayoutFunctionBuilder layoutBuilder;
    348197                Pass1 pass1;
    349198                Pass2 pass2;
    350                 GenericInstantiator instantiator;
    351                 PolyGenericCalculator polyCalculator;
     199                MemberExprFixer memberFixer;
    352200                Pass3 pass3;
    353                
    354                 layoutBuilder.mutateDeclarationList( translationUnit );
    355201                mutateTranslationUnit/*All*/( translationUnit, pass1 );
    356202                mutateTranslationUnit/*All*/( translationUnit, pass2 );
    357                 instantiator.mutateDeclarationList( translationUnit );
    358                 mutateTranslationUnit/*All*/( translationUnit, polyCalculator );
     203                instantiateGeneric( translationUnit );
     204                mutateTranslationUnit/*All*/( translationUnit, memberFixer );
    359205                mutateTranslationUnit/*All*/( translationUnit, pass3 );
    360206        }
    361207
    362         ////////////////////////////////// LayoutFunctionBuilder ////////////////////////////////////////////
    363 
    364         DeclarationWithType *LayoutFunctionBuilder::mutate( FunctionDecl *functionDecl ) {
    365                 functionDecl->set_functionType( maybeMutate( functionDecl->get_functionType(), *this ) );
    366                 mutateAll( functionDecl->get_oldDecls(), *this );
    367                 ++functionNesting;
    368                 functionDecl->set_statements( maybeMutate( functionDecl->get_statements(), *this ) );
    369                 --functionNesting;
    370                 return functionDecl;
    371         }
    372        
    373         /// Get a list of type declarations that will affect a layout function
    374         std::list< TypeDecl* > takeOtypeOnly( std::list< TypeDecl* > &decls ) {
    375                 std::list< TypeDecl * > otypeDecls;
    376 
    377                 for ( std::list< TypeDecl* >::const_iterator decl = decls.begin(); decl != decls.end(); ++decl ) {
    378                         if ( (*decl)->get_kind() == TypeDecl::Any ) {
    379                                 otypeDecls.push_back( *decl );
    380                         }
    381                 }
    382                
    383                 return otypeDecls;
    384         }
    385 
    386         /// Adds parameters for otype layout to a function type
    387         void addOtypeParams( FunctionType *layoutFnType, std::list< TypeDecl* > &otypeParams ) {
    388                 BasicType sizeAlignType( Type::Qualifiers(), BasicType::LongUnsignedInt );
    389                
    390                 for ( std::list< TypeDecl* >::const_iterator param = otypeParams.begin(); param != otypeParams.end(); ++param ) {
    391                         TypeInstType paramType( Type::Qualifiers(), (*param)->get_name(), *param );
    392                         std::string paramName = mangleType( &paramType );
    393                         layoutFnType->get_parameters().push_back( new ObjectDecl( sizeofName( paramName ), DeclarationNode::NoStorageClass, LinkageSpec::Cforall, 0, sizeAlignType.clone(), 0 ) );
    394                         layoutFnType->get_parameters().push_back( new ObjectDecl( alignofName( paramName ), DeclarationNode::NoStorageClass, LinkageSpec::Cforall, 0, sizeAlignType.clone(), 0 ) );
    395                 }
    396         }
    397 
    398         /// Builds a layout function declaration
    399         FunctionDecl *buildLayoutFunctionDecl( AggregateDecl *typeDecl, unsigned int functionNesting, FunctionType *layoutFnType ) {
    400                 // Routines at global scope marked "static" to prevent multiple definitions is separate translation units
    401                 // because each unit generates copies of the default routines for each aggregate.
    402                 FunctionDecl *layoutDecl = new FunctionDecl(
    403                         layoutofName( typeDecl ), functionNesting > 0 ? DeclarationNode::NoStorageClass : DeclarationNode::Static, LinkageSpec::AutoGen, layoutFnType, new CompoundStmt( noLabels ), true, false );
    404                 layoutDecl->fixUniqueId();
    405                 return layoutDecl;
    406         }
    407 
    408         /// Makes a unary operation
    409         Expression *makeOp( const std::string &name, Expression *arg ) {
    410                 UntypedExpr *expr = new UntypedExpr( new NameExpr( name ) );
    411                 expr->get_args().push_back( arg );
    412                 return expr;
    413         }
    414 
    415         /// Makes a binary operation
    416         Expression *makeOp( const std::string &name, Expression *lhs, Expression *rhs ) {
    417                 UntypedExpr *expr = new UntypedExpr( new NameExpr( name ) );
    418                 expr->get_args().push_back( lhs );
    419                 expr->get_args().push_back( rhs );
    420                 return expr;
    421         }
    422 
    423         /// Returns the dereference of a local pointer variable
    424         Expression *derefVar( ObjectDecl *var ) {
    425                 return makeOp( "*?", new VariableExpr( var ) );
    426         }
    427 
    428         /// makes an if-statement with a single-expression if-block and no then block
    429         Statement *makeCond( Expression *cond, Expression *ifPart ) {
    430                 return new IfStmt( noLabels, cond, new ExprStmt( noLabels, ifPart ), 0 );
    431         }
    432 
    433         /// makes a statement that assigns rhs to lhs if lhs < rhs
    434         Statement *makeAssignMax( Expression *lhs, Expression *rhs ) {
    435                 return makeCond( makeOp( "?<?", lhs, rhs ), makeOp( "?=?", lhs->clone(), rhs->clone() ) );
    436         }
    437 
    438         /// makes a statement that aligns lhs to rhs (rhs should be an integer power of two)
    439         Statement *makeAlignTo( Expression *lhs, Expression *rhs ) {
    440                 // check that the lhs is zeroed out to the level of rhs
    441                 Expression *ifCond = makeOp( "?&?", lhs, makeOp( "?-?", rhs, new ConstantExpr( Constant( new BasicType( Type::Qualifiers(), BasicType::LongUnsignedInt ), "1" ) ) ) );
    442                 // if not aligned, increment to alignment
    443                 Expression *ifExpr = makeOp( "?+=?", lhs->clone(), makeOp( "?-?", rhs->clone(), ifCond->clone() ) );
    444                 return makeCond( ifCond, ifExpr );
    445         }
    446        
    447         /// adds an expression to a compound statement
    448         void addExpr( CompoundStmt *stmts, Expression *expr ) {
    449                 stmts->get_kids().push_back( new ExprStmt( noLabels, expr ) );
    450         }
    451 
    452         /// adds a statement to a compound statement
    453         void addStmt( CompoundStmt *stmts, Statement *stmt ) {
    454                 stmts->get_kids().push_back( stmt );
    455         }
    456        
    457         Declaration *LayoutFunctionBuilder::mutate( StructDecl *structDecl ) {
    458                 // do not generate layout function for "empty" tag structs
    459                 if ( structDecl->get_members().empty() ) return structDecl;
    460 
    461                 // get parameters that can change layout, exiting early if none
    462                 std::list< TypeDecl* > otypeParams = takeOtypeOnly( structDecl->get_parameters() );
    463                 if ( otypeParams.empty() ) return structDecl;
    464 
    465                 // build layout function signature
    466                 FunctionType *layoutFnType = new FunctionType( Type::Qualifiers(), false );
    467                 BasicType *sizeAlignType = new BasicType( Type::Qualifiers(), BasicType::LongUnsignedInt );
    468                 PointerType *sizeAlignOutType = new PointerType( Type::Qualifiers(), sizeAlignType );
    469                
    470                 ObjectDecl *sizeParam = new ObjectDecl( sizeofName( structDecl->get_name() ), DeclarationNode::NoStorageClass, LinkageSpec::Cforall, 0, sizeAlignOutType, 0 );
    471                 layoutFnType->get_parameters().push_back( sizeParam );
    472                 ObjectDecl *alignParam = new ObjectDecl( alignofName( structDecl->get_name() ), DeclarationNode::NoStorageClass, LinkageSpec::Cforall, 0, sizeAlignOutType->clone(), 0 );
    473                 layoutFnType->get_parameters().push_back( alignParam );
    474                 ObjectDecl *offsetParam = new ObjectDecl( offsetofName( structDecl->get_name() ), DeclarationNode::NoStorageClass, LinkageSpec::Cforall, 0, sizeAlignOutType->clone(), 0 );
    475                 layoutFnType->get_parameters().push_back( offsetParam );
    476                 addOtypeParams( layoutFnType, otypeParams );
    477 
    478                 // build function decl
    479                 FunctionDecl *layoutDecl = buildLayoutFunctionDecl( structDecl, functionNesting, layoutFnType );
    480 
    481                 // calculate struct layout in function body
    482 
    483                 // initialize size and alignment to 0 and 1 (will have at least one member to re-edit size
    484                 addExpr( layoutDecl->get_statements(), makeOp( "?=?", derefVar( sizeParam ), new ConstantExpr( Constant( sizeAlignType->clone(), "0" ) ) ) );
    485                 addExpr( layoutDecl->get_statements(), makeOp( "?=?", derefVar( alignParam ), new ConstantExpr( Constant( sizeAlignType->clone(), "1" ) ) ) );
    486                 unsigned long n_members = 0;
    487                 bool firstMember = true;
    488                 for ( std::list< Declaration* >::const_iterator member = structDecl->get_members().begin(); member != structDecl->get_members().end(); ++member ) {
    489                         DeclarationWithType *dwt = dynamic_cast< DeclarationWithType * >( *member );
    490                         assert( dwt );
    491                         Type *memberType = dwt->get_type();
    492 
    493                         if ( firstMember ) {
    494                                 firstMember = false;
    495                         } else {
    496                                 // make sure all members after the first (automatically aligned at 0) are properly padded for alignment
    497                                 addStmt( layoutDecl->get_statements(), makeAlignTo( derefVar( sizeParam ), new AlignofExpr( memberType->clone() ) ) );
    498                         }
    499                        
    500                         // place current size in the current offset index
    501                         addExpr( layoutDecl->get_statements(), makeOp( "?=?", makeOp( "?[?]", new VariableExpr( offsetParam ), new ConstantExpr( Constant::from( n_members ) ) ),
    502                                                                               derefVar( sizeParam ) ) );
    503                         ++n_members;
    504 
    505                         // add member size to current size
    506                         addExpr( layoutDecl->get_statements(), makeOp( "?+=?", derefVar( sizeParam ), new SizeofExpr( memberType->clone() ) ) );
    507                        
    508                         // take max of member alignment and global alignment
    509                         addStmt( layoutDecl->get_statements(), makeAssignMax( derefVar( alignParam ), new AlignofExpr( memberType->clone() ) ) );
    510                 }
    511                 // make sure the type is end-padded to a multiple of its alignment
    512                 addStmt( layoutDecl->get_statements(), makeAlignTo( derefVar( sizeParam ), derefVar( alignParam ) ) );
    513 
    514                 addDeclarationAfter( layoutDecl );
    515                 return structDecl;
    516         }
    517        
    518         Declaration *LayoutFunctionBuilder::mutate( UnionDecl *unionDecl ) {
    519                 // do not generate layout function for "empty" tag unions
    520                 if ( unionDecl->get_members().empty() ) return unionDecl;
    521                
    522                 // get parameters that can change layout, exiting early if none
    523                 std::list< TypeDecl* > otypeParams = takeOtypeOnly( unionDecl->get_parameters() );
    524                 if ( otypeParams.empty() ) return unionDecl;
    525 
    526                 // build layout function signature
    527                 FunctionType *layoutFnType = new FunctionType( Type::Qualifiers(), false );
    528                 BasicType *sizeAlignType = new BasicType( Type::Qualifiers(), BasicType::LongUnsignedInt );
    529                 PointerType *sizeAlignOutType = new PointerType( Type::Qualifiers(), sizeAlignType );
    530                
    531                 ObjectDecl *sizeParam = new ObjectDecl( sizeofName( unionDecl->get_name() ), DeclarationNode::NoStorageClass, LinkageSpec::Cforall, 0, sizeAlignOutType, 0 );
    532                 layoutFnType->get_parameters().push_back( sizeParam );
    533                 ObjectDecl *alignParam = new ObjectDecl( alignofName( unionDecl->get_name() ), DeclarationNode::NoStorageClass, LinkageSpec::Cforall, 0, sizeAlignOutType->clone(), 0 );
    534                 layoutFnType->get_parameters().push_back( alignParam );
    535                 addOtypeParams( layoutFnType, otypeParams );
    536 
    537                 // build function decl
    538                 FunctionDecl *layoutDecl = buildLayoutFunctionDecl( unionDecl, functionNesting, layoutFnType );
    539 
    540                 // calculate union layout in function body
    541                 addExpr( layoutDecl->get_statements(), makeOp( "?=?", derefVar( sizeParam ), new ConstantExpr( Constant( sizeAlignType->clone(), "1" ) ) ) );
    542                 addExpr( layoutDecl->get_statements(), makeOp( "?=?", derefVar( alignParam ), new ConstantExpr( Constant( sizeAlignType->clone(), "1" ) ) ) );
    543                 for ( std::list< Declaration* >::const_iterator member = unionDecl->get_members().begin(); member != unionDecl->get_members().end(); ++member ) {
    544                         DeclarationWithType *dwt = dynamic_cast< DeclarationWithType * >( *member );
    545                         assert( dwt );
    546                         Type *memberType = dwt->get_type();
    547                        
    548                         // take max member size and global size
    549                         addStmt( layoutDecl->get_statements(), makeAssignMax( derefVar( sizeParam ), new SizeofExpr( memberType->clone() ) ) );
    550                        
    551                         // take max of member alignment and global alignment
    552                         addStmt( layoutDecl->get_statements(), makeAssignMax( derefVar( alignParam ), new AlignofExpr( memberType->clone() ) ) );
    553                 }
    554                 // make sure the type is end-padded to a multiple of its alignment
    555                 addStmt( layoutDecl->get_statements(), makeAlignTo( derefVar( sizeParam ), derefVar( alignParam ) ) );
    556 
    557                 addDeclarationAfter( layoutDecl );
    558                 return unionDecl;
    559         }
    560        
    561208        ////////////////////////////////////////// Pass1 ////////////////////////////////////////////////////
    562209
     
    598245                }
    599246
    600                 Pass1::Pass1() : useRetval( false ), tempNamer( "_temp" ) {}
     247                Pass1::Pass1() : useRetval( false ), tempNamer( "_temp" ) {
     248                        adapters.push(AdapterMap());
     249                }
    601250
    602251                /// Returns T if the given declaration is (*?=?)(T *, T) for some TypeInstType T (return not checked, but maybe should be), NULL otherwise
     
    660309
    661310                DeclarationWithType *Pass1::mutate( FunctionDecl *functionDecl ) {
    662                         // if this is a assignment function, put it in the map for this scope
     311                        // if this is a polymorphic assignment function, put it in the map for this scope
    663312                        if ( Type *assignedType = isAssignment( functionDecl ) ) {
    664313                                if ( ! dynamic_cast< TypeInstType* >( assignedType ) ) {
     
    669318                        if ( functionDecl->get_statements() ) {         // empty routine body ?
    670319                                doBeginScope();
    671                                 scopeTyVars.beginScope();
    672                                 assignOps.beginScope();
     320                                TyVarMap oldtyVars = scopeTyVars;
     321                                std::map< std::string, DeclarationWithType *> oldassignOps = assignOps;
    673322                                DeclarationWithType *oldRetval = retval;
    674323                                bool oldUseRetval = useRetval;
     
    701350                                } // for
    702351
     352                                AdapterMap & adapters = Pass1::adapters.top();
    703353                                for ( std::list< FunctionType *>::iterator funType = functions.begin(); funType != functions.end(); ++funType ) {
    704354                                        std::string mangleName = mangleAdapterName( *funType, scopeTyVars );
     
    711361                                functionDecl->set_statements( functionDecl->get_statements()->acceptMutator( *this ) );
    712362
    713                                 scopeTyVars.endScope();
    714                                 assignOps.endScope();
     363                                scopeTyVars = oldtyVars;
     364                                assignOps = oldassignOps;
     365                                // std::cerr << "end FunctionDecl: ";
     366                                // for ( TyVarMap::iterator i = scopeTyVars.begin(); i != scopeTyVars.end(); ++i ) {
     367                                //      std::cerr << i->first << " ";
     368                                // }
     369                                // std::cerr << "\n";
    715370                                retval = oldRetval;
    716371                                useRetval = oldUseRetval;
     
    745400                }
    746401
     402                Expression *Pass1::makeOffsetArray( StructInstType *ty ) {
     403                        std::list< Declaration* > &baseMembers = ty->get_baseStruct()->get_members();
     404
     405                        // make a new temporary array
     406                        Type *offsetType = new BasicType( Type::Qualifiers(), BasicType::LongUnsignedInt );
     407                        std::stringstream lenGen;
     408                        lenGen << baseMembers.size();
     409                        ConstantExpr *lenExpr = new ConstantExpr( Constant( offsetType->clone(), lenGen.str() ) );
     410                        ObjectDecl *arrayTemp = makeTemporary( new ArrayType( Type::Qualifiers(), offsetType, lenExpr, false, false ) );
     411
     412                        // build initializer list for temporary
     413                        std::list< Initializer* > inits;
     414                        for ( std::list< Declaration* >::const_iterator member = baseMembers.begin(); member != baseMembers.end(); ++member ) {
     415                                DeclarationWithType *memberDecl;
     416                                if ( DeclarationWithType *origMember = dynamic_cast< DeclarationWithType* >( *member ) ) {
     417                                        memberDecl = origMember->clone();
     418                                } else {
     419                                        memberDecl = new ObjectDecl( (*member)->get_name(), DeclarationNode::NoStorageClass, LinkageSpec::Cforall, 0, offsetType->clone(), 0 );
     420                                }
     421                                inits.push_back( new SingleInit( new OffsetofExpr( ty->clone(), memberDecl ) ) );
     422                        }
     423                        arrayTemp->set_init( new ListInit( inits ) );
     424
     425                        // return variable pointing to temporary
     426                        return new VariableExpr( arrayTemp );
     427                }
     428
    747429                void Pass1::passArgTypeVars( ApplicationExpr *appExpr, Type *parmType, Type *argBaseType, std::list< Expression *>::iterator &arg, const TyVarMap &exprTyVars, std::set< std::string > &seenTypes ) {
    748                         Type *polyType = isPolyType( parmType, exprTyVars );
    749                         if ( polyType && ! dynamic_cast< TypeInstType* >( polyType ) ) {
    750                                 std::string typeName = mangleType( polyType );
    751                                 if ( seenTypes.count( typeName ) ) return;
     430                        Type *polyBase = hasPolyBase( parmType, exprTyVars );
     431                        if ( polyBase && ! dynamic_cast< TypeInstType* >( polyBase ) ) {
     432                                std::string sizeName = sizeofName( polyBase );
     433                                if ( seenTypes.count( sizeName ) ) return;
    752434
    753435                                arg = appExpr->get_args().insert( arg, new SizeofExpr( argBaseType->clone() ) );
     
    755437                                arg = appExpr->get_args().insert( arg, new AlignofExpr( argBaseType->clone() ) );
    756438                                arg++;
    757                                 if ( dynamic_cast< StructInstType* >( polyType ) ) {
     439                                if ( dynamic_cast< StructInstType* >( polyBase ) ) {
    758440                                        if ( StructInstType *argBaseStructType = dynamic_cast< StructInstType* >( argBaseType ) ) {
    759                                                 // zero-length arrays are forbidden by C, so don't pass offset for empty struct
    760                                                 if ( ! argBaseStructType->get_baseStruct()->get_members().empty() ) {
    761                                                         arg = appExpr->get_args().insert( arg, new OffsetPackExpr( argBaseStructType->clone() ) );
    762                                                         arg++;
    763                                                 }
     441                                                arg = appExpr->get_args().insert( arg, makeOffsetArray( argBaseStructType ) );
     442                                                arg++;
    764443                                        } else {
    765444                                                throw SemanticError( "Cannot pass non-struct type for generic struct" );
     
    767446                                }
    768447
    769                                 seenTypes.insert( typeName );
     448                                seenTypes.insert( sizeName );
    770449                        }
    771450                }
     
    909588                                        return;
    910589                                } else if ( arg->get_results().front()->get_isLvalue() ) {
    911                                         // VariableExpr and MemberExpr are lvalues; need to check this isn't coming from the second arg of a comma expression though (not an lvalue)
    912                                         if ( CommaExpr *commaArg = dynamic_cast< CommaExpr* >( arg ) ) {
    913                                                 commaArg->set_arg2( new AddressExpr( commaArg->get_arg2() ) );
    914                                         } else {
    915                                                 arg = new AddressExpr( arg );
    916                                         }
     590                                        // VariableExpr and MemberExpr are lvalues
     591                                        arg = new AddressExpr( arg );
    917592                                } else {
    918593                                        // use type computed in unification to declare boxed variables
     
    1009684                        } // for
    1010685                }
     686
     687
    1011688
    1012689                FunctionDecl *Pass1::makeAdapter( FunctionType *adaptee, FunctionType *realType, const std::string &mangleName, const TyVarMap &tyVars ) {
     
    1095772                                        mangleName += makePolyMonoSuffix( originalFunction, exprTyVars );
    1096773
    1097                                         typedef ScopedMap< std::string, DeclarationWithType* >::iterator AdapterIter;
    1098                                         AdapterIter adapter = adapters.find( mangleName );
     774                                        AdapterMap & adapters = Pass1::adapters.top();
     775                                        AdapterMap::iterator adapter = adapters.find( mangleName );
    1099776                                        if ( adapter == adapters.end() ) {
    1100777                                                // adapter has not been created yet in the current scope, so define it
    1101778                                                FunctionDecl *newAdapter = makeAdapter( *funType, realFunction, mangleName, exprTyVars );
    1102                                                 std::pair< AdapterIter, bool > answer = adapters.insert( std::pair< std::string, DeclarationWithType *>( mangleName, newAdapter ) );
    1103                                                 adapter = answer.first;
     779                                                adapter = adapters.insert( adapters.begin(), std::pair< std::string, DeclarationWithType *>( mangleName, newAdapter ) );
    1104780                                                stmtsToAdd.push_back( new DeclStmt( noLabels, newAdapter ) );
    1105781                                        } // if
     
    1125801                                addAssign->get_args().push_back( appExpr->get_args().front() );
    1126802                        } // if
    1127                         addAssign->get_args().push_back( new NameExpr( sizeofName( mangleType( polyType ) ) ) );
     803                        addAssign->get_args().push_back( new NameExpr( sizeofName( polyType ) ) );
    1128804                        addAssign->get_results().front() = appExpr->get_results().front()->clone();
    1129805                        if ( appExpr->get_env() ) {
     
    1152828                                                        UntypedExpr *multiply = new UntypedExpr( new NameExpr( "?*?" ) );
    1153829                                                        multiply->get_args().push_back( appExpr->get_args().back() );
    1154                                                         multiply->get_args().push_back( new SizeofExpr( baseType1->clone() ) );
     830                                                        multiply->get_args().push_back( new NameExpr( sizeofName( baseType1 ) ) );
    1155831                                                        ret->get_args().push_back( appExpr->get_args().front() );
    1156832                                                        ret->get_args().push_back( multiply );
     
    1158834                                                        UntypedExpr *multiply = new UntypedExpr( new NameExpr( "?*?" ) );
    1159835                                                        multiply->get_args().push_back( appExpr->get_args().front() );
    1160                                                         multiply->get_args().push_back( new SizeofExpr( baseType2->clone() ) );
     836                                                        multiply->get_args().push_back( new NameExpr( sizeofName( baseType2 ) ) );
    1161837                                                        ret->get_args().push_back( multiply );
    1162838                                                        ret->get_args().push_back( appExpr->get_args().back() );
     
    1221897                                                        UntypedExpr *divide = new UntypedExpr( new NameExpr( "?/?" ) );
    1222898                                                        divide->get_args().push_back( appExpr );
    1223                                                         divide->get_args().push_back( new SizeofExpr( baseType1->clone() ) );
     899                                                        divide->get_args().push_back( new NameExpr( sizeofName( baseType1 ) ) );
    1224900                                                        divide->get_results().push_front( appExpr->get_results().front()->clone() );
    1225901                                                        if ( appExpr->get_env() ) {
     
    1231907                                                        UntypedExpr *multiply = new UntypedExpr( new NameExpr( "?*?" ) );
    1232908                                                        multiply->get_args().push_back( appExpr->get_args().back() );
    1233                                                         multiply->get_args().push_back( new SizeofExpr( baseType1->clone() ) );
     909                                                        multiply->get_args().push_back( new NameExpr( sizeofName( baseType1 ) ) );
    1234910                                                        appExpr->get_args().back() = multiply;
    1235911                                                } else if ( baseType2 ) {
    1236912                                                        UntypedExpr *multiply = new UntypedExpr( new NameExpr( "?*?" ) );
    1237913                                                        multiply->get_args().push_back( appExpr->get_args().front() );
    1238                                                         multiply->get_args().push_back( new SizeofExpr( baseType2->clone() ) );
     914                                                        multiply->get_args().push_back( new NameExpr( sizeofName( baseType2 ) ) );
    1239915                                                        appExpr->get_args().front() = multiply;
    1240916                                                } // if
     
    1246922                                                        UntypedExpr *multiply = new UntypedExpr( new NameExpr( "?*?" ) );
    1247923                                                        multiply->get_args().push_back( appExpr->get_args().back() );
    1248                                                         multiply->get_args().push_back( new SizeofExpr( baseType->clone() ) );
     924                                                        multiply->get_args().push_back( new NameExpr( sizeofName( baseType ) ) );
    1249925                                                        appExpr->get_args().back() = multiply;
    1250926                                                } // if
     
    1283959                        std::list< Expression *>::iterator paramBegin = appExpr->get_args().begin();
    1284960
    1285                         TyVarMap exprTyVars( (TypeDecl::Kind)-1 );
     961                        TyVarMap exprTyVars;
    1286962                        makeTyVarMap( function, exprTyVars );
    1287963                        ReferenceToType *polyRetType = isPolyRet( function );
     
    1306982
    1307983                        boxParams( appExpr, function, arg, exprTyVars );
     984
    1308985                        passAdapters( appExpr, function, exprTyVars );
    1309986
     
    13851062                                if ( TypeInstType *typeInst = dynamic_cast< TypeInstType *>( retval->get_type() ) ) {
    13861063                                        // find assignment operator for type variable
    1387                                         ScopedMap< std::string, DeclarationWithType *>::const_iterator assignIter = assignOps.find( typeInst->get_name() );
     1064                                        std::map< std::string, DeclarationWithType *>::const_iterator assignIter = assignOps.find( typeInst->get_name() );
    13881065                                        if ( assignIter == assignOps.end() ) {
    13891066                                                throw SemanticError( "Attempt to return dtype or ftype object in ", returnStmt->get_expr() );
     
    14071084                                        std::list< TypeDecl* >::const_iterator forallIt = forallParams.begin();
    14081085                                        for ( ; tyIt != tyParams.end() && forallIt != forallParams.end(); ++tyIt, ++forallIt ) {
    1409                                                 // Add appropriate mapping to assignment expression environment
     1086                                                if ( (*forallIt)->get_kind() != TypeDecl::Any ) continue; // skip types with no assign op (ftype/dtype)
     1087
     1088                                                std::list< DeclarationWithType* > &asserts = (*forallIt)->get_assertions();
     1089                                                assert( ! asserts.empty() && "Type param needs assignment operator assertion" );
     1090                                                DeclarationWithType *actualDecl = asserts.front();
     1091                                                TypeInstType *actualType = isTypeInstAssignment( actualDecl );
     1092                                                assert( actualType && "First assertion of type with assertions should be assignment operator" );
    14101093                                                TypeExpr *formalTypeExpr = dynamic_cast< TypeExpr* >( *tyIt );
    14111094                                                assert( formalTypeExpr && "type parameters must be type expressions" );
    14121095                                                Type *formalType = formalTypeExpr->get_type();
    1413                                                 assignExpr->get_env()->add( (*forallIt)->get_name(), formalType );
    1414 
    1415                                                 // skip types with no assign op (ftype/dtype)
    1416                                                 if ( (*forallIt)->get_kind() != TypeDecl::Any ) continue;
    1417 
    1418                                                 // find assignment operator for formal type
     1096                                                assignExpr->get_env()->add( actualType->get_name(), formalType );
     1097                                               
    14191098                                                DeclarationWithType *assertAssign = 0;
    14201099                                                if ( TypeInstType *formalTypeInstType = dynamic_cast< TypeInstType* >( formalType ) ) {
    1421                                                         ScopedMap< std::string, DeclarationWithType *>::const_iterator assertAssignIt = assignOps.find( formalTypeInstType->get_name() );
     1100                                                        std::map< std::string, DeclarationWithType *>::const_iterator assertAssignIt = assignOps.find( formalTypeInstType->get_name() );
    14221101                                                        if ( assertAssignIt == assignOps.end() ) {
    14231102                                                                throw SemanticError( "No assignment operation found for ", formalTypeInstType );
     
    14301109                                                        }
    14311110                                                }
    1432 
    1433                                                 // add inferred parameter for field assignment operator to assignment expression
    1434                                                 std::list< DeclarationWithType* > &asserts = (*forallIt)->get_assertions();
    1435                                                 assert( ! asserts.empty() && "Type param needs assignment operator assertion" );
    1436                                                 DeclarationWithType *actualDecl = asserts.front();
     1111                                               
     1112
    14371113                                                assignExpr->get_inferParams()[ actualDecl->get_uniqueId() ]
    14381114                                                        = ParamEntry( assertAssign->get_uniqueId(), assertAssign->get_type()->clone(), actualDecl->get_type()->clone(), wrapFunctionDecl( assertAssign ) );
     
    14601136
    14611137                Type * Pass1::mutate( PointerType *pointerType ) {
    1462                         scopeTyVars.beginScope();
     1138                        TyVarMap oldtyVars = scopeTyVars;
    14631139                        makeTyVarMap( pointerType, scopeTyVars );
    14641140
    14651141                        Type *ret = Mutator::mutate( pointerType );
    14661142
    1467                         scopeTyVars.endScope();
     1143                        scopeTyVars = oldtyVars;
    14681144                        return ret;
    14691145                }
    14701146
    14711147                Type * Pass1::mutate( FunctionType *functionType ) {
    1472                         scopeTyVars.beginScope();
     1148                        TyVarMap oldtyVars = scopeTyVars;
    14731149                        makeTyVarMap( functionType, scopeTyVars );
    14741150
    14751151                        Type *ret = Mutator::mutate( functionType );
    14761152
    1477                         scopeTyVars.endScope();
     1153                        scopeTyVars = oldtyVars;
    14781154                        return ret;
    14791155                }
    14801156
    14811157                void Pass1::doBeginScope() {
    1482                         adapters.beginScope();
     1158                        // push a copy of the current map
     1159                        adapters.push(adapters.top());
    14831160                        scopedAssignOps.beginScope();
    14841161                }
    14851162
    14861163                void Pass1::doEndScope() {
    1487                         adapters.endScope();
     1164                        adapters.pop();
    14881165                        scopedAssignOps.endScope();
    14891166                }
     
    15401217
    15411218                Type * Pass2::mutate( PointerType *pointerType ) {
    1542                         scopeTyVars.beginScope();
     1219                        TyVarMap oldtyVars = scopeTyVars;
    15431220                        makeTyVarMap( pointerType, scopeTyVars );
    15441221
    15451222                        Type *ret = Mutator::mutate( pointerType );
    15461223
    1547                         scopeTyVars.endScope();
     1224                        scopeTyVars = oldtyVars;
    15481225                        return ret;
    15491226                }
    15501227
    15511228                Type *Pass2::mutate( FunctionType *funcType ) {
    1552                         scopeTyVars.beginScope();
     1229                        TyVarMap oldtyVars = scopeTyVars;
    15531230                        makeTyVarMap( funcType, scopeTyVars );
    15541231
     
    15671244                        ObjectDecl newPtr( "", DeclarationNode::NoStorageClass, LinkageSpec::C, 0,
    15681245                                           new PointerType( Type::Qualifiers(), new BasicType( Type::Qualifiers(), BasicType::LongUnsignedInt ) ), 0 );
     1246//   ObjectDecl *newFunPtr = new ObjectDecl( "", DeclarationNode::NoStorageClass, LinkageSpec::Cforall, 0, new PointerType( Type::Qualifiers(), new FunctionType( Type::Qualifiers(), true ) ), 0 );
    15691247                        for ( std::list< TypeDecl *>::const_iterator tyParm = funcType->get_forall().begin(); tyParm != funcType->get_forall().end(); ++tyParm ) {
    15701248                                ObjectDecl *sizeParm, *alignParm;
     
    15721250                                if ( (*tyParm)->get_kind() == TypeDecl::Any ) {
    15731251                                        TypeInstType parmType( Type::Qualifiers(), (*tyParm)->get_name(), *tyParm );
    1574                                         std::string parmName = mangleType( &parmType );
    15751252
    15761253                                        sizeParm = newObj.clone();
    1577                                         sizeParm->set_name( sizeofName( parmName ) );
     1254                                        sizeParm->set_name( sizeofName( &parmType ) );
    15781255                                        last = funcType->get_parameters().insert( last, sizeParm );
    15791256                                        ++last;
    15801257
    15811258                                        alignParm = newObj.clone();
    1582                                         alignParm->set_name( alignofName( parmName ) );
     1259                                        alignParm->set_name( alignofName( &parmType ) );
    15831260                                        last = funcType->get_parameters().insert( last, alignParm );
    15841261                                        ++last;
     
    15951272                        std::set< std::string > seenTypes; // sizeofName for generic types we've seen
    15961273                        for ( std::list< DeclarationWithType* >::const_iterator fnParm = last; fnParm != funcType->get_parameters().end(); ++fnParm ) {
    1597                                 Type *polyType = isPolyType( (*fnParm)->get_type(), scopeTyVars );
    1598                                 if ( polyType && ! dynamic_cast< TypeInstType* >( polyType ) ) {
    1599                                         std::string typeName = mangleType( polyType );
    1600                                         if ( seenTypes.count( typeName ) ) continue;
     1274                                Type *polyBase = hasPolyBase( (*fnParm)->get_type(), scopeTyVars );
     1275                                if ( polyBase && ! dynamic_cast< TypeInstType* >( polyBase ) ) {
     1276                                        std::string sizeName = sizeofName( polyBase );
     1277                                        if ( seenTypes.count( sizeName ) ) continue;
    16011278
    16021279                                        ObjectDecl *sizeParm, *alignParm, *offsetParm;
    16031280                                        sizeParm = newObj.clone();
    1604                                         sizeParm->set_name( sizeofName( typeName ) );
     1281                                        sizeParm->set_name( sizeName );
    16051282                                        last = funcType->get_parameters().insert( last, sizeParm );
    16061283                                        ++last;
    16071284
    16081285                                        alignParm = newObj.clone();
    1609                                         alignParm->set_name( alignofName( typeName ) );
     1286                                        alignParm->set_name( alignofName( polyBase ) );
    16101287                                        last = funcType->get_parameters().insert( last, alignParm );
    16111288                                        ++last;
    16121289
    1613                                         if ( StructInstType *polyBaseStruct = dynamic_cast< StructInstType* >( polyType ) ) {
    1614                                                 // NOTE zero-length arrays are illegal in C, so empty structs have no offset array
    1615                                                 if ( ! polyBaseStruct->get_baseStruct()->get_members().empty() ) {
    1616                                                         offsetParm = newPtr.clone();
    1617                                                         offsetParm->set_name( offsetofName( typeName ) );
    1618                                                         last = funcType->get_parameters().insert( last, offsetParm );
    1619                                                         ++last;
    1620                                                 }
     1290                                        if ( dynamic_cast< StructInstType* >( polyBase ) ) {
     1291                                                offsetParm = newPtr.clone();
     1292                                                offsetParm->set_name( offsetofName( polyBase ) );
     1293                                                last = funcType->get_parameters().insert( last, offsetParm );
     1294                                                ++last;
    16211295                                        }
    16221296
    1623                                         seenTypes.insert( typeName );
     1297                                        seenTypes.insert( sizeName );
    16241298                                }
    16251299                        }
     
    16311305                        mutateAll( funcType->get_parameters(), *this );
    16321306
    1633                         scopeTyVars.endScope();
     1307                        scopeTyVars = oldtyVars;
    16341308                        return funcType;
    16351309                }
    16361310
    1637 //////////////////////////////////////// GenericInstantiator //////////////////////////////////////////////////
    1638 
    1639                 /// Makes substitutions of params into baseParams; returns true if all parameters substituted for a concrete type
    1640                 bool makeSubstitutions( const std::list< TypeDecl* >& baseParams, const std::list< Expression* >& params, std::list< TypeExpr* >& out ) {
    1641                         bool allConcrete = true;  // will finish the substitution list even if they're not all concrete
    1642 
    1643                         // substitute concrete types for given parameters, and incomplete types for placeholders
    1644                         std::list< TypeDecl* >::const_iterator baseParam = baseParams.begin();
    1645                         std::list< Expression* >::const_iterator param = params.begin();
    1646                         for ( ; baseParam != baseParams.end() && param != params.end(); ++baseParam, ++param ) {
    1647         //                      switch ( (*baseParam)->get_kind() ) {
    1648         //                      case TypeDecl::Any: {   // any type is a valid substitution here; complete types can be used to instantiate generics
    1649                                         TypeExpr *paramType = dynamic_cast< TypeExpr* >( *param );
    1650                                         assert(paramType && "Aggregate parameters should be type expressions");
    1651                                         out.push_back( paramType->clone() );
    1652                                         // check that the substituted type isn't a type variable itself
    1653                                         if ( dynamic_cast< TypeInstType* >( paramType->get_type() ) ) {
    1654                                                 allConcrete = false;
    1655                                         }
    1656         //                              break;
    1657         //                      }
    1658         //                      case TypeDecl::Dtype:  // dtype can be consistently replaced with void [only pointers, which become void*]
    1659         //                              out.push_back( new TypeExpr( new VoidType( Type::Qualifiers() ) ) );
    1660         //                              break;
    1661         //                      case TypeDecl::Ftype:  // pointer-to-ftype can be consistently replaced with void (*)(void) [similar to dtype]
    1662         //                              out.push_back( new TypeExpr( new FunctionType( Type::Qualifiers(), false ) ) );
    1663         //                              break;
    1664         //                      }
    1665                         }
    1666 
    1667                         // if any parameters left over, not done
    1668                         if ( baseParam != baseParams.end() ) return false;
    1669         //              // if not enough parameters given, substitute remaining incomplete types for placeholders
    1670         //              for ( ; baseParam != baseParams.end(); ++baseParam ) {
    1671         //                      switch ( (*baseParam)->get_kind() ) {
    1672         //                      case TypeDecl::Any:    // no more substitutions here, fail early
    1673         //                              return false;
    1674         //                      case TypeDecl::Dtype:  // dtype can be consistently replaced with void [only pointers, which become void*]
    1675         //                              out.push_back( new TypeExpr( new VoidType( Type::Qualifiers() ) ) );
    1676         //                              break;
    1677         //                      case TypeDecl::Ftype:  // pointer-to-ftype can be consistently replaced with void (*)(void) [similar to dtype]
    1678         //                              out.push_back( new TypeExpr( new FunctionType( Type::Qualifiers(), false ) ) );
    1679         //                              break;
    1680         //                      }
    1681         //              }
    1682 
    1683                         return allConcrete;
    1684                 }
    1685 
    1686                 /// Substitutes types of members of in according to baseParams => typeSubs, appending the result to out
    1687                 void substituteMembers( const std::list< Declaration* >& in, const std::list< TypeDecl* >& baseParams, const std::list< TypeExpr* >& typeSubs,
    1688                                                                 std::list< Declaration* >& out ) {
    1689                         // substitute types into new members
    1690                         TypeSubstitution subs( baseParams.begin(), baseParams.end(), typeSubs.begin() );
    1691                         for ( std::list< Declaration* >::const_iterator member = in.begin(); member != in.end(); ++member ) {
    1692                                 Declaration *newMember = (*member)->clone();
    1693                                 subs.apply(newMember);
    1694                                 out.push_back( newMember );
    1695                         }
    1696                 }
    1697 
    1698                 Type* GenericInstantiator::mutate( StructInstType *inst ) {
    1699                         // mutate subtypes
    1700                         Type *mutated = Mutator::mutate( inst );
    1701                         inst = dynamic_cast< StructInstType* >( mutated );
    1702                         if ( ! inst ) return mutated;
    1703 
    1704                         // exit early if no need for further mutation
    1705                         if ( inst->get_parameters().empty() ) return inst;
    1706                         assert( inst->get_baseParameters() && "Base struct has parameters" );
    1707 
    1708                         // check if type can be concretely instantiated; put substitutions into typeSubs
    1709                         std::list< TypeExpr* > typeSubs;
    1710                         if ( ! makeSubstitutions( *inst->get_baseParameters(), inst->get_parameters(), typeSubs ) ) {
    1711                                 deleteAll( typeSubs );
    1712                                 return inst;
    1713                         }
    1714 
    1715                         // make concrete instantiation of generic type
    1716                         StructDecl *concDecl = lookup( inst, typeSubs );
    1717                         if ( ! concDecl ) {
    1718                                 // set concDecl to new type, insert type declaration into statements to add
    1719                                 concDecl = new StructDecl( typeNamer.newName( inst->get_name() ) );
    1720                                 substituteMembers( inst->get_baseStruct()->get_members(), *inst->get_baseParameters(), typeSubs,        concDecl->get_members() );
    1721                                 DeclMutator::addDeclaration( concDecl );
    1722                                 insert( inst, typeSubs, concDecl );
    1723                         }
    1724                         StructInstType *newInst = new StructInstType( inst->get_qualifiers(), concDecl->get_name() );
    1725                         newInst->set_baseStruct( concDecl );
    1726 
    1727                         deleteAll( typeSubs );
    1728                         delete inst;
    1729                         return newInst;
    1730                 }
    1731 
    1732                 Type* GenericInstantiator::mutate( UnionInstType *inst ) {
    1733                         // mutate subtypes
    1734                         Type *mutated = Mutator::mutate( inst );
    1735                         inst = dynamic_cast< UnionInstType* >( mutated );
    1736                         if ( ! inst ) return mutated;
    1737 
    1738                         // exit early if no need for further mutation
    1739                         if ( inst->get_parameters().empty() ) return inst;
    1740                         assert( inst->get_baseParameters() && "Base union has parameters" );
    1741 
    1742                         // check if type can be concretely instantiated; put substitutions into typeSubs
    1743                         std::list< TypeExpr* > typeSubs;
    1744                         if ( ! makeSubstitutions( *inst->get_baseParameters(), inst->get_parameters(), typeSubs ) ) {
    1745                                 deleteAll( typeSubs );
    1746                                 return inst;
    1747                         }
    1748 
    1749                         // make concrete instantiation of generic type
    1750                         UnionDecl *concDecl = lookup( inst, typeSubs );
    1751                         if ( ! concDecl ) {
    1752                                 // set concDecl to new type, insert type declaration into statements to add
    1753                                 concDecl = new UnionDecl( typeNamer.newName( inst->get_name() ) );
    1754                                 substituteMembers( inst->get_baseUnion()->get_members(), *inst->get_baseParameters(), typeSubs, concDecl->get_members() );
    1755                                 DeclMutator::addDeclaration( concDecl );
    1756                                 insert( inst, typeSubs, concDecl );
    1757                         }
    1758                         UnionInstType *newInst = new UnionInstType( inst->get_qualifiers(), concDecl->get_name() );
    1759                         newInst->set_baseUnion( concDecl );
    1760 
    1761                         deleteAll( typeSubs );
    1762                         delete inst;
    1763                         return newInst;
    1764                 }
    1765 
    1766         //      /// Gets the base struct or union declaration for a member expression; NULL if not applicable
    1767         //      AggregateDecl* getMemberBaseDecl( MemberExpr *memberExpr ) {
    1768         //              // get variable for member aggregate
    1769         //              VariableExpr *varExpr = dynamic_cast< VariableExpr* >( memberExpr->get_aggregate() );
    1770         //              if ( ! varExpr ) return NULL;
    1771         //
    1772         //              // get object for variable
    1773         //              ObjectDecl *objectDecl = dynamic_cast< ObjectDecl* >( varExpr->get_var() );
    1774         //              if ( ! objectDecl ) return NULL;
    1775         //
    1776         //              // get base declaration from object type
    1777         //              Type *objectType = objectDecl->get_type();
    1778         //              StructInstType *structType = dynamic_cast< StructInstType* >( objectType );
    1779         //              if ( structType ) return structType->get_baseStruct();
    1780         //              UnionInstType *unionType = dynamic_cast< UnionInstType* >( objectType );
    1781         //              if ( unionType ) return unionType->get_baseUnion();
    1782         //
    1783         //              return NULL;
    1784         //      }
    1785         //
    1786         //      /// Finds the declaration with the given name, returning decls.end() if none such
    1787         //      std::list< Declaration* >::const_iterator findDeclNamed( const std::list< Declaration* > &decls, const std::string &name ) {
    1788         //              for( std::list< Declaration* >::const_iterator decl = decls.begin(); decl != decls.end(); ++decl ) {
    1789         //                      if ( (*decl)->get_name() == name ) return decl;
    1790         //              }
    1791         //              return decls.end();
    1792         //      }
    1793         //
    1794         //      Expression* Instantiate::mutate( MemberExpr *memberExpr ) {
    1795         //              // mutate, exiting early if no longer MemberExpr
    1796         //              Expression *expr = Mutator::mutate( memberExpr );
    1797         //              memberExpr = dynamic_cast< MemberExpr* >( expr );
    1798         //              if ( ! memberExpr ) return expr;
    1799         //
    1800         //              // get declaration of member and base declaration of member, exiting early if not found
    1801         //              AggregateDecl *memberBase = getMemberBaseDecl( memberExpr );
    1802         //              if ( ! memberBase ) return memberExpr;
    1803         //              DeclarationWithType *memberDecl = memberExpr->get_member();
    1804         //              std::list< Declaration* >::const_iterator baseIt = findDeclNamed( memberBase->get_members(), memberDecl->get_name() );
    1805         //              if ( baseIt == memberBase->get_members().end() ) return memberExpr;
    1806         //              DeclarationWithType *baseDecl = dynamic_cast< DeclarationWithType* >( *baseIt );
    1807         //              if ( ! baseDecl ) return memberExpr;
    1808         //
    1809         //              // check if stated type of the member is not the type of the member's declaration; if so, need a cast
    1810         //              // this *SHOULD* be safe, I don't think anything but the void-replacements I put in for dtypes would make it past the typechecker
    1811         //              SymTab::Indexer dummy;
    1812         //              if ( ResolvExpr::typesCompatible( memberDecl->get_type(), baseDecl->get_type(), dummy ) ) return memberExpr;
    1813         //              else return new CastExpr( memberExpr, memberDecl->get_type() );
    1814         //      }
    1815 
    1816                 void GenericInstantiator::doBeginScope() {
    1817                         DeclMutator::doBeginScope();
    1818                         instantiations.beginScope();
    1819                 }
    1820 
    1821                 void GenericInstantiator::doEndScope() {
    1822                         DeclMutator::doEndScope();
    1823                         instantiations.endScope();
    1824                 }
    1825 
    1826 ////////////////////////////////////////// PolyGenericCalculator ////////////////////////////////////////////////////
    1827 
    1828                 void PolyGenericCalculator::beginTypeScope( Type *ty ) {
    1829                         scopeTyVars.beginScope();
    1830                         makeTyVarMap( ty, scopeTyVars );
    1831                 }
    1832 
    1833                 void PolyGenericCalculator::endTypeScope() {
    1834                         scopeTyVars.endScope();
    1835                 }
     1311////////////////////////////////////////// MemberExprFixer ////////////////////////////////////////////////////
    18361312
    18371313                template< typename DeclClass >
    1838                 DeclClass * PolyGenericCalculator::handleDecl( DeclClass *decl, Type *type ) {
    1839                         beginTypeScope( type );
    1840                         knownLayouts.beginScope();
    1841                         knownOffsets.beginScope();
     1314                DeclClass * MemberExprFixer::handleDecl( DeclClass *decl, Type *type ) {
     1315                        TyVarMap oldtyVars = scopeTyVars;
     1316                        makeTyVarMap( type, scopeTyVars );
    18421317
    18431318                        DeclClass *ret = static_cast< DeclClass *>( Mutator::mutate( decl ) );
    18441319
    1845                         knownOffsets.endScope();
    1846                         knownLayouts.endScope();
    1847                         endTypeScope();
     1320                        scopeTyVars = oldtyVars;
    18481321                        return ret;
    18491322                }
    18501323
    1851                 ObjectDecl * PolyGenericCalculator::mutate( ObjectDecl *objectDecl ) {
     1324                ObjectDecl * MemberExprFixer::mutate( ObjectDecl *objectDecl ) {
    18521325                        return handleDecl( objectDecl, objectDecl->get_type() );
    18531326                }
    18541327
    1855                 DeclarationWithType * PolyGenericCalculator::mutate( FunctionDecl *functionDecl ) {
     1328                DeclarationWithType * MemberExprFixer::mutate( FunctionDecl *functionDecl ) {
    18561329                        return handleDecl( functionDecl, functionDecl->get_functionType() );
    18571330                }
    18581331
    1859                 TypedefDecl * PolyGenericCalculator::mutate( TypedefDecl *typedefDecl ) {
     1332                TypedefDecl * MemberExprFixer::mutate( TypedefDecl *typedefDecl ) {
    18601333                        return handleDecl( typedefDecl, typedefDecl->get_base() );
    18611334                }
    18621335
    1863                 TypeDecl * PolyGenericCalculator::mutate( TypeDecl *typeDecl ) {
     1336                TypeDecl * MemberExprFixer::mutate( TypeDecl *typeDecl ) {
    18641337                        scopeTyVars[ typeDecl->get_name() ] = typeDecl->get_kind();
    18651338                        return Mutator::mutate( typeDecl );
    18661339                }
    18671340
    1868                 Type * PolyGenericCalculator::mutate( PointerType *pointerType ) {
    1869                         beginTypeScope( pointerType );
     1341                Type * MemberExprFixer::mutate( PointerType *pointerType ) {
     1342                        TyVarMap oldtyVars = scopeTyVars;
     1343                        makeTyVarMap( pointerType, scopeTyVars );
    18701344
    18711345                        Type *ret = Mutator::mutate( pointerType );
    18721346
    1873                         endTypeScope();
     1347                        scopeTyVars = oldtyVars;
    18741348                        return ret;
    18751349                }
    18761350
    1877                 Type * PolyGenericCalculator::mutate( FunctionType *funcType ) {
    1878                         beginTypeScope( funcType );
    1879 
    1880                         // make sure that any type information passed into the function is accounted for
    1881                         for ( std::list< DeclarationWithType* >::const_iterator fnParm = funcType->get_parameters().begin(); fnParm != funcType->get_parameters().end(); ++fnParm ) {
    1882                                 // condition here duplicates that in Pass2::mutate( FunctionType* )
    1883                                 Type *polyType = isPolyType( (*fnParm)->get_type(), scopeTyVars );
    1884                                 if ( polyType && ! dynamic_cast< TypeInstType* >( polyType ) ) {
    1885                                         knownLayouts.insert( mangleType( polyType ) );
    1886                                 }
    1887                         }
    1888                        
    1889                         Type *ret = Mutator::mutate( funcType );
    1890 
    1891                         endTypeScope();
     1351                Type * MemberExprFixer::mutate( FunctionType *functionType ) {
     1352                        TyVarMap oldtyVars = scopeTyVars;
     1353                        makeTyVarMap( functionType, scopeTyVars );
     1354
     1355                        Type *ret = Mutator::mutate( functionType );
     1356
     1357                        scopeTyVars = oldtyVars;
    18921358                        return ret;
    18931359                }
    18941360
    1895                 Statement *PolyGenericCalculator::mutate( DeclStmt *declStmt ) {
     1361                Statement *MemberExprFixer::mutate( DeclStmt *declStmt ) {
    18961362                        if ( ObjectDecl *objectDecl = dynamic_cast< ObjectDecl *>( declStmt->get_decl() ) ) {
    1897                                 if ( findGeneric( objectDecl->get_type() ) ) {
     1363                                if ( isPolyType( objectDecl->get_type(), scopeTyVars ) ) {
    18981364                                        // change initialization of a polymorphic value object
    18991365                                        // to allocate storage with alloca
    19001366                                        Type *declType = objectDecl->get_type();
    19011367                                        UntypedExpr *alloc = new UntypedExpr( new NameExpr( "__builtin_alloca" ) );
    1902                                         alloc->get_args().push_back( new NameExpr( sizeofName( mangleType( declType ) ) ) );
     1368                                        alloc->get_args().push_back( new NameExpr( sizeofName( declType ) ) );
    19031369
    19041370                                        delete objectDecl->get_init();
     
    19321398                        ConstantExpr *fieldIndex = new ConstantExpr( Constant( new BasicType( Type::Qualifiers(), BasicType::LongUnsignedInt ), offset_namer.str() ) );
    19331399                        UntypedExpr *fieldOffset = new UntypedExpr( new NameExpr( "?[?]" ) );
    1934                         fieldOffset->get_args().push_back( new NameExpr( offsetofName( mangleType( objectType ) ) ) );
     1400                        fieldOffset->get_args().push_back( new NameExpr( offsetofName( objectType ) ) );
    19351401                        fieldOffset->get_args().push_back( fieldIndex );
    19361402                        return fieldOffset;
     
    19471413                }
    19481414               
    1949                 Expression *PolyGenericCalculator::mutate( MemberExpr *memberExpr ) {
     1415                Expression *MemberExprFixer::mutate( MemberExpr *memberExpr ) {
    19501416                        // mutate, exiting early if no longer MemberExpr
    19511417                        Expression *expr = Mutator::mutate( memberExpr );
     
    19641430                        Type *objectType = hasPolyBase( objectDecl->get_type(), scopeTyVars, &tyDepth );
    19651431                        if ( ! objectType ) return memberExpr;
    1966                         findGeneric( objectType ); // ensure layout for this type is available
    19671432
    19681433                        Expression *newMemberExpr = 0;
     
    19961461                }
    19971462
    1998                 ObjectDecl *PolyGenericCalculator::makeVar( const std::string &name, Type *type, Initializer *init ) {
    1999                         ObjectDecl *newObj = new ObjectDecl( name, DeclarationNode::NoStorageClass, LinkageSpec::C, 0, type, init );
    2000                         stmtsToAdd.push_back( new DeclStmt( noLabels, newObj ) );
    2001                         return newObj;
    2002                 }
    2003 
    2004                 void PolyGenericCalculator::addOtypeParamsToLayoutCall( UntypedExpr *layoutCall, const std::list< Type* > &otypeParams ) {
    2005                         for ( std::list< Type* >::const_iterator param = otypeParams.begin(); param != otypeParams.end(); ++param ) {
    2006                                 if ( findGeneric( *param ) ) {
    2007                                         // push size/align vars for a generic parameter back
    2008                                         std::string paramName = mangleType( *param );
    2009                                         layoutCall->get_args().push_back( new NameExpr( sizeofName( paramName ) ) );
    2010                                         layoutCall->get_args().push_back( new NameExpr( alignofName( paramName ) ) );
    2011                                 } else {
    2012                                         layoutCall->get_args().push_back( new SizeofExpr( (*param)->clone() ) );
    2013                                         layoutCall->get_args().push_back( new AlignofExpr( (*param)->clone() ) );
    2014                                 }
    2015                         }
    2016                 }
    2017 
    2018                 /// returns true if any of the otype parameters have a dynamic layout and puts all otype parameters in the output list
    2019                 bool findGenericParams( std::list< TypeDecl* > &baseParams, std::list< Expression* > &typeParams, std::list< Type* > &out ) {
    2020                         bool hasDynamicLayout = false;
    2021 
    2022                         std::list< TypeDecl* >::const_iterator baseParam = baseParams.begin();
    2023                         std::list< Expression* >::const_iterator typeParam = typeParams.begin();
    2024                         for ( ; baseParam != baseParams.end() && typeParam != typeParams.end(); ++baseParam, ++typeParam ) {
    2025                                 // skip non-otype parameters
    2026                                 if ( (*baseParam)->get_kind() != TypeDecl::Any ) continue;
    2027                                 TypeExpr *typeExpr = dynamic_cast< TypeExpr* >( *typeParam );
    2028                                 assert( typeExpr && "all otype parameters should be type expressions" );
    2029 
    2030                                 Type *type = typeExpr->get_type();
    2031                                 out.push_back( type );
    2032                                 if ( isPolyType( type ) ) hasDynamicLayout = true;
    2033                         }
    2034                         assert( baseParam == baseParams.end() && typeParam == typeParams.end() );
    2035 
    2036                         return hasDynamicLayout;
    2037                 }
    2038 
    2039                 bool PolyGenericCalculator::findGeneric( Type *ty ) {
    2040                         if ( TypeInstType *typeInst = dynamic_cast< TypeInstType* >( ty ) ) {
    2041                                 // duplicate logic from isPolyType()
    2042                                 if ( env ) {
    2043                                         if ( Type *newType = env->lookup( typeInst->get_name() ) ) {
    2044                                                 return findGeneric( newType );
    2045                                         } // if
    2046                                 } // if
    2047                                 if ( scopeTyVars.find( typeInst->get_name() ) != scopeTyVars.end() ) {
    2048                                         // NOTE assumes here that getting put in the scopeTyVars included having the layout variables set
    2049                                         return true;
    2050                                 }
    2051                                 return false;
    2052                         } else if ( StructInstType *structTy = dynamic_cast< StructInstType* >( ty ) ) {
    2053                                 // check if this type already has a layout generated for it
    2054                                 std::string typeName = mangleType( ty );
    2055                                 if ( knownLayouts.find( typeName ) != knownLayouts.end() ) return true;
    2056 
    2057                                 // check if any of the type parameters have dynamic layout; if none do, this type is (or will be) monomorphized
    2058                                 std::list< Type* > otypeParams;
    2059                                 if ( ! findGenericParams( *structTy->get_baseParameters(), structTy->get_parameters(), otypeParams ) ) return false;
    2060 
    2061                                 // insert local variables for layout and generate call to layout function
    2062                                 knownLayouts.insert( typeName );  // done early so as not to interfere with the later addition of parameters to the layout call
    2063                                 Type *layoutType = new BasicType( Type::Qualifiers(), BasicType::LongUnsignedInt );
    2064 
    2065                                 int n_members = structTy->get_baseStruct()->get_members().size();
    2066                                 if ( n_members == 0 ) {
    2067                                         // all empty structs have the same layout - size 1, align 1
    2068                                         makeVar( sizeofName( typeName ), layoutType, new SingleInit( new ConstantExpr( Constant::from( (unsigned long)1 ) ) ) );
    2069                                         makeVar( alignofName( typeName ), layoutType->clone(), new SingleInit( new ConstantExpr( Constant::from( (unsigned long)1 ) ) ) );
    2070                                         // NOTE zero-length arrays are forbidden in C, so empty structs have no offsetof array
    2071                                 } else {
    2072                                         ObjectDecl *sizeVar = makeVar( sizeofName( typeName ), layoutType );
    2073                                         ObjectDecl *alignVar = makeVar( alignofName( typeName ), layoutType->clone() );
    2074                                         ObjectDecl *offsetVar = makeVar( offsetofName( typeName ), new ArrayType( Type::Qualifiers(), layoutType->clone(), new ConstantExpr( Constant::from( n_members ) ), false, false ) );
    2075 
    2076                                         // generate call to layout function
    2077                                         UntypedExpr *layoutCall = new UntypedExpr( new NameExpr( layoutofName( structTy->get_baseStruct() ) ) );
    2078                                         layoutCall->get_args().push_back( new AddressExpr( new VariableExpr( sizeVar ) ) );
    2079                                         layoutCall->get_args().push_back( new AddressExpr( new VariableExpr( alignVar ) ) );
    2080                                         layoutCall->get_args().push_back( new VariableExpr( offsetVar ) );
    2081                                         addOtypeParamsToLayoutCall( layoutCall, otypeParams );
    2082 
    2083                                         stmtsToAdd.push_back( new ExprStmt( noLabels, layoutCall ) );
    2084                                 }
    2085 
    2086                                 return true;
    2087                         } else if ( UnionInstType *unionTy = dynamic_cast< UnionInstType* >( ty ) ) {
    2088                                 // check if this type already has a layout generated for it
    2089                                 std::string typeName = mangleType( ty );
    2090                                 if ( knownLayouts.find( typeName ) != knownLayouts.end() ) return true;
    2091 
    2092                                 // check if any of the type parameters have dynamic layout; if none do, this type is (or will be) monomorphized
    2093                                 std::list< Type* > otypeParams;
    2094                                 if ( ! findGenericParams( *unionTy->get_baseParameters(), unionTy->get_parameters(), otypeParams ) ) return false;
    2095 
    2096                                 // insert local variables for layout and generate call to layout function
    2097                                 knownLayouts.insert( typeName );  // done early so as not to interfere with the later addition of parameters to the layout call
    2098                                 Type *layoutType = new BasicType( Type::Qualifiers(), BasicType::LongUnsignedInt );
    2099 
    2100                                 ObjectDecl *sizeVar = makeVar( sizeofName( typeName ), layoutType );
    2101                                 ObjectDecl *alignVar = makeVar( alignofName( typeName ), layoutType->clone() );
    2102 
    2103                                 // generate call to layout function
    2104                                 UntypedExpr *layoutCall = new UntypedExpr( new NameExpr( layoutofName( unionTy->get_baseUnion() ) ) );
    2105                                 layoutCall->get_args().push_back( new AddressExpr( new VariableExpr( sizeVar ) ) );
    2106                                 layoutCall->get_args().push_back( new AddressExpr( new VariableExpr( alignVar ) ) );
    2107                                 addOtypeParamsToLayoutCall( layoutCall, otypeParams );
    2108 
    2109                                 stmtsToAdd.push_back( new ExprStmt( noLabels, layoutCall ) );
    2110 
    2111                                 return true;
    2112                         }
    2113 
    2114                         return false;
    2115                 }
    2116 
    2117                 Expression *PolyGenericCalculator::mutate( SizeofExpr *sizeofExpr ) {
    2118                         Type *ty = sizeofExpr->get_type();
    2119                         if ( findGeneric( ty ) ) {
    2120                                 Expression *ret = new NameExpr( sizeofName( mangleType( ty ) ) );
    2121                                 delete sizeofExpr;
    2122                                 return ret;
    2123                         }
    2124                         return sizeofExpr;
    2125                 }
    2126 
    2127                 Expression *PolyGenericCalculator::mutate( AlignofExpr *alignofExpr ) {
    2128                         Type *ty = alignofExpr->get_type();
    2129                         if ( findGeneric( ty ) ) {
    2130                                 Expression *ret = new NameExpr( alignofName( mangleType( ty ) ) );
    2131                                 delete alignofExpr;
    2132                                 return ret;
    2133                         }
    2134                         return alignofExpr;
    2135                 }
    2136 
    2137                 Expression *PolyGenericCalculator::mutate( OffsetofExpr *offsetofExpr ) {
     1463                Expression *MemberExprFixer::mutate( OffsetofExpr *offsetofExpr ) {
    21381464                        // mutate, exiting early if no longer OffsetofExpr
    21391465                        Expression *expr = Mutator::mutate( offsetofExpr );
     
    21421468
    21431469                        // only mutate expressions for polymorphic structs/unions
    2144                         Type *ty = offsetofExpr->get_type();
    2145                         if ( ! findGeneric( ty ) ) return offsetofExpr;
    2146                        
     1470                        Type *ty = isPolyType( offsetofExpr->get_type(), scopeTyVars );
     1471                        if ( ! ty ) return offsetofExpr;
     1472
    21471473                        if ( StructInstType *structType = dynamic_cast< StructInstType* >( ty ) ) {
    21481474                                // replace offsetof expression by index into offset array
     
    21601486                }
    21611487
    2162                 Expression *PolyGenericCalculator::mutate( OffsetPackExpr *offsetPackExpr ) {
    2163                         StructInstType *ty = offsetPackExpr->get_type();
    2164 
    2165                         Expression *ret = 0;
    2166                         if ( findGeneric( ty ) ) {
    2167                                 // pull offset back from generated type information
    2168                                 ret = new NameExpr( offsetofName( mangleType( ty ) ) );
    2169                         } else {
    2170                                 std::string offsetName = offsetofName( mangleType( ty ) );
    2171                                 if ( knownOffsets.find( offsetName ) != knownOffsets.end() ) {
    2172                                         // use the already-generated offsets for this type
    2173                                         ret = new NameExpr( offsetName );
    2174                                 } else {
    2175                                         knownOffsets.insert( offsetName );
    2176 
    2177                                         std::list< Declaration* > &baseMembers = ty->get_baseStruct()->get_members();
    2178                                         Type *offsetType = new BasicType( Type::Qualifiers(), BasicType::LongUnsignedInt );
    2179 
    2180                                         // build initializer list for offset array
    2181                                         std::list< Initializer* > inits;
    2182                                         for ( std::list< Declaration* >::const_iterator member = baseMembers.begin(); member != baseMembers.end(); ++member ) {
    2183                                                 DeclarationWithType *memberDecl;
    2184                                                 if ( DeclarationWithType *origMember = dynamic_cast< DeclarationWithType* >( *member ) ) {
    2185                                                         memberDecl = origMember->clone();
    2186                                                 } else {
    2187                                                         memberDecl = new ObjectDecl( (*member)->get_name(), DeclarationNode::NoStorageClass, LinkageSpec::Cforall, 0, offsetType->clone(), 0 );
    2188                                                 }
    2189                                                 inits.push_back( new SingleInit( new OffsetofExpr( ty->clone(), memberDecl ) ) );
    2190                                         }
    2191 
    2192                                         // build the offset array and replace the pack with a reference to it
    2193                                         ObjectDecl *offsetArray = makeVar( offsetName, new ArrayType( Type::Qualifiers(), offsetType, new ConstantExpr( Constant::from( baseMembers.size() ) ), false, false ),
    2194                                                         new ListInit( inits ) );
    2195                                         ret = new VariableExpr( offsetArray );
    2196                                 }
    2197                         }
    2198 
    2199                         delete offsetPackExpr;
    2200                         return ret;
    2201                 }
    2202 
    2203                 void PolyGenericCalculator::doBeginScope() {
    2204                         knownLayouts.beginScope();
    2205                         knownOffsets.beginScope();
    2206                 }
    2207 
    2208                 void PolyGenericCalculator::doEndScope() {
    2209                         knownLayouts.endScope();
    2210                         knownOffsets.endScope();
    2211                 }
    2212 
    22131488////////////////////////////////////////// Pass3 ////////////////////////////////////////////////////
    22141489
    22151490                template< typename DeclClass >
    22161491                DeclClass * Pass3::handleDecl( DeclClass *decl, Type *type ) {
    2217                         scopeTyVars.beginScope();
     1492                        TyVarMap oldtyVars = scopeTyVars;
    22181493                        makeTyVarMap( type, scopeTyVars );
    22191494
     
    22211496                        ScrubTyVars::scrub( decl, scopeTyVars );
    22221497
    2223                         scopeTyVars.endScope();
     1498                        scopeTyVars = oldtyVars;
    22241499                        return ret;
    22251500                }
     
    22511526
    22521527                Type * Pass3::mutate( PointerType *pointerType ) {
    2253                         scopeTyVars.beginScope();
     1528                        TyVarMap oldtyVars = scopeTyVars;
    22541529                        makeTyVarMap( pointerType, scopeTyVars );
    22551530
    22561531                        Type *ret = Mutator::mutate( pointerType );
    22571532
    2258                         scopeTyVars.endScope();
     1533                        scopeTyVars = oldtyVars;
    22591534                        return ret;
    22601535                }
    22611536
    22621537                Type * Pass3::mutate( FunctionType *functionType ) {
    2263                         scopeTyVars.beginScope();
     1538                        TyVarMap oldtyVars = scopeTyVars;
    22641539                        makeTyVarMap( functionType, scopeTyVars );
    22651540
    22661541                        Type *ret = Mutator::mutate( functionType );
    22671542
    2268                         scopeTyVars.endScope();
     1543                        scopeTyVars = oldtyVars;
    22691544                        return ret;
    22701545                }
Note: See TracChangeset for help on using the changeset viewer.