diff options
Diffstat (limited to 'include/clang/Basic')
-rw-r--r-- | include/clang/Basic/IdentifierTable.h | 46 | ||||
-rw-r--r-- | include/clang/Basic/OnDiskHashTable.h | 64 |
2 files changed, 110 insertions, 0 deletions
diff --git a/include/clang/Basic/IdentifierTable.h b/include/clang/Basic/IdentifierTable.h index 2cb68b39be..66c5deea54 100644 --- a/include/clang/Basic/IdentifierTable.h +++ b/include/clang/Basic/IdentifierTable.h @@ -254,6 +254,35 @@ private: } }; +/// \brief An iterator that walks over all of the known identifiers +/// in the lookup table. +/// +/// Since this iterator uses an abstract interface via virtual +/// functions, it uses an object-oriented interface rather than the +/// more standard C++ STL iterator interface. In this OO-style +/// iteration, the single function \c Next() provides dereference, +/// advance, and end-of-sequence checking in a single +/// operation. Subclasses of this iterator type will provide the +/// actual functionality. +class IdentifierIterator { +private: + IdentifierIterator(const IdentifierIterator&); // Do not implement + IdentifierIterator &operator=(const IdentifierIterator&); // Do not implement + +protected: + IdentifierIterator() { } + +public: + virtual ~IdentifierIterator(); + + /// \brief Retrieve the next string in the identifier table and + /// advances the iterator for the following string. + /// + /// \returns The next string in the identifier table. If there is + /// no such string, returns an empty \c llvm::StringRef. + virtual llvm::StringRef Next() = 0; +}; + /// IdentifierInfoLookup - An abstract class used by IdentifierTable that /// provides an interface for performing lookups from strings /// (const char *) to IdentiferInfo objects. @@ -266,6 +295,18 @@ public: /// of a reference. If the pointer is NULL then the IdentifierInfo cannot /// be found. virtual IdentifierInfo* get(llvm::StringRef Name) = 0; + + /// \brief Retrieve an iterator into the set of all identifiers + /// known to this identifier lookup source. + /// + /// This routine provides access to all of the identifiers known to + /// the identifier lookup, allowing access to the contents of the + /// identifiers without introducing the overhead of constructing + /// IdentifierInfo objects for each. + /// + /// \returns A new iterator into the set of known identifiers. The + /// caller is responsible for deleting this iterator. + virtual IdentifierIterator *getIdentifiers() const; }; /// \brief An abstract class used to resolve numerical identifier @@ -304,6 +345,11 @@ public: ExternalLookup = IILookup; } + /// \brief Retrieve the external identifier lookup object, if any. + IdentifierInfoLookup *getExternalIdentifierLookup() const { + return ExternalLookup; + } + llvm::BumpPtrAllocator& getAllocator() { return HashTable.getAllocator(); } diff --git a/include/clang/Basic/OnDiskHashTable.h b/include/clang/Basic/OnDiskHashTable.h index 8909e47146..30bf39ef43 100644 --- a/include/clang/Basic/OnDiskHashTable.h +++ b/include/clang/Basic/OnDiskHashTable.h @@ -334,6 +334,70 @@ public: iterator end() const { return iterator(); } + /// \brief Iterates over all of the keys in the table. + class key_iterator { + const unsigned char* Ptr; + unsigned NumItemsInBucketLeft; + unsigned NumEntriesLeft; + Info *InfoObj; + public: + typedef external_key_type value_type; + + key_iterator(const unsigned char* const Ptr, unsigned NumEntries, + Info *InfoObj) + : Ptr(Ptr), NumItemsInBucketLeft(0), NumEntriesLeft(NumEntries), + InfoObj(InfoObj) { } + key_iterator() + : Ptr(0), NumItemsInBucketLeft(0), NumEntriesLeft(0), InfoObj(0) { } + + friend bool operator==(const key_iterator &X, const key_iterator &Y) { + return X.NumEntriesLeft == Y.NumEntriesLeft; + } + friend bool operator!=(const key_iterator& X, const key_iterator &Y) { + return X.NumEntriesLeft != Y.NumEntriesLeft; + } + + key_iterator& operator++() { // Preincrement + if (!NumItemsInBucketLeft) { + // 'Items' starts with a 16-bit unsigned integer representing the + // number of items in this bucket. + NumItemsInBucketLeft = io::ReadUnalignedLE16(Ptr); + } + Ptr += 4; // Skip the hash. + // Determine the length of the key and the data. + const std::pair<unsigned, unsigned>& L = Info::ReadKeyDataLength(Ptr); + Ptr += L.first + L.second; + assert(NumItemsInBucketLeft); + --NumItemsInBucketLeft; + assert(NumEntriesLeft); + --NumEntriesLeft; + return *this; + } + key_iterator operator++(int) { // Postincrement + key_iterator tmp = *this; ++*this; return tmp; + } + + value_type operator*() const { + const unsigned char* LocalPtr = Ptr; + if (!NumItemsInBucketLeft) + LocalPtr += 2; // number of items in bucket + LocalPtr += 4; // Skip the hash. + + // Determine the length of the key and the data. + const std::pair<unsigned, unsigned>& L + = Info::ReadKeyDataLength(LocalPtr); + + // Read the key. + const internal_key_type& Key = InfoObj->ReadKey(LocalPtr, L.first); + return InfoObj->GetExternalKey(Key); + } + }; + + key_iterator key_begin() { + return key_iterator(Base + 4, getNumEntries(), &InfoObj); + } + key_iterator key_end() { return key_iterator(); } + /// \brief Iterates over all the entries in the table, returning /// a key/data pair. class item_iterator { |