//===-- PostfixExpression.h -------------------------------------*- 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
//
//===----------------------------------------------------------------------===//
//
//  This file implements support for postfix expressions found in several symbol
//  file formats, and their conversion to DWARF.
//
//===----------------------------------------------------------------------===//

#ifndef LLDB_SYMBOL_POSTFIXEXPRESSION_H
#define LLDB_SYMBOL_POSTFIXEXPRESSION_H

#include "llvm/ADT/StringRef.h"
#include "llvm/Support/Allocator.h"
#include "llvm/Support/Casting.h"

namespace lldb_private {

class Stream;

namespace postfix {

/// The base class for all nodes in the parsed postfix tree.
class Node {
public:
  enum Kind {
    BinaryOp,
    InitialValue,
    Integer,
    Register,
    Symbol,
    UnaryOp,
  };

protected:
  Node(Kind kind) : m_kind(kind) {}

public:
  Kind GetKind() const { return m_kind; }

private:
  Kind m_kind;
};

/// A node representing a binary expression.
class BinaryOpNode : public Node {
public:
  enum OpType {
    Align, // alignDown(a, b)
    Minus, // a - b
    Plus,  // a + b
  };

  BinaryOpNode(OpType op_type, Node &left, Node &right)
      : Node(BinaryOp), m_op_type(op_type), m_left(&left), m_right(&right) {}

  OpType GetOpType() const { return m_op_type; }

  const Node *Left() const { return m_left; }
  Node *&Left() { return m_left; }

  const Node *Right() const { return m_right; }
  Node *&Right() { return m_right; }

  static bool classof(const Node *node) { return node->GetKind() == BinaryOp; }

private:
  OpType m_op_type;
  Node *m_left;
  Node *m_right;
};

/// A node representing the canonical frame address.
class InitialValueNode: public Node {
public:
  InitialValueNode() : Node(InitialValue) {}

  static bool classof(const Node *node) {
    return node->GetKind() == InitialValue;
  }
};

/// A node representing an integer literal.
class IntegerNode : public Node {
public:
  IntegerNode(int64_t value) : Node(Integer), m_value(value) {}

  int64_t GetValue() const { return m_value; }

  static bool classof(const Node *node) { return node->GetKind() == Integer; }

private:
  int64_t m_value;
};

/// A node representing the value of a register with the given register number.
/// The register kind (RegisterKind enum) used for the specifying the register
/// number is implicit and assumed to be the same for all Register nodes in a
/// given tree.
class RegisterNode : public Node {
public:
  RegisterNode(uint32_t reg_num) : Node(Register), m_reg_num(reg_num) {}

  uint32_t GetRegNum() const { return m_reg_num; }

  static bool classof(const Node *node) { return node->GetKind() == Register; }

private:
  uint32_t m_reg_num;
};

/// A node representing a symbolic reference to a named entity. This may be a
/// register, which hasn't yet been resolved to a RegisterNode.
class SymbolNode : public Node {
public:
  SymbolNode(llvm::StringRef name) : Node(Symbol), m_name(name) {}

  llvm::StringRef GetName() const { return m_name; }

  static bool classof(const Node *node) { return node->GetKind() == Symbol; }

private:
  llvm::StringRef m_name;
};

/// A node representing a unary operation.
class UnaryOpNode : public Node {
public:
  enum OpType {
    Deref, // *a
  };

  UnaryOpNode(OpType op_type, Node &operand)
      : Node(UnaryOp), m_op_type(op_type), m_operand(&operand) {}

  OpType GetOpType() const { return m_op_type; }

  const Node *Operand() const { return m_operand; }
  Node *&Operand() { return m_operand; }

  static bool classof(const Node *node) { return node->GetKind() == UnaryOp; }

private:
  OpType m_op_type;
  Node *m_operand;
};

/// A template class implementing a visitor pattern, but with a couple of
/// twists:
/// - It uses type switch instead of virtual double dispatch. This allows the
//    node classes to be vtable-free and trivially destructible.
/// - The Visit functions get an extra Node *& parameter, which refers to the
///   child pointer of the parent of the node we are currently visiting. This
///   allows mutating algorithms, which replace the currently visited node with
///   a different one.
/// - The class is templatized on the return type of the Visit functions, which
///   means it's possible to return values from them.
template <typename ResultT = void> class Visitor {
protected:
  virtual ~Visitor() = default;

  virtual ResultT Visit(BinaryOpNode &binary, Node *&ref) = 0;
  virtual ResultT Visit(InitialValueNode &val, Node *&ref) = 0;
  virtual ResultT Visit(IntegerNode &integer, Node *&) = 0;
  virtual ResultT Visit(RegisterNode &reg, Node *&) = 0;
  virtual ResultT Visit(SymbolNode &symbol, Node *&ref) = 0;
  virtual ResultT Visit(UnaryOpNode &unary, Node *&ref) = 0;

  /// Invoke the correct Visit function based on the dynamic type of the given
  /// node.
  ResultT Dispatch(Node *&node) {
    switch (node->GetKind()) {
    case Node::BinaryOp:
      return Visit(llvm::cast<BinaryOpNode>(*node), node);
    case Node::InitialValue:
      return Visit(llvm::cast<InitialValueNode>(*node), node);
    case Node::Integer:
      return Visit(llvm::cast<IntegerNode>(*node), node);
    case Node::Register:
      return Visit(llvm::cast<RegisterNode>(*node), node);
    case Node::Symbol:
      return Visit(llvm::cast<SymbolNode>(*node), node);
    case Node::UnaryOp:
      return Visit(llvm::cast<UnaryOpNode>(*node), node);
    }
    llvm_unreachable("Fully covered switch!");
  }
};

/// A utility function for "resolving" SymbolNodes. It traverses a tree and
/// calls the callback function for all SymbolNodes it encountered. The
/// replacement function should return the node it wished to replace the current
/// SymbolNode with (this can also be the original node), or nullptr in case of
/// an error. The nodes returned by the callback are inspected and replaced
/// recursively, *except* for the case when the function returns the exact same
/// node as the input one. It returns true if all SymbolNodes were replaced
/// successfully.
bool ResolveSymbols(Node *&node,
                    llvm::function_ref<Node *(SymbolNode &symbol)> replacer);

template <typename T, typename... Args>
inline T *MakeNode(llvm::BumpPtrAllocator &alloc, Args &&... args) {
  static_assert(std::is_trivially_destructible<T>::value,
                "This object will not be destroyed!");
  return new (alloc.Allocate<T>()) T(std::forward<Args>(args)...);
}

/// Parse the given postfix expression. The parsed nodes are placed into the
/// provided allocator.
Node *Parse(llvm::StringRef expr, llvm::BumpPtrAllocator &alloc);

/// Serialize the given expression tree as DWARF. The result is written into the
/// given stream. The AST should not contain any SymbolNodes. If the expression
/// contains InitialValueNodes, the generated expression will assume that their
/// value will be provided as the top value of the initial evaluation stack (as
/// is the case with the CFA value in register eh_unwind rules).
void ToDWARF(Node &node, Stream &stream);

} // namespace postfix
} // namespace lldb_private

#endif // LLDB_SYMBOL_POSTFIXEXPRESSION_H
