Eugene Zelenko | 21fadad | 2017-11-21 23:26:08 +0000 | [diff] [blame] | 1 | //===- UnresolvedSet.h - Unresolved sets of declarations --------*- C++ -*-===// |
John McCall | ad37125 | 2010-01-20 00:46:10 +0000 | [diff] [blame] | 2 | // |
Chandler Carruth | 2946cd7 | 2019-01-19 08:50:56 +0000 | [diff] [blame] | 3 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. |
| 4 | // See https://llvm.org/LICENSE.txt for license information. |
| 5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception |
John McCall | ad37125 | 2010-01-20 00:46:10 +0000 | [diff] [blame] | 6 | // |
| 7 | //===----------------------------------------------------------------------===// |
| 8 | // |
| 9 | // This file defines the UnresolvedSet class, which is used to store |
| 10 | // collections of declarations in the AST. |
| 11 | // |
| 12 | //===----------------------------------------------------------------------===// |
| 13 | |
| 14 | #ifndef LLVM_CLANG_AST_UNRESOLVEDSET_H |
| 15 | #define LLVM_CLANG_AST_UNRESOLVEDSET_H |
| 16 | |
John McCall | a8ae222 | 2010-04-06 21:38:20 +0000 | [diff] [blame] | 17 | #include "clang/AST/DeclAccessPair.h" |
Benjamin Kramer | ea70eb3 | 2012-12-01 15:09:41 +0000 | [diff] [blame] | 18 | #include "clang/Basic/LLVM.h" |
Eugene Zelenko | 21fadad | 2017-11-21 23:26:08 +0000 | [diff] [blame] | 19 | #include "clang/Basic/Specifiers.h" |
Richard Smith | bbaaeb4 | 2019-12-10 11:34:49 -0800 | [diff] [blame] | 20 | #include "llvm/ADT/ArrayRef.h" |
Benjamin Kramer | ea70eb3 | 2012-12-01 15:09:41 +0000 | [diff] [blame] | 21 | #include "llvm/ADT/SmallVector.h" |
Benjamin Kramer | 04ec7e3 | 2015-02-01 20:31:36 +0000 | [diff] [blame] | 22 | #include "llvm/ADT/iterator.h" |
Eugene Zelenko | 21fadad | 2017-11-21 23:26:08 +0000 | [diff] [blame] | 23 | #include <cstddef> |
| 24 | #include <iterator> |
John McCall | 760af17 | 2010-02-01 03:16:54 +0000 | [diff] [blame] | 25 | |
| 26 | namespace clang { |
| 27 | |
Eugene Zelenko | 21fadad | 2017-11-21 23:26:08 +0000 | [diff] [blame] | 28 | class NamedDecl; |
| 29 | |
John McCall | ad37125 | 2010-01-20 00:46:10 +0000 | [diff] [blame] | 30 | /// The iterator over UnresolvedSets. Serves as both the const and |
| 31 | /// non-const iterator. |
Benjamin Kramer | 04ec7e3 | 2015-02-01 20:31:36 +0000 | [diff] [blame] | 32 | class UnresolvedSetIterator : public llvm::iterator_adaptor_base< |
| 33 | UnresolvedSetIterator, DeclAccessPair *, |
| 34 | std::random_access_iterator_tag, NamedDecl *, |
| 35 | std::ptrdiff_t, NamedDecl *, NamedDecl *> { |
Argyrios Kyrtzidis | 0f05fb9 | 2012-11-28 03:56:16 +0000 | [diff] [blame] | 36 | friend class ASTUnresolvedSet; |
Douglas Gregor | c69978f | 2010-05-23 19:36:40 +0000 | [diff] [blame] | 37 | friend class OverloadExpr; |
Eugene Zelenko | 21fadad | 2017-11-21 23:26:08 +0000 | [diff] [blame] | 38 | friend class UnresolvedSetImpl; |
Benjamin Kramer | 04ec7e3 | 2015-02-01 20:31:36 +0000 | [diff] [blame] | 39 | |
| 40 | explicit UnresolvedSetIterator(DeclAccessPair *Iter) |
| 41 | : iterator_adaptor_base(Iter) {} |
| 42 | explicit UnresolvedSetIterator(const DeclAccessPair *Iter) |
| 43 | : iterator_adaptor_base(const_cast<DeclAccessPair *>(Iter)) {} |
| 44 | |
John McCall | ad37125 | 2010-01-20 00:46:10 +0000 | [diff] [blame] | 45 | public: |
Reid Kleckner | d0ea597 | 2016-08-16 20:20:56 +0000 | [diff] [blame] | 46 | // Work around a bug in MSVC 2013 where explicitly default constructed |
| 47 | // temporaries with defaulted ctors are not zero initialized. |
| 48 | UnresolvedSetIterator() : iterator_adaptor_base(nullptr) {} |
John McCall | ad37125 | 2010-01-20 00:46:10 +0000 | [diff] [blame] | 49 | |
Benjamin Kramer | 04ec7e3 | 2015-02-01 20:31:36 +0000 | [diff] [blame] | 50 | NamedDecl *getDecl() const { return I->getDecl(); } |
| 51 | void setDecl(NamedDecl *ND) const { return I->setDecl(ND); } |
| 52 | AccessSpecifier getAccess() const { return I->getAccess(); } |
| 53 | void setAccess(AccessSpecifier AS) { I->setAccess(AS); } |
| 54 | const DeclAccessPair &getPair() const { return *I; } |
John McCall | ad37125 | 2010-01-20 00:46:10 +0000 | [diff] [blame] | 55 | |
| 56 | NamedDecl *operator*() const { return getDecl(); } |
Benjamin Kramer | 04ec7e3 | 2015-02-01 20:31:36 +0000 | [diff] [blame] | 57 | NamedDecl *operator->() const { return **this; } |
John McCall | ad37125 | 2010-01-20 00:46:10 +0000 | [diff] [blame] | 58 | }; |
| 59 | |
Adrian Prantl | 9fc8faf | 2018-05-09 01:00:01 +0000 | [diff] [blame] | 60 | /// A set of unresolved declarations. |
John McCall | ad37125 | 2010-01-20 00:46:10 +0000 | [diff] [blame] | 61 | class UnresolvedSetImpl { |
Eugene Zelenko | 21fadad | 2017-11-21 23:26:08 +0000 | [diff] [blame] | 62 | using DeclsTy = SmallVectorImpl<DeclAccessPair>; |
John McCall | ad37125 | 2010-01-20 00:46:10 +0000 | [diff] [blame] | 63 | |
| 64 | // Don't allow direct construction, and only permit subclassing by |
| 65 | // UnresolvedSet. |
| 66 | private: |
| 67 | template <unsigned N> friend class UnresolvedSet; |
Eugene Zelenko | 21fadad | 2017-11-21 23:26:08 +0000 | [diff] [blame] | 68 | |
David Blaikie | a9ff7a1 | 2016-03-17 18:05:07 +0000 | [diff] [blame] | 69 | UnresolvedSetImpl() = default; |
| 70 | UnresolvedSetImpl(const UnresolvedSetImpl &) = default; |
David Blaikie | a9ff7a1 | 2016-03-17 18:05:07 +0000 | [diff] [blame] | 71 | UnresolvedSetImpl &operator=(const UnresolvedSetImpl &) = default; |
John McCall | ad37125 | 2010-01-20 00:46:10 +0000 | [diff] [blame] | 72 | |
David Blaikie | 2522f8b | 2016-03-17 20:45:38 +0000 | [diff] [blame] | 73 | // FIXME: Switch these to "= default" once MSVC supports generating move ops |
| 74 | UnresolvedSetImpl(UnresolvedSetImpl &&) {} |
| 75 | UnresolvedSetImpl &operator=(UnresolvedSetImpl &&) { return *this; } |
| 76 | |
John McCall | ad37125 | 2010-01-20 00:46:10 +0000 | [diff] [blame] | 77 | public: |
| 78 | // We don't currently support assignment through this iterator, so we might |
| 79 | // as well use the same implementation twice. |
Eugene Zelenko | 21fadad | 2017-11-21 23:26:08 +0000 | [diff] [blame] | 80 | using iterator = UnresolvedSetIterator; |
| 81 | using const_iterator = UnresolvedSetIterator; |
John McCall | ad37125 | 2010-01-20 00:46:10 +0000 | [diff] [blame] | 82 | |
| 83 | iterator begin() { return iterator(decls().begin()); } |
| 84 | iterator end() { return iterator(decls().end()); } |
| 85 | |
| 86 | const_iterator begin() const { return const_iterator(decls().begin()); } |
| 87 | const_iterator end() const { return const_iterator(decls().end()); } |
| 88 | |
Richard Smith | 848934c | 2019-12-05 13:37:35 -0800 | [diff] [blame] | 89 | ArrayRef<DeclAccessPair> pairs() const { return decls(); } |
| 90 | |
John McCall | ad37125 | 2010-01-20 00:46:10 +0000 | [diff] [blame] | 91 | void addDecl(NamedDecl *D) { |
| 92 | addDecl(D, AS_none); |
| 93 | } |
| 94 | |
| 95 | void addDecl(NamedDecl *D, AccessSpecifier AS) { |
John McCall | 760af17 | 2010-02-01 03:16:54 +0000 | [diff] [blame] | 96 | decls().push_back(DeclAccessPair::make(D, AS)); |
John McCall | ad37125 | 2010-01-20 00:46:10 +0000 | [diff] [blame] | 97 | } |
| 98 | |
| 99 | /// Replaces the given declaration with the new one, once. |
| 100 | /// |
| 101 | /// \return true if the set changed |
| 102 | bool replace(const NamedDecl* Old, NamedDecl *New) { |
| 103 | for (DeclsTy::iterator I = decls().begin(), E = decls().end(); I != E; ++I) |
John McCall | 760af17 | 2010-02-01 03:16:54 +0000 | [diff] [blame] | 104 | if (I->getDecl() == Old) |
| 105 | return (I->setDecl(New), true); |
John McCall | ad37125 | 2010-01-20 00:46:10 +0000 | [diff] [blame] | 106 | return false; |
| 107 | } |
| 108 | |
| 109 | /// Replaces the declaration at the given iterator with the new one, |
| 110 | /// preserving the original access bits. |
Benjamin Kramer | 04ec7e3 | 2015-02-01 20:31:36 +0000 | [diff] [blame] | 111 | void replace(iterator I, NamedDecl *New) { I.I->setDecl(New); } |
John McCall | ad37125 | 2010-01-20 00:46:10 +0000 | [diff] [blame] | 112 | |
| 113 | void replace(iterator I, NamedDecl *New, AccessSpecifier AS) { |
Benjamin Kramer | 04ec7e3 | 2015-02-01 20:31:36 +0000 | [diff] [blame] | 114 | I.I->set(New, AS); |
John McCall | ad37125 | 2010-01-20 00:46:10 +0000 | [diff] [blame] | 115 | } |
| 116 | |
Robert Wilhelm | 25284cc | 2013-08-23 16:11:15 +0000 | [diff] [blame] | 117 | void erase(unsigned I) { decls()[I] = decls().pop_back_val(); } |
John McCall | 58cc69d | 2010-01-27 01:50:18 +0000 | [diff] [blame] | 118 | |
Benjamin Kramer | 04ec7e3 | 2015-02-01 20:31:36 +0000 | [diff] [blame] | 119 | void erase(iterator I) { *I.I = decls().pop_back_val(); } |
John McCall | ad37125 | 2010-01-20 00:46:10 +0000 | [diff] [blame] | 120 | |
Benjamin Kramer | 04ec7e3 | 2015-02-01 20:31:36 +0000 | [diff] [blame] | 121 | void setAccess(iterator I, AccessSpecifier AS) { I.I->setAccess(AS); } |
John McCall | 2cb9416 | 2010-01-28 07:38:46 +0000 | [diff] [blame] | 122 | |
John McCall | ad37125 | 2010-01-20 00:46:10 +0000 | [diff] [blame] | 123 | void clear() { decls().clear(); } |
| 124 | void set_size(unsigned N) { decls().set_size(N); } |
| 125 | |
| 126 | bool empty() const { return decls().empty(); } |
| 127 | unsigned size() const { return decls().size(); } |
| 128 | |
Benjamin Kramer | 04ec7e3 | 2015-02-01 20:31:36 +0000 | [diff] [blame] | 129 | void append(iterator I, iterator E) { decls().append(I.I, E.I); } |
John McCall | ad37125 | 2010-01-20 00:46:10 +0000 | [diff] [blame] | 130 | |
Richard Smith | 848934c | 2019-12-05 13:37:35 -0800 | [diff] [blame] | 131 | template<typename Iter> void assign(Iter I, Iter E) { decls().assign(I, E); } |
| 132 | |
John McCall | 760af17 | 2010-02-01 03:16:54 +0000 | [diff] [blame] | 133 | DeclAccessPair &operator[](unsigned I) { return decls()[I]; } |
| 134 | const DeclAccessPair &operator[](unsigned I) const { return decls()[I]; } |
John McCall | ad37125 | 2010-01-20 00:46:10 +0000 | [diff] [blame] | 135 | |
| 136 | private: |
| 137 | // These work because the only permitted subclass is UnresolvedSetImpl |
| 138 | |
| 139 | DeclsTy &decls() { |
| 140 | return *reinterpret_cast<DeclsTy*>(this); |
| 141 | } |
| 142 | const DeclsTy &decls() const { |
| 143 | return *reinterpret_cast<const DeclsTy*>(this); |
| 144 | } |
| 145 | }; |
| 146 | |
Adrian Prantl | 9fc8faf | 2018-05-09 01:00:01 +0000 | [diff] [blame] | 147 | /// A set of unresolved declarations. |
John McCall | ad37125 | 2010-01-20 00:46:10 +0000 | [diff] [blame] | 148 | template <unsigned InlineCapacity> class UnresolvedSet : |
| 149 | public UnresolvedSetImpl { |
Chris Lattner | 01cf8db | 2011-07-20 06:58:45 +0000 | [diff] [blame] | 150 | SmallVector<DeclAccessPair, InlineCapacity> Decls; |
John McCall | ad37125 | 2010-01-20 00:46:10 +0000 | [diff] [blame] | 151 | }; |
| 152 | |
Fangrui Song | 6907ce2 | 2018-07-30 19:24:48 +0000 | [diff] [blame] | 153 | |
John McCall | ad37125 | 2010-01-20 00:46:10 +0000 | [diff] [blame] | 154 | } // namespace clang |
| 155 | |
Eugene Zelenko | 21fadad | 2017-11-21 23:26:08 +0000 | [diff] [blame] | 156 | #endif // LLVM_CLANG_AST_UNRESOLVEDSET_H |