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