//===--- ByteCodeExprGen.h - Code generator for expressions -----*- 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
//
//===----------------------------------------------------------------------===//
//
// Defines the constexpr bytecode compiler.
//
//===----------------------------------------------------------------------===//

#ifndef LLVM_CLANG_AST_INTERP_BYTECODEEXPRGEN_H
#define LLVM_CLANG_AST_INTERP_BYTECODEEXPRGEN_H

#include "ByteCodeEmitter.h"
#include "EvalEmitter.h"
#include "Pointer.h"
#include "PrimType.h"
#include "Record.h"
#include "clang/AST/Decl.h"
#include "clang/AST/Expr.h"
#include "clang/AST/StmtVisitor.h"
#include "llvm/ADT/Optional.h"

namespace clang {
class QualType;

namespace interp {
class Function;
class State;

template <class Emitter> class LocalScope;
template <class Emitter> class RecordScope;
template <class Emitter> class VariableScope;
template <class Emitter> class DeclScope;
template <class Emitter> class OptionScope;

/// Compilation context for expressions.
template <class Emitter>
class ByteCodeExprGen : public ConstStmtVisitor<ByteCodeExprGen<Emitter>, bool>,
                        public Emitter {
protected:
  // Emitters for opcodes of various arities.
  using NullaryFn = bool (ByteCodeExprGen::*)(const SourceInfo &);
  using UnaryFn = bool (ByteCodeExprGen::*)(PrimType, const SourceInfo &);
  using BinaryFn = bool (ByteCodeExprGen::*)(PrimType, PrimType,
                                             const SourceInfo &);

  // Aliases for types defined in the emitter.
  using LabelTy = typename Emitter::LabelTy;
  using AddrTy = typename Emitter::AddrTy;

  // Reference to a function generating the pointer of an initialized object.s
  using InitFnRef = std::function<bool()>;

  /// Current compilation context.
  Context &Ctx;
  /// Program to link to.
  Program &P;

public:
  /// Initializes the compiler and the backend emitter.
  template <typename... Tys>
  ByteCodeExprGen(Context &Ctx, Program &P, Tys &&... Args)
      : Emitter(Ctx, P, Args...), Ctx(Ctx), P(P) {}

  // Expression visitors - result returned on stack.
  bool VisitCastExpr(const CastExpr *E);
  bool VisitIntegerLiteral(const IntegerLiteral *E);
  bool VisitParenExpr(const ParenExpr *E);
  bool VisitBinaryOperator(const BinaryOperator *E);

protected:
  bool visitExpr(const Expr *E) override;
  bool visitDecl(const VarDecl *VD) override;

protected:
  /// Emits scope cleanup instructions.
  void emitCleanup();

  /// Returns a record type from a record or pointer type.
  const RecordType *getRecordTy(QualType Ty);

  /// Returns a record from a record or pointer type.
  Record *getRecord(QualType Ty);
  Record *getRecord(const RecordDecl *RD);

  /// Returns the size int bits of an integer.
  unsigned getIntWidth(QualType Ty) {
    auto &ASTContext = Ctx.getASTContext();
    return ASTContext.getIntWidth(Ty);
  }

  /// Returns the value of CHAR_BIT.
  unsigned getCharBit() const {
    auto &ASTContext = Ctx.getASTContext();
    return ASTContext.getTargetInfo().getCharWidth();
  }

  /// Classifies a type.
  llvm::Optional<PrimType> classify(const Expr *E) const {
    return E->isGLValue() ? PT_Ptr : classify(E->getType());
  }
  llvm::Optional<PrimType> classify(QualType Ty) const {
    return Ctx.classify(Ty);
  }

  /// Checks if a pointer needs adjustment.
  bool needsAdjust(QualType Ty) const {
    return true;
  }

  /// Classifies a known primitive type
  PrimType classifyPrim(QualType Ty) const {
    if (auto T = classify(Ty)) {
      return *T;
    }
    llvm_unreachable("not a primitive type");
  }

  /// Evaluates an expression for side effects and discards the result.
  bool discard(const Expr *E);
  /// Evaluates an expression and places result on stack.
  bool visit(const Expr *E);
  /// Compiles an initializer for a local.
  bool visitInitializer(const Expr *E, InitFnRef GenPtr);

  /// Visits an expression and converts it to a boolean.
  bool visitBool(const Expr *E);

  /// Visits an initializer for a local.
  bool visitLocalInitializer(const Expr *Init, unsigned I) {
    return visitInitializer(Init, [this, I, Init] {
      return this->emitGetPtrLocal(I, Init);
    });
  }

  /// Visits an initializer for a global.
  bool visitGlobalInitializer(const Expr *Init, unsigned I) {
    return visitInitializer(Init, [this, I, Init] {
      return this->emitGetPtrGlobal(I, Init);
    });
  }

  /// Visits a delegated initializer.
  bool visitThisInitializer(const Expr *I) {
    return visitInitializer(I, [this, I] { return this->emitThis(I); });
  }

  /// Creates a local primitive value.
  unsigned allocateLocalPrimitive(DeclTy &&Decl, PrimType Ty, bool IsMutable,
                                  bool IsExtended = false);

  /// Allocates a space storing a local given its type.
  llvm::Optional<unsigned> allocateLocal(DeclTy &&Decl,
                                         bool IsExtended = false);

private:
  friend class VariableScope<Emitter>;
  friend class LocalScope<Emitter>;
  friend class RecordScope<Emitter>;
  friend class DeclScope<Emitter>;
  friend class OptionScope<Emitter>;

  /// Emits a zero initializer.
  bool visitZeroInitializer(PrimType T, const Expr *E);

  enum class DerefKind {
    /// Value is read and pushed to stack.
    Read,
    /// Direct method generates a value which is written. Returns pointer.
    Write,
    /// Direct method receives the value, pushes mutated value. Returns pointer.
    ReadWrite,
  };

  /// Method to directly load a value. If the value can be fetched directly,
  /// the direct handler is called. Otherwise, a pointer is left on the stack
  /// and the indirect handler is expected to operate on that.
  bool dereference(const Expr *LV, DerefKind AK,
                   llvm::function_ref<bool(PrimType)> Direct,
                   llvm::function_ref<bool(PrimType)> Indirect);
  bool dereferenceParam(const Expr *LV, PrimType T, const ParmVarDecl *PD,
                        DerefKind AK,
                        llvm::function_ref<bool(PrimType)> Direct,
                        llvm::function_ref<bool(PrimType)> Indirect);
  bool dereferenceVar(const Expr *LV, PrimType T, const VarDecl *PD,
                      DerefKind AK, llvm::function_ref<bool(PrimType)> Direct,
                      llvm::function_ref<bool(PrimType)> Indirect);

  /// Emits an APInt constant.
  bool emitConst(PrimType T, unsigned NumBits, const llvm::APInt &Value,
                 const Expr *E);

  /// Emits an integer constant.
  template <typename T> bool emitConst(const Expr *E, T Value) {
    QualType Ty = E->getType();
    unsigned NumBits = getIntWidth(Ty);
    APInt WrappedValue(NumBits, Value, std::is_signed<T>::value);
    return emitConst(*Ctx.classify(Ty), NumBits, WrappedValue, E);
  }

  /// Returns a pointer to a variable declaration.
  bool getPtrVarDecl(const VarDecl *VD, const Expr *E);

  /// Returns the index of a global.
  llvm::Optional<unsigned> getGlobalIdx(const VarDecl *VD);

  /// Emits the initialized pointer.
  bool emitInitFn() {
    assert(InitFn && "missing initializer");
    return (*InitFn)();
  }

protected:
  /// Variable to storage mapping.
  llvm::DenseMap<const ValueDecl *, Scope::Local> Locals;

  /// OpaqueValueExpr to location mapping.
  llvm::DenseMap<const OpaqueValueExpr *, unsigned> OpaqueExprs;

  /// Current scope.
  VariableScope<Emitter> *VarScope = nullptr;

  /// Current argument index.
  llvm::Optional<uint64_t> ArrayIndex;

  /// Flag indicating if return value is to be discarded.
  bool DiscardResult = false;

  /// Expression being initialized.
  llvm::Optional<InitFnRef> InitFn = {};
};

extern template class ByteCodeExprGen<ByteCodeEmitter>;
extern template class ByteCodeExprGen<EvalEmitter>;

/// Scope chain managing the variable lifetimes.
template <class Emitter> class VariableScope {
public:
  virtual ~VariableScope() { Ctx->VarScope = this->Parent; }

  void add(const Scope::Local &Local, bool IsExtended) {
    if (IsExtended)
      this->addExtended(Local);
    else
      this->addLocal(Local);
  }

  virtual void addLocal(const Scope::Local &Local) {
    if (this->Parent)
      this->Parent->addLocal(Local);
  }

  virtual void addExtended(const Scope::Local &Local) {
    if (this->Parent)
      this->Parent->addExtended(Local);
  }

  virtual void emitDestruction() {}

  VariableScope *getParent() { return Parent; }

protected:
  VariableScope(ByteCodeExprGen<Emitter> *Ctx)
      : Ctx(Ctx), Parent(Ctx->VarScope) {
    Ctx->VarScope = this;
  }

  /// ByteCodeExprGen instance.
  ByteCodeExprGen<Emitter> *Ctx;
  /// Link to the parent scope.
  VariableScope *Parent;
};

/// Scope for local variables.
///
/// When the scope is destroyed, instructions are emitted to tear down
/// all variables declared in this scope.
template <class Emitter> class LocalScope : public VariableScope<Emitter> {
public:
  LocalScope(ByteCodeExprGen<Emitter> *Ctx) : VariableScope<Emitter>(Ctx) {}

  ~LocalScope() override { this->emitDestruction(); }

  void addLocal(const Scope::Local &Local) override {
    if (!Idx.hasValue()) {
      Idx = this->Ctx->Descriptors.size();
      this->Ctx->Descriptors.emplace_back();
    }

    this->Ctx->Descriptors[*Idx].emplace_back(Local);
  }

  void emitDestruction() override {
    if (!Idx.hasValue())
      return;
    this->Ctx->emitDestroy(*Idx, SourceInfo{});
  }

protected:
  /// Index of the scope in the chain.
  Optional<unsigned> Idx;
};

/// Scope for storage declared in a compound statement.
template <class Emitter> class BlockScope final : public LocalScope<Emitter> {
public:
  BlockScope(ByteCodeExprGen<Emitter> *Ctx) : LocalScope<Emitter>(Ctx) {}

  void addExtended(const Scope::Local &Local) override {
    llvm_unreachable("Cannot create temporaries in full scopes");
  }
};

/// Expression scope which tracks potentially lifetime extended
/// temporaries which are hoisted to the parent scope on exit.
template <class Emitter> class ExprScope final : public LocalScope<Emitter> {
public:
  ExprScope(ByteCodeExprGen<Emitter> *Ctx) : LocalScope<Emitter>(Ctx) {}

  void addExtended(const Scope::Local &Local) override {
    this->Parent->addLocal(Local);
  }
};

} // namespace interp
} // namespace clang

#endif
