Changes in / [3cfe27f:b3f9a0cb]
- Location:
- src/GenPoly
- Files:
-
- 2 edited
-
Box.cc (modified) (17 diffs)
-
ScopedMap.h (modified) (5 diffs)
Legend:
- Unmodified
- Added
- Removed
-
src/GenPoly/Box.cc
r3cfe27f rb3f9a0cb 30 30 #include "FindFunction.h" 31 31 #include "ScopedMap.h" 32 #include "ScopedSet.h" 32 33 #include "ScrubTyVars.h" 33 34 … … 62 63 FunctionType *makeAdapterType( FunctionType *adaptee, const TyVarMap &tyVars ); 63 64 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); } 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 ) ) {} 71 73 72 74 /// Extracts types from a list of TypeExpr* 73 ConcreteType(AggregateDecl *_base, const std::list< TypeExpr* >& _params) : base(_base),params() {75 TypeList( const std::list< TypeExpr* >& _params ) : params() { 74 76 for ( std::list< TypeExpr* >::const_iterator param = _params.begin(); param != _params.end(); ++param ) { 75 77 params.push_back( (*param)->get_type()->clone() ); … … 77 79 } 78 80 79 ConcreteType& operator= (const ConcreteType& that) {81 TypeList& operator= ( const TypeList &that ) { 80 82 deleteAll( params ); 83 81 84 params.clear(); 82 83 base = that.base;84 85 cloneAll( that.params, params ); 85 86 … … 87 88 } 88 89 89 ~ConcreteType() { deleteAll( params ); } 90 91 bool operator== (const ConcreteType& that) const { 92 if ( base != that.base ) return false; 90 TypeList& operator= ( TypeList &&that ) { 91 deleteAll( params ); 92 93 params = std::move( that.params ); 94 95 return *this; 96 } 97 98 ~TypeList() { deleteAll( params ); } 99 100 bool operator== ( const TypeList& that ) const { 101 if ( params.size() != that.params.size() ) return false; 93 102 94 103 SymTab::Indexer dummy; 95 if ( params.size() != that.params.size() ) return false;96 104 for ( std::list< Type* >::const_iterator it = params.begin(), jt = that.params.begin(); it != params.end(); ++it, ++jt ) { 97 105 if ( ! ResolvExpr::typesCompatible( *it, *jt, dummy ) ) return false; … … 100 108 } 101 109 102 AggregateDecl *base; ///< Base generic type103 110 std::list< Type* > params; ///< Instantiation parameters 104 111 }; 105 112 106 /// Maps a concrete typeto the some value, accounting for scope107 template< typename Value >113 /// Maps a key and a TypeList to the some value, accounting for scope 114 template< typename Key, typename Value > 108 115 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 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 121 124 122 125 public: 123 126 /// Starts a new scope 124 void beginScope() { 125 Scope scope; 126 scopes.push_back(scope); 127 } 127 void beginScope() { instantiations.beginScope(); } 128 128 129 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; 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; 150 140 } 151 141 } 152 // no matching instantiation found142 // no matching instantiations found 153 143 return 0; 154 144 } 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* > ¶ms, 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 ); } 145 146 /// Adds a value for a (key, typeList) pair to the current scope 147 void insert( Key *key, const std::list< TypeExpr* > ¶ms, Value *value ) { 148 instantiations[ key ].push_back( Instantiation( TypeList( params ), value ) ); 149 } 168 150 }; 169 151 … … 197 179 virtual void doEndScope(); 198 180 private: 199 /// Makes a new temporary array holding the offsets of the fields of `type`, and returns a new variable expression referencing it200 Expression *makeOffsetArray( StructInstType *type );201 181 /// Pass the extra type parameters from polymorphic generic arguments or return types into a function application 202 182 void passArgTypeVars( ApplicationExpr *appExpr, Type *parmType, Type *argBaseType, std::list< Expression *>::iterator &arg, const TyVarMap &exprTyVars, std::set< std::string > &seenTypes ); … … 225 205 ObjectDecl *makeTemporary( Type *type ); 226 206 227 std::map< std::string, DeclarationWithType *> assignOps; 228 ResolvExpr::TypeMap< DeclarationWithType > scopedAssignOps; 229 ScopedMap< std::string, DeclarationWithType* > adapters; 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 230 211 DeclarationWithType *retval; 231 212 bool useRetval; … … 233 214 }; 234 215 235 /// Moves polymorphic returns in function types to pointer-type parameters, adds type size and assertion parameters to parameter lists as well 216 class OffsetPackExpr; // forward declaration so that it can be mutated by Pass2 217 218 /// * Moves polymorphic returns in function types to pointer-type parameters 219 /// * adds type size and assertion parameters to parameter lists 220 /// * does dynamic calculation of type layouts 236 221 class Pass2 : public PolyMutator { 237 222 public: … … 244 229 virtual Type *mutate( PointerType *pointerType ); 245 230 virtual Type *mutate( FunctionType *funcType ); 231 virtual Expression *mutate( SizeofExpr *sizeofExpr ); 232 virtual Expression *mutate( AlignofExpr *alignofExpr ); 233 virtual Expression *mutate( OffsetofExpr *offsetofExpr ); 234 Expression *mutate( OffsetPackExpr *offsetPackExpr ); 235 236 virtual void doBeginScope(); 237 virtual void doEndScope(); 246 238 private: 247 239 void addAdapters( FunctionType *functionType ); 240 /// Makes a new variable in the current scope with the given name, type & optional initializer 241 ObjectDecl *makeVar( const std::string &name, Type *type, Initializer *init = 0 ); 242 /// returns true if the type has a dynamic layout; such a layout will be stored in appropriately-named local variables when the function returns 243 bool findGeneric( Type *ty ); 244 /// adds type parameters to the layout call; will generate the appropriate parameters if needed 245 void addOtypeParamsToLayoutCall( UntypedExpr *layoutCall, const std::list< Type* > &otypeParams ); 248 246 249 247 std::map< UniqueId, std::string > adapterName; 248 ScopedSet< std::string > knownLayouts; ///< Set of generic type layouts known in the current scope, indexed by sizeofName 249 ScopedSet< std::string > knownOffsets; ///< Set of non-generic types for which the offset array exists in the current scope, indexed by offsetofName 250 }; 251 252 /// Special internal expression for offset arrays inserted by Pass1 and replaced by Pass2 253 class OffsetPackExpr : public Expression { 254 public: 255 OffsetPackExpr( StructInstType *type_, Expression *aname_ = 0 ) : Expression( aname_ ), type( type_ ) { 256 add_result( new ArrayType( Type::Qualifiers(), new BasicType( Type::Qualifiers(), BasicType::LongUnsignedInt ), 0, false, false ) ); 257 } 258 259 OffsetPackExpr( const OffsetPackExpr &other ) : Expression( other ), type( maybeClone( other.type ) ) {} 260 virtual ~OffsetPackExpr() { delete type; } 261 262 StructInstType *get_type() const { return type; } 263 void set_type( StructInstType *newValue ) { type = newValue; } 264 265 virtual OffsetPackExpr *clone() const { return new OffsetPackExpr( *this ); } 266 virtual void accept( Visitor &v ) { /* do nothing */ } 267 virtual Expression *acceptMutator( Mutator &m ) { 268 // only act if the mutator is a Pass2, which knows about this class 269 if ( Pass2 *m2 = dynamic_cast< Pass2* >( &m ) ) { 270 return m2->mutate( this ); 271 } else { 272 return this; 273 } 274 } 275 276 virtual void print( std::ostream &os, int indent = 0 ) const { 277 os << std::string( indent, ' ' ) << "Offset pack expression on "; 278 279 if ( type ) { 280 type->print(os, indent + 2); 281 } else { 282 os << "<NULL>"; 283 } 284 285 os << std::endl; 286 Expression::print( os, indent ); 287 } 288 289 private: 290 StructInstType *type; 250 291 }; 251 292 … … 253 294 class GenericInstantiator : public DeclMutator { 254 295 /// Map of (generic type, parameter list) pairs to concrete type instantiations 255 InstantiationMap< AggregateDecl > instantiations;296 InstantiationMap< AggregateDecl, AggregateDecl > instantiations; 256 297 /// Namer for concrete types 257 298 UniqueName typeNamer; … … 348 389 mutateTranslationUnit/*All*/( translationUnit, pass1 ); 349 390 mutateTranslationUnit/*All*/( translationUnit, pass2 ); 350 // instantiateGeneric( translationUnit );351 391 instantiator.mutateDeclarationList( translationUnit ); 352 392 mutateTranslationUnit/*All*/( translationUnit, memberFixer ); … … 653 693 654 694 DeclarationWithType *Pass1::mutate( FunctionDecl *functionDecl ) { 655 // if this is a polymorphicassignment function, put it in the map for this scope695 // if this is a assignment function, put it in the map for this scope 656 696 if ( Type *assignedType = isAssignment( functionDecl ) ) { 657 697 if ( ! dynamic_cast< TypeInstType* >( assignedType ) ) { … … 743 783 } 744 784 745 Expression *Pass1::makeOffsetArray( StructInstType *ty ) {746 std::list< Declaration* > &baseMembers = ty->get_baseStruct()->get_members();747 748 // make a new temporary array749 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 temporary756 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 temporary769 return new VariableExpr( arrayTemp );770 }771 772 785 void Pass1::passArgTypeVars( ApplicationExpr *appExpr, Type *parmType, Type *argBaseType, std::list< Expression *>::iterator &arg, const TyVarMap &exprTyVars, std::set< std::string > &seenTypes ) { 773 786 Type *polyBase = hasPolyBase( parmType, exprTyVars ); … … 782 795 if ( dynamic_cast< StructInstType* >( polyBase ) ) { 783 796 if ( StructInstType *argBaseStructType = dynamic_cast< StructInstType* >( argBaseType ) ) { 784 arg = appExpr->get_args().insert( arg, makeOffsetArray( argBaseStructType ) ); 785 arg++; 797 // zero-length arrays are forbidden by C, so don't pass offset for empty struct 798 if ( ! argBaseStructType->get_baseStruct()->get_members().empty() ) { 799 arg = appExpr->get_args().insert( arg, new OffsetPackExpr( argBaseStructType ) ); 800 arg++; 801 } 786 802 } else { 787 803 throw SemanticError( "Cannot pass non-struct type for generic struct" ); … … 1587 1603 ObjectDecl newPtr( "", DeclarationNode::NoStorageClass, LinkageSpec::C, 0, 1588 1604 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 );1590 1605 for ( std::list< TypeDecl *>::const_iterator tyParm = funcType->get_forall().begin(); tyParm != funcType->get_forall().end(); ++tyParm ) { 1591 1606 ObjectDecl *sizeParm, *alignParm; … … 1631 1646 ++last; 1632 1647 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; 1648 if ( StructInstType *polyBaseStruct = dynamic_cast< StructInstType* >( polyBase ) ) { 1649 // NOTE zero-length arrays are illegal in C, so empty structs have no offset array 1650 if ( ! polyBaseStruct->get_baseStruct()->get_members().empty() ) { 1651 offsetParm = newPtr.clone(); 1652 offsetParm->set_name( offsetofName( polyBase ) ); 1653 last = funcType->get_parameters().insert( last, offsetParm ); 1654 ++last; 1655 } 1638 1656 } 1639 1657 1640 1658 seenTypes.insert( sizeName ); 1659 knownLayouts.insert( sizeName ); // make sure that any type information passed into the function is accounted for 1641 1660 } 1642 1661 } … … 1650 1669 scopeTyVars = oldtyVars; 1651 1670 return funcType; 1671 } 1672 1673 ObjectDecl *Pass2::makeVar( const std::string &name, Type *type, Initializer *init ) { 1674 ObjectDecl *newObj = new ObjectDecl( name, DeclarationNode::NoStorageClass, LinkageSpec::C, 0, type, init ); 1675 stmtsToAdd.push_back( new DeclStmt( noLabels, newObj ) ); 1676 return newObj; 1677 } 1678 1679 void Pass2::addOtypeParamsToLayoutCall( UntypedExpr *layoutCall, const std::list< Type* > &otypeParams ) { 1680 for ( std::list< Type* >::const_iterator param = otypeParams.begin(); param != otypeParams.end(); ++param ) { 1681 if ( findGeneric( *param ) ) { 1682 // push size/align vars for a generic parameter back 1683 layoutCall->get_args().push_back( new NameExpr( sizeofName( *param ) ) ); 1684 layoutCall->get_args().push_back( new NameExpr( alignofName( *param ) ) ); 1685 } else { 1686 layoutCall->get_args().push_back( new SizeofExpr( *param ) ); 1687 layoutCall->get_args().push_back( new AlignofExpr( *param ) ); 1688 } 1689 } 1690 } 1691 1692 /// returns true if any of the otype parameters have a dynamic layout and puts all otype parameters in the output list 1693 bool findGenericParams( std::list< TypeDecl* > &baseParams, std::list< Expression* > &typeParams, std::list< Type* > &out ) { 1694 bool hasDynamicLayout = false; 1695 1696 std::list< TypeDecl* >::const_iterator baseParam = baseParams.begin(); 1697 std::list< Expression* >::const_iterator typeParam = typeParams.begin(); 1698 for ( ; baseParam != baseParams.end() && typeParam != typeParams.end(); ++baseParam, ++typeParam ) { 1699 // skip non-otype parameters 1700 if ( (*baseParam)->get_kind() != TypeDecl::Any ) continue; 1701 TypeExpr *typeExpr = dynamic_cast< TypeExpr* >( *typeParam ); 1702 assert( typeExpr && "all otype parameters should be type expressions" ); 1703 1704 Type *type = typeExpr->get_type(); 1705 out.push_back( type ); 1706 if ( isPolyType( type ) ) hasDynamicLayout = true; 1707 } 1708 assert( baseParam == baseParams.end() && typeParam == typeParams.end() ); 1709 1710 return hasDynamicLayout; 1711 } 1712 1713 bool Pass2::findGeneric( Type *ty ) { 1714 if ( dynamic_cast< TypeInstType* >( ty ) ) { 1715 // NOTE this assumes that all type variables will be properly bound, and thus have their layouts in scope 1716 return true; 1717 } else if ( StructInstType *structTy = dynamic_cast< StructInstType* >( ty ) ) { 1718 // check if this type already has a layout generated for it 1719 std::string sizeName = sizeofName( ty ); 1720 if ( knownLayouts.find( sizeName ) != knownLayouts.end() ) return true; 1721 1722 // check if any of the type parameters have dynamic layout; if none do, this type is (or will be) monomorphized 1723 std::list< Type* > otypeParams; 1724 if ( ! findGenericParams( *structTy->get_baseParameters(), structTy->get_parameters(), otypeParams ) ) return false; 1725 1726 // insert local variables for layout and generate call to layout function 1727 knownLayouts.insert( sizeName ); // done early so as not to interfere with the later addition of parameters to the layout call 1728 Type *layoutType = new BasicType( Type::Qualifiers(), BasicType::LongUnsignedInt ); 1729 1730 int n_members = structTy->get_baseStruct()->get_members().size(); 1731 if ( n_members == 0 ) { 1732 // all empty structs have the same layout - size 1, align 1 1733 makeVar( sizeName, layoutType, new SingleInit( new ConstantExpr( Constant::from( (unsigned long)1 ) ) ) ); 1734 makeVar( alignofName( ty ), layoutType->clone(), new SingleInit( new ConstantExpr( Constant::from( (unsigned long)1 ) ) ) ); 1735 // NOTE zero-length arrays are forbidden in C, so empty structs have no offsetof array 1736 } else { 1737 ObjectDecl *sizeVar = makeVar( sizeName, layoutType ); 1738 ObjectDecl *alignVar = makeVar( alignofName( ty ), layoutType->clone() ); 1739 ObjectDecl *offsetVar = makeVar( offsetofName( ty ), new ArrayType( Type::Qualifiers(), layoutType->clone(), new ConstantExpr( Constant::from( n_members ) ), false, false ) ); 1740 1741 // generate call to layout function 1742 UntypedExpr *layoutCall = new UntypedExpr( new NameExpr( "__layoutof_" + structTy->get_baseStruct()->get_name() ) ); 1743 layoutCall->get_args().push_back( new AddressExpr( new VariableExpr( sizeVar ) ) ); 1744 layoutCall->get_args().push_back( new AddressExpr( new VariableExpr( alignVar ) ) ); 1745 layoutCall->get_args().push_back( new VariableExpr( offsetVar ) ); 1746 addOtypeParamsToLayoutCall( layoutCall, otypeParams ); 1747 1748 stmtsToAdd.push_back( new ExprStmt( noLabels, layoutCall ) ); 1749 } 1750 1751 return true; 1752 } else if ( UnionInstType *unionTy = dynamic_cast< UnionInstType* >( ty ) ) { 1753 // check if this type already has a layout generated for it 1754 std::string sizeName = sizeofName( ty ); 1755 if ( knownLayouts.find( sizeName ) != knownLayouts.end() ) return true; 1756 1757 // check if any of the type parameters have dynamic layout; if none do, this type is (or will be) monomorphized 1758 std::list< Type* > otypeParams; 1759 if ( ! findGenericParams( *unionTy->get_baseParameters(), unionTy->get_parameters(), otypeParams ) ) return false; 1760 1761 // insert local variables for layout and generate call to layout function 1762 knownLayouts.insert( sizeName ); // done early so as not to interfere with the later addition of parameters to the layout call 1763 Type *layoutType = new BasicType( Type::Qualifiers(), BasicType::LongUnsignedInt ); 1764 1765 ObjectDecl *sizeVar = makeVar( sizeName, layoutType ); 1766 ObjectDecl *alignVar = makeVar( alignofName( ty ), layoutType->clone() ); 1767 1768 // generate call to layout function 1769 UntypedExpr *layoutCall = new UntypedExpr( new NameExpr( "__layoutof_" + unionTy->get_baseUnion()->get_name() ) ); 1770 layoutCall->get_args().push_back( new AddressExpr( new VariableExpr( sizeVar ) ) ); 1771 layoutCall->get_args().push_back( new AddressExpr( new VariableExpr( alignVar ) ) ); 1772 addOtypeParamsToLayoutCall( layoutCall, otypeParams ); 1773 1774 stmtsToAdd.push_back( new ExprStmt( noLabels, layoutCall ) ); 1775 1776 return true; 1777 } 1778 1779 return false; 1780 } 1781 1782 Expression *Pass2::mutate( SizeofExpr *sizeofExpr ) { 1783 Type *ty = sizeofExpr->get_type(); 1784 if ( findGeneric( ty ) ) { 1785 Expression *ret = new NameExpr( sizeofName( ty ) ); 1786 delete sizeofExpr; 1787 return ret; 1788 } 1789 return sizeofExpr; 1790 } 1791 1792 Expression *Pass2::mutate( AlignofExpr *alignofExpr ) { 1793 Type *ty = alignofExpr->get_type(); 1794 if ( findGeneric( ty ) ) { 1795 Expression *ret = new NameExpr( alignofName( ty ) ); 1796 delete alignofExpr; 1797 return ret; 1798 } 1799 return alignofExpr; 1800 } 1801 1802 Expression *Pass2::mutate( OffsetofExpr *offsetofExpr ) { 1803 findGeneric( offsetofExpr->get_type() ); 1804 return offsetofExpr; 1805 } 1806 1807 Expression *Pass2::mutate( OffsetPackExpr *offsetPackExpr ) { 1808 StructInstType *ty = offsetPackExpr->get_type(); 1809 1810 Expression *ret = 0; 1811 if ( findGeneric( ty ) ) { 1812 // pull offset back from generated type information 1813 ret = new NameExpr( offsetofName( ty ) ); 1814 } else { 1815 std::string offsetName = offsetofName( ty ); 1816 if ( knownOffsets.find( offsetName ) != knownOffsets.end() ) { 1817 // use the already-generated offsets for this type 1818 ret = new NameExpr( offsetName ); 1819 } else { 1820 std::list< Declaration* > &baseMembers = ty->get_baseStruct()->get_members(); 1821 Type *offsetType = new BasicType( Type::Qualifiers(), BasicType::LongUnsignedInt ); 1822 1823 // build initializer list for offset array 1824 std::list< Initializer* > inits; 1825 for ( std::list< Declaration* >::const_iterator member = baseMembers.begin(); member != baseMembers.end(); ++member ) { 1826 DeclarationWithType *memberDecl; 1827 if ( DeclarationWithType *origMember = dynamic_cast< DeclarationWithType* >( *member ) ) { 1828 memberDecl = origMember->clone(); 1829 } else { 1830 memberDecl = new ObjectDecl( (*member)->get_name(), DeclarationNode::NoStorageClass, LinkageSpec::Cforall, 0, offsetType->clone(), 0 ); 1831 } 1832 inits.push_back( new SingleInit( new OffsetofExpr( ty->clone(), memberDecl ) ) ); 1833 } 1834 1835 // build the offset array and replace the pack with a reference to it 1836 ObjectDecl *offsetArray = makeVar( offsetName, new ArrayType( Type::Qualifiers(), offsetType, new ConstantExpr( Constant::from( baseMembers.size() ) ), false, false ), 1837 new ListInit( inits ) ); 1838 ret = new VariableExpr( offsetArray ); 1839 } 1840 } 1841 1842 delete offsetPackExpr; 1843 return ret; 1844 } 1845 1846 void Pass2::doBeginScope() { 1847 knownLayouts.beginScope(); 1848 knownOffsets.beginScope(); 1849 } 1850 1851 void Pass2::doEndScope() { 1852 knownLayouts.endScope(); 1853 knownOffsets.beginScope(); 1652 1854 } 1653 1855 -
src/GenPoly/ScopedMap.h
r3cfe27f rb3f9a0cb 17 17 #define _SCOPEDMAP_H 18 18 19 #include <cassert> 19 20 #include <iterator> 20 21 #include <map> … … 164 165 void endScope() { 165 166 scopes.pop_back(); 167 assert( ! scopes.empty() ); 166 168 } 167 169 … … 188 190 return end(); 189 191 } 190 const_iterator find( const Key &key ) const { return const_iterator( find( key ) ); } 192 const_iterator find( const Key &key ) const { 193 return const_iterator( const_cast< ScopedMap< Key, Value >* >(this)->find( key ) ); 194 } 191 195 192 196 /// Finds the given key in the outermost scope inside the given scope where it occurs … … 200 204 return end(); 201 205 } 202 const_iterator findNext( const_iterator &it, const Key &key ) const { return const_iterator( findNext( it, key ) ); } 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 } 203 209 204 210 /// Inserts the given key-value pair into the outermost scope … … 208 214 } 209 215 std::pair< iterator, bool > insert( const Key &key, const Value &value ) { return insert( std::make_pair( key, value ) ); } 210 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 } 211 222 }; 212 223 } // namespace GenPoly
Note:
See TracChangeset
for help on using the changeset viewer.