1132732Skan//===- ASTUnresolvedSet.h - Unresolved sets of declarations -----*- C++ -*-===// 272564Sobrien// 3169702Skan// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4169702Skan// See https://llvm.org/LICENSE.txt for license information. 518334Speter// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 690091Sobrien// 718334Speter//===----------------------------------------------------------------------===// 890091Sobrien// 990091Sobrien// This file provides an UnresolvedSet-like class, whose contents are 1090091Sobrien// allocated using the allocator associated with an ASTContext. 1190091Sobrien// 1218334Speter//===----------------------------------------------------------------------===// 1390091Sobrien 1490091Sobrien#ifndef LLVM_CLANG_AST_ASTUNRESOLVEDSET_H 1590091Sobrien#define LLVM_CLANG_AST_ASTUNRESOLVEDSET_H 1690091Sobrien 1718334Speter#include "clang/AST/ASTVector.h" 1818334Speter#include "clang/AST/DeclAccessPair.h" 1990091Sobrien#include "clang/AST/UnresolvedSet.h" 20169702Skan#include "clang/Basic/Specifiers.h" 21169702Skan#include <cassert> 2218334Speter#include <cstdint> 23124160Skan 24124160Skannamespace clang { 2518334Speter 2618334Speterclass NamedDecl; 2718334Speter 2818334Speter/// An UnresolvedSet-like class which uses the ASTContext's allocator. 2918334Speterclass ASTUnresolvedSet { 3018334Speter friend class LazyASTUnresolvedSet; 3118334Speter 3218334Speter struct DeclsTy : ASTVector<DeclAccessPair> { 3318334Speter DeclsTy() = default; 3418334Speter DeclsTy(ASTContext &C, unsigned N) : ASTVector<DeclAccessPair>(C, N) {} 3518334Speter 3618334Speter bool isLazy() const { return getTag(); } 37169702Skan void setLazy(bool Lazy) { setTag(Lazy); } 3818334Speter }; 3918334Speter 4052268Sobrien DeclsTy Decls; 41132732Skan 42132732Skanpublic: 4318334Speter ASTUnresolvedSet() = default; 4418334Speter ASTUnresolvedSet(ASTContext &C, unsigned N) : Decls(C, N) {} 4518334Speter 4652268Sobrien using iterator = UnresolvedSetIterator; 4718334Speter using const_iterator = UnresolvedSetIterator; 4818334Speter 49132732Skan iterator begin() { return iterator(Decls.begin()); } 5090091Sobrien iterator end() { return iterator(Decls.end()); } 5118334Speter 5218334Speter const_iterator begin() const { return const_iterator(Decls.begin()); } 5318334Speter const_iterator end() const { return const_iterator(Decls.end()); } 5418334Speter 5518334Speter void addDecl(ASTContext &C, NamedDecl *D, AccessSpecifier AS) { 5618334Speter Decls.push_back(DeclAccessPair::make(D, AS), C); 5752268Sobrien } 58117404Skan 5990091Sobrien /// Replaces the given declaration with the new one, once. 6090091Sobrien /// 6190091Sobrien /// \return true if the set changed 62107605Sobrien bool replace(const NamedDecl *Old, NamedDecl *New, AccessSpecifier AS) { 63132732Skan for (DeclsTy::iterator I = Decls.begin(), E = Decls.end(); I != E; ++I) { 64169702Skan if (I->getDecl() == Old) { 65169702Skan I->set(New, AS); 66169702Skan return true; 67169702Skan } 68169702Skan } 6918334Speter return false; 7052518Sobrien } 7152518Sobrien 7252518Sobrien void erase(unsigned I) { 7352518Sobrien if (I == Decls.size() - 1) 74132732Skan Decls.pop_back(); 75132732Skan else 76132732Skan Decls[I] = Decls.pop_back_val(); 77132732Skan } 78132732Skan 79132732Skan void clear() { Decls.clear(); } 8018334Speter 8118334Speter bool empty() const { return Decls.empty(); } 8218334Speter unsigned size() const { return Decls.size(); } 8352268Sobrien 8418334Speter void reserve(ASTContext &C, unsigned N) { 8518334Speter Decls.reserve(C, N); 8618334Speter } 8718334Speter 8818334Speter void append(ASTContext &C, iterator I, iterator E) { 8918334Speter Decls.append(C, I.I, E.I); 9018334Speter } 9118334Speter 9218334Speter DeclAccessPair &operator[](unsigned I) { return Decls[I]; } 9318334Speter const DeclAccessPair &operator[](unsigned I) const { return Decls[I]; } 9418334Speter}; 9518334Speter 9618334Speter/// An UnresolvedSet-like class that might not have been loaded from the 9752518Sobrien/// external AST source yet. 9852518Sobrienclass LazyASTUnresolvedSet { 9952518Sobrien mutable ASTUnresolvedSet Impl; 10090091Sobrien 10152518Sobrien void getFromExternalSource(ASTContext &C) const; 10218334Speter 10352518Sobrienpublic: 10452518Sobrien ASTUnresolvedSet &get(ASTContext &C) const { 10590091Sobrien if (Impl.Decls.isLazy()) 10652518Sobrien getFromExternalSource(C); 10752518Sobrien return Impl; 10852518Sobrien } 10952518Sobrien 11052518Sobrien void reserve(ASTContext &C, unsigned N) { Impl.reserve(C, N); } 11152518Sobrien 11252518Sobrien void addLazyDecl(ASTContext &C, uintptr_t ID, AccessSpecifier AS) { 11390091Sobrien assert(Impl.empty() || Impl.Decls.isLazy()); 11490091Sobrien Impl.Decls.setLazy(true); 11590091Sobrien Impl.addDecl(C, reinterpret_cast<NamedDecl *>(ID << 2), AS); 11690091Sobrien } 11790091Sobrien}; 11852518Sobrien 119261188Spfg} // namespace clang 120261188Spfg 121261188Spfg#endif // LLVM_CLANG_AST_ASTUNRESOLVEDSET_H 122261188Spfg