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 18249423Sdim#include "clang/AST/DeclAccessPair.h" 19249423Sdim#include "clang/Basic/LLVM.h" 20249423Sdim#include "llvm/ADT/ArrayRef.h" 21249423Sdim#include "llvm/ADT/SmallVector.h" 22202879Srdivacky#include <iterator> 23202879Srdivacky 24202879Srdivackynamespace clang { 25202879Srdivacky 26202879Srdivacky/// The iterator over UnresolvedSets. Serves as both the const and 27202879Srdivacky/// non-const iterator. 28202879Srdivackyclass UnresolvedSetIterator { 29203955Srdivackyprivate: 30249423Sdim typedef llvm::MutableArrayRef<DeclAccessPair> DeclsTy; 31202879Srdivacky typedef DeclsTy::iterator IteratorTy; 32202879Srdivacky 33202879Srdivacky IteratorTy ir; 34202879Srdivacky 35202879Srdivacky friend class UnresolvedSetImpl; 36249423Sdim friend class ASTUnresolvedSet; 37208600Srdivacky friend class OverloadExpr; 38202879Srdivacky explicit UnresolvedSetIterator(DeclsTy::iterator ir) : ir(ir) {} 39202879Srdivacky explicit UnresolvedSetIterator(DeclsTy::const_iterator ir) : 40202879Srdivacky ir(const_cast<DeclsTy::iterator>(ir)) {} 41208600Srdivacky 42208600Srdivacky IteratorTy getIterator() const { return ir; } 43208600Srdivacky 44202879Srdivackypublic: 45202879Srdivacky UnresolvedSetIterator() {} 46202879Srdivacky 47202879Srdivacky typedef std::iterator_traits<IteratorTy>::difference_type difference_type; 48202879Srdivacky typedef NamedDecl *value_type; 49202879Srdivacky typedef NamedDecl **pointer; 50202879Srdivacky typedef NamedDecl *reference; 51202879Srdivacky typedef std::iterator_traits<IteratorTy>::iterator_category iterator_category; 52202879Srdivacky 53203955Srdivacky NamedDecl *getDecl() const { return ir->getDecl(); } 54263508Sdim void setDecl(NamedDecl *ND) const { return ir->setDecl(ND); } 55203955Srdivacky AccessSpecifier getAccess() const { return ir->getAccess(); } 56207632Srdivacky void setAccess(AccessSpecifier AS) { ir->setAccess(AS); } 57205408Srdivacky DeclAccessPair getPair() const { return *ir; } 58202879Srdivacky 59202879Srdivacky NamedDecl *operator*() const { return getDecl(); } 60202879Srdivacky 61202879Srdivacky UnresolvedSetIterator &operator++() { ++ir; return *this; } 62202879Srdivacky UnresolvedSetIterator operator++(int) { return UnresolvedSetIterator(ir++); } 63202879Srdivacky UnresolvedSetIterator &operator--() { --ir; return *this; } 64202879Srdivacky UnresolvedSetIterator operator--(int) { return UnresolvedSetIterator(ir--); } 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 UnresolvedSetIterator &operator-=(difference_type d) { 73202879Srdivacky ir -= d; return *this; 74202879Srdivacky } 75202879Srdivacky UnresolvedSetIterator operator-(difference_type d) const { 76202879Srdivacky return UnresolvedSetIterator(ir - d); 77202879Srdivacky } 78202879Srdivacky value_type operator[](difference_type d) const { return *(*this + d); } 79202879Srdivacky 80202879Srdivacky difference_type operator-(const UnresolvedSetIterator &o) const { 81202879Srdivacky return ir - o.ir; 82202879Srdivacky } 83202879Srdivacky 84202879Srdivacky bool operator==(const UnresolvedSetIterator &o) const { return ir == o.ir; } 85202879Srdivacky bool operator!=(const UnresolvedSetIterator &o) const { return ir != o.ir; } 86202879Srdivacky bool operator<(const UnresolvedSetIterator &o) const { return ir < o.ir; } 87202879Srdivacky bool operator<=(const UnresolvedSetIterator &o) const { return ir <= o.ir; } 88202879Srdivacky bool operator>=(const UnresolvedSetIterator &o) const { return ir >= o.ir; } 89202879Srdivacky bool operator>(const UnresolvedSetIterator &o) const { return ir > o.ir; } 90202879Srdivacky}; 91202879Srdivacky 92263508Sdim/// \brief A set of unresolved declarations. 93202879Srdivackyclass UnresolvedSetImpl { 94249423Sdim typedef SmallVectorImpl<DeclAccessPair> DeclsTy; 95202879Srdivacky 96202879Srdivacky // Don't allow direct construction, and only permit subclassing by 97202879Srdivacky // UnresolvedSet. 98202879Srdivackyprivate: 99202879Srdivacky template <unsigned N> friend class UnresolvedSet; 100202879Srdivacky UnresolvedSetImpl() {} 101243830Sdim UnresolvedSetImpl(const UnresolvedSetImpl &) LLVM_DELETED_FUNCTION; 102202879Srdivacky 103202879Srdivackypublic: 104202879Srdivacky // We don't currently support assignment through this iterator, so we might 105202879Srdivacky // as well use the same implementation twice. 106202879Srdivacky typedef UnresolvedSetIterator iterator; 107202879Srdivacky typedef UnresolvedSetIterator const_iterator; 108202879Srdivacky 109202879Srdivacky iterator begin() { return iterator(decls().begin()); } 110202879Srdivacky iterator end() { return iterator(decls().end()); } 111202879Srdivacky 112202879Srdivacky const_iterator begin() const { return const_iterator(decls().begin()); } 113202879Srdivacky const_iterator end() const { return const_iterator(decls().end()); } 114202879Srdivacky 115202879Srdivacky void addDecl(NamedDecl *D) { 116202879Srdivacky addDecl(D, AS_none); 117202879Srdivacky } 118202879Srdivacky 119202879Srdivacky void addDecl(NamedDecl *D, AccessSpecifier AS) { 120203955Srdivacky decls().push_back(DeclAccessPair::make(D, AS)); 121202879Srdivacky } 122202879Srdivacky 123202879Srdivacky /// Replaces the given declaration with the new one, once. 124202879Srdivacky /// 125202879Srdivacky /// \return true if the set changed 126202879Srdivacky bool replace(const NamedDecl* Old, NamedDecl *New) { 127202879Srdivacky for (DeclsTy::iterator I = decls().begin(), E = decls().end(); I != E; ++I) 128203955Srdivacky if (I->getDecl() == Old) 129203955Srdivacky return (I->setDecl(New), true); 130202879Srdivacky return false; 131202879Srdivacky } 132202879Srdivacky 133202879Srdivacky /// Replaces the declaration at the given iterator with the new one, 134202879Srdivacky /// preserving the original access bits. 135202879Srdivacky void replace(iterator I, NamedDecl *New) { 136203955Srdivacky I.ir->setDecl(New); 137202879Srdivacky } 138202879Srdivacky 139202879Srdivacky void replace(iterator I, NamedDecl *New, AccessSpecifier AS) { 140203955Srdivacky I.ir->set(New, AS); 141202879Srdivacky } 142202879Srdivacky 143263508Sdim void erase(unsigned I) { decls()[I] = decls().pop_back_val(); } 144203955Srdivacky 145263508Sdim void erase(iterator I) { *I.ir = decls().pop_back_val(); } 146202879Srdivacky 147203955Srdivacky void setAccess(iterator I, AccessSpecifier AS) { 148203955Srdivacky I.ir->setAccess(AS); 149203955Srdivacky } 150203955Srdivacky 151202879Srdivacky void clear() { decls().clear(); } 152202879Srdivacky void set_size(unsigned N) { decls().set_size(N); } 153202879Srdivacky 154202879Srdivacky bool empty() const { return decls().empty(); } 155202879Srdivacky unsigned size() const { return decls().size(); } 156202879Srdivacky 157202879Srdivacky void append(iterator I, iterator E) { 158202879Srdivacky decls().append(I.ir, E.ir); 159202879Srdivacky } 160202879Srdivacky 161203955Srdivacky DeclAccessPair &operator[](unsigned I) { return decls()[I]; } 162203955Srdivacky const DeclAccessPair &operator[](unsigned I) const { return decls()[I]; } 163202879Srdivacky 164202879Srdivackyprivate: 165202879Srdivacky // These work because the only permitted subclass is UnresolvedSetImpl 166202879Srdivacky 167202879Srdivacky DeclsTy &decls() { 168202879Srdivacky return *reinterpret_cast<DeclsTy*>(this); 169202879Srdivacky } 170202879Srdivacky const DeclsTy &decls() const { 171202879Srdivacky return *reinterpret_cast<const DeclsTy*>(this); 172202879Srdivacky } 173202879Srdivacky}; 174202879Srdivacky 175263508Sdim/// \brief A set of unresolved declarations. 176202879Srdivackytemplate <unsigned InlineCapacity> class UnresolvedSet : 177202879Srdivacky public UnresolvedSetImpl { 178226633Sdim SmallVector<DeclAccessPair, InlineCapacity> Decls; 179202879Srdivacky}; 180202879Srdivacky 181202879Srdivacky 182202879Srdivacky} // namespace clang 183202879Srdivacky 184202879Srdivacky#endif 185