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