Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/GenPoly/Box.cc

    r4e284ea6 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"
    3227#include "ScrubTyVars.h"
    3328
     
    3530
    3631#include "SynTree/Constant.h"
    37 #include "SynTree/Declaration.h"
     32#include "SynTree/Type.h"
    3833#include "SynTree/Expression.h"
    3934#include "SynTree/Initializer.h"
     35#include "SynTree/Statement.h"
    4036#include "SynTree/Mutator.h"
    41 #include "SynTree/Statement.h"
    42 #include "SynTree/Type.h"
    43 #include "SynTree/TypeSubstitution.h"
    4437
    4538#include "ResolvExpr/TypeEnvironment.h"
     
    4740#include "ResolvExpr/typeops.h"
    4841
    49 #include "SymTab/Indexer.h"
    5042#include "SymTab/Mangler.h"
    5143
     
    6254                FunctionType *makeAdapterType( FunctionType *adaptee, const TyVarMap &tyVars );
    6355
    64                 /// Key for a unique concrete type; generic base type paired with type parameter list
    65                 struct ConcreteType {
    66                         ConcreteType() : base(NULL), params() {}
    67 
    68                         ConcreteType(AggregateDecl *_base, const std::list< Type* >& _params) : base(_base), params() { cloneAll(_params, params); }
    69 
    70                         ConcreteType(const ConcreteType& that) : base(that.base), params() { cloneAll(that.params, params); }
    71 
    72                         /// Extracts types from a list of TypeExpr*
    73                         ConcreteType(AggregateDecl *_base, const std::list< TypeExpr* >& _params) : base(_base), params() {
    74                                 for ( std::list< TypeExpr* >::const_iterator param = _params.begin(); param != _params.end(); ++param ) {
    75                                         params.push_back( (*param)->get_type()->clone() );
    76                                 }
    77                         }
    78 
    79                         ConcreteType& operator= (const ConcreteType& that) {
    80                                 deleteAll( params );
    81                                 params.clear();
    82 
    83                                 base = that.base;
    84                                 cloneAll( that.params, params );
    85 
    86                                 return *this;
    87                         }
    88 
    89                         ~ConcreteType() { deleteAll( params ); }
    90 
    91                         bool operator== (const ConcreteType& that) const {
    92                                 if ( base != that.base ) return false;
    93 
    94                                 SymTab::Indexer dummy;
    95                                 if ( params.size() != that.params.size() ) return false;
    96                                 for ( std::list< Type* >::const_iterator it = params.begin(), jt = that.params.begin(); it != params.end(); ++it, ++jt ) {
    97                                         if ( ! ResolvExpr::typesCompatible( *it, *jt, dummy ) ) return false;
    98                                 }
    99                                 return true;
    100                         }
    101 
    102                         AggregateDecl *base;        ///< Base generic type
    103                         std::list< Type* > params;  ///< Instantiation parameters
    104                 };
    105 
    106                 /// Maps a concrete type to the some value, accounting for scope
    107                 template< typename Value >
    108                 class InstantiationMap {
    109                         /// Information about a specific instantiation of a generic type
    110                         struct Instantiation {
    111                                 ConcreteType key;  ///< Instantiation parameters for this type
    112                                 Value *value;      ///< Value for this instantiation
    113 
    114                                 Instantiation() : key(), value(0) {}
    115                                 Instantiation(const ConcreteType &_key, Value *_value) : key(_key), value(_value) {}
    116                         };
    117                         /// Map of generic types to instantiations of them
    118                         typedef std::map< AggregateDecl*, std::vector< Instantiation > > Scope;
    119 
    120                         std::vector< Scope > scopes;  ///< list of scopes, from outermost to innermost
    121 
    122                 public:
    123                         /// Starts a new scope
    124                         void beginScope() {
    125                                 Scope scope;
    126                                 scopes.push_back(scope);
    127                         }
    128 
    129                         /// Ends a scope
    130                         void endScope() {
    131                                 scopes.pop_back();
    132                         }
    133 
    134                         /// Default constructor initializes with one scope
    135                         InstantiationMap() { beginScope(); }
    136 
    137 //              private:
    138                         /// Gets the value for the concrete instantiation of this type, assuming it has already been instantiated in the current scope.
    139                         /// Returns NULL on none such.
    140                         Value *lookup( AggregateDecl *generic, const std::list< TypeExpr* >& params ) {
    141                                 ConcreteType key(generic, params);
    142                                 // scan scopes from innermost out
    143                                 for ( typename std::vector< Scope >::const_reverse_iterator scope = scopes.rbegin(); scope != scopes.rend(); ++scope ) {
    144                                         // skip scope if no instantiations of this generic type
    145                                         typename Scope::const_iterator insts = scope->find( generic );
    146                                         if ( insts == scope->end() ) continue;
    147                                         // look through instantiations for matches to concrete type
    148                                         for ( typename std::vector< Instantiation >::const_iterator inst = insts->second.begin(); inst != insts->second.end(); ++inst ) {
    149                                                 if ( inst->key == key ) return inst->value;
    150                                         }
    151                                 }
    152                                 // no matching instantiation found
    153                                 return 0;
    154                         }
    155                 public:
    156 //                      StructDecl* lookup( StructInstType *inst, const std::list< TypeExpr* > &typeSubs ) { return (StructDecl*)lookup( inst->get_baseStruct(), typeSubs ); }
    157 //                      UnionDecl* lookup( UnionInstType *inst, const std::list< TypeExpr* > &typeSubs ) { return (UnionDecl*)lookup( inst->get_baseUnion(), typeSubs ); }
    158 
    159 //              private:
    160                         /// Adds a value for a concrete type to the current scope
    161                         void insert( AggregateDecl *generic, const std::list< TypeExpr* > &params, Value *value ) {
    162                                 ConcreteType key(generic, params);
    163                                 scopes.back()[generic].push_back( Instantiation( key, value ) );
    164                         }
    165 //              public:
    166 //                      void insert( StructInstType *inst, const std::list< TypeExpr* > &typeSubs, StructDecl *decl ) { insert( inst->get_baseStruct(), typeSubs, decl ); }
    167 //                      void insert( UnionInstType *inst, const std::list< TypeExpr* > &typeSubs, UnionDecl *decl ) { insert( inst->get_baseUnion(), typeSubs, decl ); }
    168                 };
    169 
    170                 /// Adds layout-generation functions to polymorphic types
    171                 class LayoutFunctionBuilder : public DeclMutator {
    172                         unsigned int functionNesting;  // current level of nested functions
    173                 public:
    174                         LayoutFunctionBuilder() : functionNesting( 0 ) {}
    175 
    176                         virtual DeclarationWithType *mutate( FunctionDecl *functionDecl );
    177                         virtual Declaration *mutate( StructDecl *structDecl );
    178                         virtual Declaration *mutate( UnionDecl *unionDecl );
    179                 };
    180                
    18156                /// 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
    18257                class Pass1 : public PolyMutator {
     
    225100                        ObjectDecl *makeTemporary( Type *type );
    226101
     102                        typedef std::map< std::string, DeclarationWithType *> AdapterMap;
    227103                        std::map< std::string, DeclarationWithType *> assignOps;
    228104                        ResolvExpr::TypeMap< DeclarationWithType > scopedAssignOps;
    229                         ScopedMap< std::string, DeclarationWithType* > adapters;
     105                        std::stack< AdapterMap > adapters;
    230106                        DeclarationWithType *retval;
    231107                        bool useRetval;
     
    248124
    249125                        std::map< UniqueId, std::string > adapterName;
    250                 };
    251 
    252                 /// Mutator pass that replaces concrete instantiations of generic types with actual struct declarations, scoped appropriately
    253                 class GenericInstantiator : public DeclMutator {
    254                         /// Map of (generic type, parameter list) pairs to concrete type instantiations
    255                         InstantiationMap< AggregateDecl > instantiations;
    256                         /// Namer for concrete types
    257                         UniqueName typeNamer;
    258 
    259                 public:
    260                         GenericInstantiator() : DeclMutator(), instantiations(), typeNamer("_conc_") {}
    261 
    262                         virtual Type* mutate( StructInstType *inst );
    263                         virtual Type* mutate( UnionInstType *inst );
    264 
    265         //              virtual Expression* mutate( MemberExpr *memberExpr );
    266 
    267                         virtual void doBeginScope();
    268                         virtual void doEndScope();
    269                 private:
    270                         /// Wrap instantiation lookup for structs
    271                         StructDecl* lookup( StructInstType *inst, const std::list< TypeExpr* > &typeSubs ) { return (StructDecl*)instantiations.lookup( inst->get_baseStruct(), typeSubs ); }
    272                         /// Wrap instantiation lookup for unions
    273                         UnionDecl* lookup( UnionInstType *inst, const std::list< TypeExpr* > &typeSubs ) { return (UnionDecl*)instantiations.lookup( inst->get_baseUnion(), typeSubs ); }
    274                         /// Wrap instantiation insertion for structs
    275                         void insert( StructInstType *inst, const std::list< TypeExpr* > &typeSubs, StructDecl *decl ) { instantiations.insert( inst->get_baseStruct(), typeSubs, decl ); }
    276                         /// Wrap instantiation insertion for unions
    277                         void insert( UnionInstType *inst, const std::list< TypeExpr* > &typeSubs, UnionDecl *decl ) { instantiations.insert( inst->get_baseUnion(), typeSubs, decl ); }
    278126                };
    279127
     
    311159        } // anonymous namespace
    312160
     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
    313170        /// version of mutateAll with special handling for translation unit so you can check the end of the prelude when debugging
    314171        template< typename MutatorType >
     
    338195
    339196        void box( std::list< Declaration *>& translationUnit ) {
    340                 LayoutFunctionBuilder layoutBuilder;
    341197                Pass1 pass1;
    342198                Pass2 pass2;
    343                 GenericInstantiator instantiator;
    344199                MemberExprFixer memberFixer;
    345200                Pass3 pass3;
    346                
    347                 layoutBuilder.mutateDeclarationList( translationUnit );
    348201                mutateTranslationUnit/*All*/( translationUnit, pass1 );
    349202                mutateTranslationUnit/*All*/( translationUnit, pass2 );
    350 //              instantiateGeneric( translationUnit );
    351                 instantiator.mutateDeclarationList( translationUnit );
     203                instantiateGeneric( translationUnit );
    352204                mutateTranslationUnit/*All*/( translationUnit, memberFixer );
    353205                mutateTranslationUnit/*All*/( translationUnit, pass3 );
    354206        }
    355207
    356         ////////////////////////////////// LayoutFunctionBuilder ////////////////////////////////////////////
    357 
    358         DeclarationWithType *LayoutFunctionBuilder::mutate( FunctionDecl *functionDecl ) {
    359                 functionDecl->set_functionType( maybeMutate( functionDecl->get_functionType(), *this ) );
    360                 mutateAll( functionDecl->get_oldDecls(), *this );
    361                 ++functionNesting;
    362                 functionDecl->set_statements( maybeMutate( functionDecl->get_statements(), *this ) );
    363                 --functionNesting;
    364                 return functionDecl;
    365         }
    366        
    367         /// Get a list of type declarations that will affect a layout function
    368         std::list< TypeDecl* > takeOtypeOnly( std::list< TypeDecl* > &decls ) {
    369                 std::list< TypeDecl * > otypeDecls;
    370 
    371                 for ( std::list< TypeDecl* >::const_iterator decl = decls.begin(); decl != decls.end(); ++decl ) {
    372                         if ( (*decl)->get_kind() == TypeDecl::Any ) {
    373                                 otypeDecls.push_back( *decl );
    374                         }
    375                 }
    376                
    377                 return otypeDecls;
    378         }
    379 
    380         /// Adds parameters for otype layout to a function type
    381         void addOtypeParams( FunctionType *layoutFnType, std::list< TypeDecl* > &otypeParams ) {
    382                 BasicType sizeAlignType( Type::Qualifiers(), BasicType::LongUnsignedInt );
    383                
    384                 for ( std::list< TypeDecl* >::const_iterator param = otypeParams.begin(); param != otypeParams.end(); ++param ) {
    385                         TypeInstType paramType( Type::Qualifiers(), (*param)->get_name(), *param );
    386                         layoutFnType->get_parameters().push_back( new ObjectDecl( sizeofName( &paramType ), DeclarationNode::NoStorageClass, LinkageSpec::Cforall, 0, sizeAlignType.clone(), 0 ) );
    387                         layoutFnType->get_parameters().push_back( new ObjectDecl( alignofName( &paramType ), DeclarationNode::NoStorageClass, LinkageSpec::Cforall, 0, sizeAlignType.clone(), 0 ) );
    388                 }
    389         }
    390 
    391         /// Builds a layout function declaration
    392         FunctionDecl *buildLayoutFunctionDecl( const std::string &typeName, unsigned int functionNesting, FunctionType *layoutFnType ) {
    393                 // Routines at global scope marked "static" to prevent multiple definitions is separate translation units
    394                 // because each unit generates copies of the default routines for each aggregate.
    395                 FunctionDecl *layoutDecl = new FunctionDecl(
    396                         "__layoutof_" + typeName, functionNesting > 0 ? DeclarationNode::NoStorageClass : DeclarationNode::Static, LinkageSpec::AutoGen, layoutFnType, new CompoundStmt( noLabels ), true, false );
    397                 layoutDecl->fixUniqueId();
    398                 return layoutDecl;
    399         }
    400 
    401         /// Makes a unary operation
    402         Expression *makeOp( const std::string &name, Expression *arg ) {
    403                 UntypedExpr *expr = new UntypedExpr( new NameExpr( name ) );
    404                 expr->get_args().push_back( arg );
    405                 return expr;
    406         }
    407 
    408         /// Makes a binary operation
    409         Expression *makeOp( const std::string &name, Expression *lhs, Expression *rhs ) {
    410                 UntypedExpr *expr = new UntypedExpr( new NameExpr( name ) );
    411                 expr->get_args().push_back( lhs );
    412                 expr->get_args().push_back( rhs );
    413                 return expr;
    414         }
    415 
    416         /// Returns the dereference of a local pointer variable
    417         Expression *derefVar( ObjectDecl *var ) {
    418                 return makeOp( "*?", new VariableExpr( var ) );
    419         }
    420 
    421         /// makes an if-statement with a single-expression if-block and no then block
    422         Statement *makeCond( Expression *cond, Expression *ifPart ) {
    423                 return new IfStmt( noLabels, cond, new ExprStmt( noLabels, ifPart ), 0 );
    424         }
    425 
    426         /// makes a statement that assigns rhs to lhs if lhs < rhs
    427         Statement *makeAssignMax( Expression *lhs, Expression *rhs ) {
    428                 return makeCond( makeOp( "?<?", lhs, rhs ), makeOp( "?=?", lhs->clone(), rhs->clone() ) );
    429         }
    430 
    431         /// makes a statement that aligns lhs to rhs (rhs should be an integer power of two)
    432         Statement *makeAlignTo( Expression *lhs, Expression *rhs ) {
    433                 // check that the lhs is zeroed out to the level of rhs
    434                 Expression *ifCond = makeOp( "?&?", lhs, makeOp( "?-?", rhs, new ConstantExpr( Constant( new BasicType( Type::Qualifiers(), BasicType::LongUnsignedInt ), "1" ) ) ) );
    435                 // if not aligned, increment to alignment
    436                 Expression *ifExpr = makeOp( "?+=?", lhs->clone(), makeOp( "?-?", rhs->clone(), ifCond->clone() ) );
    437                 return makeCond( ifCond, ifExpr );
    438         }
    439        
    440         /// adds an expression to a compound statement
    441         void addExpr( CompoundStmt *stmts, Expression *expr ) {
    442                 stmts->get_kids().push_back( new ExprStmt( noLabels, expr ) );
    443         }
    444 
    445         /// adds a statement to a compound statement
    446         void addStmt( CompoundStmt *stmts, Statement *stmt ) {
    447                 stmts->get_kids().push_back( stmt );
    448         }
    449        
    450         Declaration *LayoutFunctionBuilder::mutate( StructDecl *structDecl ) {
    451                 // do not generate layout function for "empty" tag structs
    452                 if ( structDecl->get_members().empty() ) return structDecl;
    453 
    454                 // get parameters that can change layout, exiting early if none
    455                 std::list< TypeDecl* > otypeParams = takeOtypeOnly( structDecl->get_parameters() );
    456                 if ( otypeParams.empty() ) return structDecl;
    457 
    458                 // build layout function signature
    459                 FunctionType *layoutFnType = new FunctionType( Type::Qualifiers(), false );
    460                 BasicType *sizeAlignType = new BasicType( Type::Qualifiers(), BasicType::LongUnsignedInt );
    461                 PointerType *sizeAlignOutType = new PointerType( Type::Qualifiers(), sizeAlignType );
    462                
    463                 ObjectDecl *sizeParam = new ObjectDecl( "__sizeof_" + structDecl->get_name(), DeclarationNode::NoStorageClass, LinkageSpec::Cforall, 0, sizeAlignOutType, 0 );
    464                 layoutFnType->get_parameters().push_back( sizeParam );
    465                 ObjectDecl *alignParam = new ObjectDecl( "__alignof_" + structDecl->get_name(), DeclarationNode::NoStorageClass, LinkageSpec::Cforall, 0, sizeAlignOutType->clone(), 0 );
    466                 layoutFnType->get_parameters().push_back( alignParam );
    467                 ObjectDecl *offsetParam = new ObjectDecl( "__offsetof_" + structDecl->get_name(), DeclarationNode::NoStorageClass, LinkageSpec::Cforall, 0, sizeAlignOutType->clone(), 0 );
    468                 layoutFnType->get_parameters().push_back( offsetParam );
    469                 addOtypeParams( layoutFnType, otypeParams );
    470 
    471                 // build function decl
    472                 FunctionDecl *layoutDecl = buildLayoutFunctionDecl( structDecl->get_name(), functionNesting, layoutFnType );
    473 
    474                 // calculate struct layout in function body
    475 
    476                 // initialize size and alignment to 0 and 1 (will have at least one member to re-edit size
    477                 addExpr( layoutDecl->get_statements(), makeOp( "?=?", derefVar( sizeParam ), new ConstantExpr( Constant( sizeAlignType->clone(), "0" ) ) ) );
    478                 addExpr( layoutDecl->get_statements(), makeOp( "?=?", derefVar( alignParam ), new ConstantExpr( Constant( sizeAlignType->clone(), "1" ) ) ) );
    479                 unsigned long n_members = 0;
    480                 bool firstMember = true;
    481                 for ( std::list< Declaration* >::const_iterator member = structDecl->get_members().begin(); member != structDecl->get_members().end(); ++member ) {
    482                         DeclarationWithType *dwt = dynamic_cast< DeclarationWithType * >( *member );
    483                         assert( dwt );
    484                         Type *memberType = dwt->get_type();
    485 
    486                         if ( firstMember ) {
    487                                 firstMember = false;
    488                         } else {
    489                                 // make sure all members after the first (automatically aligned at 0) are properly padded for alignment
    490                                 addStmt( layoutDecl->get_statements(), makeAlignTo( derefVar( sizeParam ), new AlignofExpr( memberType->clone() ) ) );
    491                         }
    492                        
    493                         // place current size in the current offset index
    494                         addExpr( layoutDecl->get_statements(), makeOp( "?=?", makeOp( "?[?]", new VariableExpr( offsetParam ), new ConstantExpr( Constant::from( n_members ) ) ),
    495                                                                               derefVar( sizeParam ) ) );
    496                         ++n_members;
    497 
    498                         // add member size to current size
    499                         addExpr( layoutDecl->get_statements(), makeOp( "?+=?", derefVar( sizeParam ), new SizeofExpr( memberType->clone() ) ) );
    500                        
    501                         // take max of member alignment and global alignment
    502                         addStmt( layoutDecl->get_statements(), makeAssignMax( derefVar( alignParam ), new AlignofExpr( memberType->clone() ) ) );
    503                 }
    504                 // make sure the type is end-padded to a multiple of its alignment
    505                 addStmt( layoutDecl->get_statements(), makeAlignTo( derefVar( sizeParam ), derefVar( alignParam ) ) );
    506 
    507                 addDeclarationAfter( layoutDecl );
    508                 return structDecl;
    509         }
    510        
    511         Declaration *LayoutFunctionBuilder::mutate( UnionDecl *unionDecl ) {
    512                 // do not generate layout function for "empty" tag unions
    513                 if ( unionDecl->get_members().empty() ) return unionDecl;
    514                
    515                 // get parameters that can change layout, exiting early if none
    516                 std::list< TypeDecl* > otypeParams = takeOtypeOnly( unionDecl->get_parameters() );
    517                 if ( otypeParams.empty() ) return unionDecl;
    518 
    519                 // build layout function signature
    520                 FunctionType *layoutFnType = new FunctionType( Type::Qualifiers(), false );
    521                 BasicType *sizeAlignType = new BasicType( Type::Qualifiers(), BasicType::LongUnsignedInt );
    522                 PointerType *sizeAlignOutType = new PointerType( Type::Qualifiers(), sizeAlignType );
    523                
    524                 ObjectDecl *sizeParam = new ObjectDecl( "__sizeof_" + unionDecl->get_name(), DeclarationNode::NoStorageClass, LinkageSpec::Cforall, 0, sizeAlignOutType, 0 );
    525                 layoutFnType->get_parameters().push_back( sizeParam );
    526                 ObjectDecl *alignParam = new ObjectDecl( "__alignof_" + unionDecl->get_name(), DeclarationNode::NoStorageClass, LinkageSpec::Cforall, 0, sizeAlignOutType->clone(), 0 );
    527                 layoutFnType->get_parameters().push_back( alignParam );
    528                 addOtypeParams( layoutFnType, otypeParams );
    529 
    530                 // build function decl
    531                 FunctionDecl *layoutDecl = buildLayoutFunctionDecl( unionDecl->get_name(), functionNesting, layoutFnType );
    532 
    533                 // calculate union layout in function body
    534                 addExpr( layoutDecl->get_statements(), makeOp( "?=?", derefVar( sizeParam ), new ConstantExpr( Constant( sizeAlignType->clone(), "1" ) ) ) );
    535                 addExpr( layoutDecl->get_statements(), makeOp( "?=?", derefVar( alignParam ), new ConstantExpr( Constant( sizeAlignType->clone(), "1" ) ) ) );
    536                 for ( std::list< Declaration* >::const_iterator member = unionDecl->get_members().begin(); member != unionDecl->get_members().end(); ++member ) {
    537                         DeclarationWithType *dwt = dynamic_cast< DeclarationWithType * >( *member );
    538                         assert( dwt );
    539                         Type *memberType = dwt->get_type();
    540                        
    541                         // take max member size and global size
    542                         addStmt( layoutDecl->get_statements(), makeAssignMax( derefVar( sizeParam ), new SizeofExpr( memberType->clone() ) ) );
    543                        
    544                         // take max of member alignment and global alignment
    545                         addStmt( layoutDecl->get_statements(), makeAssignMax( derefVar( alignParam ), new AlignofExpr( memberType->clone() ) ) );
    546                 }
    547                 // make sure the type is end-padded to a multiple of its alignment
    548                 addStmt( layoutDecl->get_statements(), makeAlignTo( derefVar( sizeParam ), derefVar( alignParam ) ) );
    549 
    550                 addDeclarationAfter( layoutDecl );
    551                 return unionDecl;
    552         }
    553        
    554208        ////////////////////////////////////////// Pass1 ////////////////////////////////////////////////////
    555209
     
    591245                }
    592246
    593                 Pass1::Pass1() : useRetval( false ), tempNamer( "_temp" ) {}
     247                Pass1::Pass1() : useRetval( false ), tempNamer( "_temp" ) {
     248                        adapters.push(AdapterMap());
     249                }
    594250
    595251                /// Returns T if the given declaration is (*?=?)(T *, T) for some TypeInstType T (return not checked, but maybe should be), NULL otherwise
     
    694350                                } // for
    695351
     352                                AdapterMap & adapters = Pass1::adapters.top();
    696353                                for ( std::list< FunctionType *>::iterator funType = functions.begin(); funType != functions.end(); ++funType ) {
    697354                                        std::string mangleName = mangleAdapterName( *funType, scopeTyVars );
     
    1115772                                        mangleName += makePolyMonoSuffix( originalFunction, exprTyVars );
    1116773
    1117                                         typedef ScopedMap< std::string, DeclarationWithType* >::iterator AdapterIter;
    1118                                         AdapterIter adapter = adapters.find( mangleName );
     774                                        AdapterMap & adapters = Pass1::adapters.top();
     775                                        AdapterMap::iterator adapter = adapters.find( mangleName );
    1119776                                        if ( adapter == adapters.end() ) {
    1120777                                                // adapter has not been created yet in the current scope, so define it
    1121778                                                FunctionDecl *newAdapter = makeAdapter( *funType, realFunction, mangleName, exprTyVars );
    1122                                                 std::pair< AdapterIter, bool > answer = adapters.insert( std::pair< std::string, DeclarationWithType *>( mangleName, newAdapter ) );
    1123                                                 adapter = answer.first;
     779                                                adapter = adapters.insert( adapters.begin(), std::pair< std::string, DeclarationWithType *>( mangleName, newAdapter ) );
    1124780                                                stmtsToAdd.push_back( new DeclStmt( noLabels, newAdapter ) );
    1125781                                        } // if
     
    15001156
    15011157                void Pass1::doBeginScope() {
    1502                         adapters.beginScope();
     1158                        // push a copy of the current map
     1159                        adapters.push(adapters.top());
    15031160                        scopedAssignOps.beginScope();
    15041161                }
    15051162
    15061163                void Pass1::doEndScope() {
    1507                         adapters.endScope();
     1164                        adapters.pop();
    15081165                        scopedAssignOps.endScope();
    15091166                }
     
    16521309                }
    16531310
    1654 //////////////////////////////////////// GenericInstantiator //////////////////////////////////////////////////
    1655 
    1656                 /// Makes substitutions of params into baseParams; returns true if all parameters substituted for a concrete type
    1657                 bool makeSubstitutions( const std::list< TypeDecl* >& baseParams, const std::list< Expression* >& params, std::list< TypeExpr* >& out ) {
    1658                         bool allConcrete = true;  // will finish the substitution list even if they're not all concrete
    1659 
    1660                         // substitute concrete types for given parameters, and incomplete types for placeholders
    1661                         std::list< TypeDecl* >::const_iterator baseParam = baseParams.begin();
    1662                         std::list< Expression* >::const_iterator param = params.begin();
    1663                         for ( ; baseParam != baseParams.end() && param != params.end(); ++baseParam, ++param ) {
    1664         //                      switch ( (*baseParam)->get_kind() ) {
    1665         //                      case TypeDecl::Any: {   // any type is a valid substitution here; complete types can be used to instantiate generics
    1666                                         TypeExpr *paramType = dynamic_cast< TypeExpr* >( *param );
    1667                                         assert(paramType && "Aggregate parameters should be type expressions");
    1668                                         out.push_back( paramType->clone() );
    1669                                         // check that the substituted type isn't a type variable itself
    1670                                         if ( dynamic_cast< TypeInstType* >( paramType->get_type() ) ) {
    1671                                                 allConcrete = false;
    1672                                         }
    1673         //                              break;
    1674         //                      }
    1675         //                      case TypeDecl::Dtype:  // dtype can be consistently replaced with void [only pointers, which become void*]
    1676         //                              out.push_back( new TypeExpr( new VoidType( Type::Qualifiers() ) ) );
    1677         //                              break;
    1678         //                      case TypeDecl::Ftype:  // pointer-to-ftype can be consistently replaced with void (*)(void) [similar to dtype]
    1679         //                              out.push_back( new TypeExpr( new FunctionType( Type::Qualifiers(), false ) ) );
    1680         //                              break;
    1681         //                      }
    1682                         }
    1683 
    1684                         // if any parameters left over, not done
    1685                         if ( baseParam != baseParams.end() ) return false;
    1686         //              // if not enough parameters given, substitute remaining incomplete types for placeholders
    1687         //              for ( ; baseParam != baseParams.end(); ++baseParam ) {
    1688         //                      switch ( (*baseParam)->get_kind() ) {
    1689         //                      case TypeDecl::Any:    // no more substitutions here, fail early
    1690         //                              return false;
    1691         //                      case TypeDecl::Dtype:  // dtype can be consistently replaced with void [only pointers, which become void*]
    1692         //                              out.push_back( new TypeExpr( new VoidType( Type::Qualifiers() ) ) );
    1693         //                              break;
    1694         //                      case TypeDecl::Ftype:  // pointer-to-ftype can be consistently replaced with void (*)(void) [similar to dtype]
    1695         //                              out.push_back( new TypeExpr( new FunctionType( Type::Qualifiers(), false ) ) );
    1696         //                              break;
    1697         //                      }
    1698         //              }
    1699 
    1700                         return allConcrete;
    1701                 }
    1702 
    1703                 /// Substitutes types of members of in according to baseParams => typeSubs, appending the result to out
    1704                 void substituteMembers( const std::list< Declaration* >& in, const std::list< TypeDecl* >& baseParams, const std::list< TypeExpr* >& typeSubs,
    1705                                                                 std::list< Declaration* >& out ) {
    1706                         // substitute types into new members
    1707                         TypeSubstitution subs( baseParams.begin(), baseParams.end(), typeSubs.begin() );
    1708                         for ( std::list< Declaration* >::const_iterator member = in.begin(); member != in.end(); ++member ) {
    1709                                 Declaration *newMember = (*member)->clone();
    1710                                 subs.apply(newMember);
    1711                                 out.push_back( newMember );
    1712                         }
    1713                 }
    1714 
    1715                 Type* GenericInstantiator::mutate( StructInstType *inst ) {
    1716                         // mutate subtypes
    1717                         Type *mutated = Mutator::mutate( inst );
    1718                         inst = dynamic_cast< StructInstType* >( mutated );
    1719                         if ( ! inst ) return mutated;
    1720 
    1721                         // exit early if no need for further mutation
    1722                         if ( inst->get_parameters().empty() ) return inst;
    1723                         assert( inst->get_baseParameters() && "Base struct has parameters" );
    1724 
    1725                         // check if type can be concretely instantiated; put substitutions into typeSubs
    1726                         std::list< TypeExpr* > typeSubs;
    1727                         if ( ! makeSubstitutions( *inst->get_baseParameters(), inst->get_parameters(), typeSubs ) ) {
    1728                                 deleteAll( typeSubs );
    1729                                 return inst;
    1730                         }
    1731 
    1732                         // make concrete instantiation of generic type
    1733                         StructDecl *concDecl = lookup( inst, typeSubs );
    1734                         if ( ! concDecl ) {
    1735                                 // set concDecl to new type, insert type declaration into statements to add
    1736                                 concDecl = new StructDecl( typeNamer.newName( inst->get_name() ) );
    1737                                 substituteMembers( inst->get_baseStruct()->get_members(), *inst->get_baseParameters(), typeSubs,        concDecl->get_members() );
    1738                                 DeclMutator::addDeclaration( concDecl );
    1739                                 insert( inst, typeSubs, concDecl );
    1740                         }
    1741                         StructInstType *newInst = new StructInstType( inst->get_qualifiers(), concDecl->get_name() );
    1742                         newInst->set_baseStruct( concDecl );
    1743 
    1744                         deleteAll( typeSubs );
    1745                         delete inst;
    1746                         return newInst;
    1747                 }
    1748 
    1749                 Type* GenericInstantiator::mutate( UnionInstType *inst ) {
    1750                         // mutate subtypes
    1751                         Type *mutated = Mutator::mutate( inst );
    1752                         inst = dynamic_cast< UnionInstType* >( mutated );
    1753                         if ( ! inst ) return mutated;
    1754 
    1755                         // exit early if no need for further mutation
    1756                         if ( inst->get_parameters().empty() ) return inst;
    1757                         assert( inst->get_baseParameters() && "Base union has parameters" );
    1758 
    1759                         // check if type can be concretely instantiated; put substitutions into typeSubs
    1760                         std::list< TypeExpr* > typeSubs;
    1761                         if ( ! makeSubstitutions( *inst->get_baseParameters(), inst->get_parameters(), typeSubs ) ) {
    1762                                 deleteAll( typeSubs );
    1763                                 return inst;
    1764                         }
    1765 
    1766                         // make concrete instantiation of generic type
    1767                         UnionDecl *concDecl = lookup( inst, typeSubs );
    1768                         if ( ! concDecl ) {
    1769                                 // set concDecl to new type, insert type declaration into statements to add
    1770                                 concDecl = new UnionDecl( typeNamer.newName( inst->get_name() ) );
    1771                                 substituteMembers( inst->get_baseUnion()->get_members(), *inst->get_baseParameters(), typeSubs, concDecl->get_members() );
    1772                                 DeclMutator::addDeclaration( concDecl );
    1773                                 insert( inst, typeSubs, concDecl );
    1774                         }
    1775                         UnionInstType *newInst = new UnionInstType( inst->get_qualifiers(), concDecl->get_name() );
    1776                         newInst->set_baseUnion( concDecl );
    1777 
    1778                         deleteAll( typeSubs );
    1779                         delete inst;
    1780                         return newInst;
    1781                 }
    1782 
    1783         //      /// Gets the base struct or union declaration for a member expression; NULL if not applicable
    1784         //      AggregateDecl* getMemberBaseDecl( MemberExpr *memberExpr ) {
    1785         //              // get variable for member aggregate
    1786         //              VariableExpr *varExpr = dynamic_cast< VariableExpr* >( memberExpr->get_aggregate() );
    1787         //              if ( ! varExpr ) return NULL;
    1788         //
    1789         //              // get object for variable
    1790         //              ObjectDecl *objectDecl = dynamic_cast< ObjectDecl* >( varExpr->get_var() );
    1791         //              if ( ! objectDecl ) return NULL;
    1792         //
    1793         //              // get base declaration from object type
    1794         //              Type *objectType = objectDecl->get_type();
    1795         //              StructInstType *structType = dynamic_cast< StructInstType* >( objectType );
    1796         //              if ( structType ) return structType->get_baseStruct();
    1797         //              UnionInstType *unionType = dynamic_cast< UnionInstType* >( objectType );
    1798         //              if ( unionType ) return unionType->get_baseUnion();
    1799         //
    1800         //              return NULL;
    1801         //      }
    1802         //
    1803         //      /// Finds the declaration with the given name, returning decls.end() if none such
    1804         //      std::list< Declaration* >::const_iterator findDeclNamed( const std::list< Declaration* > &decls, const std::string &name ) {
    1805         //              for( std::list< Declaration* >::const_iterator decl = decls.begin(); decl != decls.end(); ++decl ) {
    1806         //                      if ( (*decl)->get_name() == name ) return decl;
    1807         //              }
    1808         //              return decls.end();
    1809         //      }
    1810         //
    1811         //      Expression* Instantiate::mutate( MemberExpr *memberExpr ) {
    1812         //              // mutate, exiting early if no longer MemberExpr
    1813         //              Expression *expr = Mutator::mutate( memberExpr );
    1814         //              memberExpr = dynamic_cast< MemberExpr* >( expr );
    1815         //              if ( ! memberExpr ) return expr;
    1816         //
    1817         //              // get declaration of member and base declaration of member, exiting early if not found
    1818         //              AggregateDecl *memberBase = getMemberBaseDecl( memberExpr );
    1819         //              if ( ! memberBase ) return memberExpr;
    1820         //              DeclarationWithType *memberDecl = memberExpr->get_member();
    1821         //              std::list< Declaration* >::const_iterator baseIt = findDeclNamed( memberBase->get_members(), memberDecl->get_name() );
    1822         //              if ( baseIt == memberBase->get_members().end() ) return memberExpr;
    1823         //              DeclarationWithType *baseDecl = dynamic_cast< DeclarationWithType* >( *baseIt );
    1824         //              if ( ! baseDecl ) return memberExpr;
    1825         //
    1826         //              // check if stated type of the member is not the type of the member's declaration; if so, need a cast
    1827         //              // this *SHOULD* be safe, I don't think anything but the void-replacements I put in for dtypes would make it past the typechecker
    1828         //              SymTab::Indexer dummy;
    1829         //              if ( ResolvExpr::typesCompatible( memberDecl->get_type(), baseDecl->get_type(), dummy ) ) return memberExpr;
    1830         //              else return new CastExpr( memberExpr, memberDecl->get_type() );
    1831         //      }
    1832 
    1833                 void GenericInstantiator::doBeginScope() {
    1834                         DeclMutator::doBeginScope();
    1835                         instantiations.beginScope();
    1836                 }
    1837 
    1838                 void GenericInstantiator::doEndScope() {
    1839                         DeclMutator::doEndScope();
    1840                         instantiations.endScope();
    1841                 }
    1842 
    18431311////////////////////////////////////////// MemberExprFixer ////////////////////////////////////////////////////
    18441312
Note: See TracChangeset for help on using the changeset viewer.