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