//===--- Context.cpp - Context 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 "Context.h"
#include "Boolean.h"
#include "ByteCodeEmitter.h"
#include "Char.h"
#include "Compiler.h"
#include "EvalEmitter.h"
#include "EvalSettings.h"
#include "Integral.h"
#include "InterpFrame.h"
#include "InterpHelpers.h"
#include "InterpStack.h"
#include "Pointer.h"
#include "PrimType.h"
#include "Program.h"
#include "clang/AST/ASTLambda.h"
#include "clang/AST/Expr.h"
#include "clang/Basic/TargetInfo.h"

using namespace clang;
using namespace clang::interp;

Context::Context(ASTContext &Ctx) : Ctx(Ctx), P(new Program(*this)) {
  this->ShortWidth = Ctx.getTargetInfo().getShortWidth();
  this->IntWidth = Ctx.getTargetInfo().getIntWidth();
  this->LongWidth = Ctx.getTargetInfo().getLongWidth();
  this->LongLongWidth = Ctx.getTargetInfo().getLongLongWidth();
  assert(Ctx.getTargetInfo().getCharWidth() == 8 &&
         "We're assuming 8 bit chars");
}

Context::~Context() = default;

bool Context::isPotentialConstantExpr(const EvalSettings &Settings,
                                      const FunctionDecl *FD) {
  assert(Stk.empty());

  // Get a function handle.
  const Function *Func = getOrCreateFunction(FD);
  if (!Func)
    return false;

  // Compile the function.
  Compiler<ByteCodeEmitter>(*this, *P).compileFunc(
      FD, const_cast<Function *>(Func));

  if (!Func->isValid())
    return false;

  ++EvalID;
  // And run it.
  return Run(Settings, Func);
}

void Context::isPotentialConstantExprUnevaluated(const EvalSettings &Settings,
                                                 const Expr *E,
                                                 const FunctionDecl *FD) {
  assert(Stk.empty());
  ++EvalID;
  size_t StackSizeBefore = Stk.size();
  Compiler<EvalEmitter> C(*this, *P, Settings, Stk, FrameAlloc);

  if (!C.interpretCall(FD, E)) {
    C.cleanup();
    Stk.clearTo(StackSizeBefore);
  }
}

bool Context::evaluateAsRValue(const EvalSettings &Settings, const Expr *E,
                               APValue &Result) {
  ++EvalID;
  bool Recursing = !Stk.empty();
  size_t StackSizeBefore = Stk.size();
  Compiler<EvalEmitter> C(*this, *P, Settings, Stk, FrameAlloc);

  auto Res = C.interpretExpr(E);

  if (Res.isInvalid()) {
    C.cleanup();
    Stk.clearTo(StackSizeBefore);
    return false;
  }

  if (!Recursing) {
    // We *can* actually get here with a non-empty stack, since
    // things like InterpState::noteSideEffect() exist.
    C.cleanup();
#ifndef NDEBUG
    // Make sure we don't rely on some value being still alive in
    // InterpStack memory.
    Stk.clearTo(StackSizeBefore);
#endif
  }

  Result = Res.stealAPValue();
  return true;
}

bool Context::evaluate(const EvalSettings &Settings, const Expr *E,
                       APValue &Result) {
  ++EvalID;
  bool Recursing = !Stk.empty();
  size_t StackSizeBefore = Stk.size();
  Compiler<EvalEmitter> C(*this, *P, Settings, Stk, FrameAlloc);

  auto Res = C.interpretExpr(E, /*ConvertResultToRValue=*/false,
                             /*DestroyToplevelScope=*/true);
  if (Res.isInvalid()) {
    C.cleanup();
    Stk.clearTo(StackSizeBefore);
    return false;
  }

  if (!Recursing) {
    assert(Stk.empty());
    C.cleanup();
#ifndef NDEBUG
    // Make sure we don't rely on some value being still alive in
    // InterpStack memory.
    Stk.clearTo(StackSizeBefore);
#endif
  }

  Result = Res.stealAPValue();
  return true;
}

bool Context::evaluateAsInitializer(const EvalSettings &Settings,
                                    const VarDecl *VD, const Expr *Init,
                                    APValue &Result) {
  ++EvalID;
  bool Recursing = !Stk.empty();
  size_t StackSizeBefore = Stk.size();
  Compiler<EvalEmitter> C(*this, *P, Settings, Stk, FrameAlloc);

  bool CheckGlobalInitialized =
      (VD->getType()->isRecordType() || VD->getType()->isArrayType());

  auto Res = C.interpretDecl(VD, Init, CheckGlobalInitialized);
  if (Res.isInvalid()) {
    C.cleanup();
    Stk.clearTo(StackSizeBefore);

    return false;
  }

  if (!Recursing) {
    assert(Stk.empty());
    C.cleanup();
#ifndef NDEBUG
    // Make sure we don't rely on some value being still alive in
    // InterpStack memory.
    Stk.clearTo(StackSizeBefore);
#endif
  }

  Result = Res.stealAPValue();
  return true;
}

bool Context::evaluateDestruction(const EvalSettings &Settings,
                                  const VarDecl *VD, APValue Value) {
  assert(Stk.empty());
  Compiler<EvalEmitter> C(*this, *P, Settings, Stk, FrameAlloc);

  auto Res = C.interpretDestructor(VD, Value);

  if (Res.isInvalid()) {
    C.cleanup();
    Stk.clear();
    return false;
  }

  assert(Stk.empty());

  return true;
}

void Context::registerRedecl(const VarDecl *VD, const APValue &V) {
  Expr::EvalStatus Status;
  Compiler<EvalEmitter> C(*this, *P, Status, Stk, FrameAlloc);

  C.registerRedecl(VD, V);
}

template <typename ResultT>
bool Context::evaluateStringRepr(const EvalSettings &Settings,
                                 const Expr *SizeExpr, const Expr *PtrExpr,
                                 ResultT &Result) {
  assert(Stk.empty());
  Compiler<EvalEmitter> C(*this, *P, Settings, Stk, FrameAlloc);

  // Evaluate size value.
  APValue SizeValue;
  if (!evaluateAsRValue(Settings, SizeExpr, SizeValue))
    return false;

  if (!SizeValue.isInt())
    return false;
  uint64_t Size = SizeValue.getInt().getZExtValue();

  auto PtrRes = C.interpretAsPointer(PtrExpr, [&](InterpState &S, CodePtr OpPC,
                                                  const Pointer &Ptr) {
    if (Size == 0) {
      if constexpr (std::is_same_v<ResultT, APValue>)
        Result = APValue(APValue::UninitArray{}, 0, 0);
      return true;
    }

    if (Ptr.isZero()) {
      S.FFDiag(S.Current->getSource(OpPC), diag::note_constexpr_access_null)
          << AK_Read;
      return false;
    }

    if (!Ptr.isLive() || !Ptr.isInitialized() || Ptr.isUnknownSizeArray() ||
        !Ptr.inArray())
      return false;

    // Must be char.
    if (Ptr.isBlockPointer() &&
        Ptr.getFieldDesc()->getElemDataSize() != 1 /*bytes*/)
      return false;
    if (Ptr.isStringPointer() &&
        !Ptr.asStringPointer().getLiteral()->isOrdinary())
      return false;

    bool Limited = false;
    if (Size > Ptr.getNumElems()) {
      S.FFDiag(S.Current->getSource(OpPC), diag::note_constexpr_access_past_end)
          << AK_Read;
      Size = Ptr.getNumElems();
      Limited = true;
    }

    if constexpr (std::is_same_v<ResultT, APValue>) {
      QualType CharTy = PtrExpr->getType()->getPointeeType();
      Result = APValue(APValue::UninitArray{}, Size, Size);
      for (uint64_t I = 0; I != Size; ++I) {
        if (std::optional<APValue> ElemVal =
                Ptr.atIndex(I).toRValue(*this, CharTy))
          Result.getArrayInitializedElt(I) = *ElemVal;
        else
          return false;
      }
    } else {
      assert((std::is_same_v<ResultT, std::string>));
      if (Size < Result.max_size())
        Result.resize(Size);

      const char *Addr = reinterpret_cast<const char *>(Ptr.getRawAddress());

      if (Ptr.isStringPointer())
        Result.assign(Addr, Size - static_cast<unsigned>(Limited));
      else
        Result.assign(Addr, Size);
    }

    return true;
  });

  if (PtrRes.isInvalid()) {
    C.cleanup();
    Stk.clear();
    return false;
  }

  return true;
}

bool Context::evaluateCharRange(const EvalSettings &Settings,
                                const Expr *SizeExpr, const Expr *PtrExpr,
                                APValue &Result) {
  assert(SizeExpr);
  assert(PtrExpr);

  return evaluateStringRepr(Settings, SizeExpr, PtrExpr, Result);
}

bool Context::evaluateCharRange(const EvalSettings &Settings,
                                const Expr *SizeExpr, const Expr *PtrExpr,
                                std::string &Result) {
  assert(SizeExpr);
  assert(PtrExpr);

  return evaluateStringRepr(Settings, SizeExpr, PtrExpr, Result);
}

bool Context::evaluateString(const EvalSettings &Settings, const Expr *E,
                             std::string &Result) {
  assert(Stk.empty());
  Compiler<EvalEmitter> C(*this, *P, Settings, Stk, FrameAlloc);

  auto PtrRes = C.interpretAsPointer(E, [&](InterpState &S, CodePtr OpPC,
                                            const Pointer &Ptr) {
    if (!Ptr.isReadablePointerType())
      return false;

    if (!Ptr.isConst())
      return false;

    if (Ptr.isDummy() || Ptr.isUnknownSizeArray() || Ptr.isPastEnd())
      return false;

    unsigned N = Ptr.getNumElems();

    if (Ptr.elemSize() == 1 /* bytes */) {
      const char *Chars = reinterpret_cast<const char *>(Ptr.getRawAddress());
      if (Ptr.isStringPointer()) {
        Result.assign(Chars, N - 1);
        return true;
      }
      unsigned Length = strnlen(Chars, N);
      // Wasn't null terminated.
      if (N == Length)
        return false;
      Result.assign(Chars, Length);
      return true;
    }

    PrimType ElemT;
    if (Ptr.isBlockPointer()) {
      ElemT = Ptr.getFieldDesc()->getPrimType();
    } else {
      // It may happen here that the string literal has not been decayed or
      // indexed, so check the element type in that case.
      assert(Ptr.isStringPointer());
      if (!Ptr.asStringPointer().Decayed)
        ElemT =
            *classify(Ptr.getType()->getAsArrayTypeUnsafe()->getElementType());
      else
        ElemT = *classify(Ptr.getType());
    }
    for (unsigned I = Ptr.getIndex(); I != N; ++I) {
      INT_TYPE_SWITCH(ElemT, {
        auto Elem = Ptr.loadElem<T>(I);
        if (Elem.isZero())
          return true;
        Result.push_back(static_cast<char>(Elem));
      });
    }
    // We didn't find a 0 byte.
    return false;
  });

  if (PtrRes.isInvalid()) {
    C.cleanup();
    Stk.clear();
    return false;
  }
  return true;
}

std::optional<uint64_t> Context::evaluateStrlen(const EvalSettings &Settings,
                                                const Expr *E) {
  assert(Stk.empty());
  Compiler<EvalEmitter> C(*this, *P, Settings, Stk, FrameAlloc);

  std::optional<uint64_t> Result;
  auto PtrRes = C.interpretAsPointer(E, [&](InterpState &S, CodePtr OpPC,
                                            const Pointer &Ptr) {
    if (!Ptr.isReadablePointerType())
      return false;

    if (Ptr.isPastEnd())
      return false;

    if (Ptr.isStringPointer()) {
      const auto *Lit = Ptr.asStringPointer().getLiteral();
      int64_t Off = Ptr.getByteOffset();
      if (Off < 0)
        return false;

      UnsignedOrNone ZeroIndex = Lit->findZeroCodeUnit(Off);
      if (!ZeroIndex)
        return false;
      Result = *ZeroIndex;
      return true;
    }

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

    if (Ptr.isDummy() || Ptr.isUnknownSizeArray())
      return false;

    PrimType ElemT = FieldDesc->getPrimType();
    if (!isIntegerType(ElemT))
      return false;

    unsigned N = Ptr.getNumElems();
    if (Ptr.elemSize() == 1) {
      unsigned Size = N - Ptr.getIndex();
      Result =
          strnlen(reinterpret_cast<const char *>(Ptr.getRawAddress()), Size);
      return Result != Size;
    }

    Result = 0;
    for (unsigned I = Ptr.getIndex(); I != N; ++I) {
      INT_TYPE_SWITCH(ElemT, {
        auto Elem = Ptr.elem<T>(I);
        if (Elem.isZero())
          return true;
        ++(*Result);
      });
    }
    // We didn't find a 0 byte.
    return false;
  });

  if (PtrRes.isInvalid()) {
    C.cleanup();
    Stk.clear();
    return std::nullopt;
  }
  return Result;
}

std::optional<uint64_t>
Context::tryEvaluateObjectSize(const EvalSettings &Settings, const Expr *E,
                               unsigned Kind, bool IsDynamic) {
  assert(Stk.empty());
  Compiler<EvalEmitter> C(*this, *P, Settings, Stk, FrameAlloc);

  std::optional<uint64_t> Result;
  auto PtrRes = C.interpretAsLValuePointer(E, [&](InterpState &S, CodePtr OpPC,
                                                  const Pointer &Ptr) {
    QualType T = Ptr.getType().getNonReferenceType();
    if (T->isIncompleteType() || T->isFunctionType() ||
        !T->isConstantSizeType())
      return false;

    Pointer P = Ptr;
    if (auto ObjectSize =
            evaluateBuiltinObjectSize(getASTContext(), Kind, P, E, IsDynamic)) {
      Result = *ObjectSize;
      return true;
    }
    return false;
  });

  if (PtrRes.isInvalid()) {
    C.cleanup();
    Stk.clear();
    return std::nullopt;
  }
  return Result;
}

std::optional<bool> Context::evaluateWithSubstitution(
    const EvalSettings &Settings, const FunctionDecl *Callee,
    ArrayRef<const Expr *> Args, const Expr *This, const Expr *Condition) {
  if (OptPrimType ConditionT = classify(Condition);
      !ConditionT || ConditionT != PT_Bool) {
    return std::nullopt;
  }

  assert(Stk.empty());
  Compiler<EvalEmitter> C(*this, *P, Settings, Stk, FrameAlloc);
  std::optional<bool> Result =
      C.interpretWithSubstitutions(Callee, Args, This, Condition);

  // This is somewhat of a special case here. We don't allow
  // evaluateWithSubstitution to recurse (see the Stk.empty() assertion above),
  // BUT we allow the args to fail evaluation, which means they can leave some
  // garbage on the stack. So we always clear() here, not only if the evaluation
  // failed.
  Stk.clear();
  if (!Result) {
    C.cleanup();
    return std::nullopt;
  }
  return Result;
}

const LangOptions &Context::getLangOpts() const { return Ctx.getLangOpts(); }

static PrimType integralTypeToPrimTypeS(unsigned BitWidth) {
  switch (BitWidth) {
  case 64:
    return PT_Sint64;
  case 32:
    return PT_Sint32;
  case 16:
    return PT_Sint16;
  case 8:
    return PT_Sint8;
  default:
    return PT_IntAPS;
  }
  llvm_unreachable("Unhandled BitWidth");
}

static PrimType integralTypeToPrimTypeU(unsigned BitWidth) {
  switch (BitWidth) {
  case 64:
    return PT_Uint64;
  case 32:
    return PT_Uint32;
  case 16:
    return PT_Uint16;
  case 8:
    return PT_Uint8;
  default:
    return PT_IntAP;
  }
  llvm_unreachable("Unhandled BitWidth");
}

OptPrimType Context::classify(QualType T) const {
  T = T.getCanonicalType();

  if (const auto *BT = dyn_cast<BuiltinType>(T)) {
    auto Kind = BT->getKind();
    if (Kind == BuiltinType::Bool)
      return PT_Bool;
    if (Kind == BuiltinType::NullPtr)
      return PT_Ptr;
    if (Kind == BuiltinType::BoundMember)
      return PT_MemberPtr;

    // Just trying to avoid the ASTContext::getIntWidth call below.
    if (Kind == BuiltinType::Short)
      return integralTypeToPrimTypeS(this->ShortWidth);
    if (Kind == BuiltinType::UShort)
      return integralTypeToPrimTypeU(this->ShortWidth);

    if (Kind == BuiltinType::Int)
      return integralTypeToPrimTypeS(this->IntWidth);
    if (Kind == BuiltinType::UInt)
      return integralTypeToPrimTypeU(this->IntWidth);
    if (Kind == BuiltinType::Long)
      return integralTypeToPrimTypeS(this->LongWidth);
    if (Kind == BuiltinType::ULong)
      return integralTypeToPrimTypeU(this->LongWidth);
    if (Kind == BuiltinType::LongLong)
      return integralTypeToPrimTypeS(this->LongLongWidth);
    if (Kind == BuiltinType::ULongLong)
      return integralTypeToPrimTypeU(this->LongLongWidth);

    if (Kind == BuiltinType::SChar || Kind == BuiltinType::Char_S)
      return integralTypeToPrimTypeS(8);
    if (Kind == BuiltinType::UChar || Kind == BuiltinType::Char_U ||
        Kind == BuiltinType::Char8)
      return integralTypeToPrimTypeU(8);

    if (BT->isSignedInteger())
      return integralTypeToPrimTypeS(Ctx.getIntWidth(T));
    if (BT->isUnsignedInteger())
      return integralTypeToPrimTypeU(Ctx.getIntWidth(T));

    if (BT->isFloatingPoint())
      return PT_Float;
  }

  if (T->isPointerOrReferenceType())
    return PT_Ptr;

  if (T->isMemberPointerType())
    return PT_MemberPtr;

  if (const auto *BT = T->getAs<BitIntType>()) {
    if (BT->isSigned())
      return integralTypeToPrimTypeS(BT->getNumBits());
    return integralTypeToPrimTypeU(BT->getNumBits());
  }

  if (const auto *D = T->getAsEnumDecl()) {
    if (!D->isComplete())
      return std::nullopt;
    return classify(D->getIntegerType());
  }

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

  if (const auto *OBT = T->getAs<OverflowBehaviorType>())
    return classify(OBT->getUnderlyingType());

  if (T->isObjCObjectPointerType() || T->isBlockPointerType())
    return PT_Ptr;

  if (T->isFixedPointType())
    return PT_FixedPoint;

  // Vector and complex types get here.
  return std::nullopt;
}

unsigned Context::getCharBit() const {
  return Ctx.getTargetInfo().getCharWidth();
}

/// Simple wrapper around getFloatTypeSemantics() to make code a
/// little shorter.
const llvm::fltSemantics &Context::getFloatSemantics(QualType T) const {
  return Ctx.getFloatTypeSemantics(T);
}

bool Context::Run(const EvalSettings &Settings, const Function *Func) {
  auto Memory = std::make_unique<char[]>(InterpFrame::allocSize(Func));
  InterpState State(Settings, *P, Stk, FrameAlloc, *this, Func);
  InterpFrame *Frame = new (Memory.get()) InterpFrame(
      State, Func, /*Caller=*/nullptr, CodePtr(), Func->getArgSize());
  State.Current = Frame;

  if (Interpret(State)) {
    assert(Stk.empty());
    return true;
  }

  Stk.clear();
  Frame->~InterpFrame();
  State.Current = &State.BottomFrame;
  return false;
}

const CXXMethodDecl *
Context::getOverridingFunction(const CXXRecordDecl *DynamicDecl,
                               const CXXRecordDecl *StaticDecl,
                               const CXXMethodDecl *InitialFunction) const {
  assert(DynamicDecl);
  assert(StaticDecl);
  assert(InitialFunction);

  const CXXRecordDecl *CurRecord = DynamicDecl;
  const CXXMethodDecl *FoundFunction = InitialFunction;
  for (;;) {
    const CXXMethodDecl *Overrider =
        FoundFunction->getCorrespondingMethodDeclaredInClass(CurRecord, false);
    if (Overrider)
      return Overrider;

    // Common case of only one base class.
    if (CurRecord->getNumBases() == 1) {
      CurRecord = CurRecord->bases_begin()->getType()->getAsCXXRecordDecl();
      continue;
    }

    // Otherwise, go to the base class that will lead to the StaticDecl.
    for (const CXXBaseSpecifier &Spec : CurRecord->bases()) {
      const CXXRecordDecl *Base = Spec.getType()->getAsCXXRecordDecl();
      if (Base == StaticDecl || Base->isDerivedFrom(StaticDecl)) {
        CurRecord = Base;
        break;
      }
    }
  }

  llvm_unreachable(
      "Couldn't find an overriding function in the class hierarchy?");
  return nullptr;
}

const Function *Context::getOrCreateFunction(const FunctionDecl *FuncDecl) {
  assert(FuncDecl);
  if (const Function *Func = P->getFunction(FuncDecl))
    return Func;

  // Manually created functions that haven't been assigned proper
  // parameters yet.
  if (!FuncDecl->param_empty() && !FuncDecl->param_begin())
    return nullptr;

  bool IsLambdaStaticInvoker = false;
  if (const auto *MD = dyn_cast<CXXMethodDecl>(FuncDecl);
      MD && MD->isLambdaStaticInvoker()) {
    // For a lambda static invoker, we might have to pick a specialized
    // version if the lambda is generic. In that case, the picked function
    // will *NOT* be a static invoker anymore. However, it will still
    // be a non-static member function, this (usually) requiring an
    // instance pointer. We suppress that later in this function.
    IsLambdaStaticInvoker = true;
  }
  // Set up argument indices.
  unsigned ParamOffset = 0;

  // If the return is not a primitive, a pointer to the storage where the
  // value is initialized in is passed as the first argument. See 'RVO'
  // elsewhere in the code.
  QualType Ty = FuncDecl->getReturnType();
  bool HasRVO = false;
  if (!Ty->isVoidType() && !canClassify(Ty)) {
    HasRVO = true;
    ParamOffset += align(primSize(PT_Ptr));
  }

  // If the function decl is a member decl, the next parameter is
  // the 'this' pointer. This parameter is pop()ed from the
  // InterpStack when calling the function.
  bool HasThisPointer = false;
  if (const auto *MD = dyn_cast<CXXMethodDecl>(FuncDecl)) {
    if (!IsLambdaStaticInvoker) {
      HasThisPointer = MD->isInstance();
      if (MD->isImplicitObjectMemberFunction())
        ParamOffset += align(primSize(PT_Ptr));
    }

    if (isLambdaCallOperator(MD)) {
      // The parent record needs to be complete, we need to know about all
      // the lambda captures.
      if (!MD->getParent()->isCompleteDefinition())
        return nullptr;
      if (MD->isStatic()) {
        llvm::DenseMap<const ValueDecl *, FieldDecl *> LC;
        FieldDecl *LTC;

        MD->getParent()->getCaptureFields(LC, LTC);
        // Static lambdas cannot have any captures. If this one does,
        // it has already been diagnosed and we can only ignore it.
        if (!LC.empty())
          return nullptr;
      }
    }
  }

  // Assign descriptors to all parameters.
  // Composite objects are lowered to pointers.
  llvm::SmallVector<Function::ParamDescriptor> ParamDescriptors;
  ParamDescriptors.reserve(FuncDecl->getNumParams());

  const auto *FuncProto = FuncDecl->getType()->getAs<FunctionProtoType>();
  unsigned BlockOffset = 0;
  for (auto [ParamIndex, PD] : llvm::enumerate(FuncDecl->parameters())) {
    bool IsConst = PD->getType().isConstQualified();
    bool IsVolatile = PD->getType().isVolatileQualified();

    if (PD->isInvalidDecl() ||
        !getASTContext().hasSameType(PD->getType(),
                                     FuncProto->getParamType(ParamIndex)))
      return nullptr;

    OptPrimType T = classify(PD->getType());
    PrimType PT = T.value_or(PT_Ptr);
    Descriptor *Desc = P->createDescriptor(PD, PT, nullptr, IsConst,
                                           /*IsTemporary=*/false,
                                           /*IsMutable=*/false, IsVolatile);
    unsigned PrimTSize = align(primSize(PT));
    ParamDescriptors.emplace_back(Desc, ParamOffset, BlockOffset, PT);
    ParamOffset += PrimTSize;
    BlockOffset += sizeof(Block) + PrimTSize;
  }

  // Create a handle over the emitted code.
  assert(!P->getFunction(FuncDecl));
  const Function *Func =
      P->createFunction(FuncDecl, ParamOffset, std::move(ParamDescriptors),
                        HasThisPointer, HasRVO, IsLambdaStaticInvoker);
  return Func;
}

const Function *Context::getOrCreateObjCBlock(const BlockExpr *E) {
  const BlockDecl *BD = E->getBlockDecl();
  // Set up argument indices.
  unsigned ParamOffset = 0;
  llvm::SmallVector<Function::ParamDescriptor> ParamDescriptors;

  // Assign descriptors to all parameters.
  // Composite objects are lowered to pointers.
  for (const ParmVarDecl *PD : BD->parameters()) {
    bool IsConst = PD->getType().isConstQualified();
    bool IsVolatile = PD->getType().isVolatileQualified();

    OptPrimType T = classify(PD->getType());
    PrimType PT = T.value_or(PT_Ptr);
    Descriptor *Desc = P->createDescriptor(PD, PT, nullptr, IsConst,
                                           /*IsTemporary=*/false,
                                           /*IsMutable=*/false, IsVolatile);
    ParamDescriptors.emplace_back(Desc, ParamOffset, ~0u, PT);
    ParamOffset += align(primSize(PT));
  }

  if (BD->hasCaptures())
    return nullptr;

  // Create a handle over the emitted code.
  Function *Func =
      P->createFunction(E, ParamOffset, std::move(ParamDescriptors),
                        /*HasThisPointer=*/false, /*HasRVO=*/false,
                        /*IsLambdaStaticInvoker=*/false);

  assert(Func);
  Func->setDefined(true);
  // We don't compile the BlockDecl code at all right now.
  Func->setIsFullyCompiled(true);

  return Func;
}

unsigned Context::collectBaseOffset(const RecordDecl *BaseDecl,
                                    const RecordDecl *DerivedDecl) const {
  assert(BaseDecl);
  assert(DerivedDecl);
  const auto *FinalDecl = cast<CXXRecordDecl>(BaseDecl);
  const RecordDecl *CurDecl = DerivedDecl;
  const Record *CurRecord = P->getOrCreateRecord(CurDecl);
  assert(CurDecl && FinalDecl);

  unsigned OffsetSum = 0;
  for (;;) {
    assert(CurRecord->getNumBases() > 0);
    // One level up
    for (const Record::Base &B : CurRecord->bases()) {
      const auto *BaseDecl = cast<CXXRecordDecl>(B.Decl);

      if (BaseDecl == FinalDecl || BaseDecl->isDerivedFrom(FinalDecl)) {
        OffsetSum += B.Offset;
        CurRecord = B.R;
        CurDecl = BaseDecl;
        break;
      }
    }
    if (CurDecl == FinalDecl)
      break;
  }

  assert(OffsetSum > 0);
  return OffsetSum;
}

const Record *Context::getRecord(const RecordDecl *D) const {
  return P->getOrCreateRecord(D);
}

bool Context::isUnevaluatedBuiltin(unsigned ID) {
  return ID == Builtin::BI__builtin_classify_type ||
         ID == Builtin::BI__builtin_os_log_format_buffer_size ||
         ID == Builtin::BI__builtin_constant_p || ID == Builtin::BI__noop;
}
