//===--- InterpFrame.cpp - Call Frame implementation for the 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 "InterpFrame.h"
#include "Boolean.h"
#include "Char.h"
#include "Function.h"
#include "InterpStack.h"
#include "InterpState.h"
#include "MemberPointer.h"
#include "Pointer.h"
#include "PrimType.h"
#include "Program.h"
#include "clang/AST/ASTContext.h"
#include "clang/AST/DeclCXX.h"
#include "clang/AST/ExprCXX.h"

using namespace clang;
using namespace clang::interp;

InterpFrame::InterpFrame(InterpState &S)
    : Caller(nullptr), S(S), Depth(0), Func(nullptr), RetPC(CodePtr()),
      ArgSize(0), Args(nullptr), FrameOffset(0) {}

InterpFrame::InterpFrame(InterpState &S, const Function *Func,
                         InterpFrame *Caller, CodePtr RetPC, unsigned ArgSize)
    : Caller(Caller), S(S), Depth(Caller ? Caller->Depth + 1 : 0), Func(Func),
      RetPC(RetPC), ArgSize(ArgSize), Args(static_cast<char *>(S.Stk.top())),
      FrameOffset(S.Stk.size()) {

  if (!Func)
    return;
  // Initialize argument blocks.
  for (unsigned I = 0, N = Func->getNumWrittenParams(); I != N; ++I)
    new (argBlock(I)) Block(S.EvalID, Func->getParamDescriptor(I).Desc);

  if (Func->getFrameSize() == 0)
    return;

  for (auto &Scope : Func->scopes()) {
    for (auto &Local : Scope.locals()) {
      new (localBlock(Local.Offset)) Block(S.EvalID, Local.Desc);
      // Note that we are NOT calling invokeCtor() here, since that is done
      // via the InitScope op.
      new (localInlineDesc(Local.Offset)) InlineDescriptor(Local.Desc);
    }
  }
}

InterpFrame::InterpFrame(InterpState &S, const Function *Func, CodePtr RetPC,
                         unsigned VarArgSize)
    : InterpFrame(S, Func, S.Current, RetPC, Func->getArgSize() + VarArgSize) {
  // As per our calling convention, the this pointer is
  // part of the ArgSize.
  // If the function has RVO, the RVO pointer is first.
  // If the fuction has a This pointer, that one is next.
  // Then follow the actual arguments (but those are handled
  // in getParamPointer()).
  if (Func->hasRVO()) {
    // RVO pointer offset is always 0.
  }

  if (Func->hasThisPointer())
    ThisPointerOffset = Func->hasRVO() ? sizeof(Pointer) : 0;
}

InterpFrame::~InterpFrame() {
  if (!Func)
    return;

  // De-initialize all argument blocks.
  for (unsigned I = 0, N = Func->getNumWrittenParams(); I != N; ++I)
    S.deallocate(argBlock(I));

  // When destroying the InterpFrame, call the Dtor for all block
  // that haven't been destroyed via a destroy() op yet.
  // This happens when the execution is interruped midway-through.
  destroyScopes();
}

void InterpFrame::destroyScopes() {
  if (!Func || Func->getFrameSize() == 0)
    return;
  for (auto &Scope : Func->scopes()) {
    for (auto &Local : Scope.locals()) {
      S.deallocate(localBlock(Local.Offset));
    }
  }
}

void InterpFrame::initScope(unsigned Idx) {
  if (!Func)
    return;

  for (auto &Local : Func->getScope(Idx).locals()) {
    assert(!localBlock(Local.Offset)->isInitialized());
    localBlock(Local.Offset)->invokeCtor();
  }
}

void InterpFrame::enableLocal(unsigned Idx) {
  assert(Func);

  // FIXME: This is a little dirty, but to avoid adding a flag to
  // InlineDescriptor that's only ever useful on the toplevel of local
  // variables, we reuse the IsActive flag for the enabled state. We should
  // probably use a different struct than InlineDescriptor for the block-level
  // inline descriptor of local varaibles.
  localInlineDesc(Idx)->IsActive = true;
}

void InterpFrame::destroy(unsigned Idx) {
  for (auto &Local : Func->getScope(Idx).locals_reverse()) {
    S.deallocate(localBlock(Local.Offset));
  }
}

template <typename T>
static void print(llvm::raw_ostream &OS, const T &V, ASTContext &ASTCtx,
                  QualType Ty) {
  if constexpr (std::is_same_v<Pointer, T>) {
    if (Ty->isPointerOrReferenceType())
      V.toAPValue(ASTCtx).printPretty(OS, ASTCtx, Ty);
    else {
      if (std::optional<APValue> RValue = V.toRValue(ASTCtx, Ty))
        RValue->printPretty(OS, ASTCtx, Ty);
      else
        OS << "...";
    }
  } else {
    V.toAPValue(ASTCtx).printPretty(OS, ASTCtx, Ty);
  }
}

static bool shouldSkipInBacktrace(const Function *F) {
  if (F->isLambdaStaticInvoker())
    return true;

  const FunctionDecl *FD = F->getDecl();
  if (FD->getDeclName().getCXXOverloadedOperator() == OO_New ||
      FD->getDeclName().getCXXOverloadedOperator() == OO_Array_New)
    return true;

  if (const auto *MD = dyn_cast<CXXMethodDecl>(FD);
      MD && MD->getParent()->isAnonymousStructOrUnion())
    return true;

  return false;
}

void InterpFrame::describe(llvm::raw_ostream &OS) const {
  assert(Func);
  // For lambda static invokers, we would just print __invoke().
  if (shouldSkipInBacktrace(Func))
    return;

  const Expr *CallExpr = Caller->getExpr(getRetPC());
  const FunctionDecl *F = getCallee();
  auto PrintingPolicy = S.getASTContext().getPrintingPolicy();
  PrintingPolicy.SuppressLambdaBody = true;

  bool IsMemberCall = false;
  bool ExplicitInstanceParam = false;
  if (const auto *MD = dyn_cast<CXXMethodDecl>(F)) {
    IsMemberCall = !isa<CXXConstructorDecl>(MD) && !MD->isStatic();
    ExplicitInstanceParam = MD->isExplicitObjectMemberFunction();
  }

  if (Func->hasThisPointer() && IsMemberCall) {
    if (const auto *MCE = dyn_cast_if_present<CXXMemberCallExpr>(CallExpr)) {
      const Expr *Object = MCE->getImplicitObjectArgument();
      Object->printPretty(OS, /*Helper=*/nullptr,
                          PrintingPolicy,
                          /*Indentation=*/0);
      if (Object->getType()->isPointerType())
        OS << "->";
      else
        OS << ".";
    } else if (const auto *OCE =
                   dyn_cast_if_present<CXXOperatorCallExpr>(CallExpr)) {
      OCE->getArg(0)->printPretty(OS, /*Helper=*/nullptr,
                                  PrintingPolicy,
                                  /*Indentation=*/0);
      OS << ".";
    } else if (const auto *M = dyn_cast<CXXMethodDecl>(F)) {
      print(OS, getThis(), S.getASTContext(),
            S.getASTContext().getLValueReferenceType(
                S.getASTContext().getCanonicalTagType(M->getParent())));
      OS << ".";
    }
  }

  F->getNameForDiagnostic(OS, PrintingPolicy,
                          /*Qualified=*/false);
  OS << '(';
  unsigned Off = 0;

  Off += Func->hasRVO() ? primSize(PT_Ptr) : 0;
  Off += Func->hasThisPointer() ? primSize(PT_Ptr) : 0;
  llvm::ListSeparator Comma;
  for (const ParmVarDecl *Param :
       F->parameters().slice(ExplicitInstanceParam)) {
    OS << Comma;
    QualType Ty = Param->getType();
    PrimType PrimTy = S.Ctx.classify(Ty).value_or(PT_Ptr);

    TYPE_SWITCH(PrimTy, print(OS, stackRef<T>(Off), S.getASTContext(), Ty));
    Off += align(primSize(PrimTy));
  }
  OS << ")";
}

SourceRange InterpFrame::getCallRange() const {
  if (!Caller->Func) {
    if (SourceRange NullRange = S.getRange(nullptr, {}); NullRange.isValid())
      return NullRange;
    return S.EvalLocation;
  }

  // Move up to the frame that has a valid location for the caller.
  for (const InterpFrame *C = this; C; C = C->Caller) {
    if (!C->RetPC)
      continue;
    SourceRange CallRange =
        S.getRange(C->Caller->Func, C->RetPC - sizeof(uintptr_t));
    if (CallRange.isValid())
      return CallRange;
  }
  return S.EvalLocation;
}

const FunctionDecl *InterpFrame::getCallee() const {
  if (!Func)
    return nullptr;
  return Func->getDecl();
}

Pointer InterpFrame::getLocalPointer(unsigned Offset) const {
  assert(Offset < Func->getFrameSize() && "Invalid local offset.");
  return Pointer(localBlock(Offset));
}

Block *InterpFrame::getLocalBlock(unsigned Offset) const {
  return localBlock(Offset);
}

Pointer InterpFrame::getParamPointer(unsigned Index) {
  assert(!isBottomFrame());

  Block *B = argBlock(Index);

  // Copy the initial value.
  if (!B->isInitialized()) {
    unsigned ByteOffset = Func->getParamDescriptor(Index).Offset;
    assert(B->getDescriptor()->isPrimitive());
    B->invokeCtor();
    TYPE_SWITCH(B->getDescriptor()->getPrimType(),
                new (B->data()) T(stackRef<T>(ByteOffset)));
    assert(B->isInitialized());
  }

  return Pointer(B);
}

static bool funcHasUsableBody(const Function *F) {
  assert(F);

  if (F->isConstructor() || F->isDestructor())
    return true;

  return !F->getDecl()->isImplicit();
}

SourceInfo InterpFrame::getSource(CodePtr PC) const {
  // Implicitly created functions don't have any code we could point at,
  // so return the call site.
  if (Func && !funcHasUsableBody(Func) && Caller)
    return Caller->getSource(RetPC);

  // Similarly, if the resulting source location is invalid anyway,
  // point to the caller instead.
  SourceInfo Result = S.getSource(Func, PC);
  if (Result.getLoc().isInvalid() && Caller)
    return Caller->getSource(RetPC);
  return Result;
}

const Expr *InterpFrame::getExpr(CodePtr PC) const {
  if (Func && !funcHasUsableBody(Func) && Caller)
    return Caller->getExpr(RetPC);

  return S.getExpr(Func, PC);
}

SourceLocation InterpFrame::getLocation(CodePtr PC) const {
  if (Func && !funcHasUsableBody(Func) && Caller)
    return Caller->getLocation(RetPC);

  return S.getLocation(Func, PC);
}

SourceRange InterpFrame::getRange(CodePtr PC) const {
  if (Func && !funcHasUsableBody(Func) && Caller)
    return Caller->getRange(RetPC);

  return S.getRange(Func, PC);
}

bool InterpFrame::isStdFunction() const {
  if (!Func)
    return false;
  for (const DeclContext *DC = Func->getDecl(); DC; DC = DC->getParent())
    if (DC->isStdNamespace())
      return true;

  return false;
}
