UnresolvedSet.h revision 202879
1//===-- UnresolvedSet.h - Unresolved sets of declarations ------*- 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 UnresolvedSet class, which is used to store 11// collections of declarations in the AST. 12// 13//===----------------------------------------------------------------------===// 14 15#ifndef LLVM_CLANG_AST_UNRESOLVEDSET_H 16#define LLVM_CLANG_AST_UNRESOLVEDSET_H 17 18#include <iterator> 19#include "llvm/ADT/PointerIntPair.h" 20#include "llvm/ADT/SmallVector.h" 21#include "clang/Basic/Specifiers.h" 22 23namespace clang { 24 25class NamedDecl; 26 27/// The iterator over UnresolvedSets. Serves as both the const and 28/// non-const iterator. 29class UnresolvedSetIterator { 30 31 typedef llvm::PointerIntPair<NamedDecl*, 2> DeclEntry; 32 typedef llvm::SmallVectorImpl<DeclEntry> DeclsTy; 33 typedef DeclsTy::iterator IteratorTy; 34 35 IteratorTy ir; 36 37 friend class UnresolvedSetImpl; 38 explicit UnresolvedSetIterator(DeclsTy::iterator ir) : ir(ir) {} 39 explicit UnresolvedSetIterator(DeclsTy::const_iterator ir) : 40 ir(const_cast<DeclsTy::iterator>(ir)) {} 41public: 42 UnresolvedSetIterator() {} 43 44 typedef std::iterator_traits<IteratorTy>::difference_type difference_type; 45 typedef NamedDecl *value_type; 46 typedef NamedDecl **pointer; 47 typedef NamedDecl *reference; 48 typedef std::iterator_traits<IteratorTy>::iterator_category iterator_category; 49 50 NamedDecl *getDecl() const { return ir->getPointer(); } 51 AccessSpecifier getAccess() const { return AccessSpecifier(ir->getInt()); } 52 53 NamedDecl *operator*() const { return getDecl(); } 54 55 UnresolvedSetIterator &operator++() { ++ir; return *this; } 56 UnresolvedSetIterator operator++(int) { return UnresolvedSetIterator(ir++); } 57 UnresolvedSetIterator &operator--() { --ir; return *this; } 58 UnresolvedSetIterator operator--(int) { return UnresolvedSetIterator(ir--); } 59 60 UnresolvedSetIterator &operator+=(difference_type d) { 61 ir += d; return *this; 62 } 63 UnresolvedSetIterator operator+(difference_type d) const { 64 return UnresolvedSetIterator(ir + d); 65 } 66 UnresolvedSetIterator &operator-=(difference_type d) { 67 ir -= d; return *this; 68 } 69 UnresolvedSetIterator operator-(difference_type d) const { 70 return UnresolvedSetIterator(ir - d); 71 } 72 value_type operator[](difference_type d) const { return *(*this + d); } 73 74 difference_type operator-(const UnresolvedSetIterator &o) const { 75 return ir - o.ir; 76 } 77 78 bool operator==(const UnresolvedSetIterator &o) const { return ir == o.ir; } 79 bool operator!=(const UnresolvedSetIterator &o) const { return ir != o.ir; } 80 bool operator<(const UnresolvedSetIterator &o) const { return ir < o.ir; } 81 bool operator<=(const UnresolvedSetIterator &o) const { return ir <= o.ir; } 82 bool operator>=(const UnresolvedSetIterator &o) const { return ir >= o.ir; } 83 bool operator>(const UnresolvedSetIterator &o) const { return ir > o.ir; } 84}; 85 86/// UnresolvedSet - A set of unresolved declarations. This is needed 87/// in a lot of places, but isn't really worth breaking into its own 88/// header right now. 89class UnresolvedSetImpl { 90 typedef UnresolvedSetIterator::DeclEntry DeclEntry; 91 typedef UnresolvedSetIterator::DeclsTy DeclsTy; 92 93 // Don't allow direct construction, and only permit subclassing by 94 // UnresolvedSet. 95private: 96 template <unsigned N> friend class UnresolvedSet; 97 UnresolvedSetImpl() {} 98 UnresolvedSetImpl(const UnresolvedSetImpl &) {} 99 100public: 101 // We don't currently support assignment through this iterator, so we might 102 // as well use the same implementation twice. 103 typedef UnresolvedSetIterator iterator; 104 typedef UnresolvedSetIterator const_iterator; 105 106 iterator begin() { return iterator(decls().begin()); } 107 iterator end() { return iterator(decls().end()); } 108 109 const_iterator begin() const { return const_iterator(decls().begin()); } 110 const_iterator end() const { return const_iterator(decls().end()); } 111 112 void addDecl(NamedDecl *D) { 113 addDecl(D, AS_none); 114 } 115 116 void addDecl(NamedDecl *D, AccessSpecifier AS) { 117 decls().push_back(DeclEntry(D, AS)); 118 } 119 120 /// Replaces the given declaration with the new one, once. 121 /// 122 /// \return true if the set changed 123 bool replace(const NamedDecl* Old, NamedDecl *New) { 124 for (DeclsTy::iterator I = decls().begin(), E = decls().end(); I != E; ++I) 125 if (I->getPointer() == Old) 126 return (I->setPointer(New), true); 127 return false; 128 } 129 130 /// Replaces the declaration at the given iterator with the new one, 131 /// preserving the original access bits. 132 void replace(iterator I, NamedDecl *New) { 133 I.ir->setPointer(New); 134 } 135 136 void replace(iterator I, NamedDecl *New, AccessSpecifier AS) { 137 *I.ir = DeclEntry(New, AS); 138 } 139 140 void erase(iterator I) { 141 *I.ir = decls().back(); 142 decls().pop_back(); 143 } 144 145 void clear() { decls().clear(); } 146 void set_size(unsigned N) { decls().set_size(N); } 147 148 bool empty() const { return decls().empty(); } 149 unsigned size() const { return decls().size(); } 150 151 void append(iterator I, iterator E) { 152 decls().append(I.ir, E.ir); 153 } 154 155 /// A proxy reference for implementing operator[]. 156 class Proxy { 157 DeclEntry &Ref; 158 159 friend class UnresolvedSetImpl; 160 Proxy(DeclEntry &Ref) : Ref(Ref) {} 161 162 public: 163 NamedDecl *getDecl() const { return Ref.getPointer(); } 164 void setDecl(NamedDecl *D) { Ref.setPointer(D); } 165 166 AccessSpecifier getAccess() const { return AccessSpecifier(Ref.getInt()); } 167 void setAccess(AccessSpecifier AS) const { Ref.setInt(AS); } 168 169 NamedDecl* operator->() const { return getDecl(); } 170 operator NamedDecl*() const { return getDecl(); } 171 Proxy &operator=(const Proxy &D) { Ref = D.Ref; return *this; } 172 }; 173 Proxy operator[](unsigned I) { return Proxy(decls()[I]); } 174 175 /// A proxy reference for implementing operator[] const. 176 class ConstProxy { 177 const DeclEntry &Ref; 178 179 friend class UnresolvedSetImpl; 180 ConstProxy(const DeclEntry &Ref) : Ref(Ref) {} 181 182 public: 183 NamedDecl *getDecl() const { return Ref.getPointer(); } 184 AccessSpecifier getAccess() const { return AccessSpecifier(Ref.getInt()); } 185 186 NamedDecl *operator->() const { return getDecl(); } 187 operator NamedDecl*() const { return getDecl(); } 188 }; 189 ConstProxy operator[](unsigned I) const { return ConstProxy(decls()[I]); } 190 191private: 192 // These work because the only permitted subclass is UnresolvedSetImpl 193 194 DeclsTy &decls() { 195 return *reinterpret_cast<DeclsTy*>(this); 196 } 197 const DeclsTy &decls() const { 198 return *reinterpret_cast<const DeclsTy*>(this); 199 } 200}; 201 202/// A set of unresolved declarations 203template <unsigned InlineCapacity> class UnresolvedSet : 204 public UnresolvedSetImpl { 205 llvm::SmallVector<UnresolvedSetImpl::DeclEntry, InlineCapacity> Decls; 206}; 207 208 209} // namespace clang 210 211#endif 212