//===- ParentMapContext.h - Map of parents using DynTypedNode -------*- C++ -*-===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
// Similar to ParentMap.h, but generalizes to non-Stmt nodes, which can have
// multiple parents.
//
//===----------------------------------------------------------------------===//

#ifndef LLVM_CLANG_AST_PARENTMAPCONTEXT_H
#define LLVM_CLANG_AST_PARENTMAPCONTEXT_H

#include "clang/AST/ASTContext.h"
#include "clang/AST/ASTTypeTraits.h"

namespace clang {
class DynTypedNodeList;

class ParentMapContext {
public:
  ParentMapContext(ASTContext &Ctx);

  ~ParentMapContext();

  /// Returns the parents of the given node (within the traversal scope).
  ///
  /// Note that this will lazily compute the parents of all nodes
  /// and store them for later retrieval. Thus, the first call is O(n)
  /// in the number of AST nodes.
  ///
  /// Caveats and FIXMEs:
  /// Calculating the parent map over all AST nodes will need to load the
  /// full AST. This can be undesirable in the case where the full AST is
  /// expensive to create (for example, when using precompiled header
  /// preambles). Thus, there are good opportunities for optimization here.
  /// One idea is to walk the given node downwards, looking for references
  /// to declaration contexts - once a declaration context is found, compute
  /// the parent map for the declaration context; if that can satisfy the
  /// request, loading the whole AST can be avoided. Note that this is made
  /// more complex by statements in templates having multiple parents - those
  /// problems can be solved by building closure over the templated parts of
  /// the AST, which also avoids touching large parts of the AST.
  /// Additionally, we will want to add an interface to already give a hint
  /// where to search for the parents, for example when looking at a statement
  /// inside a certain function.
  ///
  /// 'NodeT' can be one of Decl, Stmt, Type, TypeLoc,
  /// NestedNameSpecifier or NestedNameSpecifierLoc.
  template <typename NodeT> DynTypedNodeList getParents(const NodeT &Node);

  DynTypedNodeList getParents(const DynTypedNode &Node);

  /// Clear parent maps.
  void clear();

  TraversalKind getTraversalKind() const { return Traversal; }
  void setTraversalKind(TraversalKind TK) { Traversal = TK; }

  const Expr *traverseIgnored(const Expr *E) const;
  Expr *traverseIgnored(Expr *E) const;
  DynTypedNode traverseIgnored(const DynTypedNode &N) const;

  class ParentMap;

private:
  ASTContext &ASTCtx;
  TraversalKind Traversal = TK_AsIs;
  std::unique_ptr<ParentMap> Parents;
};

class TraversalKindScope {
  ParentMapContext &Ctx;
  TraversalKind TK = TK_AsIs;

public:
  TraversalKindScope(ASTContext &ASTCtx, llvm::Optional<TraversalKind> ScopeTK)
      : Ctx(ASTCtx.getParentMapContext()) {
    TK = Ctx.getTraversalKind();
    if (ScopeTK)
      Ctx.setTraversalKind(*ScopeTK);
  }

  ~TraversalKindScope() { Ctx.setTraversalKind(TK); }
};

/// Container for either a single DynTypedNode or for an ArrayRef to
/// DynTypedNode. For use with ParentMap.
class DynTypedNodeList {
  union {
    DynTypedNode SingleNode;
    ArrayRef<DynTypedNode> Nodes;
  };
  bool IsSingleNode;

public:
  DynTypedNodeList(const DynTypedNode &N) : IsSingleNode(true) {
    new (&SingleNode) DynTypedNode(N);
  }

  DynTypedNodeList(ArrayRef<DynTypedNode> A) : IsSingleNode(false) {
    new (&Nodes) ArrayRef<DynTypedNode>(A);
  }

  const DynTypedNode *begin() const {
    return !IsSingleNode ? Nodes.begin() : &SingleNode;
  }

  const DynTypedNode *end() const {
    return !IsSingleNode ? Nodes.end() : &SingleNode + 1;
  }

  size_t size() const { return end() - begin(); }
  bool empty() const { return begin() == end(); }

  const DynTypedNode &operator[](size_t N) const {
    assert(N < size() && "Out of bounds!");
    return *(begin() + N);
  }
};

template <typename NodeT>
inline DynTypedNodeList ParentMapContext::getParents(const NodeT &Node) {
  return getParents(DynTypedNode::create(Node));
}

template <typename NodeT>
inline DynTypedNodeList ASTContext::getParents(const NodeT &Node) {
  return getParentMapContext().getParents(Node);
}

template <>
inline DynTypedNodeList ASTContext::getParents(const DynTypedNode &Node) {
  return getParentMapContext().getParents(Node);
}

} // namespace clang

#endif
