//===--- Descriptor.cpp - Types for the constexpr VM ------------*- 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
//
//===----------------------------------------------------------------------===//

#include "Descriptor.h"
#include "Boolean.h"
#include "Char.h"
#include "FixedPoint.h"
#include "Floating.h"
#include "Integral.h"
#include "IntegralAP.h"
#include "MemberPointer.h"
#include "Pointer.h"
#include "PrimType.h"
#include "Record.h"
#include "Source.h"
#include "clang/AST/ExprCXX.h"

using namespace clang;
using namespace clang::interp;

template <typename T> static constexpr bool needsDtor() {
  return std::is_same_v<T, Pointer> || std::is_same_v<T, MemberPointer>;
}

template <typename T>
static void dtorTy(Block *, std::byte *Ptr, const Descriptor *) {
  static_assert(needsDtor<T>());
  reinterpret_cast<T *>(Ptr)->~T();
}

template <typename T>
static void dtorArrayTy(Block *, std::byte *Ptr, const Descriptor *D) {
  InitMapPtr &IMP = *reinterpret_cast<InitMapPtr *>(Ptr);
  IMP.deleteInitMap();

  if constexpr (needsDtor<T>()) {
    Ptr += sizeof(InitMapPtr);
    for (unsigned I = 0, NE = D->getNumElems(); I != NE; ++I) {
      reinterpret_cast<T *>(Ptr)[I].~T();
    }
  }
}

static void ctorArrayDesc(Block *B, std::byte *Ptr, bool IsConst,
                          bool IsMutable, bool IsVolatile, bool IsActive,
                          bool InUnion, const Descriptor *D) {
  const unsigned NumElems = D->getNumElems();
  const unsigned ElemSize =
      D->ElemDesc->getAllocSize() + sizeof(InlineDescriptor);

  unsigned ElemOffset = 0;
  for (unsigned I = 0; I != NumElems; ++I, ElemOffset += ElemSize) {
    auto *ElemPtr = Ptr + ElemOffset;
    auto *Desc = reinterpret_cast<InlineDescriptor *>(ElemPtr);
    auto *SD = D->ElemDesc;

    Desc->Offset = ElemOffset + sizeof(InlineDescriptor);
    Desc->Desc = SD;
    Desc->IsInitialized = true;
    Desc->IsBase = false;
    Desc->IsActive = IsActive;
    Desc->IsConst = IsConst || D->IsConst;
    Desc->IsFieldMutable = IsMutable || D->IsMutable;
    Desc->InUnion = InUnion;
    Desc->IsArrayElement = true;
    Desc->IsVolatile = IsVolatile;

    if (auto Fn = D->ElemDesc->CtorFn) {
      auto *ElemLoc = reinterpret_cast<std::byte *>(Desc + 1);
      Fn(B, ElemLoc, Desc->IsConst, Desc->IsFieldMutable, IsVolatile, IsActive,
         Desc->InUnion || SD->isUnion(), D->ElemDesc);
    }
  }
}

static void dtorArrayDesc(Block *B, std::byte *Ptr, const Descriptor *D) {
  const unsigned NumElems = D->getNumElems();
  const unsigned ElemSize =
      D->ElemDesc->getAllocSize() + sizeof(InlineDescriptor);

  unsigned ElemOffset = 0;
  auto Dtor = D->ElemDesc->DtorFn;
  assert(Dtor &&
         "a composite array without an elem dtor shouldn't have a dtor itself");
  for (unsigned I = 0; I != NumElems; ++I, ElemOffset += ElemSize) {
    auto *ElemPtr = Ptr + ElemOffset;
    auto *Desc = reinterpret_cast<InlineDescriptor *>(ElemPtr);
    auto *ElemLoc = reinterpret_cast<std::byte *>(Desc + 1);
    Dtor(B, ElemLoc, D->ElemDesc);
  }
}

static void initField(Block *B, std::byte *Ptr, bool IsConst, bool IsMutable,
                      bool IsVolatile, bool IsActive, bool IsUnionField,
                      bool InUnion, const Descriptor *D, unsigned FieldOffset) {
  auto *Desc = reinterpret_cast<InlineDescriptor *>(Ptr + FieldOffset) - 1;
  Desc->Offset = FieldOffset;
  Desc->Desc = D;
  Desc->IsInitialized = D->IsArray;
  Desc->IsBase = false;
  Desc->IsActive = IsActive && !IsUnionField;
  Desc->InUnion = InUnion;
  Desc->IsConst = IsConst || D->IsConst;
  Desc->IsFieldMutable = IsMutable || D->IsMutable;
  Desc->IsVolatile = IsVolatile || D->IsVolatile;
  // True if this field is const AND the parent is mutable.
  Desc->IsConstInMutable = Desc->IsConst && IsMutable;
  Desc->LifeState =
      D->isPrimitiveArray()
          ? Lifetime::Started
          : (Desc->IsActive ? Lifetime::NotStarted : Lifetime::Started);

  if (auto Fn = D->CtorFn)
    Fn(B, Ptr + FieldOffset, Desc->IsConst, Desc->IsFieldMutable,
       Desc->IsVolatile, Desc->IsActive, InUnion || D->isUnion(), D);
}

static void initBase(Block *B, std::byte *Ptr, bool IsConst, bool IsMutable,
                     bool IsVolatile, bool IsActive, bool InUnion,
                     const Descriptor *D, unsigned FieldOffset,
                     bool IsVirtualBase) {
  assert(D);
  assert(D->ElemRecord);
  assert(!D->ElemRecord->isUnion()); // Unions cannot be base classes.

  auto *Desc = reinterpret_cast<InlineDescriptor *>(Ptr + FieldOffset) - 1;
  Desc->Offset = FieldOffset;
  Desc->Desc = D;
  Desc->IsInitialized = D->IsArray;
  Desc->IsBase = true;
  Desc->IsVirtualBase = IsVirtualBase;
  Desc->IsActive = IsActive && !InUnion;
  Desc->IsConst = IsConst || D->IsConst;
  Desc->IsFieldMutable = IsMutable || D->IsMutable;
  Desc->InUnion = InUnion;
  Desc->IsVolatile = false;

  for (const auto &V : D->ElemRecord->bases())
    initBase(B, Ptr + FieldOffset, IsConst, IsMutable, IsVolatile, IsActive,
             InUnion, V.Desc, V.Offset, false);
  for (const auto &F : D->ElemRecord->fields())
    initField(B, Ptr + FieldOffset, IsConst, IsMutable, IsVolatile, IsActive,
              InUnion, InUnion, F.Desc, F.Offset);
}

static void ctorRecord(Block *B, std::byte *Ptr, bool IsConst, bool IsMutable,
                       bool IsVolatile, bool IsActive, bool InUnion,
                       const Descriptor *D) {
  for (const auto &V : D->ElemRecord->bases())
    initBase(B, Ptr, IsConst, IsMutable, IsVolatile, IsActive, InUnion, V.Desc,
             V.Offset,
             /*IsVirtualBase=*/false);
  for (const auto &F : D->ElemRecord->fields()) {
    bool IsUnionField = D->isUnion();
    initField(B, Ptr, IsConst, IsMutable, IsVolatile, IsActive, IsUnionField,
              InUnion || IsUnionField, F.Desc, F.Offset);
  }
  for (const auto &V : D->ElemRecord->virtual_bases())
    initBase(B, Ptr, IsConst, IsMutable, IsVolatile, IsActive, InUnion, V.Desc,
             V.Offset,
             /*IsVirtualBase=*/true);
}

static void destroyField(Block *B, std::byte *Ptr, const Descriptor *D,
                         unsigned FieldOffset) {
  if (auto Fn = D->DtorFn)
    Fn(B, Ptr + FieldOffset, D);
}

static void destroyBase(Block *B, std::byte *Ptr, const Descriptor *D,
                        unsigned FieldOffset) {
  assert(D);
  assert(D->ElemRecord);

  for (const auto &V : D->ElemRecord->bases())
    destroyBase(B, Ptr + FieldOffset, V.Desc, V.Offset);
  for (const auto &F : D->ElemRecord->fields())
    destroyField(B, Ptr + FieldOffset, F.Desc, F.Offset);
}

static void dtorRecord(Block *B, std::byte *Ptr, const Descriptor *D) {
  for (const auto &F : D->ElemRecord->bases())
    destroyBase(B, Ptr, F.Desc, F.Offset);
  for (const auto &F : D->ElemRecord->fields())
    destroyField(B, Ptr, F.Desc, F.Offset);
  for (const auto &F : D->ElemRecord->virtual_bases())
    destroyBase(B, Ptr, F.Desc, F.Offset);
}

/// Whether a record needs its descriptor dtor function called.
static bool needsRecordDtor(const Record *R) {
  for (const auto &B : R->bases()) {
    if (B.Desc->DtorFn)
      return true;
  }

  for (const auto &F : R->fields()) {
    if (F.Desc->DtorFn)
      return true;
  }

  for (const auto &V : R->virtual_bases()) {
    if (V.Desc->DtorFn)
      return true;
  }
  return false;
}

static BlockDtorFn getDtorPrim(PrimType T) {
  switch (T) {
  case PT_Ptr:
    return dtorTy<PrimConv<PT_Ptr>::T>;
  case PT_MemberPtr:
    return dtorTy<PrimConv<PT_MemberPtr>::T>;
  default:
    return nullptr;
  }
  llvm_unreachable("Unhandled PrimType");
}

// NOTE: The following #if-ed out code is for calling constructors of primitive
// types. It is currently not needed but I'm not sure if it will stay this way
// forever so I'm leaving it here for now.
#if 0
template <typename T> static constexpr bool needsCtor() {
  return false;
  if constexpr (std::is_same_v<T, Char<true>> ||
                std::is_same_v<T, Char<false>> ||
                std::is_same_v<T, Integral<16, true>> ||
                std::is_same_v<T, Integral<16, false>> ||
                std::is_same_v<T, Integral<32, true>> ||
                std::is_same_v<T, Integral<32, false>> ||
                std::is_same_v<T, Integral<64, true>> ||
                std::is_same_v<T, Integral<64, false>> ||
                std::is_same_v<T, IntegralAP<true>> ||
                std::is_same_v<T, IntegralAP<false>> ||
                std::is_same_v<T, Floating> || std::is_same_v<T, Boolean>)
    return false;

  return true;
}


static BlockCtorFn getCtorArrayPrim(PrimType Type) {
  TYPE_SWITCH(Type, if constexpr (!needsCtor<T>()) return nullptr;
              return ctorArrayTy<T>);
  llvm_unreachable("unknown Expr");
}
static BlockCtorFn getCtorPrim(PrimType T) {
  return nullptr;
  switch (T) {
  // case PT_Ptr:
    // return ctorTy<PrimConv<PT_Ptr>::T>;
  // case PT_MemberPtr:
    // return ctorTy<PrimConv<PT_MemberPtr>::T>;
  default:
    return nullptr;
  }
  llvm_unreachable("Unhandled PrimType");
}


template <typename T>
static void ctorArrayTy(Block *, std::byte *Ptr, bool, bool, bool, bool, bool,
                        const Descriptor *D) {
  new (Ptr) InitMapPtr();

  if constexpr (needsCtor<T>()) {
    Ptr += sizeof(InitMapPtr);
    for (unsigned I = 0, NE = D->getNumElems(); I < NE; ++I) {
      new (&reinterpret_cast<T *>(Ptr)[I]) T();
    }
  }
}
template <typename T>
static void ctorTy(Block *, std::byte *Ptr, bool, bool, bool, bool, bool,
                   const Descriptor *) {
  static_assert(needsCtor<T>());
  new (Ptr) T();
}
#endif

static BlockDtorFn getDtorArrayPrim(PrimType Type) {
  TYPE_SWITCH(Type, return dtorArrayTy<T>);
  llvm_unreachable("unknown Expr");
}

/// Primitives.
Descriptor::Descriptor(DeclOrExpr D, const Type *SourceTy, PrimType Type,
                       bool IsConst, bool IsTemporary, bool IsMutable,
                       bool IsVolatile)
    : Source(D), SourceType(SourceTy), ElemSize(primSize(Type)), Size(ElemSize),
      AllocSize(align(ElemSize)), PrimT(Type), IsConst(IsConst),
      IsMutable(IsMutable), IsTemporary(IsTemporary), IsVolatile(IsVolatile),
      CtorFn(nullptr), DtorFn(getDtorPrim(Type)) {
  assert(Source && "Missing source");
}

/// Primitive arrays.
Descriptor::Descriptor(DeclOrExpr D, const Type *SourceTy, PrimType Type,
                       size_t NumElems, bool IsConst, bool IsTemporary,
                       bool IsMutable, bool IsVolatile)
    : Source(D), SourceType(SourceTy), ElemSize(primSize(Type)),
      Size(ElemSize * NumElems), AllocSize(align(Size) + sizeof(InitMapPtr)),
      PrimT(Type), IsConst(IsConst), IsMutable(IsMutable),
      IsTemporary(IsTemporary), IsVolatile(IsVolatile), IsArray(true),
      CtorFn(nullptr), DtorFn(getDtorArrayPrim(Type)) {
  assert(Source && "Missing source");
  assert(NumElems <= (MaxArrayElemBytes / ElemSize));
}

/// Primitive unknown-size arrays.
Descriptor::Descriptor(DeclOrExpr D, PrimType Type, bool IsConst,
                       bool IsTemporary, UnknownSize)
    : Source(D), ElemSize(primSize(Type)), Size(UnknownSizeMark),
      AllocSize(sizeof(InitMapPtr) + alignof(void *)), PrimT(Type),
      IsConst(IsConst), IsMutable(false), IsTemporary(IsTemporary),
      IsArray(true), CtorFn(nullptr), DtorFn(getDtorArrayPrim(Type)) {
  assert(Source && "Missing source");
}

/// Arrays of composite elements.
Descriptor::Descriptor(DeclOrExpr D, const Type *SourceTy,
                       const Descriptor *Elem, unsigned NumElems, bool IsConst,
                       bool IsTemporary, bool IsMutable)
    : Source(D), SourceType(SourceTy),
      ElemSize(Elem->getAllocSize() + sizeof(InlineDescriptor)),
      Size(ElemSize * NumElems),
      AllocSize(std::max<size_t>(alignof(void *), Size)), ElemDesc(Elem),
      IsConst(IsConst), IsMutable(IsMutable), IsTemporary(IsTemporary),
      IsArray(true), CtorFn(ctorArrayDesc),
      DtorFn(Elem->DtorFn ? dtorArrayDesc : nullptr) {
  assert(Source && "Missing source");
}

/// Unknown-size arrays of composite elements.
Descriptor::Descriptor(DeclOrExpr D, const Descriptor *Elem, bool IsTemporary,
                       UnknownSize)
    : Source(D), ElemSize(Elem->getAllocSize() + sizeof(InlineDescriptor)),
      Size(UnknownSizeMark), AllocSize(alignof(void *)), ElemDesc(Elem),
      IsConst(true), IsMutable(false), IsTemporary(IsTemporary), IsArray(true),
      CtorFn(ctorArrayDesc), DtorFn(Elem->DtorFn ? dtorArrayDesc : nullptr) {
  assert(Source && "Missing source");
}

/// Composite records.
Descriptor::Descriptor(DeclOrExpr D, const Record *R, bool IsConst,
                       bool IsTemporary, bool IsMutable, bool IsVolatile)
    : Source(D), ElemSize(std::max<size_t>(alignof(void *), R->getFullSize())),
      Size(ElemSize), AllocSize(Size), ElemRecord(R), IsConst(IsConst),
      IsMutable(IsMutable), IsTemporary(IsTemporary), IsVolatile(IsVolatile),
      CtorFn(ctorRecord), DtorFn(needsRecordDtor(R) ? dtorRecord : nullptr) {
  assert(Source && "Missing source");
}

/// Dummy.
Descriptor::Descriptor(DeclOrExpr D)
    : Source(D), ElemSize(1), Size(1), AllocSize(0), ElemDesc(nullptr),
      IsConst(true), IsMutable(false), IsTemporary(false) {
  assert(Source && "Missing source");
}

QualType Descriptor::getType() const {
  if (SourceType)
    return QualType(SourceType, 0);

  if (const auto *T = dyn_cast_if_present<TypeDecl>(asDecl()))
    return T->getASTContext().getTypeDeclType(T);

  // The Source sometimes has a different type than the once
  // we really save. Try to consult the Record first.
  if (isRecord()) {
    const RecordDecl *RD = ElemRecord->getDecl();
    QualType T = RD->getASTContext().getTagType(ElaboratedTypeKeyword::None,
                                                std::nullopt, RD, false);
    if (IsConst)
      return T.withConst();
    return T;
  }

  if (const auto *E = asExpr()) {
    if (isa<CXXNewExpr>(E))
      return E->getType()->getPointeeType();

    // std::allocator.allocate() call.
    if (const auto *ME = dyn_cast<CXXMemberCallExpr>(E);
        ME && ME->getRecordDecl()->getName() == "allocator" &&
        ME->getMethodDecl()->getName() == "allocate")
      return E->getType()->getPointeeType();
    return E->getType();
  }

  if (const auto *D = asValueDecl())
    return D->getType();

  llvm_unreachable("Invalid descriptor type");
}

QualType Descriptor::getElemQualType() const {
  assert(isArray());
  QualType T;

  if (SourceType) {
    T = QualType(SourceType, 0);
  } else if (const auto *TDecl = dyn_cast_if_present<TypeDecl>(asDecl())) {
    T = TDecl->getASTContext().getTypeDeclType(TDecl);
  } else if (isRecord()) {
    const RecordDecl *RD = ElemRecord->getDecl();
    T = RD->getASTContext().getTagType(ElaboratedTypeKeyword::None,
                                       std::nullopt, RD, false);
    if (IsConst)
      T.addConst();
  } else if (const auto *E = asExpr()) {
    T = E->getType();
  } else if (const auto *D = asValueDecl()) {
    T = D->getType();
  }

  assert(!T.isNull());

  if (const auto *AT = T->getAs<AtomicType>())
    T = AT->getValueType();
  if (T->isPointerOrReferenceType())
    T = T->getPointeeType();

  if (const auto *AT = T->getAsArrayTypeUnsafe()) {
    // For primitive arrays, we don't save a QualType at all,
    // just a PrimType. Try to figure out the QualType here.
    if (isPrimitiveArray()) {
      while (T->isArrayType())
        T = T->getAsArrayTypeUnsafe()->getElementType();
      return T;
    }
    return AT->getElementType();
  }
  if (const auto *CT = T->getAs<ComplexType>())
    return CT->getElementType();
  if (const auto *CT = T->getAs<VectorType>())
    return CT->getElementType();

  return T;
}

QualType Descriptor::getDataType(const ASTContext &Ctx) const {
  auto MakeArrayType = [&](QualType ElemType) -> QualType {
    if (IsArray)
      return Ctx.getConstantArrayType(
          ElemType, APInt(64, static_cast<uint64_t>(getNumElems()), false),
          nullptr, ArraySizeModifier::Normal, 0);
    return ElemType;
  };

  if (const auto *E = asExpr()) {
    if (isa<CXXNewExpr>(E))
      return MakeArrayType(E->getType()->getPointeeType());

    // std::allocator.allocate() call.
    if (const auto *ME = dyn_cast<CXXMemberCallExpr>(E);
        ME && ME->getRecordDecl()->getName() == "allocator" &&
        ME->getMethodDecl()->getName() == "allocate")
      return MakeArrayType(E->getType()->getPointeeType());
    return E->getType();
  }

  return getType();
}

SourceLocation Descriptor::getLocation() const {
  if (auto *D = Source.asDecl())
    return D->getLocation();
  if (auto *E = Source.asExpr())
    return E->getExprLoc();
  llvm_unreachable("Invalid descriptor type");
}

SourceInfo Descriptor::getLoc() const {
  if (const auto *D = Source.asDecl())
    return SourceInfo(D);
  if (const auto *E = Source.asExpr())
    return SourceInfo(E);
  llvm_unreachable("Invalid descriptor type");
}

bool Descriptor::hasTrivialDtor() const {
  if (isPrimitive() || isPrimitiveArray())
    return true;

  if (isRecord()) {
    assert(ElemRecord);
    return ElemRecord->hasTrivialDtor();
  }

  if (!ElemDesc)
    return true;
  // Composite arrays.
  return ElemDesc->hasTrivialDtor();
}

bool Descriptor::isUnion() const { return isRecord() && ElemRecord->isUnion(); }

unsigned Descriptor::getElemDataSize() const {
  if ((isPrimitive() || isPrimitiveArray()) &&
      isIntegerOrBoolType(getPrimType())) {
    if (getPrimType() == PT_Bool)
      return 1;
    FIXED_SIZE_INT_TYPE_SWITCH(getPrimType(), { return T::bitWidth() / 8; });
  }
  return ElemSize;
}
