UnresolvedSet.h revision 243830
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/AST/DeclAccessPair.h" 21 22namespace clang { 23 24/// The iterator over UnresolvedSets. Serves as both the const and 25/// non-const iterator. 26class UnresolvedSetIterator { 27private: 28 typedef SmallVectorImpl<DeclAccessPair> DeclsTy; 29 typedef DeclsTy::iterator IteratorTy; 30 31 IteratorTy ir; 32 33 friend class UnresolvedSetImpl; 34 friend class OverloadExpr; 35 explicit UnresolvedSetIterator(DeclsTy::iterator ir) : ir(ir) {} 36 explicit UnresolvedSetIterator(DeclsTy::const_iterator ir) : 37 ir(const_cast<DeclsTy::iterator>(ir)) {} 38 39 IteratorTy getIterator() const { return ir; } 40 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->getDecl(); } 51 AccessSpecifier getAccess() const { return ir->getAccess(); } 52 void setAccess(AccessSpecifier AS) { ir->setAccess(AS); } 53 DeclAccessPair getPair() const { return *ir; } 54 55 NamedDecl *operator*() const { return getDecl(); } 56 57 UnresolvedSetIterator &operator++() { ++ir; return *this; } 58 UnresolvedSetIterator operator++(int) { return UnresolvedSetIterator(ir++); } 59 UnresolvedSetIterator &operator--() { --ir; return *this; } 60 UnresolvedSetIterator operator--(int) { return UnresolvedSetIterator(ir--); } 61 62 UnresolvedSetIterator &operator+=(difference_type d) { 63 ir += d; return *this; 64 } 65 UnresolvedSetIterator operator+(difference_type d) const { 66 return UnresolvedSetIterator(ir + d); 67 } 68 UnresolvedSetIterator &operator-=(difference_type d) { 69 ir -= d; return *this; 70 } 71 UnresolvedSetIterator operator-(difference_type d) const { 72 return UnresolvedSetIterator(ir - d); 73 } 74 value_type operator[](difference_type d) const { return *(*this + d); } 75 76 difference_type operator-(const UnresolvedSetIterator &o) const { 77 return ir - o.ir; 78 } 79 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 bool operator>=(const UnresolvedSetIterator &o) const { return ir >= o.ir; } 85 bool operator>(const UnresolvedSetIterator &o) const { return ir > o.ir; } 86}; 87 88/// UnresolvedSet - A set of unresolved declarations. 89class UnresolvedSetImpl { 90 typedef UnresolvedSetIterator::DeclsTy DeclsTy; 91 92 // Don't allow direct construction, and only permit subclassing by 93 // UnresolvedSet. 94private: 95 template <unsigned N> friend class UnresolvedSet; 96 UnresolvedSetImpl() {} 97 UnresolvedSetImpl(const UnresolvedSetImpl &) LLVM_DELETED_FUNCTION; 98 99public: 100 // We don't currently support assignment through this iterator, so we might 101 // as well use the same implementation twice. 102 typedef UnresolvedSetIterator iterator; 103 typedef UnresolvedSetIterator const_iterator; 104 105 iterator begin() { return iterator(decls().begin()); } 106 iterator end() { return iterator(decls().end()); } 107 108 const_iterator begin() const { return const_iterator(decls().begin()); } 109 const_iterator end() const { return const_iterator(decls().end()); } 110 111 void addDecl(NamedDecl *D) { 112 addDecl(D, AS_none); 113 } 114 115 void addDecl(NamedDecl *D, AccessSpecifier AS) { 116 decls().push_back(DeclAccessPair::make(D, AS)); 117 } 118 119 /// Replaces the given declaration with the new one, once. 120 /// 121 /// \return true if the set changed 122 bool replace(const NamedDecl* Old, NamedDecl *New) { 123 for (DeclsTy::iterator I = decls().begin(), E = decls().end(); I != E; ++I) 124 if (I->getDecl() == Old) 125 return (I->setDecl(New), true); 126 return false; 127 } 128 129 /// Replaces the declaration at the given iterator with the new one, 130 /// preserving the original access bits. 131 void replace(iterator I, NamedDecl *New) { 132 I.ir->setDecl(New); 133 } 134 135 void replace(iterator I, NamedDecl *New, AccessSpecifier AS) { 136 I.ir->set(New, AS); 137 } 138 139 void erase(unsigned I) { 140 decls()[I] = decls().back(); 141 decls().pop_back(); 142 } 143 144 void erase(iterator I) { 145 *I.ir = decls().back(); 146 decls().pop_back(); 147 } 148 149 void setAccess(iterator I, AccessSpecifier AS) { 150 I.ir->setAccess(AS); 151 } 152 153 void clear() { decls().clear(); } 154 void set_size(unsigned N) { decls().set_size(N); } 155 156 bool empty() const { return decls().empty(); } 157 unsigned size() const { return decls().size(); } 158 159 void append(iterator I, iterator E) { 160 decls().append(I.ir, E.ir); 161 } 162 163 DeclAccessPair &operator[](unsigned I) { return decls()[I]; } 164 const DeclAccessPair &operator[](unsigned I) const { return decls()[I]; } 165 166private: 167 // These work because the only permitted subclass is UnresolvedSetImpl 168 169 DeclsTy &decls() { 170 return *reinterpret_cast<DeclsTy*>(this); 171 } 172 const DeclsTy &decls() const { 173 return *reinterpret_cast<const DeclsTy*>(this); 174 } 175}; 176 177/// A set of unresolved declarations 178template <unsigned InlineCapacity> class UnresolvedSet : 179 public UnresolvedSetImpl { 180 SmallVector<DeclAccessPair, InlineCapacity> Decls; 181}; 182 183 184} // namespace clang 185 186#endif 187