Home | History | Annotate | Download | only in AST
      1 //===-- UnresolvedSet.h - Unresolved sets of declarations  ------*- C++ -*-===//
      2 //
      3 //                     The LLVM Compiler Infrastructure
      4 //
      5 // This file is distributed under the University of Illinois Open Source
      6 // License. See LICENSE.TXT for details.
      7 //
      8 //===----------------------------------------------------------------------===//
      9 //
     10 //  This file defines the UnresolvedSet class, which is used to store
     11 //  collections of declarations in the AST.
     12 //
     13 //===----------------------------------------------------------------------===//
     14 
     15 #ifndef LLVM_CLANG_AST_UNRESOLVEDSET_H
     16 #define LLVM_CLANG_AST_UNRESOLVEDSET_H
     17 
     18 #include "clang/AST/DeclAccessPair.h"
     19 #include "clang/Basic/LLVM.h"
     20 #include "llvm/ADT/ArrayRef.h"
     21 #include "llvm/ADT/SmallVector.h"
     22 #include "llvm/ADT/iterator.h"
     23 
     24 namespace clang {
     25 
     26 /// The iterator over UnresolvedSets.  Serves as both the const and
     27 /// non-const iterator.
     28 class UnresolvedSetIterator : public llvm::iterator_adaptor_base<
     29                                   UnresolvedSetIterator, DeclAccessPair *,
     30                                   std::random_access_iterator_tag, NamedDecl *,
     31                                   std::ptrdiff_t, NamedDecl *, NamedDecl *> {
     32   friend class UnresolvedSetImpl;
     33   friend class ASTUnresolvedSet;
     34   friend class OverloadExpr;
     35 
     36   explicit UnresolvedSetIterator(DeclAccessPair *Iter)
     37       : iterator_adaptor_base(Iter) {}
     38   explicit UnresolvedSetIterator(const DeclAccessPair *Iter)
     39       : iterator_adaptor_base(const_cast<DeclAccessPair *>(Iter)) {}
     40 
     41 public:
     42   UnresolvedSetIterator() {}
     43 
     44   NamedDecl *getDecl() const { return I->getDecl(); }
     45   void setDecl(NamedDecl *ND) const { return I->setDecl(ND); }
     46   AccessSpecifier getAccess() const { return I->getAccess(); }
     47   void setAccess(AccessSpecifier AS) { I->setAccess(AS); }
     48   const DeclAccessPair &getPair() const { return *I; }
     49 
     50   NamedDecl *operator*() const { return getDecl(); }
     51   NamedDecl *operator->() const { return **this; }
     52 };
     53 
     54 /// \brief A set of unresolved declarations.
     55 class UnresolvedSetImpl {
     56   typedef SmallVectorImpl<DeclAccessPair> DeclsTy;
     57 
     58   // Don't allow direct construction, and only permit subclassing by
     59   // UnresolvedSet.
     60 private:
     61   template <unsigned N> friend class UnresolvedSet;
     62   UnresolvedSetImpl() {}
     63   UnresolvedSetImpl(const UnresolvedSetImpl &) {}
     64 
     65 public:
     66   // We don't currently support assignment through this iterator, so we might
     67   // as well use the same implementation twice.
     68   typedef UnresolvedSetIterator iterator;
     69   typedef UnresolvedSetIterator const_iterator;
     70 
     71   iterator begin() { return iterator(decls().begin()); }
     72   iterator end() { return iterator(decls().end()); }
     73 
     74   const_iterator begin() const { return const_iterator(decls().begin()); }
     75   const_iterator end() const { return const_iterator(decls().end()); }
     76 
     77   void addDecl(NamedDecl *D) {
     78     addDecl(D, AS_none);
     79   }
     80 
     81   void addDecl(NamedDecl *D, AccessSpecifier AS) {
     82     decls().push_back(DeclAccessPair::make(D, AS));
     83   }
     84 
     85   /// Replaces the given declaration with the new one, once.
     86   ///
     87   /// \return true if the set changed
     88   bool replace(const NamedDecl* Old, NamedDecl *New) {
     89     for (DeclsTy::iterator I = decls().begin(), E = decls().end(); I != E; ++I)
     90       if (I->getDecl() == Old)
     91         return (I->setDecl(New), true);
     92     return false;
     93   }
     94 
     95   /// Replaces the declaration at the given iterator with the new one,
     96   /// preserving the original access bits.
     97   void replace(iterator I, NamedDecl *New) { I.I->setDecl(New); }
     98 
     99   void replace(iterator I, NamedDecl *New, AccessSpecifier AS) {
    100     I.I->set(New, AS);
    101   }
    102 
    103   void erase(unsigned I) { decls()[I] = decls().pop_back_val(); }
    104 
    105   void erase(iterator I) { *I.I = decls().pop_back_val(); }
    106 
    107   void setAccess(iterator I, AccessSpecifier AS) { I.I->setAccess(AS); }
    108 
    109   void clear() { decls().clear(); }
    110   void set_size(unsigned N) { decls().set_size(N); }
    111 
    112   bool empty() const { return decls().empty(); }
    113   unsigned size() const { return decls().size(); }
    114 
    115   void append(iterator I, iterator E) { decls().append(I.I, E.I); }
    116 
    117   DeclAccessPair &operator[](unsigned I) { return decls()[I]; }
    118   const DeclAccessPair &operator[](unsigned I) const { return decls()[I]; }
    119 
    120 private:
    121   // These work because the only permitted subclass is UnresolvedSetImpl
    122 
    123   DeclsTy &decls() {
    124     return *reinterpret_cast<DeclsTy*>(this);
    125   }
    126   const DeclsTy &decls() const {
    127     return *reinterpret_cast<const DeclsTy*>(this);
    128   }
    129 };
    130 
    131 /// \brief A set of unresolved declarations.
    132 template <unsigned InlineCapacity> class UnresolvedSet :
    133     public UnresolvedSetImpl {
    134   SmallVector<DeclAccessPair, InlineCapacity> Decls;
    135 };
    136 
    137 
    138 } // namespace clang
    139 
    140 #endif
    141