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 24 namespace clang { 25 26 /// The iterator over UnresolvedSets. Serves as both the const and 27 /// non-const iterator. 28 class UnresolvedSetIterator { 29 private: 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; UnresolvedSetIterator(DeclsTy::iterator ir)38 explicit UnresolvedSetIterator(DeclsTy::iterator ir) : ir(ir) {} UnresolvedSetIterator(DeclsTy::const_iterator ir)39 explicit UnresolvedSetIterator(DeclsTy::const_iterator ir) : 40 ir(const_cast<DeclsTy::iterator>(ir)) {} 41 getIterator()42 IteratorTy getIterator() const { return ir; } 43 44 public: UnresolvedSetIterator()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 getDecl()53 NamedDecl *getDecl() const { return ir->getDecl(); } getAccess()54 AccessSpecifier getAccess() const { return ir->getAccess(); } setAccess(AccessSpecifier AS)55 void setAccess(AccessSpecifier AS) { ir->setAccess(AS); } getPair()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 /// UnresolvedSet - A set of unresolved declarations. 92 class UnresolvedSetImpl { 93 typedef SmallVectorImpl<DeclAccessPair> DeclsTy; 94 95 // Don't allow direct construction, and only permit subclassing by 96 // UnresolvedSet. 97 private: 98 template <unsigned N> friend class UnresolvedSet; UnresolvedSetImpl()99 UnresolvedSetImpl() {} 100 UnresolvedSetImpl(const UnresolvedSetImpl &) LLVM_DELETED_FUNCTION; 101 102 public: 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 begin()108 iterator begin() { return iterator(decls().begin()); } end()109 iterator end() { return iterator(decls().end()); } 110 begin()111 const_iterator begin() const { return const_iterator(decls().begin()); } end()112 const_iterator end() const { return const_iterator(decls().end()); } 113 addDecl(NamedDecl * D)114 void addDecl(NamedDecl *D) { 115 addDecl(D, AS_none); 116 } 117 addDecl(NamedDecl * D,AccessSpecifier AS)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 replace(const NamedDecl * Old,NamedDecl * New)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. replace(iterator I,NamedDecl * New)134 void replace(iterator I, NamedDecl *New) { 135 I.ir->setDecl(New); 136 } 137 replace(iterator I,NamedDecl * New,AccessSpecifier AS)138 void replace(iterator I, NamedDecl *New, AccessSpecifier AS) { 139 I.ir->set(New, AS); 140 } 141 erase(unsigned I)142 void erase(unsigned I) { 143 decls()[I] = decls().back(); 144 decls().pop_back(); 145 } 146 erase(iterator I)147 void erase(iterator I) { 148 *I.ir = decls().back(); 149 decls().pop_back(); 150 } 151 setAccess(iterator I,AccessSpecifier AS)152 void setAccess(iterator I, AccessSpecifier AS) { 153 I.ir->setAccess(AS); 154 } 155 clear()156 void clear() { decls().clear(); } set_size(unsigned N)157 void set_size(unsigned N) { decls().set_size(N); } 158 empty()159 bool empty() const { return decls().empty(); } size()160 unsigned size() const { return decls().size(); } 161 append(iterator I,iterator E)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 169 private: 170 // These work because the only permitted subclass is UnresolvedSetImpl 171 decls()172 DeclsTy &decls() { 173 return *reinterpret_cast<DeclsTy*>(this); 174 } decls()175 const DeclsTy &decls() const { 176 return *reinterpret_cast<const DeclsTy*>(this); 177 } 178 }; 179 180 /// A set of unresolved declarations 181 template <unsigned InlineCapacity> class UnresolvedSet : 182 public UnresolvedSetImpl { 183 SmallVector<DeclAccessPair, InlineCapacity> Decls; 184 }; 185 186 187 } // namespace clang 188 189 #endif 190