1 //===- ASTUnresolvedSet.h - Unresolved sets of declarations -----*- C++ -*-===// 2 // 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 6 // 7 //===----------------------------------------------------------------------===// 8 // 9 // This file provides an UnresolvedSet-like class, whose contents are 10 // allocated using the allocator associated with an ASTContext. 11 // 12 //===----------------------------------------------------------------------===// 13 14 #ifndef LLVM_CLANG_AST_ASTUNRESOLVEDSET_H 15 #define LLVM_CLANG_AST_ASTUNRESOLVEDSET_H 16 17 #include "clang/AST/ASTVector.h" 18 #include "clang/AST/DeclAccessPair.h" 19 #include "clang/AST/DeclID.h" 20 #include "clang/AST/UnresolvedSet.h" 21 #include "clang/Basic/Specifiers.h" 22 #include <cassert> 23 #include <cstdint> 24 25 namespace clang { 26 27 class NamedDecl; 28 29 /// An UnresolvedSet-like class which uses the ASTContext's allocator. 30 class ASTUnresolvedSet { 31 friend class LazyASTUnresolvedSet; 32 33 struct DeclsTy : ASTVector<DeclAccessPair> { 34 DeclsTy() = default; DeclsTyDeclsTy35 DeclsTy(ASTContext &C, unsigned N) : ASTVector<DeclAccessPair>(C, N) {} 36 isLazyDeclsTy37 bool isLazy() const { return getTag(); } setLazyDeclsTy38 void setLazy(bool Lazy) { setTag(Lazy); } 39 }; 40 41 DeclsTy Decls; 42 43 public: 44 ASTUnresolvedSet() = default; ASTUnresolvedSet(ASTContext & C,unsigned N)45 ASTUnresolvedSet(ASTContext &C, unsigned N) : Decls(C, N) {} 46 47 using iterator = UnresolvedSetIterator; 48 using const_iterator = UnresolvedSetIterator; 49 begin()50 iterator begin() { return iterator(Decls.begin()); } end()51 iterator end() { return iterator(Decls.end()); } 52 begin()53 const_iterator begin() const { return const_iterator(Decls.begin()); } end()54 const_iterator end() const { return const_iterator(Decls.end()); } 55 addDecl(ASTContext & C,NamedDecl * D,AccessSpecifier AS)56 void addDecl(ASTContext &C, NamedDecl *D, AccessSpecifier AS) { 57 Decls.push_back(DeclAccessPair::make(D, AS), C); 58 } 59 addLazyDecl(ASTContext & C,GlobalDeclID ID,AccessSpecifier AS)60 void addLazyDecl(ASTContext &C, GlobalDeclID ID, AccessSpecifier AS) { 61 Decls.push_back(DeclAccessPair::makeLazy(ID.getRawValue(), AS), C); 62 } 63 64 /// Replaces the given declaration with the new one, once. 65 /// 66 /// \return true if the set changed replace(const NamedDecl * Old,NamedDecl * New,AccessSpecifier AS)67 bool replace(const NamedDecl *Old, NamedDecl *New, AccessSpecifier AS) { 68 for (DeclsTy::iterator I = Decls.begin(), E = Decls.end(); I != E; ++I) { 69 if (I->getDecl() == Old) { 70 I->set(New, AS); 71 return true; 72 } 73 } 74 return false; 75 } 76 erase(unsigned I)77 void erase(unsigned I) { 78 if (I == Decls.size() - 1) 79 Decls.pop_back(); 80 else 81 Decls[I] = Decls.pop_back_val(); 82 } 83 clear()84 void clear() { Decls.clear(); } 85 empty()86 bool empty() const { return Decls.empty(); } size()87 unsigned size() const { return Decls.size(); } 88 reserve(ASTContext & C,unsigned N)89 void reserve(ASTContext &C, unsigned N) { 90 Decls.reserve(C, N); 91 } 92 append(ASTContext & C,iterator I,iterator E)93 void append(ASTContext &C, iterator I, iterator E) { 94 Decls.append(C, I.I, E.I); 95 } 96 97 DeclAccessPair &operator[](unsigned I) { return Decls[I]; } 98 const DeclAccessPair &operator[](unsigned I) const { return Decls[I]; } 99 }; 100 101 /// An UnresolvedSet-like class that might not have been loaded from the 102 /// external AST source yet. 103 class LazyASTUnresolvedSet { 104 mutable ASTUnresolvedSet Impl; 105 106 void getFromExternalSource(ASTContext &C) const; 107 108 public: get(ASTContext & C)109 ASTUnresolvedSet &get(ASTContext &C) const { 110 if (Impl.Decls.isLazy()) 111 getFromExternalSource(C); 112 return Impl; 113 } 114 reserve(ASTContext & C,unsigned N)115 void reserve(ASTContext &C, unsigned N) { Impl.reserve(C, N); } 116 addLazyDecl(ASTContext & C,GlobalDeclID ID,AccessSpecifier AS)117 void addLazyDecl(ASTContext &C, GlobalDeclID ID, AccessSpecifier AS) { 118 assert(Impl.empty() || Impl.Decls.isLazy()); 119 Impl.Decls.setLazy(true); 120 Impl.addLazyDecl(C, ID, AS); 121 } 122 }; 123 124 } // namespace clang 125 126 #endif // LLVM_CLANG_AST_ASTUNRESOLVEDSET_H 127