UnresolvedSet.h revision 202879
1202879Srdivacky//===-- UnresolvedSet.h - Unresolved sets of declarations ------*- C++ -*-===// 2202879Srdivacky// 3202879Srdivacky// The LLVM Compiler Infrastructure 4202879Srdivacky// 5202879Srdivacky// This file is distributed under the University of Illinois Open Source 6202879Srdivacky// License. See LICENSE.TXT for details. 7202879Srdivacky// 8202879Srdivacky//===----------------------------------------------------------------------===// 9202879Srdivacky// 10202879Srdivacky// This file defines the UnresolvedSet class, which is used to store 11202879Srdivacky// collections of declarations in the AST. 12202879Srdivacky// 13202879Srdivacky//===----------------------------------------------------------------------===// 14202879Srdivacky 15202879Srdivacky#ifndef LLVM_CLANG_AST_UNRESOLVEDSET_H 16202879Srdivacky#define LLVM_CLANG_AST_UNRESOLVEDSET_H 17202879Srdivacky 18202879Srdivacky#include <iterator> 19202879Srdivacky#include "llvm/ADT/PointerIntPair.h" 20202879Srdivacky#include "llvm/ADT/SmallVector.h" 21202879Srdivacky#include "clang/Basic/Specifiers.h" 22202879Srdivacky 23202879Srdivackynamespace clang { 24202879Srdivacky 25202879Srdivackyclass NamedDecl; 26202879Srdivacky 27202879Srdivacky/// The iterator over UnresolvedSets. Serves as both the const and 28202879Srdivacky/// non-const iterator. 29202879Srdivackyclass UnresolvedSetIterator { 30202879Srdivacky 31202879Srdivacky typedef llvm::PointerIntPair<NamedDecl*, 2> DeclEntry; 32202879Srdivacky typedef llvm::SmallVectorImpl<DeclEntry> DeclsTy; 33202879Srdivacky typedef DeclsTy::iterator IteratorTy; 34202879Srdivacky 35202879Srdivacky IteratorTy ir; 36202879Srdivacky 37202879Srdivacky friend class UnresolvedSetImpl; 38202879Srdivacky explicit UnresolvedSetIterator(DeclsTy::iterator ir) : ir(ir) {} 39202879Srdivacky explicit UnresolvedSetIterator(DeclsTy::const_iterator ir) : 40202879Srdivacky ir(const_cast<DeclsTy::iterator>(ir)) {} 41202879Srdivackypublic: 42202879Srdivacky UnresolvedSetIterator() {} 43202879Srdivacky 44202879Srdivacky typedef std::iterator_traits<IteratorTy>::difference_type difference_type; 45202879Srdivacky typedef NamedDecl *value_type; 46202879Srdivacky typedef NamedDecl **pointer; 47202879Srdivacky typedef NamedDecl *reference; 48202879Srdivacky typedef std::iterator_traits<IteratorTy>::iterator_category iterator_category; 49202879Srdivacky 50202879Srdivacky NamedDecl *getDecl() const { return ir->getPointer(); } 51202879Srdivacky AccessSpecifier getAccess() const { return AccessSpecifier(ir->getInt()); } 52202879Srdivacky 53202879Srdivacky NamedDecl *operator*() const { return getDecl(); } 54202879Srdivacky 55202879Srdivacky UnresolvedSetIterator &operator++() { ++ir; return *this; } 56202879Srdivacky UnresolvedSetIterator operator++(int) { return UnresolvedSetIterator(ir++); } 57202879Srdivacky UnresolvedSetIterator &operator--() { --ir; return *this; } 58202879Srdivacky UnresolvedSetIterator operator--(int) { return UnresolvedSetIterator(ir--); } 59202879Srdivacky 60202879Srdivacky UnresolvedSetIterator &operator+=(difference_type d) { 61202879Srdivacky ir += d; return *this; 62202879Srdivacky } 63202879Srdivacky UnresolvedSetIterator operator+(difference_type d) const { 64202879Srdivacky return UnresolvedSetIterator(ir + d); 65202879Srdivacky } 66202879Srdivacky UnresolvedSetIterator &operator-=(difference_type d) { 67202879Srdivacky ir -= d; return *this; 68202879Srdivacky } 69202879Srdivacky UnresolvedSetIterator operator-(difference_type d) const { 70202879Srdivacky return UnresolvedSetIterator(ir - d); 71202879Srdivacky } 72202879Srdivacky value_type operator[](difference_type d) const { return *(*this + d); } 73202879Srdivacky 74202879Srdivacky difference_type operator-(const UnresolvedSetIterator &o) const { 75202879Srdivacky return ir - o.ir; 76202879Srdivacky } 77202879Srdivacky 78202879Srdivacky bool operator==(const UnresolvedSetIterator &o) const { return ir == o.ir; } 79202879Srdivacky bool operator!=(const UnresolvedSetIterator &o) const { return ir != o.ir; } 80202879Srdivacky bool operator<(const UnresolvedSetIterator &o) const { return ir < o.ir; } 81202879Srdivacky bool operator<=(const UnresolvedSetIterator &o) const { return ir <= o.ir; } 82202879Srdivacky bool operator>=(const UnresolvedSetIterator &o) const { return ir >= o.ir; } 83202879Srdivacky bool operator>(const UnresolvedSetIterator &o) const { return ir > o.ir; } 84202879Srdivacky}; 85202879Srdivacky 86202879Srdivacky/// UnresolvedSet - A set of unresolved declarations. This is needed 87202879Srdivacky/// in a lot of places, but isn't really worth breaking into its own 88202879Srdivacky/// header right now. 89202879Srdivackyclass UnresolvedSetImpl { 90202879Srdivacky typedef UnresolvedSetIterator::DeclEntry DeclEntry; 91202879Srdivacky typedef UnresolvedSetIterator::DeclsTy DeclsTy; 92202879Srdivacky 93202879Srdivacky // Don't allow direct construction, and only permit subclassing by 94202879Srdivacky // UnresolvedSet. 95202879Srdivackyprivate: 96202879Srdivacky template <unsigned N> friend class UnresolvedSet; 97202879Srdivacky UnresolvedSetImpl() {} 98202879Srdivacky UnresolvedSetImpl(const UnresolvedSetImpl &) {} 99202879Srdivacky 100202879Srdivackypublic: 101202879Srdivacky // We don't currently support assignment through this iterator, so we might 102202879Srdivacky // as well use the same implementation twice. 103202879Srdivacky typedef UnresolvedSetIterator iterator; 104202879Srdivacky typedef UnresolvedSetIterator const_iterator; 105202879Srdivacky 106202879Srdivacky iterator begin() { return iterator(decls().begin()); } 107202879Srdivacky iterator end() { return iterator(decls().end()); } 108202879Srdivacky 109202879Srdivacky const_iterator begin() const { return const_iterator(decls().begin()); } 110202879Srdivacky const_iterator end() const { return const_iterator(decls().end()); } 111202879Srdivacky 112202879Srdivacky void addDecl(NamedDecl *D) { 113202879Srdivacky addDecl(D, AS_none); 114202879Srdivacky } 115202879Srdivacky 116202879Srdivacky void addDecl(NamedDecl *D, AccessSpecifier AS) { 117202879Srdivacky decls().push_back(DeclEntry(D, AS)); 118202879Srdivacky } 119202879Srdivacky 120202879Srdivacky /// Replaces the given declaration with the new one, once. 121202879Srdivacky /// 122202879Srdivacky /// \return true if the set changed 123202879Srdivacky bool replace(const NamedDecl* Old, NamedDecl *New) { 124202879Srdivacky for (DeclsTy::iterator I = decls().begin(), E = decls().end(); I != E; ++I) 125202879Srdivacky if (I->getPointer() == Old) 126202879Srdivacky return (I->setPointer(New), true); 127202879Srdivacky return false; 128202879Srdivacky } 129202879Srdivacky 130202879Srdivacky /// Replaces the declaration at the given iterator with the new one, 131202879Srdivacky /// preserving the original access bits. 132202879Srdivacky void replace(iterator I, NamedDecl *New) { 133202879Srdivacky I.ir->setPointer(New); 134202879Srdivacky } 135202879Srdivacky 136202879Srdivacky void replace(iterator I, NamedDecl *New, AccessSpecifier AS) { 137202879Srdivacky *I.ir = DeclEntry(New, AS); 138202879Srdivacky } 139202879Srdivacky 140202879Srdivacky void erase(iterator I) { 141202879Srdivacky *I.ir = decls().back(); 142202879Srdivacky decls().pop_back(); 143202879Srdivacky } 144202879Srdivacky 145202879Srdivacky void clear() { decls().clear(); } 146202879Srdivacky void set_size(unsigned N) { decls().set_size(N); } 147202879Srdivacky 148202879Srdivacky bool empty() const { return decls().empty(); } 149202879Srdivacky unsigned size() const { return decls().size(); } 150202879Srdivacky 151202879Srdivacky void append(iterator I, iterator E) { 152202879Srdivacky decls().append(I.ir, E.ir); 153202879Srdivacky } 154202879Srdivacky 155202879Srdivacky /// A proxy reference for implementing operator[]. 156202879Srdivacky class Proxy { 157202879Srdivacky DeclEntry &Ref; 158202879Srdivacky 159202879Srdivacky friend class UnresolvedSetImpl; 160202879Srdivacky Proxy(DeclEntry &Ref) : Ref(Ref) {} 161202879Srdivacky 162202879Srdivacky public: 163202879Srdivacky NamedDecl *getDecl() const { return Ref.getPointer(); } 164202879Srdivacky void setDecl(NamedDecl *D) { Ref.setPointer(D); } 165202879Srdivacky 166202879Srdivacky AccessSpecifier getAccess() const { return AccessSpecifier(Ref.getInt()); } 167202879Srdivacky void setAccess(AccessSpecifier AS) const { Ref.setInt(AS); } 168202879Srdivacky 169202879Srdivacky NamedDecl* operator->() const { return getDecl(); } 170202879Srdivacky operator NamedDecl*() const { return getDecl(); } 171202879Srdivacky Proxy &operator=(const Proxy &D) { Ref = D.Ref; return *this; } 172202879Srdivacky }; 173202879Srdivacky Proxy operator[](unsigned I) { return Proxy(decls()[I]); } 174202879Srdivacky 175202879Srdivacky /// A proxy reference for implementing operator[] const. 176202879Srdivacky class ConstProxy { 177202879Srdivacky const DeclEntry &Ref; 178202879Srdivacky 179202879Srdivacky friend class UnresolvedSetImpl; 180202879Srdivacky ConstProxy(const DeclEntry &Ref) : Ref(Ref) {} 181202879Srdivacky 182202879Srdivacky public: 183202879Srdivacky NamedDecl *getDecl() const { return Ref.getPointer(); } 184202879Srdivacky AccessSpecifier getAccess() const { return AccessSpecifier(Ref.getInt()); } 185202879Srdivacky 186202879Srdivacky NamedDecl *operator->() const { return getDecl(); } 187202879Srdivacky operator NamedDecl*() const { return getDecl(); } 188202879Srdivacky }; 189202879Srdivacky ConstProxy operator[](unsigned I) const { return ConstProxy(decls()[I]); } 190202879Srdivacky 191202879Srdivackyprivate: 192202879Srdivacky // These work because the only permitted subclass is UnresolvedSetImpl 193202879Srdivacky 194202879Srdivacky DeclsTy &decls() { 195202879Srdivacky return *reinterpret_cast<DeclsTy*>(this); 196202879Srdivacky } 197202879Srdivacky const DeclsTy &decls() const { 198202879Srdivacky return *reinterpret_cast<const DeclsTy*>(this); 199202879Srdivacky } 200202879Srdivacky}; 201202879Srdivacky 202202879Srdivacky/// A set of unresolved declarations 203202879Srdivackytemplate <unsigned InlineCapacity> class UnresolvedSet : 204202879Srdivacky public UnresolvedSetImpl { 205202879Srdivacky llvm::SmallVector<UnresolvedSetImpl::DeclEntry, InlineCapacity> Decls; 206202879Srdivacky}; 207202879Srdivacky 208202879Srdivacky 209202879Srdivacky} // namespace clang 210202879Srdivacky 211202879Srdivacky#endif 212