summaryrefslogtreecommitdiff
path: root/clang-r353983/include/clang/AST/UnresolvedSet.h
diff options
context:
space:
mode:
Diffstat (limited to 'clang-r353983/include/clang/AST/UnresolvedSet.h')
-rw-r--r--clang-r353983/include/clang/AST/UnresolvedSet.h151
1 files changed, 151 insertions, 0 deletions
diff --git a/clang-r353983/include/clang/AST/UnresolvedSet.h b/clang-r353983/include/clang/AST/UnresolvedSet.h
new file mode 100644
index 00000000..cfc0b87e
--- /dev/null
+++ b/clang-r353983/include/clang/AST/UnresolvedSet.h
@@ -0,0 +1,151 @@
+//===- UnresolvedSet.h - Unresolved sets of declarations --------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines the UnresolvedSet class, which is used to store
+// collections of declarations in the AST.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_AST_UNRESOLVEDSET_H
+#define LLVM_CLANG_AST_UNRESOLVEDSET_H
+
+#include "clang/AST/DeclAccessPair.h"
+#include "clang/Basic/LLVM.h"
+#include "clang/Basic/Specifiers.h"
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/iterator.h"
+#include <cstddef>
+#include <iterator>
+
+namespace clang {
+
+class NamedDecl;
+
+/// The iterator over UnresolvedSets. Serves as both the const and
+/// non-const iterator.
+class UnresolvedSetIterator : public llvm::iterator_adaptor_base<
+ UnresolvedSetIterator, DeclAccessPair *,
+ std::random_access_iterator_tag, NamedDecl *,
+ std::ptrdiff_t, NamedDecl *, NamedDecl *> {
+ friend class ASTUnresolvedSet;
+ friend class OverloadExpr;
+ friend class UnresolvedSetImpl;
+
+ explicit UnresolvedSetIterator(DeclAccessPair *Iter)
+ : iterator_adaptor_base(Iter) {}
+ explicit UnresolvedSetIterator(const DeclAccessPair *Iter)
+ : iterator_adaptor_base(const_cast<DeclAccessPair *>(Iter)) {}
+
+public:
+ // Work around a bug in MSVC 2013 where explicitly default constructed
+ // temporaries with defaulted ctors are not zero initialized.
+ UnresolvedSetIterator() : iterator_adaptor_base(nullptr) {}
+
+ NamedDecl *getDecl() const { return I->getDecl(); }
+ void setDecl(NamedDecl *ND) const { return I->setDecl(ND); }
+ AccessSpecifier getAccess() const { return I->getAccess(); }
+ void setAccess(AccessSpecifier AS) { I->setAccess(AS); }
+ const DeclAccessPair &getPair() const { return *I; }
+
+ NamedDecl *operator*() const { return getDecl(); }
+ NamedDecl *operator->() const { return **this; }
+};
+
+/// A set of unresolved declarations.
+class UnresolvedSetImpl {
+ using DeclsTy = SmallVectorImpl<DeclAccessPair>;
+
+ // Don't allow direct construction, and only permit subclassing by
+ // UnresolvedSet.
+private:
+ template <unsigned N> friend class UnresolvedSet;
+
+ UnresolvedSetImpl() = default;
+ UnresolvedSetImpl(const UnresolvedSetImpl &) = default;
+ UnresolvedSetImpl &operator=(const UnresolvedSetImpl &) = default;
+
+ // FIXME: Switch these to "= default" once MSVC supports generating move ops
+ UnresolvedSetImpl(UnresolvedSetImpl &&) {}
+ UnresolvedSetImpl &operator=(UnresolvedSetImpl &&) { return *this; }
+
+public:
+ // We don't currently support assignment through this iterator, so we might
+ // as well use the same implementation twice.
+ using iterator = UnresolvedSetIterator;
+ using const_iterator = UnresolvedSetIterator;
+
+ iterator begin() { return iterator(decls().begin()); }
+ iterator end() { return iterator(decls().end()); }
+
+ const_iterator begin() const { return const_iterator(decls().begin()); }
+ const_iterator end() const { return const_iterator(decls().end()); }
+
+ void addDecl(NamedDecl *D) {
+ addDecl(D, AS_none);
+ }
+
+ void addDecl(NamedDecl *D, AccessSpecifier AS) {
+ decls().push_back(DeclAccessPair::make(D, AS));
+ }
+
+ /// Replaces the given declaration with the new one, once.
+ ///
+ /// \return true if the set changed
+ bool replace(const NamedDecl* Old, NamedDecl *New) {
+ for (DeclsTy::iterator I = decls().begin(), E = decls().end(); I != E; ++I)
+ if (I->getDecl() == Old)
+ return (I->setDecl(New), true);
+ return false;
+ }
+
+ /// Replaces the declaration at the given iterator with the new one,
+ /// preserving the original access bits.
+ void replace(iterator I, NamedDecl *New) { I.I->setDecl(New); }
+
+ void replace(iterator I, NamedDecl *New, AccessSpecifier AS) {
+ I.I->set(New, AS);
+ }
+
+ void erase(unsigned I) { decls()[I] = decls().pop_back_val(); }
+
+ void erase(iterator I) { *I.I = decls().pop_back_val(); }
+
+ void setAccess(iterator I, AccessSpecifier AS) { I.I->setAccess(AS); }
+
+ void clear() { decls().clear(); }
+ void set_size(unsigned N) { decls().set_size(N); }
+
+ bool empty() const { return decls().empty(); }
+ unsigned size() const { return decls().size(); }
+
+ void append(iterator I, iterator E) { decls().append(I.I, E.I); }
+
+ DeclAccessPair &operator[](unsigned I) { return decls()[I]; }
+ const DeclAccessPair &operator[](unsigned I) const { return decls()[I]; }
+
+private:
+ // These work because the only permitted subclass is UnresolvedSetImpl
+
+ DeclsTy &decls() {
+ return *reinterpret_cast<DeclsTy*>(this);
+ }
+ const DeclsTy &decls() const {
+ return *reinterpret_cast<const DeclsTy*>(this);
+ }
+};
+
+/// A set of unresolved declarations.
+template <unsigned InlineCapacity> class UnresolvedSet :
+ public UnresolvedSetImpl {
+ SmallVector<DeclAccessPair, InlineCapacity> Decls;
+};
+
+
+} // namespace clang
+
+#endif // LLVM_CLANG_AST_UNRESOLVEDSET_H