Changes in src/GenPoly/Box.cc [aa19ccf:4e284ea6]
- File:
-
- 1 edited
-
src/GenPoly/Box.cc (modified) (51 diffs)
Legend:
- Unmodified
- Added
- Removed
-
src/GenPoly/Box.cc
raa19ccf 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 ScopedMap< 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 /// * Moves polymorphic returns in function types to pointer-type parameters 217 /// * adds type size and assertion parameters to parameter lists 235 /// Moves polymorphic returns in function types to pointer-type parameters, adds type size and assertion parameters to parameter lists as well 218 236 class Pass2 : public PolyMutator { 219 237 public: … … 226 244 virtual Type *mutate( PointerType *pointerType ); 227 245 virtual Type *mutate( FunctionType *funcType ); 228 229 246 private: 230 247 void addAdapters( FunctionType *functionType ); … … 236 253 class GenericInstantiator : public DeclMutator { 237 254 /// Map of (generic type, parameter list) pairs to concrete type instantiations 238 InstantiationMap< AggregateDecl , AggregateDecl> instantiations;255 InstantiationMap< AggregateDecl > instantiations; 239 256 /// Namer for concrete types 240 257 UniqueName typeNamer; … … 261 278 }; 262 279 263 /// Replaces member and size/align/offsetof expressions on polymorphic generic types with calculated expressions. 264 /// * Replaces member expressions for polymorphic types with calculated add-field-offset-and-dereference 265 /// * Calculates polymorphic offsetof expressions from offset array 266 /// * Inserts dynamic calculation of polymorphic type layouts where needed 267 class PolyGenericCalculator : public PolyMutator { 268 public: 280 /// Replaces member expressions for polymorphic types with calculated add-field-offset-and-dereference; 281 /// also fixes offsetof expressions. 282 class MemberExprFixer : public PolyMutator { 283 public: 269 284 template< typename DeclClass > 270 285 DeclClass *handleDecl( DeclClass *decl, Type *type ); … … 277 292 virtual Type *mutate( FunctionType *funcType ); 278 293 virtual Expression *mutate( MemberExpr *memberExpr ); 279 virtual Expression *mutate( SizeofExpr *sizeofExpr );280 virtual Expression *mutate( AlignofExpr *alignofExpr );281 294 virtual Expression *mutate( OffsetofExpr *offsetofExpr ); 282 virtual Expression *mutate( OffsetPackExpr *offsetPackExpr );283 284 virtual void doBeginScope();285 virtual void doEndScope();286 287 private:288 /// Makes a new variable in the current scope with the given name, type & optional initializer289 ObjectDecl *makeVar( const std::string &name, Type *type, Initializer *init = 0 );290 /// returns true if the type has a dynamic layout; such a layout will be stored in appropriately-named local variables when the function returns291 bool findGeneric( Type *ty );292 /// adds type parameters to the layout call; will generate the appropriate parameters if needed293 void addOtypeParamsToLayoutCall( UntypedExpr *layoutCall, const std::list< Type* > &otypeParams );294 295 /// Enters a new scope for type-variables, adding the type variables from ty296 void beginTypeScope( Type *ty );297 /// Exits the type-variable scope298 void endTypeScope();299 300 ScopedSet< std::string > knownLayouts; ///< Set of generic type layouts known in the current scope, indexed by sizeofName301 ScopedSet< std::string > knownOffsets; ///< Set of non-generic types for which the offset array exists in the current scope, indexed by offsetofName302 295 }; 303 296 … … 349 342 Pass2 pass2; 350 343 GenericInstantiator instantiator; 351 PolyGenericCalculator polyCalculator;344 MemberExprFixer memberFixer; 352 345 Pass3 pass3; 353 346 … … 355 348 mutateTranslationUnit/*All*/( translationUnit, pass1 ); 356 349 mutateTranslationUnit/*All*/( translationUnit, pass2 ); 350 // instantiateGeneric( translationUnit ); 357 351 instantiator.mutateDeclarationList( translationUnit ); 358 mutateTranslationUnit/*All*/( translationUnit, polyCalculator );352 mutateTranslationUnit/*All*/( translationUnit, memberFixer ); 359 353 mutateTranslationUnit/*All*/( translationUnit, pass3 ); 360 354 } … … 390 384 for ( std::list< TypeDecl* >::const_iterator param = otypeParams.begin(); param != otypeParams.end(); ++param ) { 391 385 TypeInstType paramType( Type::Qualifiers(), (*param)->get_name(), *param ); 392 std::string paramName = mangleType( ¶mType ); 393 layoutFnType->get_parameters().push_back( new ObjectDecl( sizeofName( paramName ), DeclarationNode::NoStorageClass, LinkageSpec::Cforall, 0, sizeAlignType.clone(), 0 ) ); 394 layoutFnType->get_parameters().push_back( new ObjectDecl( alignofName( paramName ), DeclarationNode::NoStorageClass, LinkageSpec::Cforall, 0, sizeAlignType.clone(), 0 ) ); 386 layoutFnType->get_parameters().push_back( new ObjectDecl( sizeofName( ¶mType ), DeclarationNode::NoStorageClass, LinkageSpec::Cforall, 0, sizeAlignType.clone(), 0 ) ); 387 layoutFnType->get_parameters().push_back( new ObjectDecl( alignofName( ¶mType ), DeclarationNode::NoStorageClass, LinkageSpec::Cforall, 0, sizeAlignType.clone(), 0 ) ); 395 388 } 396 389 } 397 390 398 391 /// Builds a layout function declaration 399 FunctionDecl *buildLayoutFunctionDecl( AggregateDecl *typeDecl, unsigned int functionNesting, FunctionType *layoutFnType ) {392 FunctionDecl *buildLayoutFunctionDecl( const std::string &typeName, unsigned int functionNesting, FunctionType *layoutFnType ) { 400 393 // Routines at global scope marked "static" to prevent multiple definitions is separate translation units 401 394 // because each unit generates copies of the default routines for each aggregate. 402 395 FunctionDecl *layoutDecl = new FunctionDecl( 403 layoutofName( typeDecl ), functionNesting > 0 ? DeclarationNode::NoStorageClass : DeclarationNode::Static, LinkageSpec::AutoGen, layoutFnType, new CompoundStmt( noLabels ), true, false );396 "__layoutof_" + typeName, functionNesting > 0 ? DeclarationNode::NoStorageClass : DeclarationNode::Static, LinkageSpec::AutoGen, layoutFnType, new CompoundStmt( noLabels ), true, false ); 404 397 layoutDecl->fixUniqueId(); 405 398 return layoutDecl; … … 468 461 PointerType *sizeAlignOutType = new PointerType( Type::Qualifiers(), sizeAlignType ); 469 462 470 ObjectDecl *sizeParam = new ObjectDecl( sizeofName( structDecl->get_name()), DeclarationNode::NoStorageClass, LinkageSpec::Cforall, 0, sizeAlignOutType, 0 );463 ObjectDecl *sizeParam = new ObjectDecl( "__sizeof_" + structDecl->get_name(), DeclarationNode::NoStorageClass, LinkageSpec::Cforall, 0, sizeAlignOutType, 0 ); 471 464 layoutFnType->get_parameters().push_back( sizeParam ); 472 ObjectDecl *alignParam = new ObjectDecl( alignofName( structDecl->get_name()), DeclarationNode::NoStorageClass, LinkageSpec::Cforall, 0, sizeAlignOutType->clone(), 0 );465 ObjectDecl *alignParam = new ObjectDecl( "__alignof_" + structDecl->get_name(), DeclarationNode::NoStorageClass, LinkageSpec::Cforall, 0, sizeAlignOutType->clone(), 0 ); 473 466 layoutFnType->get_parameters().push_back( alignParam ); 474 ObjectDecl *offsetParam = new ObjectDecl( offsetofName( structDecl->get_name()), DeclarationNode::NoStorageClass, LinkageSpec::Cforall, 0, sizeAlignOutType->clone(), 0 );467 ObjectDecl *offsetParam = new ObjectDecl( "__offsetof_" + structDecl->get_name(), DeclarationNode::NoStorageClass, LinkageSpec::Cforall, 0, sizeAlignOutType->clone(), 0 ); 475 468 layoutFnType->get_parameters().push_back( offsetParam ); 476 469 addOtypeParams( layoutFnType, otypeParams ); 477 470 478 471 // build function decl 479 FunctionDecl *layoutDecl = buildLayoutFunctionDecl( structDecl , functionNesting, layoutFnType );472 FunctionDecl *layoutDecl = buildLayoutFunctionDecl( structDecl->get_name(), functionNesting, layoutFnType ); 480 473 481 474 // calculate struct layout in function body … … 529 522 PointerType *sizeAlignOutType = new PointerType( Type::Qualifiers(), sizeAlignType ); 530 523 531 ObjectDecl *sizeParam = new ObjectDecl( sizeofName( unionDecl->get_name()), DeclarationNode::NoStorageClass, LinkageSpec::Cforall, 0, sizeAlignOutType, 0 );524 ObjectDecl *sizeParam = new ObjectDecl( "__sizeof_" + unionDecl->get_name(), DeclarationNode::NoStorageClass, LinkageSpec::Cforall, 0, sizeAlignOutType, 0 ); 532 525 layoutFnType->get_parameters().push_back( sizeParam ); 533 ObjectDecl *alignParam = new ObjectDecl( alignofName( unionDecl->get_name()), DeclarationNode::NoStorageClass, LinkageSpec::Cforall, 0, sizeAlignOutType->clone(), 0 );526 ObjectDecl *alignParam = new ObjectDecl( "__alignof_" + unionDecl->get_name(), DeclarationNode::NoStorageClass, LinkageSpec::Cforall, 0, sizeAlignOutType->clone(), 0 ); 534 527 layoutFnType->get_parameters().push_back( alignParam ); 535 528 addOtypeParams( layoutFnType, otypeParams ); 536 529 537 530 // build function decl 538 FunctionDecl *layoutDecl = buildLayoutFunctionDecl( unionDecl , functionNesting, layoutFnType );531 FunctionDecl *layoutDecl = buildLayoutFunctionDecl( unionDecl->get_name(), functionNesting, layoutFnType ); 539 532 540 533 // calculate union layout in function body … … 660 653 661 654 DeclarationWithType *Pass1::mutate( FunctionDecl *functionDecl ) { 662 // 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 663 656 if ( Type *assignedType = isAssignment( functionDecl ) ) { 664 657 if ( ! dynamic_cast< TypeInstType* >( assignedType ) ) { … … 669 662 if ( functionDecl->get_statements() ) { // empty routine body ? 670 663 doBeginScope(); 671 scopeTyVars.beginScope();672 assignOps.beginScope();664 TyVarMap oldtyVars = scopeTyVars; 665 std::map< std::string, DeclarationWithType *> oldassignOps = assignOps; 673 666 DeclarationWithType *oldRetval = retval; 674 667 bool oldUseRetval = useRetval; … … 711 704 functionDecl->set_statements( functionDecl->get_statements()->acceptMutator( *this ) ); 712 705 713 scopeTyVars.endScope(); 714 assignOps.endScope(); 706 scopeTyVars = oldtyVars; 707 assignOps = oldassignOps; 708 // std::cerr << "end FunctionDecl: "; 709 // for ( TyVarMap::iterator i = scopeTyVars.begin(); i != scopeTyVars.end(); ++i ) { 710 // std::cerr << i->first << " "; 711 // } 712 // std::cerr << "\n"; 715 713 retval = oldRetval; 716 714 useRetval = oldUseRetval; … … 745 743 } 746 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 747 772 void Pass1::passArgTypeVars( ApplicationExpr *appExpr, Type *parmType, Type *argBaseType, std::list< Expression *>::iterator &arg, const TyVarMap &exprTyVars, std::set< std::string > &seenTypes ) { 748 Type *poly Type = isPolyType( parmType, exprTyVars );749 if ( poly Type && ! dynamic_cast< TypeInstType* >( polyType ) ) {750 std::string typeName = mangleType( polyType );751 if ( seenTypes.count( typeName ) ) return;773 Type *polyBase = hasPolyBase( parmType, exprTyVars ); 774 if ( polyBase && ! dynamic_cast< TypeInstType* >( polyBase ) ) { 775 std::string sizeName = sizeofName( polyBase ); 776 if ( seenTypes.count( sizeName ) ) return; 752 777 753 778 arg = appExpr->get_args().insert( arg, new SizeofExpr( argBaseType->clone() ) ); … … 755 780 arg = appExpr->get_args().insert( arg, new AlignofExpr( argBaseType->clone() ) ); 756 781 arg++; 757 if ( dynamic_cast< StructInstType* >( poly Type ) ) {782 if ( dynamic_cast< StructInstType* >( polyBase ) ) { 758 783 if ( StructInstType *argBaseStructType = dynamic_cast< StructInstType* >( argBaseType ) ) { 759 // zero-length arrays are forbidden by C, so don't pass offset for empty struct 760 if ( ! argBaseStructType->get_baseStruct()->get_members().empty() ) { 761 arg = appExpr->get_args().insert( arg, new OffsetPackExpr( argBaseStructType->clone() ) ); 762 arg++; 763 } 784 arg = appExpr->get_args().insert( arg, makeOffsetArray( argBaseStructType ) ); 785 arg++; 764 786 } else { 765 787 throw SemanticError( "Cannot pass non-struct type for generic struct" ); … … 767 789 } 768 790 769 seenTypes.insert( typeName );791 seenTypes.insert( sizeName ); 770 792 } 771 793 } … … 909 931 return; 910 932 } else if ( arg->get_results().front()->get_isLvalue() ) { 911 // VariableExpr and MemberExpr are lvalues; need to check this isn't coming from the second arg of a comma expression though (not an lvalue) 912 if ( CommaExpr *commaArg = dynamic_cast< CommaExpr* >( arg ) ) { 913 commaArg->set_arg2( new AddressExpr( commaArg->get_arg2() ) ); 914 } else { 915 arg = new AddressExpr( arg ); 916 } 933 // VariableExpr and MemberExpr are lvalues 934 arg = new AddressExpr( arg ); 917 935 } else { 918 936 // use type computed in unification to declare boxed variables … … 1009 1027 } // for 1010 1028 } 1029 1030 1011 1031 1012 1032 FunctionDecl *Pass1::makeAdapter( FunctionType *adaptee, FunctionType *realType, const std::string &mangleName, const TyVarMap &tyVars ) { … … 1125 1145 addAssign->get_args().push_back( appExpr->get_args().front() ); 1126 1146 } // if 1127 addAssign->get_args().push_back( new NameExpr( sizeofName( mangleType( polyType )) ) );1147 addAssign->get_args().push_back( new NameExpr( sizeofName( polyType ) ) ); 1128 1148 addAssign->get_results().front() = appExpr->get_results().front()->clone(); 1129 1149 if ( appExpr->get_env() ) { … … 1152 1172 UntypedExpr *multiply = new UntypedExpr( new NameExpr( "?*?" ) ); 1153 1173 multiply->get_args().push_back( appExpr->get_args().back() ); 1154 multiply->get_args().push_back( new SizeofExpr( baseType1->clone() ) );1174 multiply->get_args().push_back( new NameExpr( sizeofName( baseType1 ) ) ); 1155 1175 ret->get_args().push_back( appExpr->get_args().front() ); 1156 1176 ret->get_args().push_back( multiply ); … … 1158 1178 UntypedExpr *multiply = new UntypedExpr( new NameExpr( "?*?" ) ); 1159 1179 multiply->get_args().push_back( appExpr->get_args().front() ); 1160 multiply->get_args().push_back( new SizeofExpr( baseType2->clone() ) );1180 multiply->get_args().push_back( new NameExpr( sizeofName( baseType2 ) ) ); 1161 1181 ret->get_args().push_back( multiply ); 1162 1182 ret->get_args().push_back( appExpr->get_args().back() ); … … 1221 1241 UntypedExpr *divide = new UntypedExpr( new NameExpr( "?/?" ) ); 1222 1242 divide->get_args().push_back( appExpr ); 1223 divide->get_args().push_back( new SizeofExpr( baseType1->clone() ) );1243 divide->get_args().push_back( new NameExpr( sizeofName( baseType1 ) ) ); 1224 1244 divide->get_results().push_front( appExpr->get_results().front()->clone() ); 1225 1245 if ( appExpr->get_env() ) { … … 1231 1251 UntypedExpr *multiply = new UntypedExpr( new NameExpr( "?*?" ) ); 1232 1252 multiply->get_args().push_back( appExpr->get_args().back() ); 1233 multiply->get_args().push_back( new SizeofExpr( baseType1->clone() ) );1253 multiply->get_args().push_back( new NameExpr( sizeofName( baseType1 ) ) ); 1234 1254 appExpr->get_args().back() = multiply; 1235 1255 } else if ( baseType2 ) { 1236 1256 UntypedExpr *multiply = new UntypedExpr( new NameExpr( "?*?" ) ); 1237 1257 multiply->get_args().push_back( appExpr->get_args().front() ); 1238 multiply->get_args().push_back( new SizeofExpr( baseType2->clone() ) );1258 multiply->get_args().push_back( new NameExpr( sizeofName( baseType2 ) ) ); 1239 1259 appExpr->get_args().front() = multiply; 1240 1260 } // if … … 1246 1266 UntypedExpr *multiply = new UntypedExpr( new NameExpr( "?*?" ) ); 1247 1267 multiply->get_args().push_back( appExpr->get_args().back() ); 1248 multiply->get_args().push_back( new SizeofExpr( baseType->clone() ) );1268 multiply->get_args().push_back( new NameExpr( sizeofName( baseType ) ) ); 1249 1269 appExpr->get_args().back() = multiply; 1250 1270 } // if … … 1283 1303 std::list< Expression *>::iterator paramBegin = appExpr->get_args().begin(); 1284 1304 1285 TyVarMap exprTyVars ( (TypeDecl::Kind)-1 );1305 TyVarMap exprTyVars; 1286 1306 makeTyVarMap( function, exprTyVars ); 1287 1307 ReferenceToType *polyRetType = isPolyRet( function ); … … 1306 1326 1307 1327 boxParams( appExpr, function, arg, exprTyVars ); 1328 1308 1329 passAdapters( appExpr, function, exprTyVars ); 1309 1330 … … 1385 1406 if ( TypeInstType *typeInst = dynamic_cast< TypeInstType *>( retval->get_type() ) ) { 1386 1407 // find assignment operator for type variable 1387 ScopedMap< std::string, DeclarationWithType *>::const_iterator assignIter = assignOps.find( typeInst->get_name() );1408 std::map< std::string, DeclarationWithType *>::const_iterator assignIter = assignOps.find( typeInst->get_name() ); 1388 1409 if ( assignIter == assignOps.end() ) { 1389 1410 throw SemanticError( "Attempt to return dtype or ftype object in ", returnStmt->get_expr() ); … … 1407 1428 std::list< TypeDecl* >::const_iterator forallIt = forallParams.begin(); 1408 1429 for ( ; tyIt != tyParams.end() && forallIt != forallParams.end(); ++tyIt, ++forallIt ) { 1409 // 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" ); 1410 1437 TypeExpr *formalTypeExpr = dynamic_cast< TypeExpr* >( *tyIt ); 1411 1438 assert( formalTypeExpr && "type parameters must be type expressions" ); 1412 1439 Type *formalType = formalTypeExpr->get_type(); 1413 assignExpr->get_env()->add( (*forallIt)->get_name(), formalType ); 1414 1415 // skip types with no assign op (ftype/dtype) 1416 if ( (*forallIt)->get_kind() != TypeDecl::Any ) continue; 1417 1418 // find assignment operator for formal type 1440 assignExpr->get_env()->add( actualType->get_name(), formalType ); 1441 1419 1442 DeclarationWithType *assertAssign = 0; 1420 1443 if ( TypeInstType *formalTypeInstType = dynamic_cast< TypeInstType* >( formalType ) ) { 1421 ScopedMap< std::string, DeclarationWithType *>::const_iterator assertAssignIt = assignOps.find( formalTypeInstType->get_name() );1444 std::map< std::string, DeclarationWithType *>::const_iterator assertAssignIt = assignOps.find( formalTypeInstType->get_name() ); 1422 1445 if ( assertAssignIt == assignOps.end() ) { 1423 1446 throw SemanticError( "No assignment operation found for ", formalTypeInstType ); … … 1430 1453 } 1431 1454 } 1432 1433 // add inferred parameter for field assignment operator to assignment expression 1434 std::list< DeclarationWithType* > &asserts = (*forallIt)->get_assertions(); 1435 assert( ! asserts.empty() && "Type param needs assignment operator assertion" ); 1436 DeclarationWithType *actualDecl = asserts.front(); 1455 1456 1437 1457 assignExpr->get_inferParams()[ actualDecl->get_uniqueId() ] 1438 1458 = ParamEntry( assertAssign->get_uniqueId(), assertAssign->get_type()->clone(), actualDecl->get_type()->clone(), wrapFunctionDecl( assertAssign ) ); … … 1460 1480 1461 1481 Type * Pass1::mutate( PointerType *pointerType ) { 1462 scopeTyVars.beginScope();1482 TyVarMap oldtyVars = scopeTyVars; 1463 1483 makeTyVarMap( pointerType, scopeTyVars ); 1464 1484 1465 1485 Type *ret = Mutator::mutate( pointerType ); 1466 1486 1467 scopeTyVars .endScope();1487 scopeTyVars = oldtyVars; 1468 1488 return ret; 1469 1489 } 1470 1490 1471 1491 Type * Pass1::mutate( FunctionType *functionType ) { 1472 scopeTyVars.beginScope();1492 TyVarMap oldtyVars = scopeTyVars; 1473 1493 makeTyVarMap( functionType, scopeTyVars ); 1474 1494 1475 1495 Type *ret = Mutator::mutate( functionType ); 1476 1496 1477 scopeTyVars .endScope();1497 scopeTyVars = oldtyVars; 1478 1498 return ret; 1479 1499 } … … 1540 1560 1541 1561 Type * Pass2::mutate( PointerType *pointerType ) { 1542 scopeTyVars.beginScope();1562 TyVarMap oldtyVars = scopeTyVars; 1543 1563 makeTyVarMap( pointerType, scopeTyVars ); 1544 1564 1545 1565 Type *ret = Mutator::mutate( pointerType ); 1546 1566 1547 scopeTyVars .endScope();1567 scopeTyVars = oldtyVars; 1548 1568 return ret; 1549 1569 } 1550 1570 1551 1571 Type *Pass2::mutate( FunctionType *funcType ) { 1552 scopeTyVars.beginScope();1572 TyVarMap oldtyVars = scopeTyVars; 1553 1573 makeTyVarMap( funcType, scopeTyVars ); 1554 1574 … … 1567 1587 ObjectDecl newPtr( "", DeclarationNode::NoStorageClass, LinkageSpec::C, 0, 1568 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 ); 1569 1590 for ( std::list< TypeDecl *>::const_iterator tyParm = funcType->get_forall().begin(); tyParm != funcType->get_forall().end(); ++tyParm ) { 1570 1591 ObjectDecl *sizeParm, *alignParm; … … 1572 1593 if ( (*tyParm)->get_kind() == TypeDecl::Any ) { 1573 1594 TypeInstType parmType( Type::Qualifiers(), (*tyParm)->get_name(), *tyParm ); 1574 std::string parmName = mangleType( &parmType );1575 1595 1576 1596 sizeParm = newObj.clone(); 1577 sizeParm->set_name( sizeofName( parmName ) );1597 sizeParm->set_name( sizeofName( &parmType ) ); 1578 1598 last = funcType->get_parameters().insert( last, sizeParm ); 1579 1599 ++last; 1580 1600 1581 1601 alignParm = newObj.clone(); 1582 alignParm->set_name( alignofName( parmName ) );1602 alignParm->set_name( alignofName( &parmType ) ); 1583 1603 last = funcType->get_parameters().insert( last, alignParm ); 1584 1604 ++last; … … 1595 1615 std::set< std::string > seenTypes; // sizeofName for generic types we've seen 1596 1616 for ( std::list< DeclarationWithType* >::const_iterator fnParm = last; fnParm != funcType->get_parameters().end(); ++fnParm ) { 1597 Type *poly Type = isPolyType( (*fnParm)->get_type(), scopeTyVars );1598 if ( poly Type && ! dynamic_cast< TypeInstType* >( polyType ) ) {1599 std::string typeName = mangleType( polyType );1600 if ( seenTypes.count( typeName ) ) continue;1617 Type *polyBase = hasPolyBase( (*fnParm)->get_type(), scopeTyVars ); 1618 if ( polyBase && ! dynamic_cast< TypeInstType* >( polyBase ) ) { 1619 std::string sizeName = sizeofName( polyBase ); 1620 if ( seenTypes.count( sizeName ) ) continue; 1601 1621 1602 1622 ObjectDecl *sizeParm, *alignParm, *offsetParm; 1603 1623 sizeParm = newObj.clone(); 1604 sizeParm->set_name( size ofName( typeName ));1624 sizeParm->set_name( sizeName ); 1605 1625 last = funcType->get_parameters().insert( last, sizeParm ); 1606 1626 ++last; 1607 1627 1608 1628 alignParm = newObj.clone(); 1609 alignParm->set_name( alignofName( typeName ) );1629 alignParm->set_name( alignofName( polyBase ) ); 1610 1630 last = funcType->get_parameters().insert( last, alignParm ); 1611 1631 ++last; 1612 1632 1613 if ( StructInstType *polyBaseStruct = dynamic_cast< StructInstType* >( polyType ) ) { 1614 // NOTE zero-length arrays are illegal in C, so empty structs have no offset array 1615 if ( ! polyBaseStruct->get_baseStruct()->get_members().empty() ) { 1616 offsetParm = newPtr.clone(); 1617 offsetParm->set_name( offsetofName( typeName ) ); 1618 last = funcType->get_parameters().insert( last, offsetParm ); 1619 ++last; 1620 } 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; 1621 1638 } 1622 1639 1623 seenTypes.insert( typeName );1640 seenTypes.insert( sizeName ); 1624 1641 } 1625 1642 } … … 1631 1648 mutateAll( funcType->get_parameters(), *this ); 1632 1649 1633 scopeTyVars .endScope();1650 scopeTyVars = oldtyVars; 1634 1651 return funcType; 1635 1652 } … … 1824 1841 } 1825 1842 1826 ////////////////////////////////////////// PolyGenericCalculator //////////////////////////////////////////////////// 1827 1828 void PolyGenericCalculator::beginTypeScope( Type *ty ) { 1829 scopeTyVars.beginScope(); 1830 makeTyVarMap( ty, scopeTyVars ); 1831 } 1832 1833 void PolyGenericCalculator::endTypeScope() { 1834 scopeTyVars.endScope(); 1835 } 1843 ////////////////////////////////////////// MemberExprFixer //////////////////////////////////////////////////// 1836 1844 1837 1845 template< typename DeclClass > 1838 DeclClass * PolyGenericCalculator::handleDecl( DeclClass *decl, Type *type ) { 1839 beginTypeScope( type ); 1840 knownLayouts.beginScope(); 1841 knownOffsets.beginScope(); 1846 DeclClass * MemberExprFixer::handleDecl( DeclClass *decl, Type *type ) { 1847 TyVarMap oldtyVars = scopeTyVars; 1848 makeTyVarMap( type, scopeTyVars ); 1842 1849 1843 1850 DeclClass *ret = static_cast< DeclClass *>( Mutator::mutate( decl ) ); 1844 1851 1845 knownOffsets.endScope(); 1846 knownLayouts.endScope(); 1847 endTypeScope(); 1852 scopeTyVars = oldtyVars; 1848 1853 return ret; 1849 1854 } 1850 1855 1851 ObjectDecl * PolyGenericCalculator::mutate( ObjectDecl *objectDecl ) {1856 ObjectDecl * MemberExprFixer::mutate( ObjectDecl *objectDecl ) { 1852 1857 return handleDecl( objectDecl, objectDecl->get_type() ); 1853 1858 } 1854 1859 1855 DeclarationWithType * PolyGenericCalculator::mutate( FunctionDecl *functionDecl ) {1860 DeclarationWithType * MemberExprFixer::mutate( FunctionDecl *functionDecl ) { 1856 1861 return handleDecl( functionDecl, functionDecl->get_functionType() ); 1857 1862 } 1858 1863 1859 TypedefDecl * PolyGenericCalculator::mutate( TypedefDecl *typedefDecl ) {1864 TypedefDecl * MemberExprFixer::mutate( TypedefDecl *typedefDecl ) { 1860 1865 return handleDecl( typedefDecl, typedefDecl->get_base() ); 1861 1866 } 1862 1867 1863 TypeDecl * PolyGenericCalculator::mutate( TypeDecl *typeDecl ) {1868 TypeDecl * MemberExprFixer::mutate( TypeDecl *typeDecl ) { 1864 1869 scopeTyVars[ typeDecl->get_name() ] = typeDecl->get_kind(); 1865 1870 return Mutator::mutate( typeDecl ); 1866 1871 } 1867 1872 1868 Type * PolyGenericCalculator::mutate( PointerType *pointerType ) { 1869 beginTypeScope( pointerType ); 1873 Type * MemberExprFixer::mutate( PointerType *pointerType ) { 1874 TyVarMap oldtyVars = scopeTyVars; 1875 makeTyVarMap( pointerType, scopeTyVars ); 1870 1876 1871 1877 Type *ret = Mutator::mutate( pointerType ); 1872 1878 1873 endTypeScope();1879 scopeTyVars = oldtyVars; 1874 1880 return ret; 1875 1881 } 1876 1882 1877 Type * PolyGenericCalculator::mutate( FunctionType *funcType ) { 1878 beginTypeScope( funcType ); 1879 1880 // make sure that any type information passed into the function is accounted for 1881 for ( std::list< DeclarationWithType* >::const_iterator fnParm = funcType->get_parameters().begin(); fnParm != funcType->get_parameters().end(); ++fnParm ) { 1882 // condition here duplicates that in Pass2::mutate( FunctionType* ) 1883 Type *polyType = isPolyType( (*fnParm)->get_type(), scopeTyVars ); 1884 if ( polyType && ! dynamic_cast< TypeInstType* >( polyType ) ) { 1885 knownLayouts.insert( mangleType( polyType ) ); 1886 } 1887 } 1888 1889 Type *ret = Mutator::mutate( funcType ); 1890 1891 endTypeScope(); 1883 Type * MemberExprFixer::mutate( FunctionType *functionType ) { 1884 TyVarMap oldtyVars = scopeTyVars; 1885 makeTyVarMap( functionType, scopeTyVars ); 1886 1887 Type *ret = Mutator::mutate( functionType ); 1888 1889 scopeTyVars = oldtyVars; 1892 1890 return ret; 1893 1891 } 1894 1892 1895 Statement * PolyGenericCalculator::mutate( DeclStmt *declStmt ) {1893 Statement *MemberExprFixer::mutate( DeclStmt *declStmt ) { 1896 1894 if ( ObjectDecl *objectDecl = dynamic_cast< ObjectDecl *>( declStmt->get_decl() ) ) { 1897 if ( findGeneric( objectDecl->get_type()) ) {1895 if ( isPolyType( objectDecl->get_type(), scopeTyVars ) ) { 1898 1896 // change initialization of a polymorphic value object 1899 1897 // to allocate storage with alloca 1900 1898 Type *declType = objectDecl->get_type(); 1901 1899 UntypedExpr *alloc = new UntypedExpr( new NameExpr( "__builtin_alloca" ) ); 1902 alloc->get_args().push_back( new NameExpr( sizeofName( mangleType( declType )) ) );1900 alloc->get_args().push_back( new NameExpr( sizeofName( declType ) ) ); 1903 1901 1904 1902 delete objectDecl->get_init(); … … 1932 1930 ConstantExpr *fieldIndex = new ConstantExpr( Constant( new BasicType( Type::Qualifiers(), BasicType::LongUnsignedInt ), offset_namer.str() ) ); 1933 1931 UntypedExpr *fieldOffset = new UntypedExpr( new NameExpr( "?[?]" ) ); 1934 fieldOffset->get_args().push_back( new NameExpr( offsetofName( mangleType( objectType )) ) );1932 fieldOffset->get_args().push_back( new NameExpr( offsetofName( objectType ) ) ); 1935 1933 fieldOffset->get_args().push_back( fieldIndex ); 1936 1934 return fieldOffset; … … 1947 1945 } 1948 1946 1949 Expression * PolyGenericCalculator::mutate( MemberExpr *memberExpr ) {1947 Expression *MemberExprFixer::mutate( MemberExpr *memberExpr ) { 1950 1948 // mutate, exiting early if no longer MemberExpr 1951 1949 Expression *expr = Mutator::mutate( memberExpr ); … … 1964 1962 Type *objectType = hasPolyBase( objectDecl->get_type(), scopeTyVars, &tyDepth ); 1965 1963 if ( ! objectType ) return memberExpr; 1966 findGeneric( objectType ); // ensure layout for this type is available1967 1964 1968 1965 Expression *newMemberExpr = 0; … … 1996 1993 } 1997 1994 1998 ObjectDecl *PolyGenericCalculator::makeVar( const std::string &name, Type *type, Initializer *init ) { 1999 ObjectDecl *newObj = new ObjectDecl( name, DeclarationNode::NoStorageClass, LinkageSpec::C, 0, type, init ); 2000 stmtsToAdd.push_back( new DeclStmt( noLabels, newObj ) ); 2001 return newObj; 2002 } 2003 2004 void PolyGenericCalculator::addOtypeParamsToLayoutCall( UntypedExpr *layoutCall, const std::list< Type* > &otypeParams ) { 2005 for ( std::list< Type* >::const_iterator param = otypeParams.begin(); param != otypeParams.end(); ++param ) { 2006 if ( findGeneric( *param ) ) { 2007 // push size/align vars for a generic parameter back 2008 std::string paramName = mangleType( *param ); 2009 layoutCall->get_args().push_back( new NameExpr( sizeofName( paramName ) ) ); 2010 layoutCall->get_args().push_back( new NameExpr( alignofName( paramName ) ) ); 2011 } else { 2012 layoutCall->get_args().push_back( new SizeofExpr( (*param)->clone() ) ); 2013 layoutCall->get_args().push_back( new AlignofExpr( (*param)->clone() ) ); 2014 } 2015 } 2016 } 2017 2018 /// returns true if any of the otype parameters have a dynamic layout and puts all otype parameters in the output list 2019 bool findGenericParams( std::list< TypeDecl* > &baseParams, std::list< Expression* > &typeParams, std::list< Type* > &out ) { 2020 bool hasDynamicLayout = false; 2021 2022 std::list< TypeDecl* >::const_iterator baseParam = baseParams.begin(); 2023 std::list< Expression* >::const_iterator typeParam = typeParams.begin(); 2024 for ( ; baseParam != baseParams.end() && typeParam != typeParams.end(); ++baseParam, ++typeParam ) { 2025 // skip non-otype parameters 2026 if ( (*baseParam)->get_kind() != TypeDecl::Any ) continue; 2027 TypeExpr *typeExpr = dynamic_cast< TypeExpr* >( *typeParam ); 2028 assert( typeExpr && "all otype parameters should be type expressions" ); 2029 2030 Type *type = typeExpr->get_type(); 2031 out.push_back( type ); 2032 if ( isPolyType( type ) ) hasDynamicLayout = true; 2033 } 2034 assert( baseParam == baseParams.end() && typeParam == typeParams.end() ); 2035 2036 return hasDynamicLayout; 2037 } 2038 2039 bool PolyGenericCalculator::findGeneric( Type *ty ) { 2040 if ( TypeInstType *typeInst = dynamic_cast< TypeInstType* >( ty ) ) { 2041 // duplicate logic from isPolyType() 2042 if ( env ) { 2043 if ( Type *newType = env->lookup( typeInst->get_name() ) ) { 2044 return findGeneric( newType ); 2045 } // if 2046 } // if 2047 if ( scopeTyVars.find( typeInst->get_name() ) != scopeTyVars.end() ) { 2048 // NOTE assumes here that getting put in the scopeTyVars included having the layout variables set 2049 return true; 2050 } 2051 return false; 2052 } else if ( StructInstType *structTy = dynamic_cast< StructInstType* >( ty ) ) { 2053 // check if this type already has a layout generated for it 2054 std::string typeName = mangleType( ty ); 2055 if ( knownLayouts.find( typeName ) != knownLayouts.end() ) return true; 2056 2057 // check if any of the type parameters have dynamic layout; if none do, this type is (or will be) monomorphized 2058 std::list< Type* > otypeParams; 2059 if ( ! findGenericParams( *structTy->get_baseParameters(), structTy->get_parameters(), otypeParams ) ) return false; 2060 2061 // insert local variables for layout and generate call to layout function 2062 knownLayouts.insert( typeName ); // done early so as not to interfere with the later addition of parameters to the layout call 2063 Type *layoutType = new BasicType( Type::Qualifiers(), BasicType::LongUnsignedInt ); 2064 2065 int n_members = structTy->get_baseStruct()->get_members().size(); 2066 if ( n_members == 0 ) { 2067 // all empty structs have the same layout - size 1, align 1 2068 makeVar( sizeofName( typeName ), layoutType, new SingleInit( new ConstantExpr( Constant::from( (unsigned long)1 ) ) ) ); 2069 makeVar( alignofName( typeName ), layoutType->clone(), new SingleInit( new ConstantExpr( Constant::from( (unsigned long)1 ) ) ) ); 2070 // NOTE zero-length arrays are forbidden in C, so empty structs have no offsetof array 2071 } else { 2072 ObjectDecl *sizeVar = makeVar( sizeofName( typeName ), layoutType ); 2073 ObjectDecl *alignVar = makeVar( alignofName( typeName ), layoutType->clone() ); 2074 ObjectDecl *offsetVar = makeVar( offsetofName( typeName ), new ArrayType( Type::Qualifiers(), layoutType->clone(), new ConstantExpr( Constant::from( n_members ) ), false, false ) ); 2075 2076 // generate call to layout function 2077 UntypedExpr *layoutCall = new UntypedExpr( new NameExpr( layoutofName( structTy->get_baseStruct() ) ) ); 2078 layoutCall->get_args().push_back( new AddressExpr( new VariableExpr( sizeVar ) ) ); 2079 layoutCall->get_args().push_back( new AddressExpr( new VariableExpr( alignVar ) ) ); 2080 layoutCall->get_args().push_back( new VariableExpr( offsetVar ) ); 2081 addOtypeParamsToLayoutCall( layoutCall, otypeParams ); 2082 2083 stmtsToAdd.push_back( new ExprStmt( noLabels, layoutCall ) ); 2084 } 2085 2086 return true; 2087 } else if ( UnionInstType *unionTy = dynamic_cast< UnionInstType* >( ty ) ) { 2088 // check if this type already has a layout generated for it 2089 std::string typeName = mangleType( ty ); 2090 if ( knownLayouts.find( typeName ) != knownLayouts.end() ) return true; 2091 2092 // check if any of the type parameters have dynamic layout; if none do, this type is (or will be) monomorphized 2093 std::list< Type* > otypeParams; 2094 if ( ! findGenericParams( *unionTy->get_baseParameters(), unionTy->get_parameters(), otypeParams ) ) return false; 2095 2096 // insert local variables for layout and generate call to layout function 2097 knownLayouts.insert( typeName ); // done early so as not to interfere with the later addition of parameters to the layout call 2098 Type *layoutType = new BasicType( Type::Qualifiers(), BasicType::LongUnsignedInt ); 2099 2100 ObjectDecl *sizeVar = makeVar( sizeofName( typeName ), layoutType ); 2101 ObjectDecl *alignVar = makeVar( alignofName( typeName ), layoutType->clone() ); 2102 2103 // generate call to layout function 2104 UntypedExpr *layoutCall = new UntypedExpr( new NameExpr( layoutofName( unionTy->get_baseUnion() ) ) ); 2105 layoutCall->get_args().push_back( new AddressExpr( new VariableExpr( sizeVar ) ) ); 2106 layoutCall->get_args().push_back( new AddressExpr( new VariableExpr( alignVar ) ) ); 2107 addOtypeParamsToLayoutCall( layoutCall, otypeParams ); 2108 2109 stmtsToAdd.push_back( new ExprStmt( noLabels, layoutCall ) ); 2110 2111 return true; 2112 } 2113 2114 return false; 2115 } 2116 2117 Expression *PolyGenericCalculator::mutate( SizeofExpr *sizeofExpr ) { 2118 Type *ty = sizeofExpr->get_type(); 2119 if ( findGeneric( ty ) ) { 2120 Expression *ret = new NameExpr( sizeofName( mangleType( ty ) ) ); 2121 delete sizeofExpr; 2122 return ret; 2123 } 2124 return sizeofExpr; 2125 } 2126 2127 Expression *PolyGenericCalculator::mutate( AlignofExpr *alignofExpr ) { 2128 Type *ty = alignofExpr->get_type(); 2129 if ( findGeneric( ty ) ) { 2130 Expression *ret = new NameExpr( alignofName( mangleType( ty ) ) ); 2131 delete alignofExpr; 2132 return ret; 2133 } 2134 return alignofExpr; 2135 } 2136 2137 Expression *PolyGenericCalculator::mutate( OffsetofExpr *offsetofExpr ) { 1995 Expression *MemberExprFixer::mutate( OffsetofExpr *offsetofExpr ) { 2138 1996 // mutate, exiting early if no longer OffsetofExpr 2139 1997 Expression *expr = Mutator::mutate( offsetofExpr ); … … 2142 2000 2143 2001 // only mutate expressions for polymorphic structs/unions 2144 Type *ty = offsetofExpr->get_type();2145 if ( ! findGeneric( ty )) return offsetofExpr;2146 2002 Type *ty = isPolyType( offsetofExpr->get_type(), scopeTyVars ); 2003 if ( ! ty ) return offsetofExpr; 2004 2147 2005 if ( StructInstType *structType = dynamic_cast< StructInstType* >( ty ) ) { 2148 2006 // replace offsetof expression by index into offset array … … 2160 2018 } 2161 2019 2162 Expression *PolyGenericCalculator::mutate( OffsetPackExpr *offsetPackExpr ) {2163 StructInstType *ty = offsetPackExpr->get_type();2164 2165 Expression *ret = 0;2166 if ( findGeneric( ty ) ) {2167 // pull offset back from generated type information2168 ret = new NameExpr( offsetofName( mangleType( ty ) ) );2169 } else {2170 std::string offsetName = offsetofName( mangleType( ty ) );2171 if ( knownOffsets.find( offsetName ) != knownOffsets.end() ) {2172 // use the already-generated offsets for this type2173 ret = new NameExpr( offsetName );2174 } else {2175 knownOffsets.insert( offsetName );2176 2177 std::list< Declaration* > &baseMembers = ty->get_baseStruct()->get_members();2178 Type *offsetType = new BasicType( Type::Qualifiers(), BasicType::LongUnsignedInt );2179 2180 // build initializer list for offset array2181 std::list< Initializer* > inits;2182 for ( std::list< Declaration* >::const_iterator member = baseMembers.begin(); member != baseMembers.end(); ++member ) {2183 DeclarationWithType *memberDecl;2184 if ( DeclarationWithType *origMember = dynamic_cast< DeclarationWithType* >( *member ) ) {2185 memberDecl = origMember->clone();2186 } else {2187 memberDecl = new ObjectDecl( (*member)->get_name(), DeclarationNode::NoStorageClass, LinkageSpec::Cforall, 0, offsetType->clone(), 0 );2188 }2189 inits.push_back( new SingleInit( new OffsetofExpr( ty->clone(), memberDecl ) ) );2190 }2191 2192 // build the offset array and replace the pack with a reference to it2193 ObjectDecl *offsetArray = makeVar( offsetName, new ArrayType( Type::Qualifiers(), offsetType, new ConstantExpr( Constant::from( baseMembers.size() ) ), false, false ),2194 new ListInit( inits ) );2195 ret = new VariableExpr( offsetArray );2196 }2197 }2198 2199 delete offsetPackExpr;2200 return ret;2201 }2202 2203 void PolyGenericCalculator::doBeginScope() {2204 knownLayouts.beginScope();2205 knownOffsets.beginScope();2206 }2207 2208 void PolyGenericCalculator::doEndScope() {2209 knownLayouts.endScope();2210 knownOffsets.endScope();2211 }2212 2213 2020 ////////////////////////////////////////// Pass3 //////////////////////////////////////////////////// 2214 2021 2215 2022 template< typename DeclClass > 2216 2023 DeclClass * Pass3::handleDecl( DeclClass *decl, Type *type ) { 2217 scopeTyVars.beginScope();2024 TyVarMap oldtyVars = scopeTyVars; 2218 2025 makeTyVarMap( type, scopeTyVars ); 2219 2026 … … 2221 2028 ScrubTyVars::scrub( decl, scopeTyVars ); 2222 2029 2223 scopeTyVars .endScope();2030 scopeTyVars = oldtyVars; 2224 2031 return ret; 2225 2032 } … … 2251 2058 2252 2059 Type * Pass3::mutate( PointerType *pointerType ) { 2253 scopeTyVars.beginScope();2060 TyVarMap oldtyVars = scopeTyVars; 2254 2061 makeTyVarMap( pointerType, scopeTyVars ); 2255 2062 2256 2063 Type *ret = Mutator::mutate( pointerType ); 2257 2064 2258 scopeTyVars .endScope();2065 scopeTyVars = oldtyVars; 2259 2066 return ret; 2260 2067 } 2261 2068 2262 2069 Type * Pass3::mutate( FunctionType *functionType ) { 2263 scopeTyVars.beginScope();2070 TyVarMap oldtyVars = scopeTyVars; 2264 2071 makeTyVarMap( functionType, scopeTyVars ); 2265 2072 2266 2073 Type *ret = Mutator::mutate( functionType ); 2267 2074 2268 scopeTyVars .endScope();2075 scopeTyVars = oldtyVars; 2269 2076 return ret; 2270 2077 }
Note:
See TracChangeset
for help on using the changeset viewer.