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