Changes in / [78885b5:53ba273]


Ignore:
Location:
src
Files:
1 deleted
18 edited

Legend:

Unmodified
Added
Removed
  • src/CodeGen/CodeGenerator.cc

    r78885b5 r53ba273  
    455455
    456456        void CodeGenerator::visit( UntypedOffsetofExpr *offsetofExpr ) {
    457                 assert( false && "UntypedOffsetofExpr should not reach code generation" );
     457                assert( false );
    458458        }
    459459
     
    464464                output << ", " << mangleName( offsetofExpr->get_member() );
    465465                output << ")";
    466         }
    467 
    468         void CodeGenerator::visit( OffsetPackExpr *offsetPackExpr ) {
    469                 assert( false && "OffsetPackExpr should not reach code generation" );
    470466        }
    471467 
  • src/CodeGen/CodeGenerator.h

    r78885b5 r53ba273  
    6565                virtual void visit( UntypedOffsetofExpr *offsetofExpr );
    6666                virtual void visit( OffsetofExpr *offsetofExpr );
    67                 virtual void visit( OffsetPackExpr *offsetPackExpr );
    6867                virtual void visit( LogicalExpr *logicalExpr );
    6968                virtual void visit( ConditionalExpr *conditionalExpr );
  • src/GenPoly/Box.cc

    r78885b5 r53ba273  
    3030#include "FindFunction.h"
    3131#include "ScopedMap.h"
    32 #include "ScopedSet.h"
    3332#include "ScrubTyVars.h"
    3433
     
    6362                FunctionType *makeAdapterType( FunctionType *adaptee, const TyVarMap &tyVars );
    6463
    65                 /// Abstracts type equality for a list of parameter types
    66                 struct TypeList {
    67                         TypeList() : params() {}
    68                         TypeList( const std::list< Type* > &_params ) : params() { cloneAll(_params, params); }
    69                         TypeList( std::list< Type* > &&_params ) : params( _params ) {}
    70 
    71                         TypeList( const TypeList &that ) : params() { cloneAll(that.params, params); }
    72                         TypeList( TypeList &&that ) : params( std::move( that.params ) ) {}
     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); }
    7371
    7472                        /// Extracts types from a list of TypeExpr*
    75                         TypeList( const std::list< TypeExpr* >& _params ) : params() {
     73                        ConcreteType(AggregateDecl *_base, const std::list< TypeExpr* >& _params) : base(_base), params() {
    7674                                for ( std::list< TypeExpr* >::const_iterator param = _params.begin(); param != _params.end(); ++param ) {
    7775                                        params.push_back( (*param)->get_type()->clone() );
     
    7977                        }
    8078
    81                         TypeList& operator= ( const TypeList &that ) {
     79                        ConcreteType& operator= (const ConcreteType& that) {
    8280                                deleteAll( params );
    83 
    8481                                params.clear();
     82
     83                                base = that.base;
    8584                                cloneAll( that.params, params );
    8685
     
    8887                        }
    8988
    90                         TypeList& operator= ( TypeList &&that ) {
    91                                 deleteAll( params );
    92 
    93                                 params = std::move( that.params );
    94 
    95                                 return *this;
    96                         }
    97 
    98                         ~TypeList() { deleteAll( params ); }
    99 
    100                         bool operator== ( const TypeList& that ) const {
     89                        ~ConcreteType() { deleteAll( params ); }
     90
     91                        bool operator== (const ConcreteType& that) const {
     92                                if ( base != that.base ) return false;
     93
     94                                SymTab::Indexer dummy;
    10195                                if ( params.size() != that.params.size() ) return false;
    102 
    103                                 SymTab::Indexer dummy;
    10496                                for ( std::list< Type* >::const_iterator it = params.begin(), jt = that.params.begin(); it != params.end(); ++it, ++jt ) {
    10597                                        if ( ! ResolvExpr::typesCompatible( *it, *jt, dummy ) ) return false;
     
    108100                        }
    109101
     102                        AggregateDecl *base;        ///< Base generic type
    110103                        std::list< Type* > params;  ///< Instantiation parameters
    111104                };
    112105
    113                 /// Maps a key and a TypeList to the some value, accounting for scope
    114                 template< typename Key, typename Value >
     106                /// Maps a concrete type to the some value, accounting for scope
     107                template< typename Value >
    115108                class InstantiationMap {
    116                         /// Wraps value for a specific (Key, TypeList) combination
    117                         typedef std::pair< TypeList, Value* > Instantiation;
    118                         /// List of TypeLists paired with their appropriate values
    119                         typedef std::vector< Instantiation > ValueList;
    120                         /// Underlying map type; maps keys to a linear list of corresponding TypeLists and values
    121                         typedef ScopedMap< Key*, ValueList > InnerMap;
    122 
    123                         InnerMap instantiations;  ///< instantiations
     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
    124121
    125122                public:
    126123                        /// Starts a new scope
    127                         void beginScope() { instantiations.beginScope(); }
     124                        void beginScope() {
     125                                Scope scope;
     126                                scopes.push_back(scope);
     127                        }
    128128
    129129                        /// Ends a scope
    130                         void endScope() { instantiations.endScope(); }
    131 
    132                         /// Gets the value for the (key, typeList) pair, returns NULL on none such.
    133                         Value *lookup( Key *key, const std::list< TypeExpr* >& params ) const {
    134                                 TypeList typeList( params );
    135                                
    136                                 // scan scopes for matches to the key
    137                                 for ( typename InnerMap::const_iterator insts = instantiations.find( key ); insts != instantiations.end(); insts = instantiations.findNext( insts, key ) ) {
    138                                         for ( typename ValueList::const_reverse_iterator inst = insts->second.rbegin(); inst != insts->second.rend(); ++inst ) {
    139                                                 if ( inst->first == typeList ) return inst->second;
     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;
    140150                                        }
    141151                                }
    142                                 // no matching instantiations found
     152                                // no matching instantiation found
    143153                                return 0;
    144154                        }
    145 
    146                         /// Adds a value for a (key, typeList) pair to the current scope
    147                         void insert( Key *key, const std::list< TypeExpr* > &params, Value *value ) {
    148                                 instantiations[ key ].push_back( Instantiation( TypeList( params ), value ) );
    149                         }
     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 ); }
    150168                };
    151169
     
    179197                        virtual void doEndScope();
    180198                  private:
     199                        /// Makes a new temporary array holding the offsets of the fields of `type`, and returns a new variable expression referencing it
     200                        Expression *makeOffsetArray( StructInstType *type );
    181201                        /// Pass the extra type parameters from polymorphic generic arguments or return types into a function application
    182202                        void passArgTypeVars( ApplicationExpr *appExpr, Type *parmType, Type *argBaseType, std::list< Expression *>::iterator &arg, const TyVarMap &exprTyVars, std::set< std::string > &seenTypes );
     
    205225                        ObjectDecl *makeTemporary( Type *type );
    206226
    207                         std::map< std::string, DeclarationWithType *> assignOps;     ///< Currently known type variable assignment operators
    208                         ResolvExpr::TypeMap< DeclarationWithType > scopedAssignOps;  ///< Currently known assignment operators
    209                         ScopedMap< std::string, DeclarationWithType* > adapters;     ///< Set of adapter functions in the current scope
    210                        
     227                        std::map< std::string, DeclarationWithType *> assignOps;
     228                        ResolvExpr::TypeMap< DeclarationWithType > scopedAssignOps;
     229                        ScopedMap< std::string, DeclarationWithType* > adapters;
    211230                        DeclarationWithType *retval;
    212231                        bool useRetval;
     
    214233                };
    215234
    216                 /// * Moves polymorphic returns in function types to pointer-type parameters
    217                 /// * adds type size and assertion parameters to parameter lists
    218                 /// * does dynamic calculation of type layouts
     235                /// Moves polymorphic returns in function types to pointer-type parameters, adds type size and assertion parameters to parameter lists as well
    219236                class Pass2 : public PolyMutator {
    220237                  public:
     
    227244                        virtual Type *mutate( PointerType *pointerType );
    228245                        virtual Type *mutate( FunctionType *funcType );
    229                         virtual Expression *mutate( SizeofExpr *sizeofExpr );
    230                         virtual Expression *mutate( AlignofExpr *alignofExpr );
    231                         virtual Expression *mutate( OffsetofExpr *offsetofExpr );
    232                         virtual Expression *mutate( OffsetPackExpr *offsetPackExpr );
    233 
    234                         virtual void doBeginScope();
    235                         virtual void doEndScope();
    236246                  private:
    237247                        void addAdapters( FunctionType *functionType );
    238                         /// Makes a new variable in the current scope with the given name, type & optional initializer
    239                         ObjectDecl *makeVar( const std::string &name, Type *type, Initializer *init = 0 );
    240                         /// returns true if the type has a dynamic layout; such a layout will be stored in appropriately-named local variables when the function returns
    241                         bool findGeneric( Type *ty );
    242                         /// adds type parameters to the layout call; will generate the appropriate parameters if needed
    243                         void addOtypeParamsToLayoutCall( UntypedExpr *layoutCall, const std::list< Type* > &otypeParams );
    244248
    245249                        std::map< UniqueId, std::string > adapterName;
    246                         ScopedSet< std::string > knownLayouts;          ///< Set of generic type layouts known in the current scope, indexed by sizeofName
    247                         ScopedSet< std::string > knownOffsets;          ///< Set of non-generic types for which the offset array exists in the current scope, indexed by offsetofName
    248250                };
    249251
     
    251253                class GenericInstantiator : public DeclMutator {
    252254                        /// Map of (generic type, parameter list) pairs to concrete type instantiations
    253                         InstantiationMap< AggregateDecl, AggregateDecl > instantiations;
     255                        InstantiationMap< AggregateDecl > instantiations;
    254256                        /// Namer for concrete types
    255257                        UniqueName typeNamer;
     
    346348                mutateTranslationUnit/*All*/( translationUnit, pass1 );
    347349                mutateTranslationUnit/*All*/( translationUnit, pass2 );
     350//              instantiateGeneric( translationUnit );
    348351                instantiator.mutateDeclarationList( translationUnit );
    349352                mutateTranslationUnit/*All*/( translationUnit, memberFixer );
     
    650653
    651654                DeclarationWithType *Pass1::mutate( FunctionDecl *functionDecl ) {
    652                         // if this is a assignment function, put it in the map for this scope
     655                        // if this is a polymorphic assignment function, put it in the map for this scope
    653656                        if ( Type *assignedType = isAssignment( functionDecl ) ) {
    654657                                if ( ! dynamic_cast< TypeInstType* >( assignedType ) ) {
     
    740743                }
    741744
     745                Expression *Pass1::makeOffsetArray( StructInstType *ty ) {
     746                        std::list< Declaration* > &baseMembers = ty->get_baseStruct()->get_members();
     747
     748                        // make a new temporary array
     749                        Type *offsetType = new BasicType( Type::Qualifiers(), BasicType::LongUnsignedInt );
     750                        std::stringstream lenGen;
     751                        lenGen << baseMembers.size();
     752                        ConstantExpr *lenExpr = new ConstantExpr( Constant( offsetType->clone(), lenGen.str() ) );
     753                        ObjectDecl *arrayTemp = makeTemporary( new ArrayType( Type::Qualifiers(), offsetType, lenExpr, false, false ) );
     754
     755                        // build initializer list for temporary
     756                        std::list< Initializer* > inits;
     757                        for ( std::list< Declaration* >::const_iterator member = baseMembers.begin(); member != baseMembers.end(); ++member ) {
     758                                DeclarationWithType *memberDecl;
     759                                if ( DeclarationWithType *origMember = dynamic_cast< DeclarationWithType* >( *member ) ) {
     760                                        memberDecl = origMember->clone();
     761                                } else {
     762                                        memberDecl = new ObjectDecl( (*member)->get_name(), DeclarationNode::NoStorageClass, LinkageSpec::Cforall, 0, offsetType->clone(), 0 );
     763                                }
     764                                inits.push_back( new SingleInit( new OffsetofExpr( ty->clone(), memberDecl ) ) );
     765                        }
     766                        arrayTemp->set_init( new ListInit( inits ) );
     767
     768                        // return variable pointing to temporary
     769                        return new VariableExpr( arrayTemp );
     770                }
     771
    742772                void Pass1::passArgTypeVars( ApplicationExpr *appExpr, Type *parmType, Type *argBaseType, std::list< Expression *>::iterator &arg, const TyVarMap &exprTyVars, std::set< std::string > &seenTypes ) {
    743773                        Type *polyBase = hasPolyBase( parmType, exprTyVars );
     
    752782                                if ( dynamic_cast< StructInstType* >( polyBase ) ) {
    753783                                        if ( StructInstType *argBaseStructType = dynamic_cast< StructInstType* >( argBaseType ) ) {
    754                                                 // zero-length arrays are forbidden by C, so don't pass offset for empty struct
    755                                                 if ( ! argBaseStructType->get_baseStruct()->get_members().empty() ) {
    756                                                         arg = appExpr->get_args().insert( arg, new OffsetPackExpr( argBaseStructType->clone() ) );
    757                                                         arg++;
    758                                                 }
     784                                                arg = appExpr->get_args().insert( arg, makeOffsetArray( argBaseStructType ) );
     785                                                arg++;
    759786                                        } else {
    760787                                                throw SemanticError( "Cannot pass non-struct type for generic struct" );
     
    904931                                        return;
    905932                                } else if ( arg->get_results().front()->get_isLvalue() ) {
    906                                         // VariableExpr and MemberExpr are lvalues; need to check this isn't coming from the second arg of a comma expression though (not an lvalue)
    907                                         if ( CommaExpr *commaArg = dynamic_cast< CommaExpr* >( arg ) ) {
    908                                                 commaArg->set_arg2( new AddressExpr( commaArg->get_arg2() ) );
    909                                         } else {
    910                                                 arg = new AddressExpr( arg );
    911                                         }
     933                                        // VariableExpr and MemberExpr are lvalues
     934                                        arg = new AddressExpr( arg );
    912935                                } else {
    913936                                        // use type computed in unification to declare boxed variables
     
    10041027                        } // for
    10051028                }
     1029
     1030
    10061031
    10071032                FunctionDecl *Pass1::makeAdapter( FunctionType *adaptee, FunctionType *realType, const std::string &mangleName, const TyVarMap &tyVars ) {
     
    14031428                                        std::list< TypeDecl* >::const_iterator forallIt = forallParams.begin();
    14041429                                        for ( ; tyIt != tyParams.end() && forallIt != forallParams.end(); ++tyIt, ++forallIt ) {
    1405                                                 // Add appropriate mapping to assignment expression environment
     1430                                                if ( (*forallIt)->get_kind() != TypeDecl::Any ) continue; // skip types with no assign op (ftype/dtype)
     1431
     1432                                                std::list< DeclarationWithType* > &asserts = (*forallIt)->get_assertions();
     1433                                                assert( ! asserts.empty() && "Type param needs assignment operator assertion" );
     1434                                                DeclarationWithType *actualDecl = asserts.front();
     1435                                                TypeInstType *actualType = isTypeInstAssignment( actualDecl );
     1436                                                assert( actualType && "First assertion of type with assertions should be assignment operator" );
    14061437                                                TypeExpr *formalTypeExpr = dynamic_cast< TypeExpr* >( *tyIt );
    14071438                                                assert( formalTypeExpr && "type parameters must be type expressions" );
    14081439                                                Type *formalType = formalTypeExpr->get_type();
    1409                                                 assignExpr->get_env()->add( (*forallIt)->get_name(), formalType );
    1410 
    1411                                                 // skip types with no assign op (ftype/dtype)
    1412                                                 if ( (*forallIt)->get_kind() != TypeDecl::Any ) continue;
    1413 
    1414                                                 // find assignment operator for formal type
     1440                                                assignExpr->get_env()->add( actualType->get_name(), formalType );
     1441                                               
    14151442                                                DeclarationWithType *assertAssign = 0;
    14161443                                                if ( TypeInstType *formalTypeInstType = dynamic_cast< TypeInstType* >( formalType ) ) {
     
    14261453                                                        }
    14271454                                                }
    1428 
    1429                                                 // add inferred parameter for field assignment operator to assignment expression
    1430                                                 std::list< DeclarationWithType* > &asserts = (*forallIt)->get_assertions();
    1431                                                 assert( ! asserts.empty() && "Type param needs assignment operator assertion" );
    1432                                                 DeclarationWithType *actualDecl = asserts.front();
     1455                                               
     1456
    14331457                                                assignExpr->get_inferParams()[ actualDecl->get_uniqueId() ]
    14341458                                                        = ParamEntry( assertAssign->get_uniqueId(), assertAssign->get_type()->clone(), actualDecl->get_type()->clone(), wrapFunctionDecl( assertAssign ) );
     
    15631587                        ObjectDecl newPtr( "", DeclarationNode::NoStorageClass, LinkageSpec::C, 0,
    15641588                                           new PointerType( Type::Qualifiers(), new BasicType( Type::Qualifiers(), BasicType::LongUnsignedInt ) ), 0 );
     1589//   ObjectDecl *newFunPtr = new ObjectDecl( "", DeclarationNode::NoStorageClass, LinkageSpec::Cforall, 0, new PointerType( Type::Qualifiers(), new FunctionType( Type::Qualifiers(), true ) ), 0 );
    15651590                        for ( std::list< TypeDecl *>::const_iterator tyParm = funcType->get_forall().begin(); tyParm != funcType->get_forall().end(); ++tyParm ) {
    15661591                                ObjectDecl *sizeParm, *alignParm;
     
    16061631                                        ++last;
    16071632
    1608                                         if ( StructInstType *polyBaseStruct = dynamic_cast< StructInstType* >( polyBase ) ) {
    1609                                                 // NOTE zero-length arrays are illegal in C, so empty structs have no offset array
    1610                                                 if ( ! polyBaseStruct->get_baseStruct()->get_members().empty() ) {
    1611                                                         offsetParm = newPtr.clone();
    1612                                                         offsetParm->set_name( offsetofName( polyBase ) );
    1613                                                         last = funcType->get_parameters().insert( last, offsetParm );
    1614                                                         ++last;
    1615                                                 }
     1633                                        if ( dynamic_cast< StructInstType* >( polyBase ) ) {
     1634                                                offsetParm = newPtr.clone();
     1635                                                offsetParm->set_name( offsetofName( polyBase ) );
     1636                                                last = funcType->get_parameters().insert( last, offsetParm );
     1637                                                ++last;
    16161638                                        }
    16171639
    16181640                                        seenTypes.insert( sizeName );
    1619                                         knownLayouts.insert( sizeName );  // make sure that any type information passed into the function is accounted for
    16201641                                }
    16211642                        }
     
    16291650                        scopeTyVars = oldtyVars;
    16301651                        return funcType;
    1631                 }
    1632 
    1633                 ObjectDecl *Pass2::makeVar( const std::string &name, Type *type, Initializer *init ) {
    1634                         ObjectDecl *newObj = new ObjectDecl( name, DeclarationNode::NoStorageClass, LinkageSpec::C, 0, type, init );
    1635                         stmtsToAdd.push_back( new DeclStmt( noLabels, newObj ) );
    1636                         return newObj;
    1637                 }
    1638 
    1639                 void Pass2::addOtypeParamsToLayoutCall( UntypedExpr *layoutCall, const std::list< Type* > &otypeParams ) {
    1640                         for ( std::list< Type* >::const_iterator param = otypeParams.begin(); param != otypeParams.end(); ++param ) {
    1641                                 if ( findGeneric( *param ) ) {
    1642                                         // push size/align vars for a generic parameter back
    1643                                         layoutCall->get_args().push_back( new NameExpr( sizeofName( *param ) ) );
    1644                                         layoutCall->get_args().push_back( new NameExpr( alignofName( *param ) ) );
    1645                                 } else {
    1646                                         layoutCall->get_args().push_back( new SizeofExpr( (*param)->clone() ) );
    1647                                         layoutCall->get_args().push_back( new AlignofExpr( (*param)->clone() ) );
    1648                                 }
    1649                         }
    1650                 }
    1651 
    1652                 /// returns true if any of the otype parameters have a dynamic layout and puts all otype parameters in the output list
    1653                 bool findGenericParams( std::list< TypeDecl* > &baseParams, std::list< Expression* > &typeParams, std::list< Type* > &out ) {
    1654                         bool hasDynamicLayout = false;
    1655 
    1656                         std::list< TypeDecl* >::const_iterator baseParam = baseParams.begin();
    1657                         std::list< Expression* >::const_iterator typeParam = typeParams.begin();
    1658                         for ( ; baseParam != baseParams.end() && typeParam != typeParams.end(); ++baseParam, ++typeParam ) {
    1659                                 // skip non-otype parameters
    1660                                 if ( (*baseParam)->get_kind() != TypeDecl::Any ) continue;
    1661                                 TypeExpr *typeExpr = dynamic_cast< TypeExpr* >( *typeParam );
    1662                                 assert( typeExpr && "all otype parameters should be type expressions" );
    1663 
    1664                                 Type *type = typeExpr->get_type();
    1665                                 out.push_back( type );
    1666                                 if ( isPolyType( type ) ) hasDynamicLayout = true;
    1667                         }
    1668                         assert( baseParam == baseParams.end() && typeParam == typeParams.end() );
    1669 
    1670                         return hasDynamicLayout;
    1671                 }
    1672                
    1673                 bool Pass2::findGeneric( Type *ty ) {
    1674                         if ( dynamic_cast< TypeInstType* >( ty ) ) {
    1675                                 // NOTE this assumes that all type variables will be properly bound, and thus have their layouts in scope
    1676                                 return true;
    1677                         } else if ( StructInstType *structTy = dynamic_cast< StructInstType* >( ty ) ) {
    1678                                 // check if this type already has a layout generated for it
    1679                                 std::string sizeName = sizeofName( ty );
    1680                                 if ( knownLayouts.find( sizeName ) != knownLayouts.end() ) return true;
    1681                                
    1682                                 // check if any of the type parameters have dynamic layout; if none do, this type is (or will be) monomorphized
    1683                                 std::list< Type* > otypeParams;
    1684                                 if ( ! findGenericParams( *structTy->get_baseParameters(), structTy->get_parameters(), otypeParams ) ) return false;
    1685 
    1686                                 // insert local variables for layout and generate call to layout function
    1687                                 knownLayouts.insert( sizeName );  // done early so as not to interfere with the later addition of parameters to the layout call
    1688                                 Type *layoutType = new BasicType( Type::Qualifiers(), BasicType::LongUnsignedInt );
    1689 
    1690                                 int n_members = structTy->get_baseStruct()->get_members().size();
    1691                                 if ( n_members == 0 ) {
    1692                                         // all empty structs have the same layout - size 1, align 1
    1693                                         makeVar( sizeName, layoutType, new SingleInit( new ConstantExpr( Constant::from( (unsigned long)1 ) ) ) );
    1694                                         makeVar( alignofName( ty ), layoutType->clone(), new SingleInit( new ConstantExpr( Constant::from( (unsigned long)1 ) ) ) );
    1695                                         // NOTE zero-length arrays are forbidden in C, so empty structs have no offsetof array
    1696                                 } else {
    1697                                         ObjectDecl *sizeVar = makeVar( sizeName, layoutType );
    1698                                         ObjectDecl *alignVar = makeVar( alignofName( ty ), layoutType->clone() );
    1699                                         ObjectDecl *offsetVar = makeVar( offsetofName( ty ), new ArrayType( Type::Qualifiers(), layoutType->clone(), new ConstantExpr( Constant::from( n_members ) ), false, false ) );
    1700 
    1701                                         // generate call to layout function
    1702                                         UntypedExpr *layoutCall = new UntypedExpr( new NameExpr( "__layoutof_" + structTy->get_baseStruct()->get_name() ) );
    1703                                         layoutCall->get_args().push_back( new AddressExpr( new VariableExpr( sizeVar ) ) );
    1704                                         layoutCall->get_args().push_back( new AddressExpr( new VariableExpr( alignVar ) ) );
    1705                                         layoutCall->get_args().push_back( new VariableExpr( offsetVar ) );
    1706                                         addOtypeParamsToLayoutCall( layoutCall, otypeParams );
    1707 
    1708                                         stmtsToAdd.push_back( new ExprStmt( noLabels, layoutCall ) );
    1709                                 }
    1710                                
    1711                                 return true;
    1712                         } else if ( UnionInstType *unionTy = dynamic_cast< UnionInstType* >( ty ) ) {
    1713                                 // check if this type already has a layout generated for it
    1714                                 std::string sizeName = sizeofName( ty );
    1715                                 if ( knownLayouts.find( sizeName ) != knownLayouts.end() ) return true;
    1716                                
    1717                                 // check if any of the type parameters have dynamic layout; if none do, this type is (or will be) monomorphized
    1718                                 std::list< Type* > otypeParams;
    1719                                 if ( ! findGenericParams( *unionTy->get_baseParameters(), unionTy->get_parameters(), otypeParams ) ) return false;
    1720 
    1721                                 // insert local variables for layout and generate call to layout function
    1722                                 knownLayouts.insert( sizeName );  // done early so as not to interfere with the later addition of parameters to the layout call
    1723                                 Type *layoutType = new BasicType( Type::Qualifiers(), BasicType::LongUnsignedInt );
    1724 
    1725                                 ObjectDecl *sizeVar = makeVar( sizeName, layoutType );
    1726                                 ObjectDecl *alignVar = makeVar( alignofName( ty ), layoutType->clone() );
    1727                                
    1728                                 // generate call to layout function
    1729                                 UntypedExpr *layoutCall = new UntypedExpr( new NameExpr( "__layoutof_" + unionTy->get_baseUnion()->get_name() ) );
    1730                                 layoutCall->get_args().push_back( new AddressExpr( new VariableExpr( sizeVar ) ) );
    1731                                 layoutCall->get_args().push_back( new AddressExpr( new VariableExpr( alignVar ) ) );
    1732                                 addOtypeParamsToLayoutCall( layoutCall, otypeParams );
    1733 
    1734                                 stmtsToAdd.push_back( new ExprStmt( noLabels, layoutCall ) );
    1735 
    1736                                 return true;
    1737                         }
    1738                        
    1739                         return false;
    1740                 }
    1741                
    1742                 Expression *Pass2::mutate( SizeofExpr *sizeofExpr ) {
    1743                         Type *ty = sizeofExpr->get_type();
    1744                         if ( findGeneric( ty ) ) {
    1745                                 Expression *ret = new NameExpr( sizeofName( ty ) );
    1746                                 delete sizeofExpr;
    1747                                 return ret;
    1748                         }
    1749                         return sizeofExpr;
    1750                 }
    1751 
    1752                 Expression *Pass2::mutate( AlignofExpr *alignofExpr ) {
    1753                         Type *ty = alignofExpr->get_type();
    1754                         if ( findGeneric( ty ) ) {
    1755                                 Expression *ret = new NameExpr( alignofName( ty ) );
    1756                                 delete alignofExpr;
    1757                                 return ret;
    1758                         }
    1759                         return alignofExpr;
    1760                 }
    1761 
    1762                 Expression *Pass2::mutate( OffsetofExpr *offsetofExpr ) {
    1763                         findGeneric( offsetofExpr->get_type() );
    1764                         return offsetofExpr;
    1765                 }
    1766 
    1767                 Expression *Pass2::mutate( OffsetPackExpr *offsetPackExpr ) {
    1768                         StructInstType *ty = offsetPackExpr->get_type();
    1769 
    1770                         Expression *ret = 0;
    1771                         if ( findGeneric( ty ) ) {
    1772                                 // pull offset back from generated type information
    1773                                 ret = new NameExpr( offsetofName( ty ) );
    1774                         } else {
    1775                                 std::string offsetName = offsetofName( ty );
    1776                                 if ( knownOffsets.find( offsetName ) != knownOffsets.end() ) {
    1777                                         // use the already-generated offsets for this type
    1778                                         ret = new NameExpr( offsetName );
    1779                                 } else {
    1780                                         knownOffsets.insert( offsetName );
    1781                                        
    1782                                         std::list< Declaration* > &baseMembers = ty->get_baseStruct()->get_members();
    1783                                         Type *offsetType = new BasicType( Type::Qualifiers(), BasicType::LongUnsignedInt );
    1784 
    1785                                         // build initializer list for offset array
    1786                                         std::list< Initializer* > inits;
    1787                                         for ( std::list< Declaration* >::const_iterator member = baseMembers.begin(); member != baseMembers.end(); ++member ) {
    1788                                                 DeclarationWithType *memberDecl;
    1789                                                 if ( DeclarationWithType *origMember = dynamic_cast< DeclarationWithType* >( *member ) ) {
    1790                                                         memberDecl = origMember->clone();
    1791                                                 } else {
    1792                                                         memberDecl = new ObjectDecl( (*member)->get_name(), DeclarationNode::NoStorageClass, LinkageSpec::Cforall, 0, offsetType->clone(), 0 );
    1793                                                 }
    1794                                                 inits.push_back( new SingleInit( new OffsetofExpr( ty->clone(), memberDecl ) ) );
    1795                                         }
    1796 
    1797                                         // build the offset array and replace the pack with a reference to it
    1798                                         ObjectDecl *offsetArray = makeVar( offsetName, new ArrayType( Type::Qualifiers(), offsetType, new ConstantExpr( Constant::from( baseMembers.size() ) ), false, false ),
    1799                                                         new ListInit( inits ) );
    1800                                         ret = new VariableExpr( offsetArray );
    1801                                 }
    1802                         }
    1803 
    1804                         delete offsetPackExpr;
    1805                         return ret;
    1806                 }
    1807 
    1808                 void Pass2::doBeginScope() {
    1809                         knownLayouts.beginScope();
    1810                         knownOffsets.beginScope();
    1811                 }
    1812                
    1813                 void Pass2::doEndScope() {
    1814                         knownLayouts.endScope();
    1815                         knownOffsets.beginScope();
    18161652                }
    18171653
  • src/GenPoly/ScopedMap.h

    r78885b5 r53ba273  
    1717#define _SCOPEDMAP_H
    1818
    19 #include <cassert>
    2019#include <iterator>
    2120#include <map>
     
    165164                void endScope() {
    166165                        scopes.pop_back();
    167                         assert( ! scopes.empty() );
    168166                }
    169167
     
    190188                        return end();
    191189                }
    192                 const_iterator find( const Key &key ) const {
    193                                 return const_iterator( const_cast< ScopedMap< Key, Value >* >(this)->find( key ) );
    194                 }
     190                const_iterator find( const Key &key ) const { return const_iterator( find( key ) ); }
    195191               
    196192                /// Finds the given key in the outermost scope inside the given scope where it occurs
     
    204200                        return end();
    205201                }
    206                 const_iterator findNext( const_iterator &it, const Key &key ) const {
    207                                 return const_iterator( const_cast< ScopedMap< Key, Value >* >(this)->findNext( it, key ) );
    208                 }
     202                const_iterator findNext( const_iterator &it, const Key &key ) const { return const_iterator( findNext( it, key ) ); }
    209203
    210204                /// Inserts the given key-value pair into the outermost scope
     
    214208                }
    215209                std::pair< iterator, bool > insert( const Key &key, const Value &value ) { return insert( std::make_pair( key, value ) ); }
    216 
    217                 Value& operator[] ( const Key &key ) {
    218                         iterator slot = find( key );
    219                         if ( slot != end() ) return slot->second;
    220                         return insert( key, Value() ).first->second;
    221                 }
     210               
    222211        };
    223212} // namespace GenPoly
  • src/InitTweak/InitModel.h

    r78885b5 r53ba273  
    7575                        void visit( UntypedOffsetofExpr * ) { throw 0; }
    7676                        void visit( OffsetofExpr * ) { throw 0; }
    77                         void visit( OffsetPackExpr * ) { throw 0; }
    7877                        void visit( AttrExpr * ) { throw 0; }
    7978                        void visit( LogicalExpr * ) { throw 0; }
  • src/ResolvExpr/AlternativeFinder.cc

    r78885b5 r53ba273  
    848848        }
    849849
    850         void AlternativeFinder::visit( OffsetPackExpr *offsetPackExpr ) {
    851                 alternatives.push_back( Alternative( offsetPackExpr->clone(), env, Cost::zero ) );
    852         }
    853 
    854850        void AlternativeFinder::resolveAttr( DeclarationWithType *funcDecl, FunctionType *function, Type *argType, const TypeEnvironment &env ) {
    855851                // assume no polymorphism
  • src/ResolvExpr/AlternativeFinder.h

    r78885b5 r53ba273  
    5959                virtual void visit( UntypedOffsetofExpr *offsetofExpr );
    6060                virtual void visit( OffsetofExpr *offsetofExpr );
    61                 virtual void visit( OffsetPackExpr *offsetPackExpr );
    6261                virtual void visit( AttrExpr *attrExpr );
    6362                virtual void visit( LogicalExpr *logicalExpr );
  • src/SymTab/Indexer.cc

    r78885b5 r53ba273  
    344344                maybeAccept( offsetofExpr->get_type(), *this );
    345345                maybeAccept( offsetofExpr->get_member(), *this );
    346         }
    347 
    348         void Indexer::visit( OffsetPackExpr *offsetPackExpr ) {
    349                 acceptAllNewScope( offsetPackExpr->get_results(), *this );
    350                 maybeAccept( offsetPackExpr->get_type(), *this );
    351346        }
    352347
  • src/SymTab/Indexer.h

    r78885b5 r53ba273  
    5959                virtual void visit( UntypedOffsetofExpr *offsetofExpr );
    6060                virtual void visit( OffsetofExpr *offsetofExpr );
    61                 virtual void visit( OffsetPackExpr *offsetPackExpr );
    6261                virtual void visit( AttrExpr *attrExpr );
    6362                virtual void visit( LogicalExpr *logicalExpr );
  • src/SynTree/Expression.cc

    r78885b5 r53ba273  
    222222}
    223223
    224 OffsetPackExpr::OffsetPackExpr( StructInstType *type_, Expression *aname_ ) : Expression( aname_ ), type( type_ ) {
    225         add_result( new ArrayType( Type::Qualifiers(), new BasicType( Type::Qualifiers(), BasicType::LongUnsignedInt ), 0, false, false ) );
    226 }
    227 
    228 OffsetPackExpr::OffsetPackExpr( const OffsetPackExpr &other ) : Expression( other ), type( maybeClone( other.type ) ) {}
    229 
    230 OffsetPackExpr::~OffsetPackExpr() { delete type; }
    231 
    232 void OffsetPackExpr::print( std::ostream &os, int indent ) const {
    233         os << std::string( indent, ' ' ) << "Offset pack expression on ";
    234 
    235         if ( type ) {
    236                 type->print(os, indent + 2);
    237         } else {
    238                 os << "<NULL>";
    239         }
    240 
    241         os << std::endl;
    242         Expression::print( os, indent );
    243 }
    244 
    245224AttrExpr::AttrExpr( Expression *attr, Expression *expr_, Expression *_aname ) :
    246225                Expression( _aname ), attr( attr ), expr(expr_), type(0), isType(false) {
  • src/SynTree/Expression.h

    r78885b5 r53ba273  
    362362};
    363363
    364 /// Expression representing a pack of field-offsets for a generic type
    365 class OffsetPackExpr : public Expression {
    366 public:
    367         OffsetPackExpr( StructInstType *type_, Expression *aname_ = 0 );
    368         OffsetPackExpr( const OffsetPackExpr &other );
    369         virtual ~OffsetPackExpr();
    370 
    371         StructInstType *get_type() const { return type; }
    372         void set_type( StructInstType *newValue ) { type = newValue; }
    373 
    374         virtual OffsetPackExpr *clone() const { return new OffsetPackExpr( *this ); }
    375         virtual void accept( Visitor &v ) { v.visit( this ); }
    376         virtual Expression *acceptMutator( Mutator &m ) { return m.mutate( this ); }
    377 
    378         virtual void print( std::ostream &os, int indent = 0 ) const;
    379 
    380 private:
    381         StructInstType *type;
    382 };
    383 
    384364/// AttrExpr represents an @attribute expression (like sizeof, but user-defined)
    385365class AttrExpr : public Expression {
  • src/SynTree/Mutator.cc

    r78885b5 r53ba273  
    274274}
    275275
    276 Expression *Mutator::mutate( OffsetPackExpr *offsetPackExpr ) {
    277         mutateAll( offsetPackExpr->get_results(), *this );
    278         offsetPackExpr->set_type( maybeMutate( offsetPackExpr->get_type(), *this ) );
    279         return offsetPackExpr;
    280 }
    281 
    282276Expression *Mutator::mutate( AttrExpr *attrExpr ) {
    283277        mutateAll( attrExpr->get_results(), *this );
  • src/SynTree/Mutator.h

    r78885b5 r53ba273  
    6767        virtual Expression* mutate( UntypedOffsetofExpr *offsetofExpr );
    6868        virtual Expression* mutate( OffsetofExpr *offsetofExpr );
    69         virtual Expression* mutate( OffsetPackExpr *offsetPackExpr );
    7069        virtual Expression* mutate( AttrExpr *attrExpr );
    7170        virtual Expression* mutate( LogicalExpr *logicalExpr );
  • src/SynTree/SynTree.h

    r78885b5 r53ba273  
    7272class UntypedOffsetofExpr;
    7373class OffsetofExpr;
    74 class OffsetPackExpr;
    7574class AttrExpr;
    7675class LogicalExpr;
  • src/SynTree/Visitor.cc

    r78885b5 r53ba273  
    230230}
    231231
    232 void Visitor::visit( OffsetPackExpr *offsetPackExpr ) {
    233         acceptAll( offsetPackExpr->get_results(), *this );
    234         maybeAccept( offsetPackExpr->get_type(), *this );
    235 }
    236 
    237232void Visitor::visit( AttrExpr *attrExpr ) {
    238233        acceptAll( attrExpr->get_results(), *this );
  • src/SynTree/Visitor.h

    r78885b5 r53ba273  
    6767        virtual void visit( UntypedOffsetofExpr *offsetofExpr );
    6868        virtual void visit( OffsetofExpr *offsetofExpr );
    69         virtual void visit( OffsetPackExpr *offsetPackExpr );
    7069        virtual void visit( AttrExpr *attrExpr );
    7170        virtual void visit( LogicalExpr *logicalExpr );
  • src/Tuples/FlattenTuple.cc

    r78885b5 r53ba273  
    4949        void FlattenTuple::CollectArgs::visit( UntypedOffsetofExpr *expr )  {  currentArgs.insert( currentArgs.end(), expr );  }
    5050        void FlattenTuple::CollectArgs::visit( OffsetofExpr        *expr )  {  currentArgs.insert( currentArgs.end(), expr );  }
    51         void FlattenTuple::CollectArgs::visit( OffsetPackExpr      *expr )  {  currentArgs.insert( currentArgs.end(), expr );  }
    5251        void FlattenTuple::CollectArgs::visit( AttrExpr            *expr )  {  currentArgs.insert( currentArgs.end(), expr );  }
    5352        void FlattenTuple::CollectArgs::visit( LogicalExpr         *expr )  {  currentArgs.insert( currentArgs.end(), expr );  }
  • src/Tuples/FlattenTuple.h

    r78885b5 r53ba273  
    4545                        virtual void visit( UntypedOffsetofExpr * );
    4646                        virtual void visit( OffsetofExpr * );
    47                         virtual void visit( OffsetPackExpr * );
    4847                        virtual void visit( AttrExpr * );
    4948                        virtual void visit( LogicalExpr * );
Note: See TracChangeset for help on using the changeset viewer.