Changeset 2dcd80a for src/GenPoly
- Timestamp:
- Dec 14, 2022, 12:23:42 PM (4 years ago)
- Branches:
- ADT, ast-experimental, master, stuck-waitfor-destruct
- Children:
- 441a6a7
- Parents:
- 7d9598d8 (diff), d8bdf13 (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the(diff)links above to see all the changes relative to each parent. - Location:
- src/GenPoly
- Files:
-
- 4 edited
-
Box.cc (modified) (16 diffs)
-
ErasableScopedMap.h (modified) (1 diff)
-
GenPoly.cc (modified) (2 diffs)
-
GenPoly.h (modified) (1 diff)
Legend:
- Unmodified
- Added
- Removed
-
src/GenPoly/Box.cc
r7d9598d8 r2dcd80a 37 37 #include "InitTweak/InitTweak.h" // for getFunctionName, isAssignment 38 38 #include "Lvalue.h" // for generalizedLvalue 39 #include "ResolvExpr/TypeEnvironment.h" // for EqvClass40 39 #include "ResolvExpr/typeops.h" // for typesCompatible 41 40 #include "ScopedSet.h" // for ScopedSet, ScopedSet<>::iter... … … 95 94 private: 96 95 /// Pass the extra type parameters from polymorphic generic arguments or return types into a function application 97 void passArgTypeVars( ApplicationExpr *appExpr, Type *parmType, Type *argBaseType, std::list< Expression *>::iterator &arg, const TyVarMap &exprTyVars, std::set< std::string > &seenTypes ); 96 /// Will insert 0, 2 or 3 more arguments. 97 std::list< Expression *>::iterator passArgTypeVars( ApplicationExpr *appExpr, Type *parmType, Type *argBaseType, std::list< Expression *>::iterator arg, const TyVarMap &exprTyVars, std::set< std::string > &seenTypes ); 98 98 /// passes extra type parameters into a polymorphic function application 99 99 /// Returns an iterator to the first argument after the added … … 488 488 makeTyVarMap( functionType, scopeTyVars ); 489 489 490 std::list< DeclarationWithType *> ¶mList = functionType->parameters;491 490 std::list< FunctionType const *> functions; 492 491 for ( TypeDecl * const tyVar : functionType->forall ) { … … 495 494 } // for 496 495 } // for 497 for ( DeclarationWithType * const arg : paramList) {496 for ( DeclarationWithType * const arg : functionType->parameters ) { 498 497 findFunction( arg->get_type(), functions, scopeTyVars, needsAdapter ); 499 498 } // for … … 532 531 } 533 532 534 void Pass1::passArgTypeVars( ApplicationExpr *appExpr, Type *parmType, Type *argBaseType, std::list< Expression *>::iterator &arg, const TyVarMap &exprTyVars, std::set< std::string > &seenTypes ) {533 std::list< Expression *>::iterator Pass1::passArgTypeVars( ApplicationExpr *appExpr, Type *parmType, Type *argBaseType, std::list< Expression *>::iterator arg, const TyVarMap &exprTyVars, std::set< std::string > &seenTypes ) { 535 534 Type *polyType = isPolyType( parmType, exprTyVars ); 536 535 if ( polyType && ! dynamic_cast< TypeInstType* >( polyType ) ) { 537 536 std::string typeName = mangleType( polyType ); 538 if ( seenTypes.count( typeName ) ) return ;537 if ( seenTypes.count( typeName ) ) return arg; 539 538 540 539 arg = appExpr->get_args().insert( arg, new SizeofExpr( argBaseType->clone() ) ); … … 556 555 seenTypes.insert( typeName ); 557 556 } 557 return arg; 558 558 } 559 559 … … 562 562 std::list< Expression *>::iterator arg = appExpr->args.begin(); 563 563 // pass size/align for type variables 564 // NOTE: This is iterating over a map. This means the sorting 565 // order of the keys changes behaviour, as the iteration order 566 // is visible outside the loop. - The order matches the orignal 567 // order because the vars have been renamed with numbers that, 568 // even when converted to strings, sort in the original order. 569 // (At least, that is the best explination I have.) 564 570 for ( std::pair<std::string, TypeDecl::Data> const & tyParam : exprTyVars ) { 565 ResolvExpr::EqvClass eqvClass; 566 if ( tyParam.second.isComplete ) { 567 Type *concrete = env->lookup( tyParam.first ); 568 // If there is an unbound type variable, it should have detected already. 569 assertf( concrete, "Unbound type variable: %s in: %s", 570 toCString( tyParam.first ), toCString( *env ) ); 571 572 arg = appExpr->get_args().insert( arg, new SizeofExpr( concrete->clone() ) ); 573 arg++; 574 arg = appExpr->get_args().insert( arg, new AlignofExpr( concrete->clone() ) ); 575 arg++; 576 } // if 571 if ( !tyParam.second.isComplete ) continue; 572 Type *concrete = env->lookup( tyParam.first ); 573 // If there is an unbound type variable, it should have detected already. 574 assertf( concrete, "Unbound type variable: %s in: %s", 575 toCString( tyParam.first ), toCString( *env ) ); 576 577 arg = appExpr->get_args().insert( arg, new SizeofExpr( concrete->clone() ) ); 578 arg++; 579 arg = appExpr->get_args().insert( arg, new AlignofExpr( concrete->clone() ) ); 580 arg++; 577 581 } // for 578 582 … … 582 586 assert( funcType ); 583 587 584 // These iterators don't advance in unison.585 std::list< DeclarationWithType* >::const_iterator fnParm = funcType->get_parameters().begin();586 std::list< Expression* >::const_iterator fnArg = arg;587 std::set< std::string > seenTypes; ///< names for generic types we've seen588 // Iterator over the original function arguments. 589 std::list< Expression* >::const_iterator fnArg; 590 // Names for generic types we've seen. 591 std::set< std::string > seenTypes; 588 592 589 593 // a polymorphic return type may need to be added to the argument list 590 594 if ( polyRetType ) { 591 595 Type *concRetType = replaceWithConcrete( polyRetType, env ); 592 passArgTypeVars( appExpr, polyRetType, concRetType, arg, exprTyVars, seenTypes ); 593 ++fnArg; // skip the return parameter in the argument list 596 arg = passArgTypeVars( appExpr, polyRetType, concRetType, arg, exprTyVars, seenTypes ); 597 // Skip the return parameter in the argument list. 598 fnArg = arg + 1; 599 } else { 600 fnArg = arg; 594 601 } 595 602 596 603 // add type information args for presently unseen types in parameter list 604 std::list< DeclarationWithType* >::const_iterator fnParm = funcType->get_parameters().begin(); 597 605 for ( ; fnParm != funcType->get_parameters().end() && fnArg != appExpr->get_args().end(); ++fnParm, ++fnArg ) { 598 if ( ! (*fnArg)->get_result() ) continue;599 606 Type * argType = (*fnArg)->get_result(); 600 passArgTypeVars( appExpr, (*fnParm)->get_type(), argType, arg, exprTyVars, seenTypes ); 607 if ( ! argType ) continue; 608 arg = passArgTypeVars( appExpr, (*fnParm)->get_type(), argType, arg, exprTyVars, seenTypes ); 601 609 } 602 610 return arg; … … 680 688 Expression *Pass1::applyAdapter( ApplicationExpr *appExpr, FunctionType *function ) { 681 689 Expression *ret = appExpr; 682 // if ( ! function->get_returnVals().empty() && isPolyType( function->get_returnVals().front()->get_type(), tyVars ) ) {683 690 if ( isDynRet( function, scopeTyVars ) ) { 684 691 ret = addRetParam( appExpr, function->returnVals.front()->get_type() ); … … 772 779 773 780 void Pass1::addInferredParams( ApplicationExpr *appExpr, std::list< Expression *>::iterator arg, FunctionType *functionType, const TyVarMap &tyVars ) { 774 std::list< Expression *>::iterator cur = arg;775 781 for ( TypeDecl * const tyVar : functionType->forall ) { 776 782 for ( DeclarationWithType * const assert : tyVar->assertions ) { … … 779 785 Expression *newExpr = inferParam->second.expr->clone(); 780 786 boxParam( newExpr, assert->get_type(), tyVars ); 781 appExpr->get_args().insert( cur, newExpr ); 787 arg = appExpr->get_args().insert( arg, newExpr ); 788 ++arg; 782 789 } // for 783 790 } // for … … 922 929 // only attempt to create an adapter or pass one as a parameter if we haven't already done so for this 923 930 // pre-substitution parameter function type. 924 if ( adaptersDone.find( mangleName ) == adaptersDone.end() ) {925 adaptersDone.insert( adaptersDone.begin(), mangleName );931 // The second part of the insert result is "is the value new". 932 if ( adaptersDone.insert( mangleName ).second ) { 926 933 927 934 // apply substitution to type variables to figure out what the adapter's type should look like … … 1106 1113 1107 1114 Expression *ret = appExpr; 1115 // Save iterator to the first original parameter (works with lists). 1108 1116 std::list< Expression *>::iterator paramBegin = appExpr->get_args().begin(); 1109 1117 … … 1172 1180 1173 1181 void Pass1::premutate( AddressExpr * ) { visit_children = false; } 1182 1174 1183 Expression * Pass1::postmutate( AddressExpr * addrExpr ) { 1175 1184 assert( addrExpr->arg->result && ! addrExpr->arg->result->isVoid() ); … … 1232 1241 1233 1242 void Pass2::addAdapters( FunctionType *functionType ) { 1234 std::list< DeclarationWithType *> ¶mList = functionType->parameters;1235 1243 std::list< FunctionType const *> functions; 1236 1244 for ( DeclarationWithType * const arg : functionType->parameters ) { … … 1245 1253 std::string adapterName = makeAdapterName( mangleName ); 1246 1254 // adapter may not be used in body, pass along with unused attribute. 1247 paramList.push_front( new ObjectDecl( adapterName, Type::StorageClasses(), LinkageSpec::C, 0, new PointerType( Type::Qualifiers(), makeAdapterType( funType, scopeTyVars ) ), 0, { new Attribute( "unused" ) } ) ); 1255 functionType->parameters.push_front( 1256 new ObjectDecl( adapterName, Type::StorageClasses(), LinkageSpec::C, 0, new PointerType( Type::Qualifiers(), makeAdapterType( funType, scopeTyVars ) ), 0, { new Attribute( "unused" ) } ) ); 1248 1257 adaptersDone.insert( adaptersDone.begin(), mangleName ); 1249 1258 } 1250 1259 } 1251 // deleteAll( functions );1252 1260 } 1253 1261 -
src/GenPoly/ErasableScopedMap.h
r7d9598d8 r2dcd80a 23 23 24 24 namespace GenPoly { 25 /// A map where the items are placed into nested scopes; 26 /// inserted items are placed into the innermost scope, lookup looks from the innermost scope outward; 27 /// erasing a key means that find() will no longer report any instance of the key in a scope further 28 /// out, but the erasure itself is scoped. Key erasure works by inserting a sentinal value into the 29 /// value field, and thus only works for Value types where a meaningful sentinal can be chosen. 30 template<typename Key, typename Value> 31 class ErasableScopedMap { 32 typedef std::map< Key, Value > Scope; 33 typedef std::vector< Scope > ScopeList; 34 35 ScopeList scopes; ///< scoped list of maps 36 Value erased; ///< sentinal value for erased keys 37 public: 38 typedef typename Scope::key_type key_type; 39 typedef typename Scope::mapped_type mapped_type; 40 typedef typename Scope::value_type value_type; 41 typedef typename ScopeList::size_type size_type; 42 typedef typename ScopeList::difference_type difference_type; 43 typedef typename Scope::reference reference; 44 typedef typename Scope::const_reference const_reference; 45 typedef typename Scope::pointer pointer; 46 typedef typename Scope::const_pointer const_pointer; 47 48 class iterator : public std::iterator< std::bidirectional_iterator_tag, 49 value_type > { 50 friend class ErasableScopedMap; 51 friend class const_iterator; 52 typedef typename std::map< Key, Value >::iterator wrapped_iterator; 53 typedef typename std::vector< std::map< Key, Value > > scope_list; 54 typedef typename scope_list::size_type size_type; 55 56 /// Checks if this iterator points to a valid item 57 bool is_valid() const { 58 return it != map->scopes[i].end() && it->second != map->erased; 25 26 /// A map where the items are placed into nested scopes. 27 /// Inserted items are placed into the innermost scope, lookup looks from the 28 /// innermost scope outward. Erasing a key means that find() will no longer 29 /// report any instance of the key in a scope further out, but the erasure 30 /// itself is scoped. Key erasure works by inserting a sentinal value into 31 /// the value field, and thus only works for Value types where a meaningful 32 /// sentinal can be chosen. 33 template<typename Key, typename Value> 34 class ErasableScopedMap { 35 typedef std::map< Key, Value > Scope; 36 typedef std::vector< Scope > ScopeList; 37 38 /// Scoped list of maps. 39 ScopeList scopes; 40 /// Sentinal value for erased keys. 41 Value erased; 42 public: 43 typedef typename Scope::key_type key_type; 44 typedef typename Scope::mapped_type mapped_type; 45 typedef typename Scope::value_type value_type; 46 typedef typename ScopeList::size_type size_type; 47 typedef typename ScopeList::difference_type difference_type; 48 typedef typename Scope::reference reference; 49 typedef typename Scope::const_reference const_reference; 50 typedef typename Scope::pointer pointer; 51 typedef typename Scope::const_pointer const_pointer; 52 53 // Both iterator types are complete bidirection iterators, defined below. 54 class iterator; 55 class const_iterator; 56 57 /// Starts a new scope 58 void beginScope() { 59 Scope scope; 60 scopes.push_back(scope); 61 } 62 63 /// Ends a scope; invalidates any iterators pointing to elements of that scope 64 void endScope() { 65 scopes.pop_back(); 66 assert( ! scopes.empty() ); 67 } 68 69 /// Default constructor initializes with one scope 70 ErasableScopedMap( const Value &erased_ ) : erased( erased_ ) { beginScope(); } 71 72 iterator begin() { return iterator(*this, scopes.back().begin(), scopes.size()-1).next_valid(); } 73 const_iterator begin() const { return const_iterator(*this, scopes.back().begin(), scopes.size()-1).next_valid(); } 74 const_iterator cbegin() const { return const_iterator(*this, scopes.back().begin(), scopes.size()-1).next_valid(); } 75 iterator end() { return iterator(*this, scopes[0].end(), 0); } 76 const_iterator end() const { return const_iterator(*this, scopes[0].end(), 0); } 77 const_iterator cend() const { return const_iterator(*this, scopes[0].end(), 0); } 78 79 /// Gets the index of the current scope (counted from 1) 80 size_type currentScope() const { return scopes.size(); } 81 82 /// Finds the given key in the outermost scope it occurs; returns end() for none such 83 iterator find( const Key &key ) { 84 for ( size_type i = scopes.size() - 1; ; --i ) { 85 typename Scope::iterator val = scopes[i].find( key ); 86 if ( val != scopes[i].end() ) { 87 return val->second == erased ? end() : iterator( *this, val, i ); 59 88 } 60 61 /// Increments on invalid 62 iterator& next_valid() { 63 if ( ! is_valid() ) { ++(*this); } 64 return *this; 89 if ( i == 0 ) break; 90 } 91 return end(); 92 } 93 const_iterator find( const Key &key ) const { 94 return const_iterator( const_cast< ErasableScopedMap< Key, Value >* >(this)->find( key ) ); 95 } 96 97 /// Finds the given key in the outermost scope inside the given scope where it occurs 98 iterator findNext( const_iterator &it, const Key &key ) { 99 if ( it.i == 0 ) return end(); 100 for ( size_type i = it.i - 1; ; --i ) { 101 typename Scope::iterator val = scopes[i].find( key ); 102 if ( val != scopes[i].end() ) { 103 return val->second == erased ? end() : iterator( *this, val, i ); 65 104 } 66 67 /// Decrements on invalid 68 iterator& prev_valid() { 69 if ( ! is_valid() ) { --(*this); } 70 return *this; 71 } 72 73 iterator(ErasableScopedMap< Key, Value > const &_map, const wrapped_iterator &_it, size_type _i) 74 : map(&_map), it(_it), i(_i) {} 75 76 public: 77 iterator(const iterator &that) : map(that.map), it(that.it), i(that.i) {} 78 iterator& operator= (const iterator &that) { 79 map = that.map; i = that.i; it = that.it; 80 return *this; 81 } 82 83 reference operator* () { return *it; } 84 pointer operator-> () { return it.operator->(); } 85 86 iterator& operator++ () { 87 if ( it == map->scopes[i].end() ) { 88 if ( i == 0 ) return *this; 89 --i; 90 it = map->scopes[i].begin(); 91 } else { 92 ++it; 93 } 94 return next_valid(); 95 } 96 iterator& operator++ (int) { iterator tmp = *this; ++(*this); return tmp; } 97 98 iterator& operator-- () { 99 // may fail if this is the begin iterator; allowed by STL spec 100 if ( it == map->scopes[i].begin() ) { 101 ++i; 102 it = map->scopes[i].end(); 103 } 104 --it; 105 return prev_valid(); 106 } 107 iterator& operator-- (int) { iterator tmp = *this; --(*this); return tmp; } 108 109 bool operator== (const iterator &that) { 110 return map == that.map && i == that.i && it == that.it; 111 } 112 bool operator!= (const iterator &that) { return !( *this == that ); } 113 114 private: 115 ErasableScopedMap< Key, Value > const *map; 116 wrapped_iterator it; 117 size_type i; 118 }; 119 120 class const_iterator : public std::iterator< std::bidirectional_iterator_tag, 121 value_type > { 122 friend class ErasableScopedMap; 123 typedef typename std::map< Key, Value >::iterator wrapped_iterator; 124 typedef typename std::map< Key, Value >::const_iterator wrapped_const_iterator; 125 typedef typename std::vector< std::map< Key, Value > > scope_list; 126 typedef typename scope_list::size_type size_type; 127 128 /// Checks if this iterator points to a valid item 129 bool is_valid() const { 130 return it != map->scopes[i].end() && it->second != map->erased; 131 } 132 133 /// Increments on invalid 134 const_iterator& next_valid() { 135 if ( ! is_valid() ) { ++(*this); } 136 return *this; 137 } 138 139 /// Decrements on invalid 140 const_iterator& prev_valid() { 141 if ( ! is_valid() ) { --(*this); } 142 return *this; 143 } 144 145 const_iterator(ErasableScopedMap< Key, Value > const &_map, const wrapped_const_iterator &_it, size_type _i) 146 : map(&_map), it(_it), i(_i) {} 147 public: 148 const_iterator(const iterator &that) : map(that.map), it(that.it), i(that.i) {} 149 const_iterator(const const_iterator &that) : map(that.map), it(that.it), i(that.i) {} 150 const_iterator& operator= (const iterator &that) { 151 map = that.map; i = that.i; it = that.it; 152 return *this; 153 } 154 const_iterator& operator= (const const_iterator &that) { 155 map = that.map; i = that.i; it = that.it; 156 return *this; 157 } 158 159 const_reference operator* () { return *it; } 160 const_pointer operator-> () { return it.operator->(); } 161 162 const_iterator& operator++ () { 163 if ( it == map->scopes[i].end() ) { 164 if ( i == 0 ) return *this; 165 --i; 166 it = map->scopes[i].begin(); 167 } else { 168 ++it; 169 } 170 return next_valid(); 171 } 172 const_iterator& operator++ (int) { const_iterator tmp = *this; ++(*this); return tmp; } 173 174 const_iterator& operator-- () { 175 // may fail if this is the begin iterator; allowed by STL spec 176 if ( it == map->scopes[i].begin() ) { 177 ++i; 178 it = map->scopes[i].end(); 179 } 180 --it; 181 return prev_valid(); 182 } 183 const_iterator& operator-- (int) { const_iterator tmp = *this; --(*this); return tmp; } 184 185 bool operator== (const const_iterator &that) { 186 return map == that.map && i == that.i && it == that.it; 187 } 188 bool operator!= (const const_iterator &that) { return !( *this == that ); } 189 190 private: 191 ErasableScopedMap< Key, Value > const *map; 192 wrapped_const_iterator it; 193 size_type i; 194 }; 195 196 /// Starts a new scope 197 void beginScope() { 198 Scope scope; 199 scopes.push_back(scope); 200 } 201 202 /// Ends a scope; invalidates any iterators pointing to elements of that scope 203 void endScope() { 204 scopes.pop_back(); 205 assert( ! scopes.empty() ); 206 } 207 208 /// Default constructor initializes with one scope 209 ErasableScopedMap( const Value &erased_ ) : erased( erased_ ) { beginScope(); } 210 211 iterator begin() { return iterator(*this, scopes.back().begin(), scopes.size()-1).next_valid(); } 212 const_iterator begin() const { return const_iterator(*this, scopes.back().begin(), scopes.size()-1).next_valid(); } 213 const_iterator cbegin() const { return const_iterator(*this, scopes.back().begin(), scopes.size()-1).next_valid(); } 214 iterator end() { return iterator(*this, scopes[0].end(), 0); } 215 const_iterator end() const { return const_iterator(*this, scopes[0].end(), 0); } 216 const_iterator cend() const { return const_iterator(*this, scopes[0].end(), 0); } 217 218 /// Gets the index of the current scope (counted from 1) 219 size_type currentScope() const { return scopes.size(); } 220 221 /// Finds the given key in the outermost scope it occurs; returns end() for none such 222 iterator find( const Key &key ) { 223 for ( size_type i = scopes.size() - 1; ; --i ) { 224 typename Scope::iterator val = scopes[i].find( key ); 225 if ( val != scopes[i].end() ) { 226 return val->second == erased ? end() : iterator( *this, val, i ); 227 } 228 if ( i == 0 ) break; 229 } 230 return end(); 231 } 232 const_iterator find( const Key &key ) const { 233 return const_iterator( const_cast< ErasableScopedMap< Key, Value >* >(this)->find( key ) ); 234 } 235 236 /// Finds the given key in the outermost scope inside the given scope where it occurs 237 iterator findNext( const_iterator &it, const Key &key ) { 238 if ( it.i == 0 ) return end(); 239 for ( size_type i = it.i - 1; ; --i ) { 240 typename Scope::iterator val = scopes[i].find( key ); 241 if ( val != scopes[i].end() ) { 242 return val->second == erased ? end() : iterator( *this, val, i ); 243 } 244 if ( i == 0 ) break; 245 } 246 return end(); 247 } 248 const_iterator findNext( const_iterator &it, const Key &key ) const { 249 return const_iterator( const_cast< ErasableScopedMap< Key, Value >* >(this)->findNext( it, key ) ); 250 } 251 252 /// Inserts the given key-value pair into the outermost scope 253 std::pair< iterator, bool > insert( const value_type &value ) { 254 std::pair< typename Scope::iterator, bool > res = scopes.back().insert( value ); 255 return std::make_pair( iterator(*this, res.first, scopes.size()-1), res.second ); 256 } 257 std::pair< iterator, bool > insert( const Key &key, const Value &value ) { return insert( std::make_pair( key, value ) ); } 258 259 /// Marks the given element as erased from this scope inward; returns 1 for erased an element, 0 otherwise 260 size_type erase( const Key &key ) { 261 typename Scope::iterator val = scopes.back().find( key ); 262 if ( val != scopes.back().end() ) { 263 val->second = erased; 264 return 1; 265 } else { 266 scopes.back().insert( val, std::make_pair( key, erased ) ); 267 return 0; 268 } 269 } 270 271 Value& operator[] ( const Key &key ) { 272 iterator slot = find( key ); 273 if ( slot != end() ) return slot->second; 274 return insert( key, Value() ).first->second; 275 } 276 }; 105 if ( i == 0 ) break; 106 } 107 return end(); 108 } 109 const_iterator findNext( const_iterator &it, const Key &key ) const { 110 return const_iterator( const_cast< ErasableScopedMap< Key, Value >* >(this)->findNext( it, key ) ); 111 } 112 113 /// Inserts the given key-value pair into the outermost scope 114 std::pair< iterator, bool > insert( const value_type &value ) { 115 std::pair< typename Scope::iterator, bool > res = scopes.back().insert( value ); 116 return std::make_pair( iterator(*this, res.first, scopes.size()-1), res.second ); 117 } 118 std::pair< iterator, bool > insert( const Key &key, const Value &value ) { return insert( std::make_pair( key, value ) ); } 119 120 /// Marks the given element as erased from this scope inward; returns 1 for erased an element, 0 otherwise 121 size_type erase( const Key &key ) { 122 typename Scope::iterator val = scopes.back().find( key ); 123 if ( val != scopes.back().end() ) { 124 val->second = erased; 125 return 1; 126 } else { 127 scopes.back().insert( val, std::make_pair( key, erased ) ); 128 return 0; 129 } 130 } 131 132 Value& operator[] ( const Key &key ) { 133 iterator slot = find( key ); 134 if ( slot != end() ) return slot->second; 135 return insert( key, Value() ).first->second; 136 } 137 }; 138 139 template<typename Key, typename Value> 140 class ErasableScopedMap<Key, Value>::iterator : 141 public std::iterator< std::bidirectional_iterator_tag, value_type > { 142 friend class ErasableScopedMap; 143 typedef typename std::map< Key, Value >::iterator wrapped_iterator; 144 typedef typename std::vector< std::map< Key, Value > > scope_list; 145 typedef typename scope_list::size_type size_type; 146 147 /// Checks if this iterator points to a valid item 148 bool is_valid() const { 149 return it != map->scopes[i].end() && it->second != map->erased; 150 } 151 152 /// Increments on invalid 153 iterator& next_valid() { 154 if ( ! is_valid() ) { ++(*this); } 155 return *this; 156 } 157 158 /// Decrements on invalid 159 iterator& prev_valid() { 160 if ( ! is_valid() ) { --(*this); } 161 return *this; 162 } 163 164 iterator(ErasableScopedMap< Key, Value > const &_map, const wrapped_iterator &_it, size_type _i) 165 : map(&_map), it(_it), i(_i) {} 166 167 public: 168 iterator(const iterator &that) : map(that.map), it(that.it), i(that.i) {} 169 iterator& operator= (const iterator &that) { 170 map = that.map; i = that.i; it = that.it; 171 return *this; 172 } 173 174 reference operator* () { return *it; } 175 pointer operator-> () { return it.operator->(); } 176 177 iterator& operator++ () { 178 if ( it == map->scopes[i].end() ) { 179 if ( i == 0 ) return *this; 180 --i; 181 it = map->scopes[i].begin(); 182 } else { 183 ++it; 184 } 185 return next_valid(); 186 } 187 188 iterator& operator++ (int) { iterator tmp = *this; ++(*this); return tmp; } 189 190 iterator& operator-- () { 191 // may fail if this is the begin iterator; allowed by STL spec 192 if ( it == map->scopes[i].begin() ) { 193 ++i; 194 it = map->scopes[i].end(); 195 } 196 --it; 197 return prev_valid(); 198 } 199 iterator& operator-- (int) { iterator tmp = *this; --(*this); return tmp; } 200 201 bool operator== (const iterator &that) { 202 return map == that.map && i == that.i && it == that.it; 203 } 204 bool operator!= (const iterator &that) { return !( *this == that ); } 205 206 private: 207 ErasableScopedMap< Key, Value > const *map; 208 wrapped_iterator it; 209 size_type i; 210 }; 211 212 template<typename Key, typename Value> 213 class ErasableScopedMap<Key, Value>::const_iterator : 214 public std::iterator< std::bidirectional_iterator_tag, value_type > { 215 friend class ErasableScopedMap; 216 typedef typename std::map< Key, Value >::iterator wrapped_iterator; 217 typedef typename std::map< Key, Value >::const_iterator wrapped_const_iterator; 218 typedef typename std::vector< std::map< Key, Value > > scope_list; 219 typedef typename scope_list::size_type size_type; 220 221 /// Checks if this iterator points to a valid item 222 bool is_valid() const { 223 return it != map->scopes[i].end() && it->second != map->erased; 224 } 225 226 /// Increments on invalid 227 const_iterator& next_valid() { 228 if ( ! is_valid() ) { ++(*this); } 229 return *this; 230 } 231 232 /// Decrements on invalid 233 const_iterator& prev_valid() { 234 if ( ! is_valid() ) { --(*this); } 235 return *this; 236 } 237 238 const_iterator(ErasableScopedMap< Key, Value > const &_map, const wrapped_const_iterator &_it, size_type _i) 239 : map(&_map), it(_it), i(_i) {} 240 public: 241 const_iterator(const iterator &that) : map(that.map), it(that.it), i(that.i) {} 242 const_iterator(const const_iterator &that) : map(that.map), it(that.it), i(that.i) {} 243 const_iterator& operator= (const iterator &that) { 244 map = that.map; i = that.i; it = that.it; 245 return *this; 246 } 247 const_iterator& operator= (const const_iterator &that) { 248 map = that.map; i = that.i; it = that.it; 249 return *this; 250 } 251 252 const_reference operator* () { return *it; } 253 const_pointer operator-> () { return it.operator->(); } 254 255 const_iterator& operator++ () { 256 if ( it == map->scopes[i].end() ) { 257 if ( i == 0 ) return *this; 258 --i; 259 it = map->scopes[i].begin(); 260 } else { 261 ++it; 262 } 263 return next_valid(); 264 } 265 const_iterator& operator++ (int) { const_iterator tmp = *this; ++(*this); return tmp; } 266 267 const_iterator& operator-- () { 268 // may fail if this is the begin iterator; allowed by STL spec 269 if ( it == map->scopes[i].begin() ) { 270 ++i; 271 it = map->scopes[i].end(); 272 } 273 --it; 274 return prev_valid(); 275 } 276 const_iterator& operator-- (int) { const_iterator tmp = *this; --(*this); return tmp; } 277 278 bool operator== (const const_iterator &that) { 279 return map == that.map && i == that.i && it == that.it; 280 } 281 bool operator!= (const const_iterator &that) { return !( *this == that ); } 282 283 private: 284 ErasableScopedMap< Key, Value > const *map; 285 wrapped_const_iterator it; 286 size_type i; 287 }; 288 277 289 } // namespace GenPoly 278 290 -
src/GenPoly/GenPoly.cc
r7d9598d8 r2dcd80a 783 783 const ast::FunctionType * function = getFunctionType( expr->func->result ); 784 784 assertf( function, "ApplicationExpr has non-function type: %s", toString( expr->func->result ).c_str() ); 785 TypeVarMap exprTyVars = { ast::TypeD ecl::Data() };785 TypeVarMap exprTyVars = { ast::TypeData() }; 786 786 makeTypeVarMap( function, exprTyVars ); 787 787 return needsBoxing( param, arg, exprTyVars, subst ); … … 793 793 794 794 void addToTypeVarMap( const ast::TypeInstType * type, TypeVarMap & typeVars ) { 795 typeVars.insert( *type, ast::TypeD ecl::Data( type->base ) );795 typeVars.insert( *type, ast::TypeData( type->base ) ); 796 796 } 797 797 -
src/GenPoly/GenPoly.h
r7d9598d8 r2dcd80a 20 20 21 21 #include "ErasableScopedMap.h" // for ErasableScopedMap 22 #include "AST/Decl.hpp" // for TypeDecl::Data22 #include "AST/Decl.hpp" // for AggregateDecl 23 23 #include "AST/Fwd.hpp" // for ApplicationExpr, BaseInstType, Func... 24 #include "AST/Type.hpp" // for TypeInstType::TypeEnvKey25 24 #include "SymTab/Mangler.h" // for Mangler 26 25 #include "SynTree/Declaration.h" // for TypeDecl::Data, AggregateDecl, Type... 27 26 #include "SynTree/SynTree.h" // for Visitor Nodes 28 27 28 namespace ast { 29 struct TypeEnvKey; 30 } 31 29 32 namespace GenPoly { 30 33 31 34 typedef ErasableScopedMap< std::string, TypeDecl::Data > TyVarMap; 32 using TypeVarMap = ErasableScopedMap< ast::Type InstType::TypeEnvKey, ast::TypeDecl::Data >;35 using TypeVarMap = ErasableScopedMap< ast::TypeEnvKey, ast::TypeData >; 33 36 34 37 /// Replaces a TypeInstType by its referrent in the environment, if applicable
Note:
See TracChangeset
for help on using the changeset viewer.