Changeset ae357ec for src/GenPoly/Box.cc


Ignore:
Timestamp:
Mar 8, 2016, 10:25:06 PM (8 years ago)
Author:
Peter A. Buhr <pabuhr@…>
Branches:
ADT, aaron-thesis, arm-eh, ast-experimental, cleanup-dtors, ctor, deferred_resn, demangler, enum, forall-pointer-decay, gc_noraii, jacob/cs343-translation, jenkins-sandbox, master, memory, new-ast, new-ast-unique-expr, new-env, no_list, persistent-indexer, pthread-emulation, qualifiedEnum, resolv-new, string, with_gc
Children:
5447e09
Parents:
b63e376 (diff), bed4c63e (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the (diff) links above to see all the changes relative to each parent.
Message:

Merge branch 'master' of plg2:software/cfa/cfa-cc

File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/GenPoly/Box.cc

    rb63e376 rae357ec  
    1414//
    1515
     16#include <algorithm>
     17#include <iterator>
     18#include <list>
     19#include <map>
    1620#include <set>
    1721#include <stack>
    1822#include <string>
    19 #include <iterator>
    20 #include <algorithm>
     23#include <utility>
     24#include <vector>
    2125#include <cassert>
    2226
    2327#include "Box.h"
    24 #include "InstantiateGeneric.h"
     28#include "DeclMutator.h"
    2529#include "PolyMutator.h"
    2630#include "FindFunction.h"
     31#include "ScopedMap.h"
    2732#include "ScrubTyVars.h"
    2833
     
    3035
    3136#include "SynTree/Constant.h"
    32 #include "SynTree/Type.h"
     37#include "SynTree/Declaration.h"
    3338#include "SynTree/Expression.h"
    3439#include "SynTree/Initializer.h"
     40#include "SynTree/Mutator.h"
    3541#include "SynTree/Statement.h"
    36 #include "SynTree/Mutator.h"
     42#include "SynTree/Type.h"
     43#include "SynTree/TypeSubstitution.h"
    3744
    3845#include "ResolvExpr/TypeEnvironment.h"
     
    4047#include "ResolvExpr/typeops.h"
    4148
     49#include "SymTab/Indexer.h"
    4250#include "SymTab/Mangler.h"
    4351
     
    5462                FunctionType *makeAdapterType( FunctionType *adaptee, const TyVarMap &tyVars );
    5563
     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               
    56181                /// 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
    57182                class Pass1 : public PolyMutator {
     
    100225                        ObjectDecl *makeTemporary( Type *type );
    101226
    102                         typedef std::map< std::string, DeclarationWithType *> AdapterMap;
    103227                        std::map< std::string, DeclarationWithType *> assignOps;
    104228                        ResolvExpr::TypeMap< DeclarationWithType > scopedAssignOps;
    105                         std::stack< AdapterMap > adapters;
     229                        ScopedMap< std::string, DeclarationWithType* > adapters;
    106230                        DeclarationWithType *retval;
    107231                        bool useRetval;
     
    124248
    125249                        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 ); }
    126278                };
    127279
     
    159311        } // anonymous namespace
    160312
    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 
    170313        /// version of mutateAll with special handling for translation unit so you can check the end of the prelude when debugging
    171314        template< typename MutatorType >
     
    195338
    196339        void box( std::list< Declaration *>& translationUnit ) {
     340                LayoutFunctionBuilder layoutBuilder;
    197341                Pass1 pass1;
    198342                Pass2 pass2;
     343                GenericInstantiator instantiator;
    199344                MemberExprFixer memberFixer;
    200345                Pass3 pass3;
     346               
     347                layoutBuilder.mutateDeclarationList( translationUnit );
    201348                mutateTranslationUnit/*All*/( translationUnit, pass1 );
    202349                mutateTranslationUnit/*All*/( translationUnit, pass2 );
    203                 instantiateGeneric( translationUnit );
     350//              instantiateGeneric( translationUnit );
     351                instantiator.mutateDeclarationList( translationUnit );
    204352                mutateTranslationUnit/*All*/( translationUnit, memberFixer );
    205353                mutateTranslationUnit/*All*/( translationUnit, pass3 );
    206354        }
    207355
     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       
    208554        ////////////////////////////////////////// Pass1 ////////////////////////////////////////////////////
    209555
     
    245591                }
    246592
    247                 Pass1::Pass1() : useRetval( false ), tempNamer( "_temp" ) {
    248                         adapters.push(AdapterMap());
    249                 }
     593                Pass1::Pass1() : useRetval( false ), tempNamer( "_temp" ) {}
    250594
    251595                /// Returns T if the given declaration is (*?=?)(T *, T) for some TypeInstType T (return not checked, but maybe should be), NULL otherwise
     
    350694                                } // for
    351695
    352                                 AdapterMap & adapters = Pass1::adapters.top();
    353696                                for ( std::list< FunctionType *>::iterator funType = functions.begin(); funType != functions.end(); ++funType ) {
    354697                                        std::string mangleName = mangleAdapterName( *funType, scopeTyVars );
     
    7721115                                        mangleName += makePolyMonoSuffix( originalFunction, exprTyVars );
    7731116
    774                                         AdapterMap & adapters = Pass1::adapters.top();
    775                                         AdapterMap::iterator adapter = adapters.find( mangleName );
     1117                                        typedef ScopedMap< std::string, DeclarationWithType* >::iterator AdapterIter;
     1118                                        AdapterIter adapter = adapters.find( mangleName );
    7761119                                        if ( adapter == adapters.end() ) {
    7771120                                                // adapter has not been created yet in the current scope, so define it
    7781121                                                FunctionDecl *newAdapter = makeAdapter( *funType, realFunction, mangleName, exprTyVars );
    779                                                 adapter = adapters.insert( adapters.begin(), std::pair< std::string, DeclarationWithType *>( mangleName, newAdapter ) );
     1122                                                std::pair< AdapterIter, bool > answer = adapters.insert( std::pair< std::string, DeclarationWithType *>( mangleName, newAdapter ) );
     1123                                                adapter = answer.first;
    7801124                                                stmtsToAdd.push_back( new DeclStmt( noLabels, newAdapter ) );
    7811125                                        } // if
     
    11561500
    11571501                void Pass1::doBeginScope() {
    1158                         // push a copy of the current map
    1159                         adapters.push(adapters.top());
     1502                        adapters.beginScope();
    11601503                        scopedAssignOps.beginScope();
    11611504                }
    11621505
    11631506                void Pass1::doEndScope() {
    1164                         adapters.pop();
     1507                        adapters.endScope();
    11651508                        scopedAssignOps.endScope();
    11661509                }
     
    13091652                }
    13101653
     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
    13111843////////////////////////////////////////// MemberExprFixer ////////////////////////////////////////////////////
    13121844
Note: See TracChangeset for help on using the changeset viewer.