1eec51cf1ba5f0e62c9cdb81b5c63babdd6e649abJohn McCall//===-- UnresolvedSet.h - Unresolved sets of declarations  ------*- C++ -*-===//
2eec51cf1ba5f0e62c9cdb81b5c63babdd6e649abJohn McCall//
3eec51cf1ba5f0e62c9cdb81b5c63babdd6e649abJohn McCall//                     The LLVM Compiler Infrastructure
4eec51cf1ba5f0e62c9cdb81b5c63babdd6e649abJohn McCall//
5eec51cf1ba5f0e62c9cdb81b5c63babdd6e649abJohn McCall// This file is distributed under the University of Illinois Open Source
6eec51cf1ba5f0e62c9cdb81b5c63babdd6e649abJohn McCall// License. See LICENSE.TXT for details.
7eec51cf1ba5f0e62c9cdb81b5c63babdd6e649abJohn McCall//
8eec51cf1ba5f0e62c9cdb81b5c63babdd6e649abJohn McCall//===----------------------------------------------------------------------===//
9eec51cf1ba5f0e62c9cdb81b5c63babdd6e649abJohn McCall//
10eec51cf1ba5f0e62c9cdb81b5c63babdd6e649abJohn McCall//  This file defines the UnresolvedSet class, which is used to store
11eec51cf1ba5f0e62c9cdb81b5c63babdd6e649abJohn McCall//  collections of declarations in the AST.
12eec51cf1ba5f0e62c9cdb81b5c63babdd6e649abJohn McCall//
13eec51cf1ba5f0e62c9cdb81b5c63babdd6e649abJohn McCall//===----------------------------------------------------------------------===//
14eec51cf1ba5f0e62c9cdb81b5c63babdd6e649abJohn McCall
15eec51cf1ba5f0e62c9cdb81b5c63babdd6e649abJohn McCall#ifndef LLVM_CLANG_AST_UNRESOLVEDSET_H
16eec51cf1ba5f0e62c9cdb81b5c63babdd6e649abJohn McCall#define LLVM_CLANG_AST_UNRESOLVEDSET_H
17eec51cf1ba5f0e62c9cdb81b5c63babdd6e649abJohn McCall
18eec51cf1ba5f0e62c9cdb81b5c63babdd6e649abJohn McCall#include <iterator>
197264fa161fe77b74163417ce7ab28e3da46381f7John McCall#include "llvm/ADT/SmallVector.h"
20161755a09898c95d21bfff33707da9ca41cd53c5John McCall#include "clang/AST/DeclAccessPair.h"
21b13b737a2450167c82e148590e8019b839ce6b98John McCall
22b13b737a2450167c82e148590e8019b839ce6b98John McCallnamespace clang {
23b13b737a2450167c82e148590e8019b839ce6b98John McCall
24eec51cf1ba5f0e62c9cdb81b5c63babdd6e649abJohn McCall/// The iterator over UnresolvedSets.  Serves as both the const and
25eec51cf1ba5f0e62c9cdb81b5c63babdd6e649abJohn McCall/// non-const iterator.
26eec51cf1ba5f0e62c9cdb81b5c63babdd6e649abJohn McCallclass UnresolvedSetIterator {
27b13b737a2450167c82e148590e8019b839ce6b98John McCallprivate:
28686775deca8b8685eb90801495880e3abdd844c2Chris Lattner  typedef SmallVectorImpl<DeclAccessPair> DeclsTy;
29eec51cf1ba5f0e62c9cdb81b5c63babdd6e649abJohn McCall  typedef DeclsTy::iterator IteratorTy;
30eec51cf1ba5f0e62c9cdb81b5c63babdd6e649abJohn McCall
31eec51cf1ba5f0e62c9cdb81b5c63babdd6e649abJohn McCall  IteratorTy ir;
32eec51cf1ba5f0e62c9cdb81b5c63babdd6e649abJohn McCall
33eec51cf1ba5f0e62c9cdb81b5c63babdd6e649abJohn McCall  friend class UnresolvedSetImpl;
34928e6fcf66fc4f342bcf7cc96bf56986c9c2a833Douglas Gregor  friend class OverloadExpr;
35eec51cf1ba5f0e62c9cdb81b5c63babdd6e649abJohn McCall  explicit UnresolvedSetIterator(DeclsTy::iterator ir) : ir(ir) {}
36eec51cf1ba5f0e62c9cdb81b5c63babdd6e649abJohn McCall  explicit UnresolvedSetIterator(DeclsTy::const_iterator ir) :
37eec51cf1ba5f0e62c9cdb81b5c63babdd6e649abJohn McCall    ir(const_cast<DeclsTy::iterator>(ir)) {}
38928e6fcf66fc4f342bcf7cc96bf56986c9c2a833Douglas Gregor
39928e6fcf66fc4f342bcf7cc96bf56986c9c2a833Douglas Gregor  IteratorTy getIterator() const { return ir; }
40928e6fcf66fc4f342bcf7cc96bf56986c9c2a833Douglas Gregor
41eec51cf1ba5f0e62c9cdb81b5c63babdd6e649abJohn McCallpublic:
42eec51cf1ba5f0e62c9cdb81b5c63babdd6e649abJohn McCall  UnresolvedSetIterator() {}
43eec51cf1ba5f0e62c9cdb81b5c63babdd6e649abJohn McCall
44eec51cf1ba5f0e62c9cdb81b5c63babdd6e649abJohn McCall  typedef std::iterator_traits<IteratorTy>::difference_type difference_type;
45eec51cf1ba5f0e62c9cdb81b5c63babdd6e649abJohn McCall  typedef NamedDecl *value_type;
46eec51cf1ba5f0e62c9cdb81b5c63babdd6e649abJohn McCall  typedef NamedDecl **pointer;
47eec51cf1ba5f0e62c9cdb81b5c63babdd6e649abJohn McCall  typedef NamedDecl *reference;
48eec51cf1ba5f0e62c9cdb81b5c63babdd6e649abJohn McCall  typedef std::iterator_traits<IteratorTy>::iterator_category iterator_category;
49eec51cf1ba5f0e62c9cdb81b5c63babdd6e649abJohn McCall
50b13b737a2450167c82e148590e8019b839ce6b98John McCall  NamedDecl *getDecl() const { return ir->getDecl(); }
51b13b737a2450167c82e148590e8019b839ce6b98John McCall  AccessSpecifier getAccess() const { return ir->getAccess(); }
526cdc161527a513f28dfc6f6ec27eb287f8268024Douglas Gregor  void setAccess(AccessSpecifier AS) { ir->setAccess(AS); }
539aa472c45d2bd81b7b52c225e8acc560d716db97John McCall  DeclAccessPair getPair() const { return *ir; }
54eec51cf1ba5f0e62c9cdb81b5c63babdd6e649abJohn McCall
55eec51cf1ba5f0e62c9cdb81b5c63babdd6e649abJohn McCall  NamedDecl *operator*() const { return getDecl(); }
56eec51cf1ba5f0e62c9cdb81b5c63babdd6e649abJohn McCall
57eec51cf1ba5f0e62c9cdb81b5c63babdd6e649abJohn McCall  UnresolvedSetIterator &operator++() { ++ir; return *this; }
58eec51cf1ba5f0e62c9cdb81b5c63babdd6e649abJohn McCall  UnresolvedSetIterator operator++(int) { return UnresolvedSetIterator(ir++); }
59eec51cf1ba5f0e62c9cdb81b5c63babdd6e649abJohn McCall  UnresolvedSetIterator &operator--() { --ir; return *this; }
60eec51cf1ba5f0e62c9cdb81b5c63babdd6e649abJohn McCall  UnresolvedSetIterator operator--(int) { return UnresolvedSetIterator(ir--); }
61eec51cf1ba5f0e62c9cdb81b5c63babdd6e649abJohn McCall
62eec51cf1ba5f0e62c9cdb81b5c63babdd6e649abJohn McCall  UnresolvedSetIterator &operator+=(difference_type d) {
63eec51cf1ba5f0e62c9cdb81b5c63babdd6e649abJohn McCall    ir += d; return *this;
64eec51cf1ba5f0e62c9cdb81b5c63babdd6e649abJohn McCall  }
65eec51cf1ba5f0e62c9cdb81b5c63babdd6e649abJohn McCall  UnresolvedSetIterator operator+(difference_type d) const {
66eec51cf1ba5f0e62c9cdb81b5c63babdd6e649abJohn McCall    return UnresolvedSetIterator(ir + d);
67eec51cf1ba5f0e62c9cdb81b5c63babdd6e649abJohn McCall  }
68eec51cf1ba5f0e62c9cdb81b5c63babdd6e649abJohn McCall  UnresolvedSetIterator &operator-=(difference_type d) {
69eec51cf1ba5f0e62c9cdb81b5c63babdd6e649abJohn McCall    ir -= d; return *this;
70eec51cf1ba5f0e62c9cdb81b5c63babdd6e649abJohn McCall  }
71eec51cf1ba5f0e62c9cdb81b5c63babdd6e649abJohn McCall  UnresolvedSetIterator operator-(difference_type d) const {
72eec51cf1ba5f0e62c9cdb81b5c63babdd6e649abJohn McCall    return UnresolvedSetIterator(ir - d);
73eec51cf1ba5f0e62c9cdb81b5c63babdd6e649abJohn McCall  }
74eec51cf1ba5f0e62c9cdb81b5c63babdd6e649abJohn McCall  value_type operator[](difference_type d) const { return *(*this + d); }
75eec51cf1ba5f0e62c9cdb81b5c63babdd6e649abJohn McCall
76eec51cf1ba5f0e62c9cdb81b5c63babdd6e649abJohn McCall  difference_type operator-(const UnresolvedSetIterator &o) const {
77eec51cf1ba5f0e62c9cdb81b5c63babdd6e649abJohn McCall    return ir - o.ir;
78eec51cf1ba5f0e62c9cdb81b5c63babdd6e649abJohn McCall  }
79eec51cf1ba5f0e62c9cdb81b5c63babdd6e649abJohn McCall
80eec51cf1ba5f0e62c9cdb81b5c63babdd6e649abJohn McCall  bool operator==(const UnresolvedSetIterator &o) const { return ir == o.ir; }
81eec51cf1ba5f0e62c9cdb81b5c63babdd6e649abJohn McCall  bool operator!=(const UnresolvedSetIterator &o) const { return ir != o.ir; }
82eec51cf1ba5f0e62c9cdb81b5c63babdd6e649abJohn McCall  bool operator<(const UnresolvedSetIterator &o) const { return ir < o.ir; }
83eec51cf1ba5f0e62c9cdb81b5c63babdd6e649abJohn McCall  bool operator<=(const UnresolvedSetIterator &o) const { return ir <= o.ir; }
84eec51cf1ba5f0e62c9cdb81b5c63babdd6e649abJohn McCall  bool operator>=(const UnresolvedSetIterator &o) const { return ir >= o.ir; }
85eec51cf1ba5f0e62c9cdb81b5c63babdd6e649abJohn McCall  bool operator>(const UnresolvedSetIterator &o) const { return ir > o.ir; }
86eec51cf1ba5f0e62c9cdb81b5c63babdd6e649abJohn McCall};
87eec51cf1ba5f0e62c9cdb81b5c63babdd6e649abJohn McCall
88928e6fcf66fc4f342bcf7cc96bf56986c9c2a833Douglas Gregor/// UnresolvedSet - A set of unresolved declarations.
89eec51cf1ba5f0e62c9cdb81b5c63babdd6e649abJohn McCallclass UnresolvedSetImpl {
90eec51cf1ba5f0e62c9cdb81b5c63babdd6e649abJohn McCall  typedef UnresolvedSetIterator::DeclsTy DeclsTy;
91eec51cf1ba5f0e62c9cdb81b5c63babdd6e649abJohn McCall
92eec51cf1ba5f0e62c9cdb81b5c63babdd6e649abJohn McCall  // Don't allow direct construction, and only permit subclassing by
93eec51cf1ba5f0e62c9cdb81b5c63babdd6e649abJohn McCall  // UnresolvedSet.
94eec51cf1ba5f0e62c9cdb81b5c63babdd6e649abJohn McCallprivate:
95eec51cf1ba5f0e62c9cdb81b5c63babdd6e649abJohn McCall  template <unsigned N> friend class UnresolvedSet;
96eec51cf1ba5f0e62c9cdb81b5c63babdd6e649abJohn McCall  UnresolvedSetImpl() {}
97eec51cf1ba5f0e62c9cdb81b5c63babdd6e649abJohn McCall  UnresolvedSetImpl(const UnresolvedSetImpl &) {}
98eec51cf1ba5f0e62c9cdb81b5c63babdd6e649abJohn McCall
99eec51cf1ba5f0e62c9cdb81b5c63babdd6e649abJohn McCallpublic:
100eec51cf1ba5f0e62c9cdb81b5c63babdd6e649abJohn McCall  // We don't currently support assignment through this iterator, so we might
101eec51cf1ba5f0e62c9cdb81b5c63babdd6e649abJohn McCall  // as well use the same implementation twice.
102eec51cf1ba5f0e62c9cdb81b5c63babdd6e649abJohn McCall  typedef UnresolvedSetIterator iterator;
103eec51cf1ba5f0e62c9cdb81b5c63babdd6e649abJohn McCall  typedef UnresolvedSetIterator const_iterator;
104eec51cf1ba5f0e62c9cdb81b5c63babdd6e649abJohn McCall
105eec51cf1ba5f0e62c9cdb81b5c63babdd6e649abJohn McCall  iterator begin() { return iterator(decls().begin()); }
106eec51cf1ba5f0e62c9cdb81b5c63babdd6e649abJohn McCall  iterator end() { return iterator(decls().end()); }
107eec51cf1ba5f0e62c9cdb81b5c63babdd6e649abJohn McCall
108eec51cf1ba5f0e62c9cdb81b5c63babdd6e649abJohn McCall  const_iterator begin() const { return const_iterator(decls().begin()); }
109eec51cf1ba5f0e62c9cdb81b5c63babdd6e649abJohn McCall  const_iterator end() const { return const_iterator(decls().end()); }
110eec51cf1ba5f0e62c9cdb81b5c63babdd6e649abJohn McCall
111eec51cf1ba5f0e62c9cdb81b5c63babdd6e649abJohn McCall  void addDecl(NamedDecl *D) {
112eec51cf1ba5f0e62c9cdb81b5c63babdd6e649abJohn McCall    addDecl(D, AS_none);
113eec51cf1ba5f0e62c9cdb81b5c63babdd6e649abJohn McCall  }
114eec51cf1ba5f0e62c9cdb81b5c63babdd6e649abJohn McCall
115eec51cf1ba5f0e62c9cdb81b5c63babdd6e649abJohn McCall  void addDecl(NamedDecl *D, AccessSpecifier AS) {
116b13b737a2450167c82e148590e8019b839ce6b98John McCall    decls().push_back(DeclAccessPair::make(D, AS));
117eec51cf1ba5f0e62c9cdb81b5c63babdd6e649abJohn McCall  }
118eec51cf1ba5f0e62c9cdb81b5c63babdd6e649abJohn McCall
119eec51cf1ba5f0e62c9cdb81b5c63babdd6e649abJohn McCall  /// Replaces the given declaration with the new one, once.
120eec51cf1ba5f0e62c9cdb81b5c63babdd6e649abJohn McCall  ///
121eec51cf1ba5f0e62c9cdb81b5c63babdd6e649abJohn McCall  /// \return true if the set changed
122eec51cf1ba5f0e62c9cdb81b5c63babdd6e649abJohn McCall  bool replace(const NamedDecl* Old, NamedDecl *New) {
123eec51cf1ba5f0e62c9cdb81b5c63babdd6e649abJohn McCall    for (DeclsTy::iterator I = decls().begin(), E = decls().end(); I != E; ++I)
124b13b737a2450167c82e148590e8019b839ce6b98John McCall      if (I->getDecl() == Old)
125b13b737a2450167c82e148590e8019b839ce6b98John McCall        return (I->setDecl(New), true);
126eec51cf1ba5f0e62c9cdb81b5c63babdd6e649abJohn McCall    return false;
127eec51cf1ba5f0e62c9cdb81b5c63babdd6e649abJohn McCall  }
128eec51cf1ba5f0e62c9cdb81b5c63babdd6e649abJohn McCall
129eec51cf1ba5f0e62c9cdb81b5c63babdd6e649abJohn McCall  /// Replaces the declaration at the given iterator with the new one,
130eec51cf1ba5f0e62c9cdb81b5c63babdd6e649abJohn McCall  /// preserving the original access bits.
131eec51cf1ba5f0e62c9cdb81b5c63babdd6e649abJohn McCall  void replace(iterator I, NamedDecl *New) {
132b13b737a2450167c82e148590e8019b839ce6b98John McCall    I.ir->setDecl(New);
133eec51cf1ba5f0e62c9cdb81b5c63babdd6e649abJohn McCall  }
134eec51cf1ba5f0e62c9cdb81b5c63babdd6e649abJohn McCall
135eec51cf1ba5f0e62c9cdb81b5c63babdd6e649abJohn McCall  void replace(iterator I, NamedDecl *New, AccessSpecifier AS) {
136b13b737a2450167c82e148590e8019b839ce6b98John McCall    I.ir->set(New, AS);
137eec51cf1ba5f0e62c9cdb81b5c63babdd6e649abJohn McCall  }
138eec51cf1ba5f0e62c9cdb81b5c63babdd6e649abJohn McCall
139c373d48502ca7683ab55385f5bd624d778eb288dJohn McCall  void erase(unsigned I) {
140c373d48502ca7683ab55385f5bd624d778eb288dJohn McCall    decls()[I] = decls().back();
141c373d48502ca7683ab55385f5bd624d778eb288dJohn McCall    decls().pop_back();
142c373d48502ca7683ab55385f5bd624d778eb288dJohn McCall  }
143c373d48502ca7683ab55385f5bd624d778eb288dJohn McCall
144eec51cf1ba5f0e62c9cdb81b5c63babdd6e649abJohn McCall  void erase(iterator I) {
145eec51cf1ba5f0e62c9cdb81b5c63babdd6e649abJohn McCall    *I.ir = decls().back();
146eec51cf1ba5f0e62c9cdb81b5c63babdd6e649abJohn McCall    decls().pop_back();
147eec51cf1ba5f0e62c9cdb81b5c63babdd6e649abJohn McCall  }
148eec51cf1ba5f0e62c9cdb81b5c63babdd6e649abJohn McCall
149233a6419097ed97b67ff8efcacef9af613262ca3John McCall  void setAccess(iterator I, AccessSpecifier AS) {
150b13b737a2450167c82e148590e8019b839ce6b98John McCall    I.ir->setAccess(AS);
151233a6419097ed97b67ff8efcacef9af613262ca3John McCall  }
152233a6419097ed97b67ff8efcacef9af613262ca3John McCall
153eec51cf1ba5f0e62c9cdb81b5c63babdd6e649abJohn McCall  void clear() { decls().clear(); }
154eec51cf1ba5f0e62c9cdb81b5c63babdd6e649abJohn McCall  void set_size(unsigned N) { decls().set_size(N); }
155eec51cf1ba5f0e62c9cdb81b5c63babdd6e649abJohn McCall
156eec51cf1ba5f0e62c9cdb81b5c63babdd6e649abJohn McCall  bool empty() const { return decls().empty(); }
157eec51cf1ba5f0e62c9cdb81b5c63babdd6e649abJohn McCall  unsigned size() const { return decls().size(); }
158eec51cf1ba5f0e62c9cdb81b5c63babdd6e649abJohn McCall
159eec51cf1ba5f0e62c9cdb81b5c63babdd6e649abJohn McCall  void append(iterator I, iterator E) {
160eec51cf1ba5f0e62c9cdb81b5c63babdd6e649abJohn McCall    decls().append(I.ir, E.ir);
161eec51cf1ba5f0e62c9cdb81b5c63babdd6e649abJohn McCall  }
162eec51cf1ba5f0e62c9cdb81b5c63babdd6e649abJohn McCall
163b13b737a2450167c82e148590e8019b839ce6b98John McCall  DeclAccessPair &operator[](unsigned I) { return decls()[I]; }
164b13b737a2450167c82e148590e8019b839ce6b98John McCall  const DeclAccessPair &operator[](unsigned I) const { return decls()[I]; }
165eec51cf1ba5f0e62c9cdb81b5c63babdd6e649abJohn McCall
166eec51cf1ba5f0e62c9cdb81b5c63babdd6e649abJohn McCallprivate:
167eec51cf1ba5f0e62c9cdb81b5c63babdd6e649abJohn McCall  // These work because the only permitted subclass is UnresolvedSetImpl
168eec51cf1ba5f0e62c9cdb81b5c63babdd6e649abJohn McCall
169eec51cf1ba5f0e62c9cdb81b5c63babdd6e649abJohn McCall  DeclsTy &decls() {
170eec51cf1ba5f0e62c9cdb81b5c63babdd6e649abJohn McCall    return *reinterpret_cast<DeclsTy*>(this);
171eec51cf1ba5f0e62c9cdb81b5c63babdd6e649abJohn McCall  }
172eec51cf1ba5f0e62c9cdb81b5c63babdd6e649abJohn McCall  const DeclsTy &decls() const {
173eec51cf1ba5f0e62c9cdb81b5c63babdd6e649abJohn McCall    return *reinterpret_cast<const DeclsTy*>(this);
174eec51cf1ba5f0e62c9cdb81b5c63babdd6e649abJohn McCall  }
175eec51cf1ba5f0e62c9cdb81b5c63babdd6e649abJohn McCall};
176eec51cf1ba5f0e62c9cdb81b5c63babdd6e649abJohn McCall
177eec51cf1ba5f0e62c9cdb81b5c63babdd6e649abJohn McCall/// A set of unresolved declarations
178eec51cf1ba5f0e62c9cdb81b5c63babdd6e649abJohn McCalltemplate <unsigned InlineCapacity> class UnresolvedSet :
179eec51cf1ba5f0e62c9cdb81b5c63babdd6e649abJohn McCall    public UnresolvedSetImpl {
180686775deca8b8685eb90801495880e3abdd844c2Chris Lattner  SmallVector<DeclAccessPair, InlineCapacity> Decls;
181eec51cf1ba5f0e62c9cdb81b5c63babdd6e649abJohn McCall};
182eec51cf1ba5f0e62c9cdb81b5c63babdd6e649abJohn McCall
183eec51cf1ba5f0e62c9cdb81b5c63babdd6e649abJohn McCall
184eec51cf1ba5f0e62c9cdb81b5c63babdd6e649abJohn McCall} // namespace clang
185eec51cf1ba5f0e62c9cdb81b5c63babdd6e649abJohn McCall
186eec51cf1ba5f0e62c9cdb81b5c63babdd6e649abJohn McCall#endif
187