clang API Documentation

ASTUnresolvedSet.h
Go to the documentation of this file.
00001 //===-- ASTUnresolvedSet.h - Unresolved sets of declarations  ---*- C++ -*-===//
00002 //
00003 //                     The LLVM Compiler Infrastructure
00004 //
00005 // This file is distributed under the University of Illinois Open Source
00006 // License. See LICENSE.TXT for details.
00007 //
00008 //===----------------------------------------------------------------------===//
00009 //
00010 //  This file provides an UnresolvedSet-like class, whose contents are
00011 //  allocated using the allocator associated with an ASTContext.
00012 //
00013 //===----------------------------------------------------------------------===//
00014 
00015 #ifndef LLVM_CLANG_AST_ASTUNRESOLVEDSET_H
00016 #define LLVM_CLANG_AST_ASTUNRESOLVEDSET_H
00017 
00018 #include "clang/AST/ASTVector.h"
00019 #include "clang/AST/UnresolvedSet.h"
00020 
00021 namespace clang {
00022 
00023 /// \brief An UnresolvedSet-like class which uses the ASTContext's allocator.
00024 class ASTUnresolvedSet {
00025   struct DeclsTy : ASTVector<DeclAccessPair> {
00026     DeclsTy() {}
00027     DeclsTy(ASTContext &C, unsigned N) : ASTVector<DeclAccessPair>(C, N) {}
00028 
00029     bool isLazy() const { return getTag(); }
00030     void setLazy(bool Lazy) { setTag(Lazy); }
00031   };
00032 
00033   DeclsTy Decls;
00034 
00035   friend class LazyASTUnresolvedSet;
00036 
00037 public:
00038   ASTUnresolvedSet() {}
00039   ASTUnresolvedSet(ASTContext &C, unsigned N) : Decls(C, N) {}
00040 
00041   typedef UnresolvedSetIterator iterator;
00042   typedef UnresolvedSetIterator const_iterator;
00043 
00044   iterator begin() { return iterator(Decls.begin()); }
00045   iterator end() { return iterator(Decls.end()); }
00046 
00047   const_iterator begin() const { return const_iterator(Decls.begin()); }
00048   const_iterator end() const { return const_iterator(Decls.end()); }
00049 
00050   void addDecl(ASTContext &C, NamedDecl *D, AccessSpecifier AS) {
00051     Decls.push_back(DeclAccessPair::make(D, AS), C);
00052   }
00053 
00054   /// Replaces the given declaration with the new one, once.
00055   ///
00056   /// \return true if the set changed
00057   bool replace(const NamedDecl *Old, NamedDecl *New, AccessSpecifier AS) {
00058     for (DeclsTy::iterator I = Decls.begin(), E = Decls.end(); I != E; ++I) {
00059       if (I->getDecl() == Old) {
00060         I->set(New, AS);
00061         return true;
00062       }
00063     }
00064     return false;
00065   }
00066 
00067   void erase(unsigned I) { Decls[I] = Decls.pop_back_val(); }
00068 
00069   void clear() { Decls.clear(); }
00070 
00071   bool empty() const { return Decls.empty(); }
00072   unsigned size() const { return Decls.size(); }
00073 
00074   void reserve(ASTContext &C, unsigned N) {
00075     Decls.reserve(C, N);
00076   }
00077 
00078   void append(ASTContext &C, iterator I, iterator E) {
00079     Decls.append(C, I.ir, E.ir);
00080   }
00081 
00082   DeclAccessPair &operator[](unsigned I) { return Decls[I]; }
00083   const DeclAccessPair &operator[](unsigned I) const { return Decls[I]; }
00084 };
00085 
00086 /// \brief An UnresolvedSet-like class that might not have been loaded from the
00087 /// external AST source yet.
00088 class LazyASTUnresolvedSet {
00089   mutable ASTUnresolvedSet Impl;
00090 
00091   void getFromExternalSource(ASTContext &C) const;
00092 
00093 public:
00094   ASTUnresolvedSet &get(ASTContext &C) const {
00095     if (Impl.Decls.isLazy())
00096       getFromExternalSource(C);
00097     return Impl;
00098   }
00099 
00100   void reserve(ASTContext &C, unsigned N) { Impl.reserve(C, N); }
00101   void addLazyDecl(ASTContext &C, uintptr_t ID, AccessSpecifier AS) {
00102     assert(Impl.empty() || Impl.Decls.isLazy());
00103     Impl.Decls.setLazy(true);
00104     Impl.addDecl(C, reinterpret_cast<NamedDecl*>(ID << 2), AS);
00105   }
00106 };
00107 
00108 } // namespace clang
00109 
00110 #endif