diff options
author | rdivacky <rdivacky@FreeBSD.org> | 2010-01-23 11:10:26 +0000 |
---|---|---|
committer | rdivacky <rdivacky@FreeBSD.org> | 2010-01-23 11:10:26 +0000 |
commit | 2fce988e86bc01829142e4362d4eff1af0925147 (patch) | |
tree | c69d3f4f13d508570bb5257a6aea735f88bdf09c /include/clang/AST/UnresolvedSet.h | |
parent | a3fa5c7f1b5e2ba4d6ec033dc0e2376326b05824 (diff) | |
download | FreeBSD-src-2fce988e86bc01829142e4362d4eff1af0925147.zip FreeBSD-src-2fce988e86bc01829142e4362d4eff1af0925147.tar.gz |
Update clang to r94309.
Diffstat (limited to 'include/clang/AST/UnresolvedSet.h')
-rw-r--r-- | include/clang/AST/UnresolvedSet.h | 211 |
1 files changed, 211 insertions, 0 deletions
diff --git a/include/clang/AST/UnresolvedSet.h b/include/clang/AST/UnresolvedSet.h new file mode 100644 index 0000000..055d152 --- /dev/null +++ b/include/clang/AST/UnresolvedSet.h @@ -0,0 +1,211 @@ +//===-- UnresolvedSet.h - Unresolved sets of declarations ------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// 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 <iterator> +#include "llvm/ADT/PointerIntPair.h" +#include "llvm/ADT/SmallVector.h" +#include "clang/Basic/Specifiers.h" + +namespace clang { + +class NamedDecl; + +/// The iterator over UnresolvedSets. Serves as both the const and +/// non-const iterator. +class UnresolvedSetIterator { + + typedef llvm::PointerIntPair<NamedDecl*, 2> DeclEntry; + typedef llvm::SmallVectorImpl<DeclEntry> DeclsTy; + typedef DeclsTy::iterator IteratorTy; + + IteratorTy ir; + + friend class UnresolvedSetImpl; + explicit UnresolvedSetIterator(DeclsTy::iterator ir) : ir(ir) {} + explicit UnresolvedSetIterator(DeclsTy::const_iterator ir) : + ir(const_cast<DeclsTy::iterator>(ir)) {} +public: + UnresolvedSetIterator() {} + + typedef std::iterator_traits<IteratorTy>::difference_type difference_type; + typedef NamedDecl *value_type; + typedef NamedDecl **pointer; + typedef NamedDecl *reference; + typedef std::iterator_traits<IteratorTy>::iterator_category iterator_category; + + NamedDecl *getDecl() const { return ir->getPointer(); } + AccessSpecifier getAccess() const { return AccessSpecifier(ir->getInt()); } + + NamedDecl *operator*() const { return getDecl(); } + + UnresolvedSetIterator &operator++() { ++ir; return *this; } + UnresolvedSetIterator operator++(int) { return UnresolvedSetIterator(ir++); } + UnresolvedSetIterator &operator--() { --ir; return *this; } + UnresolvedSetIterator operator--(int) { return UnresolvedSetIterator(ir--); } + + UnresolvedSetIterator &operator+=(difference_type d) { + ir += d; return *this; + } + UnresolvedSetIterator operator+(difference_type d) const { + return UnresolvedSetIterator(ir + d); + } + UnresolvedSetIterator &operator-=(difference_type d) { + ir -= d; return *this; + } + UnresolvedSetIterator operator-(difference_type d) const { + return UnresolvedSetIterator(ir - d); + } + value_type operator[](difference_type d) const { return *(*this + d); } + + difference_type operator-(const UnresolvedSetIterator &o) const { + return ir - o.ir; + } + + bool operator==(const UnresolvedSetIterator &o) const { return ir == o.ir; } + bool operator!=(const UnresolvedSetIterator &o) const { return ir != o.ir; } + bool operator<(const UnresolvedSetIterator &o) const { return ir < o.ir; } + bool operator<=(const UnresolvedSetIterator &o) const { return ir <= o.ir; } + bool operator>=(const UnresolvedSetIterator &o) const { return ir >= o.ir; } + bool operator>(const UnresolvedSetIterator &o) const { return ir > o.ir; } +}; + +/// UnresolvedSet - A set of unresolved declarations. This is needed +/// in a lot of places, but isn't really worth breaking into its own +/// header right now. +class UnresolvedSetImpl { + typedef UnresolvedSetIterator::DeclEntry DeclEntry; + typedef UnresolvedSetIterator::DeclsTy DeclsTy; + + // Don't allow direct construction, and only permit subclassing by + // UnresolvedSet. +private: + template <unsigned N> friend class UnresolvedSet; + UnresolvedSetImpl() {} + UnresolvedSetImpl(const UnresolvedSetImpl &) {} + +public: + // We don't currently support assignment through this iterator, so we might + // as well use the same implementation twice. + typedef UnresolvedSetIterator iterator; + typedef UnresolvedSetIterator const_iterator; + + 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(DeclEntry(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->getPointer() == Old) + return (I->setPointer(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.ir->setPointer(New); + } + + void replace(iterator I, NamedDecl *New, AccessSpecifier AS) { + *I.ir = DeclEntry(New, AS); + } + + void erase(iterator I) { + *I.ir = decls().back(); + decls().pop_back(); + } + + 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.ir, E.ir); + } + + /// A proxy reference for implementing operator[]. + class Proxy { + DeclEntry &Ref; + + friend class UnresolvedSetImpl; + Proxy(DeclEntry &Ref) : Ref(Ref) {} + + public: + NamedDecl *getDecl() const { return Ref.getPointer(); } + void setDecl(NamedDecl *D) { Ref.setPointer(D); } + + AccessSpecifier getAccess() const { return AccessSpecifier(Ref.getInt()); } + void setAccess(AccessSpecifier AS) const { Ref.setInt(AS); } + + NamedDecl* operator->() const { return getDecl(); } + operator NamedDecl*() const { return getDecl(); } + Proxy &operator=(const Proxy &D) { Ref = D.Ref; return *this; } + }; + Proxy operator[](unsigned I) { return Proxy(decls()[I]); } + + /// A proxy reference for implementing operator[] const. + class ConstProxy { + const DeclEntry &Ref; + + friend class UnresolvedSetImpl; + ConstProxy(const DeclEntry &Ref) : Ref(Ref) {} + + public: + NamedDecl *getDecl() const { return Ref.getPointer(); } + AccessSpecifier getAccess() const { return AccessSpecifier(Ref.getInt()); } + + NamedDecl *operator->() const { return getDecl(); } + operator NamedDecl*() const { return getDecl(); } + }; + ConstProxy operator[](unsigned I) const { return ConstProxy(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 { + llvm::SmallVector<UnresolvedSetImpl::DeclEntry, InlineCapacity> Decls; +}; + + +} // namespace clang + +#endif |