1c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot//===- ScopedHashTable.h - A simple scoped hash table -----------*- C++ -*-===// 2c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot// 3c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot// The LLVM Compiler Infrastructure 4c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot// 5c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot// This file is distributed under the University of Illinois Open Source 6c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot// License. See LICENSE.TXT for details. 7c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot// 8c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot//===----------------------------------------------------------------------===// 9c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot// 10c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot// This file implements an efficient scoped hash table, which is useful for 11c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot// things like dominator-based optimizations. This allows clients to do things 12c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot// like this: 13c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot// 14c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot// ScopedHashTable<int, int> HT; 15c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot// { 16c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot// ScopedHashTableScope<int, int> Scope1(HT); 17c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot// HT.insert(0, 0); 18c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot// HT.insert(1, 1); 19c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot// { 20c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot// ScopedHashTableScope<int, int> Scope2(HT); 21c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot// HT.insert(0, 42); 22c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot// } 23c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot// } 24c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot// 25c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot// Looking up the value for "0" in the Scope2 block will return 42. Looking 26c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot// up the value for 0 before 42 is inserted or after Scope2 is popped will 27c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot// return 0. 28c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot// 29c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot//===----------------------------------------------------------------------===// 30c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot 31c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot#ifndef LLVM_ADT_SCOPEDHASHTABLE_H 32c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot#define LLVM_ADT_SCOPEDHASHTABLE_H 33c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot 34c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot#include "llvm/ADT/DenseMap.h" 35c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot#include "llvm/ADT/DenseMapInfo.h" 36c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot#include "llvm/Support/Allocator.h" 37c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot#include <cassert> 38c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot#include <new> 39c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot 40c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robotnamespace llvm { 41c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot 42c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robottemplate <typename K, typename V, typename KInfo = DenseMapInfo<K>, 43c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot typename AllocatorTy = MallocAllocator> 44c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robotclass ScopedHashTable; 45c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot 46c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robottemplate <typename K, typename V> 47c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robotclass ScopedHashTableVal { 48c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot ScopedHashTableVal *NextInScope; 49c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot ScopedHashTableVal *NextForKey; 50c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot K Key; 51c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot V Val; 52c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot 53c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot ScopedHashTableVal(const K &key, const V &val) : Key(key), Val(val) {} 54c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot 55c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robotpublic: 56c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot const K &getKey() const { return Key; } 57c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot const V &getValue() const { return Val; } 58c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot V &getValue() { return Val; } 59c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot 60c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot ScopedHashTableVal *getNextForKey() { return NextForKey; } 61c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot const ScopedHashTableVal *getNextForKey() const { return NextForKey; } 62c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot ScopedHashTableVal *getNextInScope() { return NextInScope; } 63c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot 64c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot template <typename AllocatorTy> 65c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot static ScopedHashTableVal *Create(ScopedHashTableVal *nextInScope, 66c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot ScopedHashTableVal *nextForKey, 67c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot const K &key, const V &val, 68c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot AllocatorTy &Allocator) { 69c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot ScopedHashTableVal *New = Allocator.template Allocate<ScopedHashTableVal>(); 70c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot // Set up the value. 71c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot new (New) ScopedHashTableVal(key, val); 72c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot New->NextInScope = nextInScope; 73c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot New->NextForKey = nextForKey; 74c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot return New; 75c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot } 76c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot 77c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot template <typename AllocatorTy> void Destroy(AllocatorTy &Allocator) { 78c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot // Free memory referenced by the item. 79c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot this->~ScopedHashTableVal(); 80c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot Allocator.Deallocate(this); 81c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot } 82c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot}; 83c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot 84c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robottemplate <typename K, typename V, typename KInfo = DenseMapInfo<K>, 85c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot typename AllocatorTy = MallocAllocator> 86c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robotclass ScopedHashTableScope { 87c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// HT - The hashtable that we are active for. 88c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot ScopedHashTable<K, V, KInfo, AllocatorTy> &HT; 89c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot 90c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// PrevScope - This is the scope that we are shadowing in HT. 91c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot ScopedHashTableScope *PrevScope; 92c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot 93c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// LastValInScope - This is the last value that was inserted for this scope 94c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// or null if none have been inserted yet. 95c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot ScopedHashTableVal<K, V> *LastValInScope; 96c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot 97c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robotpublic: 98c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot ScopedHashTableScope(ScopedHashTable<K, V, KInfo, AllocatorTy> &HT); 99c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot ScopedHashTableScope(ScopedHashTableScope &) = delete; 100c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot ScopedHashTableScope &operator=(ScopedHashTableScope &) = delete; 101c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot ~ScopedHashTableScope(); 102c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot 103c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot ScopedHashTableScope *getParentScope() { return PrevScope; } 104c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot const ScopedHashTableScope *getParentScope() const { return PrevScope; } 105c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot 106c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robotprivate: 107c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot friend class ScopedHashTable<K, V, KInfo, AllocatorTy>; 108c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot 109c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot ScopedHashTableVal<K, V> *getLastValInScope() { 110c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot return LastValInScope; 111c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot } 112c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot 113c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot void setLastValInScope(ScopedHashTableVal<K, V> *Val) { 114c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot LastValInScope = Val; 115c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot } 116c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot}; 117c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot 118c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robottemplate <typename K, typename V, typename KInfo = DenseMapInfo<K>> 119c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robotclass ScopedHashTableIterator { 120c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot ScopedHashTableVal<K, V> *Node; 121c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot 122c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robotpublic: 123c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot ScopedHashTableIterator(ScopedHashTableVal<K, V> *node) : Node(node) {} 124c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot 125c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot V &operator*() const { 126c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot assert(Node && "Dereference end()"); 127c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot return Node->getValue(); 128c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot } 129c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot V *operator->() const { 130c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot return &Node->getValue(); 131c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot } 132c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot 133c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot bool operator==(const ScopedHashTableIterator &RHS) const { 134c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot return Node == RHS.Node; 135c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot } 136c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot bool operator!=(const ScopedHashTableIterator &RHS) const { 137c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot return Node != RHS.Node; 138c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot } 139c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot 140c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot inline ScopedHashTableIterator& operator++() { // Preincrement 141c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot assert(Node && "incrementing past end()"); 142c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot Node = Node->getNextForKey(); 143c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot return *this; 144c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot } 145c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot ScopedHashTableIterator operator++(int) { // Postincrement 146c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot ScopedHashTableIterator tmp = *this; ++*this; return tmp; 147c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot } 148c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot}; 149c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot 150c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robottemplate <typename K, typename V, typename KInfo, typename AllocatorTy> 151c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robotclass ScopedHashTable { 152c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robotpublic: 153c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// ScopeTy - This is a helpful typedef that allows clients to get easy access 154c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// to the name of the scope for this hash table. 155c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot using ScopeTy = ScopedHashTableScope<K, V, KInfo, AllocatorTy>; 156c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot using size_type = unsigned; 157c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot 158c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robotprivate: 159c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot friend class ScopedHashTableScope<K, V, KInfo, AllocatorTy>; 160c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot 161c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot using ValTy = ScopedHashTableVal<K, V>; 162c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot 163c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot DenseMap<K, ValTy*, KInfo> TopLevelMap; 164c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot ScopeTy *CurScope = nullptr; 165c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot 166c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot AllocatorTy Allocator; 167c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot 168c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robotpublic: 169c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot ScopedHashTable() = default; 170c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot ScopedHashTable(AllocatorTy A) : Allocator(A) {} 171c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot ScopedHashTable(const ScopedHashTable &) = delete; 172c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot ScopedHashTable &operator=(const ScopedHashTable &) = delete; 173c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot 174c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot ~ScopedHashTable() { 175c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot assert(!CurScope && TopLevelMap.empty() && "Scope imbalance!"); 176c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot } 177c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot 178c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// Access to the allocator. 179c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot AllocatorTy &getAllocator() { return Allocator; } 180c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot const AllocatorTy &getAllocator() const { return Allocator; } 181c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot 182c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// Return 1 if the specified key is in the table, 0 otherwise. 183c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot size_type count(const K &Key) const { 184c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot return TopLevelMap.count(Key); 185c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot } 186c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot 187c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot V lookup(const K &Key) const { 188c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot auto I = TopLevelMap.find(Key); 189c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot if (I != TopLevelMap.end()) 190c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot return I->second->getValue(); 191c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot 192c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot return V(); 193c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot } 194c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot 195c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot void insert(const K &Key, const V &Val) { 196c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot insertIntoScope(CurScope, Key, Val); 197c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot } 198c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot 199c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot using iterator = ScopedHashTableIterator<K, V, KInfo>; 200c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot 201c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot iterator end() { return iterator(0); } 202c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot 203c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot iterator begin(const K &Key) { 204c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot typename DenseMap<K, ValTy*, KInfo>::iterator I = 205c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot TopLevelMap.find(Key); 206c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot if (I == TopLevelMap.end()) return end(); 207c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot return iterator(I->second); 208c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot } 209c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot 210c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot ScopeTy *getCurScope() { return CurScope; } 211c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot const ScopeTy *getCurScope() const { return CurScope; } 212c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot 213c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// insertIntoScope - This inserts the specified key/value at the specified 214c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// (possibly not the current) scope. While it is ok to insert into a scope 215c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// that isn't the current one, it isn't ok to insert *underneath* an existing 216c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// value of the specified key. 217c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot void insertIntoScope(ScopeTy *S, const K &Key, const V &Val) { 218c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot assert(S && "No scope active!"); 219c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot ScopedHashTableVal<K, V> *&KeyEntry = TopLevelMap[Key]; 220c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot KeyEntry = ValTy::Create(S->getLastValInScope(), KeyEntry, Key, Val, 221c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot Allocator); 222c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot S->setLastValInScope(KeyEntry); 223c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot } 224c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot}; 225c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot 226c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot/// ScopedHashTableScope ctor - Install this as the current scope for the hash 227c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot/// table. 228c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robottemplate <typename K, typename V, typename KInfo, typename Allocator> 229c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team RobotScopedHashTableScope<K, V, KInfo, Allocator>:: 230c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot ScopedHashTableScope(ScopedHashTable<K, V, KInfo, Allocator> &ht) : HT(ht) { 231c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot PrevScope = HT.CurScope; 232c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot HT.CurScope = this; 233c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot LastValInScope = nullptr; 234c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot} 235c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot 236c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robottemplate <typename K, typename V, typename KInfo, typename Allocator> 237c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team RobotScopedHashTableScope<K, V, KInfo, Allocator>::~ScopedHashTableScope() { 238c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot assert(HT.CurScope == this && "Scope imbalance!"); 239c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot HT.CurScope = PrevScope; 240c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot 241c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot // Pop and delete all values corresponding to this scope. 242c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot while (ScopedHashTableVal<K, V> *ThisEntry = LastValInScope) { 243c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot // Pop this value out of the TopLevelMap. 244c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot if (!ThisEntry->getNextForKey()) { 245c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot assert(HT.TopLevelMap[ThisEntry->getKey()] == ThisEntry && 246c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot "Scope imbalance!"); 247c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot HT.TopLevelMap.erase(ThisEntry->getKey()); 248c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot } else { 249c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot ScopedHashTableVal<K, V> *&KeyEntry = HT.TopLevelMap[ThisEntry->getKey()]; 250c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot assert(KeyEntry == ThisEntry && "Scope imbalance!"); 251c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot KeyEntry = ThisEntry->getNextForKey(); 252c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot } 253c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot 254c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot // Pop this value out of the scope. 255c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot LastValInScope = ThisEntry->getNextInScope(); 256c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot 257c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot // Delete this entry. 258c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot ThisEntry->Destroy(HT.getAllocator()); 259c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot } 260c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot} 261c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot 262c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot} // end namespace llvm 263c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot 264c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot#endif // LLVM_ADT_SCOPEDHASHTABLE_H 265