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