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