UnresolvedSet.h revision 243830
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/SmallVector.h"
20207619Srdivacky#include "clang/AST/DeclAccessPair.h"
21202879Srdivacky
22202879Srdivackynamespace clang {
23202879Srdivacky
24202879Srdivacky/// The iterator over UnresolvedSets.  Serves as both the const and
25202879Srdivacky/// non-const iterator.
26202879Srdivackyclass UnresolvedSetIterator {
27203955Srdivackyprivate:
28226633Sdim  typedef SmallVectorImpl<DeclAccessPair> DeclsTy;
29202879Srdivacky  typedef DeclsTy::iterator IteratorTy;
30202879Srdivacky
31202879Srdivacky  IteratorTy ir;
32202879Srdivacky
33202879Srdivacky  friend class UnresolvedSetImpl;
34208600Srdivacky  friend class OverloadExpr;
35202879Srdivacky  explicit UnresolvedSetIterator(DeclsTy::iterator ir) : ir(ir) {}
36202879Srdivacky  explicit UnresolvedSetIterator(DeclsTy::const_iterator ir) :
37202879Srdivacky    ir(const_cast<DeclsTy::iterator>(ir)) {}
38208600Srdivacky
39208600Srdivacky  IteratorTy getIterator() const { return ir; }
40208600Srdivacky
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
50203955Srdivacky  NamedDecl *getDecl() const { return ir->getDecl(); }
51203955Srdivacky  AccessSpecifier getAccess() const { return ir->getAccess(); }
52207632Srdivacky  void setAccess(AccessSpecifier AS) { ir->setAccess(AS); }
53205408Srdivacky  DeclAccessPair getPair() const { return *ir; }
54202879Srdivacky
55202879Srdivacky  NamedDecl *operator*() const { return getDecl(); }
56202879Srdivacky
57202879Srdivacky  UnresolvedSetIterator &operator++() { ++ir; return *this; }
58202879Srdivacky  UnresolvedSetIterator operator++(int) { return UnresolvedSetIterator(ir++); }
59202879Srdivacky  UnresolvedSetIterator &operator--() { --ir; return *this; }
60202879Srdivacky  UnresolvedSetIterator operator--(int) { return UnresolvedSetIterator(ir--); }
61202879Srdivacky
62202879Srdivacky  UnresolvedSetIterator &operator+=(difference_type d) {
63202879Srdivacky    ir += d; return *this;
64202879Srdivacky  }
65202879Srdivacky  UnresolvedSetIterator operator+(difference_type d) const {
66202879Srdivacky    return UnresolvedSetIterator(ir + d);
67202879Srdivacky  }
68202879Srdivacky  UnresolvedSetIterator &operator-=(difference_type d) {
69202879Srdivacky    ir -= d; return *this;
70202879Srdivacky  }
71202879Srdivacky  UnresolvedSetIterator operator-(difference_type d) const {
72202879Srdivacky    return UnresolvedSetIterator(ir - d);
73202879Srdivacky  }
74202879Srdivacky  value_type operator[](difference_type d) const { return *(*this + d); }
75202879Srdivacky
76202879Srdivacky  difference_type operator-(const UnresolvedSetIterator &o) const {
77202879Srdivacky    return ir - o.ir;
78202879Srdivacky  }
79202879Srdivacky
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  bool operator>=(const UnresolvedSetIterator &o) const { return ir >= o.ir; }
85202879Srdivacky  bool operator>(const UnresolvedSetIterator &o) const { return ir > o.ir; }
86202879Srdivacky};
87202879Srdivacky
88208600Srdivacky/// UnresolvedSet - A set of unresolved declarations.
89202879Srdivackyclass UnresolvedSetImpl {
90202879Srdivacky  typedef UnresolvedSetIterator::DeclsTy DeclsTy;
91202879Srdivacky
92202879Srdivacky  // Don't allow direct construction, and only permit subclassing by
93202879Srdivacky  // UnresolvedSet.
94202879Srdivackyprivate:
95202879Srdivacky  template <unsigned N> friend class UnresolvedSet;
96202879Srdivacky  UnresolvedSetImpl() {}
97243830Sdim  UnresolvedSetImpl(const UnresolvedSetImpl &) LLVM_DELETED_FUNCTION;
98202879Srdivacky
99202879Srdivackypublic:
100202879Srdivacky  // We don't currently support assignment through this iterator, so we might
101202879Srdivacky  // as well use the same implementation twice.
102202879Srdivacky  typedef UnresolvedSetIterator iterator;
103202879Srdivacky  typedef UnresolvedSetIterator const_iterator;
104202879Srdivacky
105202879Srdivacky  iterator begin() { return iterator(decls().begin()); }
106202879Srdivacky  iterator end() { return iterator(decls().end()); }
107202879Srdivacky
108202879Srdivacky  const_iterator begin() const { return const_iterator(decls().begin()); }
109202879Srdivacky  const_iterator end() const { return const_iterator(decls().end()); }
110202879Srdivacky
111202879Srdivacky  void addDecl(NamedDecl *D) {
112202879Srdivacky    addDecl(D, AS_none);
113202879Srdivacky  }
114202879Srdivacky
115202879Srdivacky  void addDecl(NamedDecl *D, AccessSpecifier AS) {
116203955Srdivacky    decls().push_back(DeclAccessPair::make(D, AS));
117202879Srdivacky  }
118202879Srdivacky
119202879Srdivacky  /// Replaces the given declaration with the new one, once.
120202879Srdivacky  ///
121202879Srdivacky  /// \return true if the set changed
122202879Srdivacky  bool replace(const NamedDecl* Old, NamedDecl *New) {
123202879Srdivacky    for (DeclsTy::iterator I = decls().begin(), E = decls().end(); I != E; ++I)
124203955Srdivacky      if (I->getDecl() == Old)
125203955Srdivacky        return (I->setDecl(New), true);
126202879Srdivacky    return false;
127202879Srdivacky  }
128202879Srdivacky
129202879Srdivacky  /// Replaces the declaration at the given iterator with the new one,
130202879Srdivacky  /// preserving the original access bits.
131202879Srdivacky  void replace(iterator I, NamedDecl *New) {
132203955Srdivacky    I.ir->setDecl(New);
133202879Srdivacky  }
134202879Srdivacky
135202879Srdivacky  void replace(iterator I, NamedDecl *New, AccessSpecifier AS) {
136203955Srdivacky    I.ir->set(New, AS);
137202879Srdivacky  }
138202879Srdivacky
139203955Srdivacky  void erase(unsigned I) {
140203955Srdivacky    decls()[I] = decls().back();
141203955Srdivacky    decls().pop_back();
142203955Srdivacky  }
143203955Srdivacky
144202879Srdivacky  void erase(iterator I) {
145202879Srdivacky    *I.ir = decls().back();
146202879Srdivacky    decls().pop_back();
147202879Srdivacky  }
148202879Srdivacky
149203955Srdivacky  void setAccess(iterator I, AccessSpecifier AS) {
150203955Srdivacky    I.ir->setAccess(AS);
151203955Srdivacky  }
152203955Srdivacky
153202879Srdivacky  void clear() { decls().clear(); }
154202879Srdivacky  void set_size(unsigned N) { decls().set_size(N); }
155202879Srdivacky
156202879Srdivacky  bool empty() const { return decls().empty(); }
157202879Srdivacky  unsigned size() const { return decls().size(); }
158202879Srdivacky
159202879Srdivacky  void append(iterator I, iterator E) {
160202879Srdivacky    decls().append(I.ir, E.ir);
161202879Srdivacky  }
162202879Srdivacky
163203955Srdivacky  DeclAccessPair &operator[](unsigned I) { return decls()[I]; }
164203955Srdivacky  const DeclAccessPair &operator[](unsigned I) const { return decls()[I]; }
165202879Srdivacky
166202879Srdivackyprivate:
167202879Srdivacky  // These work because the only permitted subclass is UnresolvedSetImpl
168202879Srdivacky
169202879Srdivacky  DeclsTy &decls() {
170202879Srdivacky    return *reinterpret_cast<DeclsTy*>(this);
171202879Srdivacky  }
172202879Srdivacky  const DeclsTy &decls() const {
173202879Srdivacky    return *reinterpret_cast<const DeclsTy*>(this);
174202879Srdivacky  }
175202879Srdivacky};
176202879Srdivacky
177202879Srdivacky/// A set of unresolved declarations
178202879Srdivackytemplate <unsigned InlineCapacity> class UnresolvedSet :
179202879Srdivacky    public UnresolvedSetImpl {
180226633Sdim  SmallVector<DeclAccessPair, InlineCapacity> Decls;
181202879Srdivacky};
182202879Srdivacky
183202879Srdivacky
184202879Srdivacky} // namespace clang
185202879Srdivacky
186202879Srdivacky#endif
187