Changes in src/GenPoly/Box.cc [89173242:4e284ea6]
- File:
-
- 1 edited
-
src/GenPoly/Box.cc (modified) (17 diffs)
Legend:
- Unmodified
- Added
- Removed
-
src/GenPoly/Box.cc
r89173242 r4e284ea6 30 30 #include "FindFunction.h" 31 31 #include "ScopedMap.h" 32 #include "ScopedSet.h"33 32 #include "ScrubTyVars.h" 34 33 … … 63 62 FunctionType *makeAdapterType( FunctionType *adaptee, const TyVarMap &tyVars ); 64 63 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); } 73 71 74 72 /// 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() { 76 74 for ( std::list< TypeExpr* >::const_iterator param = _params.begin(); param != _params.end(); ++param ) { 77 75 params.push_back( (*param)->get_type()->clone() ); … … 79 77 } 80 78 81 TypeList& operator= ( const TypeList &that) {79 ConcreteType& operator= (const ConcreteType& that) { 82 80 deleteAll( params ); 83 84 81 params.clear(); 82 83 base = that.base; 85 84 cloneAll( that.params, params ); 86 85 … … 88 87 } 89 88 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; 101 95 if ( params.size() != that.params.size() ) return false; 102 103 SymTab::Indexer dummy;104 96 for ( std::list< Type* >::const_iterator it = params.begin(), jt = that.params.begin(); it != params.end(); ++it, ++jt ) { 105 97 if ( ! ResolvExpr::typesCompatible( *it, *jt, dummy ) ) return false; … … 108 100 } 109 101 102 AggregateDecl *base; ///< Base generic type 110 103 std::list< Type* > params; ///< Instantiation parameters 111 104 }; 112 105 113 /// Maps a key and a TypeListto the some value, accounting for scope114 template< typename Key, typenameValue >106 /// Maps a concrete type to the some value, accounting for scope 107 template< typename Value > 115 108 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 124 121 125 122 public: 126 123 /// Starts a new scope 127 void beginScope() { instantiations.beginScope(); } 124 void beginScope() { 125 Scope scope; 126 scopes.push_back(scope); 127 } 128 128 129 129 /// Ends a scope 130 void endScope() { instantiations.endScope(); } 131 132 /// Gets the value for the (key, typeList) pair, returns NULL on none such. 133 Value *lookup( Key *key, const std::list< TypeExpr* >& params ) const { 134 TypeList typeList( params ); 135 136 // scan scopes for matches to the key 137 for ( typename InnerMap::const_iterator insts = instantiations.find( key ); insts != instantiations.end(); insts = instantiations.findNext( insts, key ) ) { 138 for ( typename ValueList::const_reverse_iterator inst = insts->second.rbegin(); inst != insts->second.rend(); ++inst ) { 139 if ( inst->first == typeList ) return inst->second; 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; 140 150 } 141 151 } 142 // no matching instantiation sfound152 // no matching instantiation found 143 153 return 0; 144 154 } 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 } 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 ); } 150 168 }; 151 169 … … 179 197 virtual void doEndScope(); 180 198 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 ); 181 201 /// Pass the extra type parameters from polymorphic generic arguments or return types into a function application 182 202 void passArgTypeVars( ApplicationExpr *appExpr, Type *parmType, Type *argBaseType, std::list< Expression *>::iterator &arg, const TyVarMap &exprTyVars, std::set< std::string > &seenTypes ); … … 205 225 ObjectDecl *makeTemporary( Type *type ); 206 226 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; 211 230 DeclarationWithType *retval; 212 231 bool useRetval; … … 214 233 }; 215 234 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 235 /// Moves polymorphic returns in function types to pointer-type parameters, adds type size and assertion parameters to parameter lists as well 221 236 class Pass2 : public PolyMutator { 222 237 public: … … 229 244 virtual Type *mutate( PointerType *pointerType ); 230 245 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();238 246 private: 239 247 void addAdapters( FunctionType *functionType ); 240 /// Makes a new variable in the current scope with the given name, type & optional initializer241 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 returns243 bool findGeneric( Type *ty );244 /// adds type parameters to the layout call; will generate the appropriate parameters if needed245 void addOtypeParamsToLayoutCall( UntypedExpr *layoutCall, const std::list< Type* > &otypeParams );246 248 247 249 std::map< UniqueId, std::string > adapterName; 248 ScopedSet< std::string > knownLayouts; ///< Set of generic type layouts known in the current scope, indexed by sizeofName249 ScopedSet< std::string > knownOffsets; ///< Set of non-generic types for which the offset array exists in the current scope, indexed by offsetofName250 };251 252 /// Special internal expression for offset arrays inserted by Pass1 and replaced by Pass2253 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 class269 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;291 250 }; 292 251 … … 294 253 class GenericInstantiator : public DeclMutator { 295 254 /// Map of (generic type, parameter list) pairs to concrete type instantiations 296 InstantiationMap< AggregateDecl , AggregateDecl> instantiations;255 InstantiationMap< AggregateDecl > instantiations; 297 256 /// Namer for concrete types 298 257 UniqueName typeNamer; … … 389 348 mutateTranslationUnit/*All*/( translationUnit, pass1 ); 390 349 mutateTranslationUnit/*All*/( translationUnit, pass2 ); 350 // instantiateGeneric( translationUnit ); 391 351 instantiator.mutateDeclarationList( translationUnit ); 392 352 mutateTranslationUnit/*All*/( translationUnit, memberFixer ); … … 693 653 694 654 DeclarationWithType *Pass1::mutate( FunctionDecl *functionDecl ) { 695 // if this is a assignment function, put it in the map for this scope655 // if this is a polymorphic assignment function, put it in the map for this scope 696 656 if ( Type *assignedType = isAssignment( functionDecl ) ) { 697 657 if ( ! dynamic_cast< TypeInstType* >( assignedType ) ) { … … 783 743 } 784 744 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 785 772 void Pass1::passArgTypeVars( ApplicationExpr *appExpr, Type *parmType, Type *argBaseType, std::list< Expression *>::iterator &arg, const TyVarMap &exprTyVars, std::set< std::string > &seenTypes ) { 786 773 Type *polyBase = hasPolyBase( parmType, exprTyVars ); … … 795 782 if ( dynamic_cast< StructInstType* >( polyBase ) ) { 796 783 if ( StructInstType *argBaseStructType = dynamic_cast< StructInstType* >( argBaseType ) ) { 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 } 784 arg = appExpr->get_args().insert( arg, makeOffsetArray( argBaseStructType ) ); 785 arg++; 802 786 } else { 803 787 throw SemanticError( "Cannot pass non-struct type for generic struct" ); … … 1603 1587 ObjectDecl newPtr( "", DeclarationNode::NoStorageClass, LinkageSpec::C, 0, 1604 1588 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 ); 1605 1590 for ( std::list< TypeDecl *>::const_iterator tyParm = funcType->get_forall().begin(); tyParm != funcType->get_forall().end(); ++tyParm ) { 1606 1591 ObjectDecl *sizeParm, *alignParm; … … 1646 1631 ++last; 1647 1632 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 } 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; 1656 1638 } 1657 1639 1658 1640 seenTypes.insert( sizeName ); 1659 knownLayouts.insert( sizeName ); // make sure that any type information passed into the function is accounted for1660 1641 } 1661 1642 } … … 1669 1650 scopeTyVars = oldtyVars; 1670 1651 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 back1683 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 list1693 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 parameters1700 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 scope1716 return true;1717 } else if ( StructInstType *structTy = dynamic_cast< StructInstType* >( ty ) ) {1718 // check if this type already has a layout generated for it1719 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) monomorphized1723 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 function1727 knownLayouts.insert( sizeName ); // done early so as not to interfere with the later addition of parameters to the layout call1728 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 11733 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 array1736 } 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 function1742 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 it1754 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) monomorphized1758 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 function1762 knownLayouts.insert( sizeName ); // done early so as not to interfere with the later addition of parameters to the layout call1763 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 function1769 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 information1813 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 type1818 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 array1824 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 it1836 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();1854 1652 } 1855 1653
Note:
See TracChangeset
for help on using the changeset viewer.