//===--- 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) {}

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())) {
#ifndef NDEBUG
  FrameOffset = S.Stk.size();
#endif

  if (!Func)
    return;

  FuncFlags |= Func->hasRVO() * HasRVOFlag;
  FuncFlags |= Func->hasThisPointer() * HasThisFlag;

  // 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()).
}

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, const Context &Ctx,
                  QualType Ty) {
  if constexpr (std::is_same_v<Pointer, T>) {
    if (Ty->isPointerOrReferenceType())
      V.toAPValue(Ctx.getASTContext()).printPretty(OS, Ctx.getASTContext(), Ty);
    else {
      if (std::optional<APValue> RValue = V.toRValue(Ctx, Ty))
        RValue->printPretty(OS, Ctx.getASTContext(), Ty);
      else
        OS << "...";
    }
  } else {
    V.toAPValue(Ctx.getASTContext()).printPretty(OS, Ctx.getASTContext(), 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 ASTContext &ASTCtx = S.getASTContext();
  const Expr *CallExpr = Caller->getExpr(getRetPC());
  const FunctionDecl *F = getCallee();
  auto PrintingPolicy = ASTCtx.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.getContext(),
            ASTCtx.getLValueReferenceType(
                ASTCtx.getCanonicalTagType(M->getParent())));
      OS << '.';
    }
  }

  F->getNameForDiagnostic(OS, PrintingPolicy, /*Qualified=*/false);
  OS << '(';
  unsigned Off = 0;
  unsigned ParamIndex = ExplicitInstanceParam;
  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;
    PrimType PrimT = Func->getParamDescriptor(ParamIndex).T;
    TYPE_SWITCH(PrimT,
                print(OS, stackRef<T>(Off), S.getContext(), Param->getType()));
    Off += align(primSize(PrimT));
    ++ParamIndex;
  }
  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;
}
