//===------------- InterpBuiltinObjectSize.cpp ------------------*- 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
//
//===----------------------------------------------------------------------===//

// Implementation of the frontend part of the __builtin_object_size and
// __builtin_dynamic_object_size builtins.

#include "InterpHelpers.h"
#include "Pointer.h"
#include "Record.h"
#include "clang/AST/RecordLayout.h"

using namespace clang;
using namespace clang::interp;

enum : uint8_t {
  Regular = 1 << 0,
  IgnoreBaseCasts = 1 << 1,
  SurroundingArray = 1 << 2,
};

// Helper to check if a Type can be passed to
// ASTContext::getRecordLayout().
static bool validType(QualType T) {
  if (const RecordDecl *RD = T->getAsRecordDecl())
    return ASTContext::hasLayout(RD);
  return true;
}

static QualType computeFieldType(const ASTContext &ASTCtx,
                                 const OpaquePointer &OP,
                                 unsigned TypeModifier = 0) {
  QualType CurType = OP.getObjectType();

  unsigned Drop = 0;
  if (TypeModifier & IgnoreBaseCasts && OP.PathLength != 0 &&
      OP.path().back().Kind == PointerPathEntry::Base)
    Drop = 1;

  if (TypeModifier & SurroundingArray && OP.PathLength != 0 &&
      OP.path().back().Kind == PointerPathEntry::Array)
    Drop = 1;

  for (const PointerPathEntry &Entry : OP.path().drop_back(Drop)) {
    switch (Entry.Kind) {
    case PointerPathEntry::Base:
      CurType = ASTCtx.getCanonicalTagType(Entry.RD.getPointer());
      break;
    case PointerPathEntry::Field:
      CurType = Entry.FD->getType();
      break;
    case PointerPathEntry::Array:
    case PointerPathEntry::NegativeArray:
      if (!CurType->isArrayType())
        continue;
      CurType = CurType->getAsArrayTypeUnsafe()->getElementType();
    }
  }

  return CurType;
}

static std::optional<unsigned> computeFullDescSize(const ASTContext &ASTCtx,
                                                   const Descriptor *Desc) {
  if (Desc->isPrimitive() || Desc->isArray()) {
    QualType T = Desc->getType();
    if (!validType(T))
      return std::nullopt;
    return ASTCtx.getTypeSizeInChars(T).getQuantity();
  }

  if (Desc->isRecord()) {
    // Can't use Descriptor::getType() as that may return a pointer type. Look
    // at the decl directly.

    const RecordDecl *RD = Desc->ElemRecord->getDecl();
    if (!ASTContext::hasLayout(RD))
      return std::nullopt;

    return ASTCtx.getTypeSizeInChars(ASTCtx.getCanonicalTagType(RD))
        .getQuantity();
  }

  return std::nullopt;
}

/// Compute the byte offset of \p Ptr in the full declaration.
static unsigned computePointerOffset(const ASTContext &ASTCtx,
                                     const Pointer &Ptr) {
  return Ptr.computeLayoutOffset(ASTCtx).value_or(0);
}

/// Does Ptr point to the last subobject?
static bool pointsToLastObject(const Pointer &Ptr) {
  Pointer P = Ptr;
  while (!P.isRoot()) {

    if (P.isArrayElement()) {
      P = P.expand().getArray();
      continue;
    }
    if (P.isBaseClass()) {
      if (P.getRecord()->getNumFields() > 0)
        return false;
      P = P.getBase();
      continue;
    }

    Pointer Base = P.getBase();
    if (const Record *R = Base.getRecord()) {
      assert(P.getField());
      if (P.getField()->getFieldIndex() != R->getNumFields() - 1)
        return false;
    }
    P = Base;
  }

  return true;
}

/// Does Ptr point to the last object AND to a flexible array member?
static bool isUserWritingOffTheEnd(const ASTContext &Ctx, const Pointer &Ptr,
                                   bool InvalidBase) {
  auto isFlexibleArrayMember = [&](const Descriptor *FieldDesc) {
    using FAMKind = LangOptions::StrictFlexArraysLevelKind;
    FAMKind StrictFlexArraysLevel =
        Ctx.getLangOpts().getStrictFlexArraysLevel();

    if (StrictFlexArraysLevel == FAMKind::Default)
      return true;

    unsigned NumElems = FieldDesc->getNumElems();
    if (NumElems == 0 && StrictFlexArraysLevel != FAMKind::IncompleteOnly)
      return true;

    if (NumElems == 1 && StrictFlexArraysLevel == FAMKind::OneZeroOrIncomplete)
      return true;
    return false;
  };

  const Descriptor *FieldDesc = Ptr.getFieldDesc();
  if (!FieldDesc->isArray())
    return false;

  return InvalidBase && pointsToLastObject(Ptr) &&
         isFlexibleArrayMember(FieldDesc);
}

static bool isUserWritingOffTheEnd(const ASTContext &ASTCtx,
                                   const OpaquePointer &OP) {
  if (OP.PathLength == 0)
    return false;

  QualType CurType = OP.getObjectType();
  for (unsigned I = 0; I != OP.PathLength; ++I) {
    const PointerPathEntry &Entry = OP.Path[I];
    switch (Entry.Kind) {
    case PointerPathEntry::Base:
      return false;
    case PointerPathEntry::Field: {
      const FieldDecl *FD = OP.Path[I].FD;
      if (!FD->getParent()->isUnion() &&
          FD->getFieldIndex() != FD->getParent()->getNumFields() - 1)
        return false;
      CurType = FD->getType();
    } break;
    case PointerPathEntry::Array: {
      if (I == OP.PathLength - 1)
        break;

      if (!CurType->isArrayType())
        break;

      unsigned Index = OP.Path[I].Index;
      const ArrayType *AT = CurType->getAsArrayTypeUnsafe();
      assert(AT);
      if (const auto *CAT = dyn_cast<ConstantArrayType>(AT)) {
        if (Index != CAT->getLimitedSize() - 1)
          return false;
        CurType = CAT->getElementType();
      } else {
        return false;
      }
    } break;
    case PointerPathEntry::NegativeArray:
      return false;
    }
  }

  // We're pointing to the last field in the full object.
  // CurType is now the most derived type.
  if (!CurType->isArrayType())
    return false;

  if (isa<IncompleteArrayType>(CurType))
    return true;

  const auto *CAT = dyn_cast<ConstantArrayType>(CurType);
  if (!CAT)
    return false;

  using FAMKind = LangOptions::StrictFlexArraysLevelKind;
  FAMKind StrictFlexArraysLevel =
      ASTCtx.getLangOpts().getStrictFlexArraysLevel();

  if (StrictFlexArraysLevel == FAMKind::Default)
    return true;

  unsigned Size = CAT->getZExtSize();
  if (Size == 0 && StrictFlexArraysLevel != FAMKind::IncompleteOnly)
    return true;

  if (Size == 1 && StrictFlexArraysLevel == FAMKind::OneZeroOrIncomplete)
    return true;
  return false;
}

/// Determine the offset of the given pointer. Depending on \c
/// UseClosestSurroundingVariable, the offset is either relative to the full
/// object or to the closest surrounding field or array.
static std::optional<uint64_t>
computeOpaquePtrOffset(const ASTContext &ASTCtx, const Pointer &Ptr,
                       bool UseClosestSurroundingVariable,
                       bool &OffsetIsNegative) {
  const OpaquePointer &OP = Ptr.asOpaquePointer();

  uint64_t Offset = 0;
  std::optional<uint64_t> SurroundingArrayOffset;
  QualType CurType = OP.getObjectType();
  for (const PointerPathEntry &Entry : OP.path()) {
    switch (Entry.Kind) {
    case PointerPathEntry::Base: {
      const RecordDecl *RD = CurType->getAsRecordDecl();
      if (!ASTContext::hasLayout(RD))
        return std::nullopt;

      const ASTRecordLayout &Layout = ASTCtx.getASTRecordLayout(RD);
      Offset += Layout.getBaseClassOffset(Entry.RD.getPointer()).getQuantity();

      CurType = ASTCtx.getCanonicalTagType(Entry.RD.getPointer());
    } break;

    case PointerPathEntry::Field: {
      const FieldDecl *FD = Entry.FD;
      const RecordDecl *RD = FD->getParent();
      if (!ASTContext::hasLayout(RD))
        return std::nullopt;

      const ASTRecordLayout &Layout = ASTCtx.getASTRecordLayout(RD);
      Offset +=
          ASTCtx.toCharUnitsFromBits(Layout.getFieldOffset(FD->getFieldIndex()))
              .getQuantity();

      CurType = FD->getType();
    } break;
    case PointerPathEntry::Array:
    case PointerPathEntry::NegativeArray: {
      bool Add = (Entry.Kind == PointerPathEntry::Array);
      uint64_t Index = Entry.Index;
      if (!Add) {
        // NegativeArray is always > 0.
        OffsetIsNegative = true;
      }
      SurroundingArrayOffset = Offset;
      if (!CurType->isArrayType()) {
        if (Add)
          Offset += Index * ASTCtx.getTypeSizeInChars(CurType).getQuantity();
        else
          Offset -= Index * ASTCtx.getTypeSizeInChars(CurType).getQuantity();
        continue;
      }
      const ArrayType *AT = CurType->getAsArrayTypeUnsafe();
      assert(AT);
      QualType ElemTy = AT->getElementType();
      if (!validType(ElemTy) || isa<VariableArrayType>(AT))
        return std::nullopt;
      if (Add)
        Offset += Index * ASTCtx.getTypeSizeInChars(ElemTy).getQuantity();
      else
        Offset -= Index * ASTCtx.getTypeSizeInChars(ElemTy).getQuantity();
      CurType = AT->getElementType();
    } break;
    }
  }

  if (UseClosestSurroundingVariable && SurroundingArrayOffset)
    return Offset - *SurroundingArrayOffset;

  QualType Ty = CurType.getNonReferenceType();

  if (UseClosestSurroundingVariable &&
      (Ty->isIncompleteType() || Ty->isFunctionType()))
    return std::nullopt;

  if (isa<VariableArrayType>(Ty))
    return std::nullopt;

  if (OP.PathLength == 1 && OP.path().back().Kind == PointerPathEntry::Field &&
      isa<IncompleteArrayType>(CurType)) {
    return Offset;
  }

  if (UseClosestSurroundingVariable)
    return 0;

  return Offset;
}

/// Check if the given pointer points to the complete object, i.e. either to the
/// very beginning or after the end (into the flexible array member) of the
/// object.
static bool pointsToCompleteObject(const ASTContext &ASTCtx,
                                   const Pointer &Ptr) {
  const OpaquePointer &OP = Ptr.asOpaquePointer();
  if (OP.PathLength == 0)
    return true;

  QualType FieldType = computeFieldType(ASTCtx, OP);
  if (OP.isArrayElement())
    FieldType = OP.getSurroundingArray();
  return isa<IncompleteArrayType>(FieldType);
}

static std::optional<unsigned>
computeOpaqueSize(const ASTContext &ASTCtx, const Pointer &Ptr,
                  bool UseClosestSurroundingVariable, bool WritingOffTheEnd,
                  bool DetermineForCompleteObject) {
  const OpaquePointer &OP = Ptr.asOpaquePointer();

  CharUnits TypeSize;
  // NOTE: Clang does not consider base casts. GCC does.
  if (UseClosestSurroundingVariable) {
    QualType FieldTy =
        computeFieldType(ASTCtx, OP, SurroundingArray | IgnoreBaseCasts);
    if (!validType(FieldTy))
      return std::nullopt;
    TypeSize = ASTCtx.getTypeSizeInChars(FieldTy);
  } else {
    QualType ObjectTy = OP.getObjectType();
    if (!validType(ObjectTy))
      return std::nullopt;
    TypeSize = ASTCtx.getTypeSizeInChars(ObjectTy);
  }

  // The Flexible array member should only be checked if we're pointing to the
  // object as a whole, or if we're looking for the whole object size.
  if (!WritingOffTheEnd && !DetermineForCompleteObject)
    return TypeSize.getQuantity();

  // Check if we need to add the flexible array member size.
  const VarDecl *Base = OP.getBaseVarDecl();
  if (!Base)
    return TypeSize.getQuantity();

  // If the base type is an incomplete array type (not a flexible array member
  // of a struct), and we're looking for the complete object... we can't.
  if (DetermineForCompleteObject && isa<IncompleteArrayType>(Base->getType()))
    return std::nullopt;

  if (!Base->getType()->isRecordType())
    return TypeSize.getQuantity();

  if (!Base->hasInit())
    return TypeSize.getQuantity();
  CharUnits FlexibleArraySize = Base->getFlexibleArrayInitChars(ASTCtx);
  return (TypeSize + FlexibleArraySize).getQuantity();
}

namespace clang {
namespace interp {

/// Evaluate __builtin_object_size or __builtin_dynamic_object_size for the
/// given pointer and Kind.
///
/// When computing the final result, the most important variable is
/// UseClosestSurroundingVariable. If it is true, we will use the field the
/// pointer points to, or the parent array of the element.
/// UseClosestSurroundingVariable is true for Kind 1 and 3.
UnsignedOrNone evaluateBuiltinObjectSize(const ASTContext &ASTCtx,
                                         unsigned Kind, Pointer &Ptr,
                                         const Expr *E, bool IsDynamic) {
  if (Ptr.isZero())
    return std::nullopt;

  bool InvalidBase = false;
  if (Ptr.isOpaquePointer()) {
    bool UseClosestSurroundingVariable = (Kind == 1) || (Kind == 3);
    const OpaquePointer &OP = Ptr.asOpaquePointer();
    InvalidBase = OP.Base.getType()->isPointerType();
    bool DetermineForCompleteObject = pointsToCompleteObject(ASTCtx, Ptr);
    bool WritingOffTheEnd = isUserWritingOffTheEnd(ASTCtx, OP);

    // Either the size of the full variable (Kind = 0 or 2) or the size of the
    // closest surrounding variable (Kind = 1 or 3).
    std::optional<unsigned> FullSize =
        computeOpaqueSize(ASTCtx, Ptr, UseClosestSurroundingVariable,
                          WritingOffTheEnd, DetermineForCompleteObject);

    if (!FullSize)
      return std::nullopt;

    // Similar to the FullSize above, the offset is relative either to the full
    // variable or to the closest surrounding variable.
    bool OffsetIsNegative = false;
    std::optional<uint64_t> Offset = computeOpaquePtrOffset(
        ASTCtx, Ptr, UseClosestSurroundingVariable, OffsetIsNegative);

    if (!Offset)
      return std::nullopt;

    if (OffsetIsNegative)
      return 0u;

    // For __builtin_dynamic_object_size on a counted_by-annotated flexible
    // array member, defer to IR generation (emitCountedBySize in CGBuiltin):
    // its runtime computation uses the live 'count' field and is more accurate
    // than the layout/initializer-derived size we'd produce here. Use the same
    // findStructFieldAccess form-recognition CGBuiltin does, so we refuse to
    // fold on exactly the shapes that path handles (and, importantly, *not*
    // on '&af.fam' which designates the array-as-a-whole and stays on the
    // layout-derived path to match GCC).
    if (IsDynamic) {
      const auto *ME =
          dyn_cast_if_present<MemberExpr>(findStructFieldAccess(E));
      const auto *FD = ME ? dyn_cast<FieldDecl>(ME->getMemberDecl()) : nullptr;
      if (FD && FD->getType()->isCountAttributedType())
        return std::nullopt;
    }

    if (!UseClosestSurroundingVariable || DetermineForCompleteObject) {
      // Kind=3 wants a lower bound, so we can't fall back to this.
      if (Kind == 3 && !DetermineForCompleteObject)
        return std::nullopt;

      if (InvalidBase)
        return std::nullopt;

      QualType ObjectTy = OP.getObjectType();
      if (ObjectTy->isIncompleteType() || isa<VariableArrayType>(ObjectTy) ||
          ObjectTy->isFunctionType())
        return std::nullopt;
    }

    *Offset += (Ptr.getByteOffset() *
                ASTCtx.getTypeSizeInChars(OP.getFieldType()).getQuantity());

    if (*Offset > *FullSize)
      return 0u;

    if (Kind == 1 && InvalidBase && WritingOffTheEnd)
      return std::nullopt;

    assert(*Offset <= *FullSize);
    return static_cast<unsigned>(*FullSize - *Offset);
  }

  // ----------------------------------------------------------------------------------------------------

  if (Ptr.isDummy() && Ptr.getType()->isPointerType())
    return std::nullopt;

  if (!Ptr.isBlockPointer())
    return std::nullopt;

  if (Ptr.isDummy()) {
    if (const VarDecl *VD = Ptr.getRootVarDecl();
        VD && VD->getType()->isPointerType())
      InvalidBase = true;
  }

  bool UseFieldDesc = (Kind & 1u);
  bool ReportMinimum = (Kind & 2u);

  // According to the GCC documentation, we want the size of the subobject
  // denoted by the pointer. But that's not quite right -- what we actually
  // want is the size of the immediately-enclosing array, if there is one.
  if (Ptr.isArrayElement())
    Ptr = Ptr.expand();

  bool DetermineForCompleteObject = Ptr.getFieldDesc() == Ptr.getDeclDesc();
  const Descriptor *DeclDesc = Ptr.getDeclDesc();
  assert(DeclDesc);

  if (!UseFieldDesc || DetermineForCompleteObject) {
    // Can't read beyond the pointer decl desc.
    if (!ReportMinimum && DeclDesc->getDataType(ASTCtx)->isPointerType())
      return std::nullopt;

    if (InvalidBase)
      return std::nullopt;
  } else {
    if (isUserWritingOffTheEnd(ASTCtx, Ptr, InvalidBase)) {
      // If we cannot determine the size of the initial allocation, then we
      // can't given an accurate upper-bound. However, we are still able to give
      // conservative lower-bounds for Type=3.
      if (Kind == 1)
        return std::nullopt;
    }
  }

  // The "closest surrounding subobject" is NOT a base class,
  // so strip the base class casts.
  if (UseFieldDesc && Ptr.isBaseClass())
    Ptr = Ptr.stripBaseCasts();

  const Descriptor *Desc = UseFieldDesc ? Ptr.getFieldDesc() : DeclDesc;
  assert(Desc);

  std::optional<unsigned> FullSize = computeFullDescSize(ASTCtx, Desc);
  if (!FullSize)
    return std::nullopt;

  unsigned ByteOffset;
  if (UseFieldDesc) {
    if (Ptr.isBaseClass()) {
      assert(computePointerOffset(ASTCtx, Ptr.getBase()) <=
             computePointerOffset(ASTCtx, Ptr));
      ByteOffset = computePointerOffset(ASTCtx, Ptr.getBase()) -
                   computePointerOffset(ASTCtx, Ptr);
    } else {
      if (Ptr.inArray())
        ByteOffset =
            computePointerOffset(ASTCtx, Ptr) -
            computePointerOffset(ASTCtx, Ptr.expand().atIndex(0).narrow());
      else
        ByteOffset = 0;
    }
  } else
    ByteOffset = computePointerOffset(ASTCtx, Ptr);

  assert(ByteOffset <= *FullSize);
  return *FullSize - ByteOffset;
}
} // namespace interp
} // namespace clang
