LCOV - code coverage report
Current view: top level - include/llvm/ADT - StringMap.h (source / functions) Hit Total Coverage
Test: llvm-toolchain.info Lines: 830 1000 83.0 %
Date: 2018-10-20 13:21:21 Functions: 687 2207 31.1 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : //===- StringMap.h - String Hash table map interface ------------*- C++ -*-===//
       2             : //
       3             : //                     The LLVM Compiler Infrastructure
       4             : //
       5             : // This file is distributed under the University of Illinois Open Source
       6             : // License. See LICENSE.TXT for details.
       7             : //
       8             : //===----------------------------------------------------------------------===//
       9             : //
      10             : // This file defines the StringMap class.
      11             : //
      12             : //===----------------------------------------------------------------------===//
      13             : 
      14             : #ifndef LLVM_ADT_STRINGMAP_H
      15             : #define LLVM_ADT_STRINGMAP_H
      16             : 
      17             : #include "llvm/ADT/StringRef.h"
      18             : #include "llvm/ADT/iterator.h"
      19             : #include "llvm/ADT/iterator_range.h"
      20             : #include "llvm/Support/Allocator.h"
      21             : #include "llvm/Support/PointerLikeTypeTraits.h"
      22             : #include "llvm/Support/ErrorHandling.h"
      23             : #include <algorithm>
      24             : #include <cassert>
      25             : #include <cstdint>
      26             : #include <cstdlib>
      27             : #include <cstring>
      28             : #include <initializer_list>
      29             : #include <iterator>
      30             : #include <utility>
      31             : 
      32             : namespace llvm {
      33             : 
      34             : template<typename ValueTy> class StringMapConstIterator;
      35             : template<typename ValueTy> class StringMapIterator;
      36             : template<typename ValueTy> class StringMapKeyIterator;
      37             : 
      38             : /// StringMapEntryBase - Shared base class of StringMapEntry instances.
      39             : class StringMapEntryBase {
      40             :   size_t StrLen;
      41             : 
      42             : public:
      43   181809536 :   explicit StringMapEntryBase(size_t Len) : StrLen(Len) {}
      44             : 
      45           0 :   size_t getKeyLength() const { return StrLen; }
      46             : };
      47             : 
      48             : /// StringMapImpl - This is the base class of StringMap that is shared among
      49             : /// all of its instantiations.
      50             : class StringMapImpl {
      51             : protected:
      52             :   // Array of NumBuckets pointers to entries, null pointers are holes.
      53             :   // TheTable[NumBuckets] contains a sentinel value for easy iteration. Followed
      54             :   // by an array of the actual hash values as unsigned integers.
      55             :   StringMapEntryBase **TheTable = nullptr;
      56             :   unsigned NumBuckets = 0;
      57             :   unsigned NumItems = 0;
      58             :   unsigned NumTombstones = 0;
      59             :   unsigned ItemSize;
      60             : 
      61             : protected:
      62             :   explicit StringMapImpl(unsigned itemSize)
      63    12009928 :       : ItemSize(itemSize) {}
      64             :   StringMapImpl(StringMapImpl &&RHS)
      65      191849 :       : TheTable(RHS.TheTable), NumBuckets(RHS.NumBuckets),
      66      191849 :         NumItems(RHS.NumItems), NumTombstones(RHS.NumTombstones),
      67      290557 :         ItemSize(RHS.ItemSize) {
      68      142495 :     RHS.TheTable = nullptr;
      69      142495 :     RHS.NumBuckets = 0;
      70      142495 :     RHS.NumItems = 0;
      71      142495 :     RHS.NumTombstones = 0;
      72             :   }
      73             : 
      74             :   StringMapImpl(unsigned InitSize, unsigned ItemSize);
      75             :   unsigned RehashTable(unsigned BucketNo = 0);
      76             : 
      77             :   /// LookupBucketFor - Look up the bucket that the specified string should end
      78             :   /// up in.  If it already exists as a key in the map, the Item pointer for the
      79             :   /// specified bucket will be non-null.  Otherwise, it will be null.  In either
      80             :   /// case, the FullHashValue field of the bucket will be set to the hash value
      81             :   /// of the string.
      82             :   unsigned LookupBucketFor(StringRef Key);
      83             : 
      84             :   /// FindKey - Look up the bucket that contains the specified key. If it exists
      85             :   /// in the map, return the bucket number of the key.  Otherwise return -1.
      86             :   /// This does not modify the map.
      87             :   int FindKey(StringRef Key) const;
      88             : 
      89             :   /// RemoveKey - Remove the specified StringMapEntry from the table, but do not
      90             :   /// delete it.  This aborts if the value isn't in the table.
      91             :   void RemoveKey(StringMapEntryBase *V);
      92             : 
      93             :   /// RemoveKey - Remove the StringMapEntry for the specified key from the
      94             :   /// table, returning it.  If the key is not in the table, this returns null.
      95             :   StringMapEntryBase *RemoveKey(StringRef Key);
      96             : 
      97             :   /// Allocate the table with the specified number of buckets and otherwise
      98             :   /// setup the map as empty.
      99             :   void init(unsigned Size);
     100             : 
     101             : public:
     102             :   static StringMapEntryBase *getTombstoneVal() {
     103             :     uintptr_t Val = static_cast<uintptr_t>(-1);
     104             :     Val <<= PointerLikeTypeTraits<StringMapEntryBase *>::NumLowBitsAvailable;
     105             :     return reinterpret_cast<StringMapEntryBase *>(Val);
     106             :   }
     107             : 
     108           0 :   unsigned getNumBuckets() const { return NumBuckets; }
     109           0 :   unsigned getNumItems() const { return NumItems; }
     110             : 
     111           8 :   bool empty() const { return NumItems == 0; }
     112           0 :   unsigned size() const { return NumItems; }
     113             : 
     114             :   void swap(StringMapImpl &Other) {
     115             :     std::swap(TheTable, Other.TheTable);
     116             :     std::swap(NumBuckets, Other.NumBuckets);
     117             :     std::swap(NumItems, Other.NumItems);
     118             :     std::swap(NumTombstones, Other.NumTombstones);
     119             :   }
     120             : };
     121             : 
     122             : /// StringMapEntry - This is used to represent one value that is inserted into
     123             : /// a StringMap.  It contains the Value itself and the key: the string length
     124             : /// and data.
     125             : template<typename ValueTy>
     126      167985 : class StringMapEntry : public StringMapEntryBase {
     127             : public:
     128             :   ValueTy second;
     129             : 
     130     6496959 :   explicit StringMapEntry(size_t strLen)
     131     6243625 :     : StringMapEntryBase(strLen), second() {}
     132             :   template <typename... InitTy>
     133   175238168 :   StringMapEntry(size_t strLen, InitTy &&... InitVals)
     134   175312395 :       : StringMapEntryBase(strLen), second(std::forward<InitTy>(InitVals)...) {}
     135           0 :   StringMapEntry(StringMapEntry &E) = delete;
     136           0 : 
     137           0 :   StringRef getKey() const {
     138   201976860 :     return StringRef(getKeyData(), getKeyLength());
     139           0 :   }
     140           0 : 
     141       34704 :   const ValueTy &getValue() const { return second; }
     142     1203533 :   ValueTy &getValue() { return second; }
     143             : 
     144     2383191 :   void setValue(const ValueTy &V) { second = V; }
     145             : 
     146             :   /// getKeyData - Return the start of the string data that is the key for this
     147             :   /// value.  The string data is always stored immediately after the
     148           3 :   /// StringMapEntry object.
     149  1176639147 :   const char *getKeyData() const {return reinterpret_cast<const char*>(this+1);}
     150             : 
     151    31990155 :   StringRef first() const { return StringRef(getKeyData(), getKeyLength()); }
     152             : 
     153             :   /// Create a StringMapEntry for the specified key construct the value using
     154             :   /// \p InitiVals.
     155           1 :   template <typename AllocatorTy, typename... InitTy>
     156   181809225 :   static StringMapEntry *Create(StringRef Key, AllocatorTy &Allocator,
     157           2 :                                 InitTy &&... InitVals) {
     158             :     size_t KeyLength = Key.size();
     159             : 
     160             :     // Allocate a new item with space for the string at the end and a null
     161             :     // terminator.
     162   181809225 :     size_t AllocSize = sizeof(StringMapEntry) + KeyLength + 1;
     163             :     size_t Alignment = alignof(StringMapEntry);
     164             : 
     165             :     StringMapEntry *NewItem =
     166   181805635 :       static_cast<StringMapEntry*>(Allocator.Allocate(AllocSize,Alignment));
     167             :     assert(NewItem && "Unhandled out-of-memory");
     168           0 : 
     169             :     // Construct the value.
     170           0 :     new (NewItem) StringMapEntry(KeyLength, std::forward<InitTy>(InitVals)...);
     171             : 
     172             :     // Copy the string information.
     173             :     char *StrBuffer = const_cast<char*>(NewItem->getKeyData());
     174   181809164 :     if (KeyLength > 0)
     175   181808759 :       memcpy(StrBuffer, Key.data(), KeyLength);
     176   181809164 :     StrBuffer[KeyLength] = 0;  // Null terminate for convenience of clients.
     177   181809164 :     return NewItem;
     178             :   }
     179    19064717 : 
     180           0 :   /// Create - Create a StringMapEntry with normal malloc/free.
     181           0 :   template <typename... InitType>
     182           0 :   static StringMapEntry *Create(StringRef Key, InitType &&... InitVal) {
     183           0 :     MallocAllocator A;
     184     2370889 :     return Create(Key, A, std::forward<InitType>(InitVal)...);
     185    19064717 :   }
     186             : 
     187             :   static StringMapEntry *Create(StringRef Key) {
     188     2370889 :     return Create(Key, ValueTy());
     189    19064715 :   }
     190             : 
     191           0 :   /// GetStringMapEntryFromKeyData - Given key data that is known to be embedded
     192             :   /// into a StringMapEntry, return the StringMapEntry itself.
     193           0 :   static StringMapEntry &GetStringMapEntryFromKeyData(const char *KeyData) {
     194             :     char *Ptr = const_cast<char*>(KeyData) - sizeof(StringMapEntry<ValueTy>);
     195             :     return *reinterpret_cast<StringMapEntry*>(Ptr);
     196             :   }
     197    19064717 : 
     198    19064467 :   /// Destroy - Destroy this StringMapEntry, releasing memory back to the
     199    19064717 :   /// specified allocator.
     200    19064717 :   template<typename AllocatorTy>
     201           0 :   void Destroy(AllocatorTy &Allocator) {
     202      489888 :     // Free memory referenced by the item.
     203           0 :     size_t AllocSize = sizeof(StringMapEntry) + getKeyLength() + 1;
     204           0 :     this->~StringMapEntry();
     205           0 :     Allocator.Deallocate(static_cast<void *>(this), AllocSize);
     206           0 :   }
     207           0 : 
     208      489888 :   /// Destroy this object, releasing memory back to the malloc allocator.
     209             :   void Destroy() {
     210             :     MallocAllocator A;
     211             :     Destroy(A);
     212      489888 :   }
     213           0 : };
     214           0 : 
     215             : /// StringMap - This is an unconventional map that is specialized for handling
     216             : /// keys that are "strings", which are basically ranges of bytes. This does some
     217             : /// funky memory allocation and hashing things to make it extremely efficient,
     218           0 : /// storing the string data *after* the value in the map.
     219           0 : template<typename ValueTy, typename AllocatorTy = MallocAllocator>
     220      489888 : class StringMap : public StringMapImpl {
     221      489663 :   AllocatorTy Allocator;
     222      489888 : 
     223      489888 : public:
     224           0 :   using MapEntryTy = StringMapEntry<ValueTy>;
     225     6768513 : 
     226     5601365 :   StringMap() : StringMapImpl(static_cast<unsigned>(sizeof(MapEntryTy))) {}
     227           0 : 
     228      633715 :   explicit StringMap(unsigned InitialSize)
     229      633715 :     : StringMapImpl(InitialSize, static_cast<unsigned>(sizeof(MapEntryTy))) {}
     230           0 : 
     231     6822544 :   explicit StringMap(AllocatorTy A)
     232       54031 :     : StringMapImpl(static_cast<unsigned>(sizeof(MapEntryTy))), Allocator(A) {}
     233             : 
     234             :   StringMap(unsigned InitialSize, AllocatorTy A)
     235     6768513 :     : StringMapImpl(InitialSize, static_cast<unsigned>(sizeof(MapEntryTy))),
     236           0 :       Allocator(A) {}
     237           0 : 
     238       37292 :   StringMap(std::initializer_list<std::pair<StringRef, ValueTy>> List)
     239        1584 :       : StringMapImpl(List.size(), static_cast<unsigned>(sizeof(MapEntryTy))) {
     240        6759 :     for (const auto &P : List) {
     241        5175 :       insert(P);
     242           0 :     }
     243     6770098 :   }
     244     6794235 : 
     245     6768520 :   StringMap(StringMap &&RHS)
     246     6768514 :       : StringMapImpl(std::move(RHS)), Allocator(std::move(RHS.Allocator)) {}
     247           0 : 
     248       75397 :   StringMap(const StringMap &RHS) :
     249           0 :     StringMapImpl(static_cast<unsigned>(sizeof(MapEntryTy))),
     250       28570 :     Allocator(RHS.Allocator) {
     251         134 :     if (RHS.empty())
     252           0 :       return;
     253           0 : 
     254       75263 :     // Allocate TheTable of the same size as RHS's TheTable, and set the
     255      134905 :     // sentinel appropriately (and NumBuckets).
     256      173575 :     init(RHS.NumBuckets);
     257         111 :     unsigned *HashTable = (unsigned *)(TheTable + NumBuckets + 1),
     258       75374 :              *RHSHashTable = (unsigned *)(RHS.TheTable + NumBuckets + 1);
     259           0 : 
     260         113 :     NumItems = RHS.NumItems;
     261         111 :     NumTombstones = RHS.NumTombstones;
     262        1928 :     for (unsigned I = 0, E = NumBuckets; I != E; ++I) {
     263        1754 :       StringMapEntryBase *Bucket = RHS.TheTable[I];
     264        1752 :       if (!Bucket || Bucket == getTombstoneVal()) {
     265        1553 :         TheTable[I] = Bucket;
     266       76892 :         continue;
     267       75263 :       }
     268       75341 : 
     269       75540 :       TheTable[I] = MapEntryTy::Create(
     270           2 :           static_cast<MapEntryTy *>(Bucket)->getKey(), Allocator,
     271     5604168 :           static_cast<MapEntryTy *>(Bucket)->getValue());
     272      118000 :       HashTable[I] = RHSHashTable[I];
     273           2 :     }
     274         110 : 
     275         108 :     // Note that here we've copied everything from the RHS into this object,
     276          98 :     // tombstones included. We could, instead, have re-probed for each key to
     277     5604198 :     // instantiate this new object without any tombstone buckets. The
     278          96 :     // assumption here is that items are rarely deleted from most StringMaps,
     279          66 :     // and so tombstones are rare, so the cost of re-probing for all inputs is
     280        3004 :     // not worthwhile.
     281     5607168 :   }
     282        2938 : 
     283        1497 :   StringMap &operator=(StringMap RHS) {
     284     1208226 :     StringMapImpl::swap(RHS);
     285          10 :     std::swap(Allocator, RHS.Allocator);
     286      335088 :     return *this;
     287      253551 :   }
     288         160 : 
     289    11723268 :   ~StringMap() {
     290     5606698 :     // Delete all the elements in the map, but don't reset the elements
     291     5604169 :     // to default values.  This is a copy of clear(), but avoids unnecessary
     292     5604170 :     // work not required in the destructor.
     293     6118379 :     if (!empty()) {
     294   291884105 :       for (unsigned I = 0, E = NumBuckets; I != E; ++I) {
     295   290977569 :         StringMapEntryBase *Bucket = TheTable[I];
     296   291038518 :         if (Bucket && Bucket != getTombstoneVal()) {
     297      548972 :           static_cast<MapEntryTy*>(Bucket)->Destroy(Allocator);
     298      532185 :         }
     299      473162 :       }
     300          16 :     }
     301     7129090 :     free(TheTable);
     302     6119030 :   }
     303         106 : 
     304   149257707 :   AllocatorTy &getAllocator() { return Allocator; }
     305      952370 :   const AllocatorTy &getAllocator() const { return Allocator; }
     306      813267 : 
     307     1088524 :   using key_type = const char*;
     308     1217925 :   using mapped_type = ValueTy;
     309       70167 :   using value_type = StringMapEntry<ValueTy>;
     310        2056 :   using size_type = size_t;
     311       21902 : 
     312      178950 :   using const_iterator = StringMapConstIterator<ValueTy>;
     313     1476460 :   using iterator = StringMapIterator<ValueTy>;
     314     1120237 : 
     315      490597 :   iterator begin() {
     316          18 :     return iterator(TheTable, NumBuckets == 0);
     317      172013 :   }
     318      235184 :   iterator end() {
     319     1735500 :     return iterator(TheTable+NumBuckets, true);
     320      383007 :   }
     321      181563 :   const_iterator begin() const {
     322      129427 :     return const_iterator(TheTable, NumBuckets == 0);
     323        4675 :   }
     324        2603 :   const_iterator end() const {
     325     3822637 :     return const_iterator(TheTable+NumBuckets, true);
     326      260377 :   }
     327      563861 : 
     328      560641 :   iterator_range<StringMapKeyIterator<ValueTy>> keys() const {
     329      479455 :     return make_range(StringMapKeyIterator<ValueTy>(begin()),
     330        2652 :                       StringMapKeyIterator<ValueTy>(end()));
     331       54432 :   }
     332       97777 : 
     333     1131935 :   iterator find(StringRef Key) {
     334     1336033 :     int Bucket = FindKey(Key);
     335     1323379 :     if (Bucket == -1) return end();
     336      930760 :     return iterator(TheTable+Bucket, true);
     337       72016 :   }
     338        6609 : 
     339      683679 :   const_iterator find(StringRef Key) const {
     340     1359027 :     int Bucket = FindKey(Key);
     341     1821607 :     if (Bucket == -1) return end();
     342     1590344 :     return const_iterator(TheTable+Bucket, true);
     343       23916 :   }
     344       49305 : 
     345       36914 :   /// lookup - Return the entry for the specified key, or a default
     346        8024 :   /// constructed value if no such entry exists.
     347     1820171 :   ValueTy lookup(StringRef Key) const {
     348      272441 :     const_iterator it = find(Key);
     349      581745 :     if (it != end())
     350      566660 :       return it->second;
     351     1940283 :     return ValueTy();
     352    66715755 :   }
     353    66267824 : 
     354    66136814 :   /// Lookup the ValueTy for the \p Key, or create a default constructed value
     355     1022392 :   /// if the key is not in the map.
     356    31734387 :   ValueTy &operator[](StringRef Key) { return try_emplace(Key).first->second; }
     357      109057 : 
     358      111139 :   /// count - Return 1 if the element is in the map, 0 otherwise.
     359     2186574 :   size_type count(StringRef Key) const {
     360     2039692 :     return find(Key) == end() ? 0 : 1;
     361      424385 :   }
     362      422385 : 
     363       30193 :   /// insert - Insert the specified key/value pair into the map.  If the key
     364      259776 :   /// already exists in the map, return false and ignore the request, otherwise
     365     3202167 :   /// insert it and return true.
     366    63700508 :   bool insert(MapEntryTy *KeyValue) {
     367    63340786 :     unsigned BucketNo = LookupBucketFor(KeyValue->getKey());
     368    63340506 :     StringMapEntryBase *&Bucket = TheTable[BucketNo];
     369     2649344 :     if (Bucket && Bucket != getTombstoneVal())
     370      317074 :       return false;  // Already exists in map.
     371      604177 : 
     372     2157387 :     if (Bucket == getTombstoneVal())
     373      513643 :       --NumTombstones;
     374     2756408 :     Bucket = KeyValue;
     375     5360166 :     ++NumItems;
     376    10087428 :     assert(NumItems + NumTombstones <= NumBuckets);
     377     9748950 : 
     378    10361050 :     RehashTable();
     379     3399080 :     return true;
     380     5702223 :   }
     381    10340235 : 
     382    10624689 :   /// insert - Inserts the specified key/value pair into the map if the key
     383     6358613 :   /// isn't already in the map. The bool component of the returned pair is true
     384      678193 :   /// if and only if the insertion takes place, and the iterator component of
     385      518660 :   /// the pair points to the element with key equivalent to the key of the pair.
     386      514059 :   std::pair<iterator, bool> insert(std::pair<StringRef, ValueTy> KV) {
     387  1135035483 :     return try_emplace(KV.first, std::move(KV.second));
     388     7852186 :   }
     389     7311812 : 
     390    10430202 :   /// Emplace a new element for the specified key into the map if the key isn't
     391     2321670 :   /// already in the map. The bool component of the returned pair is true
     392     1521529 :   /// if and only if the insertion takes place, and the iterator component of
     393       47614 :   /// the pair points to the element with key equivalent to the key of the pair.
     394      122073 :   template <typename... ArgsTy>
     395  1159946679 :   std::pair<iterator, bool> try_emplace(StringRef Key, ArgsTy &&... Args) {
     396  1159935066 :     unsigned BucketNo = LookupBucketFor(Key);
     397  1160017437 :     StringMapEntryBase *&Bucket = TheTable[BucketNo];
     398  1159648542 :     if (Bucket && Bucket != getTombstoneVal())
     399      297492 :       return std::make_pair(iterator(TheTable + BucketNo, false),
     400       12254 :                             false); // Already exists in map.
     401      305026 : 
     402   342974435 :     if (Bucket == getTombstoneVal())
     403     1123034 :       --NumTombstones;
     404   343375879 :     Bucket = MapEntryTy::Create(Key, Allocator, std::forward<ArgsTy>(Args)...);
     405   346544072 :     ++NumItems;
     406      662695 :     assert(NumItems + NumTombstones <= NumBuckets);
     407      219221 : 
     408   344439979 :     BucketNo = RehashTable(BucketNo);
     409   346137400 :     return std::make_pair(iterator(TheTable + BucketNo, false), true);
     410     4257982 :   }
     411    61421390 : 
     412      322701 :   // clear - Empties out the StringMap
     413     1578210 :   void clear() {
     414     1330919 :     if (empty()) return;
     415     4797822 : 
     416     4876645 :     // Zap all values, resetting the keys back to non-present (not tombstone),
     417     5279775 :     // which is safe because we're removing all elements.
     418     7261034 :     for (unsigned I = 0, E = NumBuckets; I != E; ++I) {
     419     9989212 :       StringMapEntryBase *&Bucket = TheTable[I];
     420     9786149 :       if (Bucket && Bucket != getTombstoneVal()) {
     421     3198643 :         static_cast<MapEntryTy*>(Bucket)->Destroy(Allocator);
     422     1741224 :       }
     423     1041042 :       Bucket = nullptr;
     424     1001901 :     }
     425     1122206 : 
     426      291036 :     NumItems = 0;
     427     1261780 :     NumTombstones = 0;
     428     4072258 :   }
     429     2495973 : 
     430     1522469 :   /// remove - Remove the specified key/value pair from the map, but do not
     431    35127735 :   /// erase it.  This aborts if the key is not in the map.
     432    36080865 :   void remove(MapEntryTy *KeyValue) {
     433   139514786 :     RemoveKey(KeyValue);
     434   112113666 :   }
     435   100108932 : 
     436     5675013 :   void erase(iterator I) {
     437     4241008 :     MapEntryTy &V = *I;
     438     4216073 :     remove(&V);
     439     2914239 :     V.Destroy(Allocator);
     440     2636238 :   }
     441    31998670 : 
     442    31990671 :   bool erase(StringRef Key) {
     443    32868829 :     iterator I = find(Key);
     444    10921201 :     if (I == end()) return false;
     445     3897272 :     erase(I);
     446     2574944 :     return true;
     447     1517867 :   }
     448     5421666 : };
     449    35984785 : 
     450    35875129 : template <typename DerivedTy, typename ValueTy>
     451    37353976 : class StringMapIterBase
     452    12245192 :     : public iterator_facade_base<DerivedTy, std::forward_iterator_tag,
     453     4042892 :                                   ValueTy> {
     454     6925144 : protected:
     455     6298766 :   StringMapEntryBase **Ptr = nullptr;
     456     8050426 : 
     457     6244580 : public:
     458     4575973 :   StringMapIterBase() = default;
     459     1862055 : 
     460     1258060 :   explicit StringMapIterBase(StringMapEntryBase **Bucket,
     461    39878375 :                              bool NoAdvance = false)
     462    32080519 :       : Ptr(Bucket) {
     463    35997229 :     if (!NoAdvance) AdvancePastEmptyBuckets();
     464     7904005 :   }
     465     3957048 : 
     466     1099304 :   DerivedTy &operator=(const DerivedTy &Other) {
     467      591829 :     Ptr = Other.Ptr;
     468      221509 :     return static_cast<DerivedTy &>(*this);
     469    10752635 :   }
     470    12338952 : 
     471    11463351 :   bool operator==(const DerivedTy &RHS) const { return Ptr == RHS.Ptr; }
     472    10671824 : 
     473   135056990 :   DerivedTy &operator++() { // Preincrement
     474   116780353 :     ++Ptr;
     475      544242 :     AdvancePastEmptyBuckets();
     476     4480089 :     return static_cast<DerivedTy &>(*this);
     477      555007 :   }
     478     4068699 : 
     479     4483151 :   DerivedTy operator++(int) { // Post-increment
     480     2765052 :     DerivedTy Tmp(Ptr);
     481   137246254 :     ++*this;
     482   142136720 :     return Tmp;
     483   139882424 :   }
     484   135475781 : 
     485     5996444 : private:
     486    36036526 :   void AdvancePastEmptyBuckets() {
     487  1397759075 :     while (*Ptr == nullptr || *Ptr == StringMapImpl::getTombstoneVal())
     488   136895446 :       ++Ptr;
     489   100498593 :   }
     490   117713469 : };
     491   115636914 : 
     492     5962043 : template <typename ValueTy>
     493      413774 : class StringMapConstIterator
     494    20543993 :     : public StringMapIterBase<StringMapConstIterator<ValueTy>,
     495    19803729 :                                const StringMapEntry<ValueTy>> {
     496     2486894 :   using base = StringMapIterBase<StringMapConstIterator<ValueTy>,
     497   136553199 :                                  const StringMapEntry<ValueTy>>;
     498   137841022 : 
     499   296807599 : public:
     500   264609904 :   StringMapConstIterator() = default;
     501    27714629 :   explicit StringMapConstIterator(StringMapEntryBase **Bucket,
     502     3372273 :                                   bool NoAdvance = false)
     503     3369624 :       : base(Bucket, NoAdvance) {}
     504    24169661 : 
     505     4280326 :   const StringMapEntry<ValueTy> &operator*() const {
     506    21160461 :     return *static_cast<const StringMapEntry<ValueTy> *>(*this->Ptr);
     507    20738298 :   }
     508     1114065 : };
     509    24768202 : 
     510    41323720 : template <typename ValueTy>
     511    43659898 : class StringMapIterator : public StringMapIterBase<StringMapIterator<ValueTy>,
     512    23890635 :                                                    StringMapEntry<ValueTy>> {
     513     3391918 :   using base =
     514     9666418 :       StringMapIterBase<StringMapIterator<ValueTy>, StringMapEntry<ValueTy>>;
     515     1392850 : 
     516    25083940 : public:
     517     3320725 :   StringMapIterator() = default;
     518    26562113 :   explicit StringMapIterator(StringMapEntryBase **Bucket,
     519    23779655 :                              bool NoAdvance = false)
     520     4402044 :       : base(Bucket, NoAdvance) {}
     521     2448841 : 
     522    26588066 :   StringMapEntry<ValueTy> &operator*() const {
     523   770495104 :     return *static_cast<StringMapEntry<ValueTy> *>(*this->Ptr);
     524      188089 :   }
     525    23454009 : 
     526    23566592 :   operator StringMapConstIterator<ValueTy>() const {
     527    25865672 :     return StringMapConstIterator<ValueTy>(this->Ptr, true);
     528    23303731 :   }
     529     2372673 : };
     530    31895801 : 
     531   139091108 : template <typename ValueTy>
     532    23296440 : class StringMapKeyIterator
     533     2396757 :     : public iterator_adaptor_base<StringMapKeyIterator<ValueTy>,
     534    25665218 :                                    StringMapConstIterator<ValueTy>,
     535    27075340 :                                    std::forward_iterator_tag, StringRef> {
     536     2751106 :   using base = iterator_adaptor_base<StringMapKeyIterator<ValueTy>,
     537     2780842 :                                      StringMapConstIterator<ValueTy>,
     538    26050784 :                                      std::forward_iterator_tag, StringRef>;
     539    24033563 : 
     540      179521 : public:
     541      529587 :   StringMapKeyIterator() = default;
     542     1147576 :   explicit StringMapKeyIterator(StringMapConstIterator<ValueTy> Iter)
     543      626530 :       : base(std::move(Iter)) {}
     544     1250879 : 
     545      763511 :   StringRef &operator*() {
     546      125133 :     Key = this->wrapped()->getKey();
     547      202669 :     return Key;
     548     1859253 :   }
     549     1468944 : 
     550     1426471 : private:
     551     1777952 :   StringRef Key;
     552    14896251 : };
     553     4031532 : 
     554     4369523 : } // end namespace llvm
     555    10013269 : 
     556     5113341 : #endif // LLVM_ADT_STRINGMAP_H

Generated by: LCOV version 1.13