//===- ASTUnresolvedSet.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 provides an UnresolvedSet-like class, whose contents are
//  allocated using the allocator associated with an ASTContext.
//
//===----------------------------------------------------------------------===//

#ifndef LLVM_CLANG_AST_ASTUNRESOLVEDSET_H
#define LLVM_CLANG_AST_ASTUNRESOLVEDSET_H

#include "clang/AST/ASTVector.h"
#include "clang/AST/DeclAccessPair.h"
#include "clang/AST/UnresolvedSet.h"
#include "clang/Basic/Specifiers.h"
#include <cassert>
#include <cstdint>

namespace clang {

class NamedDecl;

/// \brief An UnresolvedSet-like class which uses the ASTContext's allocator.
class ASTUnresolvedSet {
  friend class LazyASTUnresolvedSet;

  struct DeclsTy : ASTVector<DeclAccessPair> {
    DeclsTy() = default;
    DeclsTy(ASTContext &C, unsigned N) : ASTVector<DeclAccessPair>(C, N) {}

    bool isLazy() const { return getTag(); }
    void setLazy(bool Lazy) { setTag(Lazy); }
  };

  DeclsTy Decls;

public:
  ASTUnresolvedSet() = default;
  ASTUnresolvedSet(ASTContext &C, unsigned N) : Decls(C, N) {}

  using iterator = UnresolvedSetIterator;
  using const_iterator = UnresolvedSetIterator;

  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(ASTContext &C, NamedDecl *D, AccessSpecifier AS) {
    Decls.push_back(DeclAccessPair::make(D, AS), C);
  }

  /// Replaces the given declaration with the new one, once.
  ///
  /// \return true if the set changed
  bool replace(const NamedDecl *Old, NamedDecl *New, AccessSpecifier AS) {
    for (DeclsTy::iterator I = Decls.begin(), E = Decls.end(); I != E; ++I) {
      if (I->getDecl() == Old) {
        I->set(New, AS);
        return true;
      }
    }
    return false;
  }

  void erase(unsigned I) { Decls[I] = Decls.pop_back_val(); }

  void clear() { Decls.clear(); }

  bool empty() const { return Decls.empty(); }
  unsigned size() const { return Decls.size(); }

  void reserve(ASTContext &C, unsigned N) {
    Decls.reserve(C, N);
  }

  void append(ASTContext &C, iterator I, iterator E) {
    Decls.append(C, I.I, E.I);
  }

  DeclAccessPair &operator[](unsigned I) { return Decls[I]; }
  const DeclAccessPair &operator[](unsigned I) const { return Decls[I]; }
};

/// \brief An UnresolvedSet-like class that might not have been loaded from the
/// external AST source yet.
class LazyASTUnresolvedSet {
  mutable ASTUnresolvedSet Impl;

  void getFromExternalSource(ASTContext &C) const;

public:
  ASTUnresolvedSet &get(ASTContext &C) const {
    if (Impl.Decls.isLazy())
      getFromExternalSource(C);
    return Impl;
  }

  void reserve(ASTContext &C, unsigned N) { Impl.reserve(C, N); }

  void addLazyDecl(ASTContext &C, uintptr_t ID, AccessSpecifier AS) {
    assert(Impl.empty() || Impl.Decls.isLazy());
    Impl.Decls.setLazy(true);
    Impl.addDecl(C, reinterpret_cast<NamedDecl *>(ID << 2), AS);
  }
};

} // namespace clang

#endif // LLVM_CLANG_AST_ASTUNRESOLVEDSET_H
