//===------ Interpreter.cpp - Incremental Compilation and Execution -------===//
//
// 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
//
//===----------------------------------------------------------------------===//
//
// This file implements the component which performs incremental code
// compilation and execution.
//
//===----------------------------------------------------------------------===//

#include "DeviceOffload.h"
#include "IncrementalExecutor.h"
#include "IncrementalParser.h"
#include "InterpreterUtils.h"

#include "clang/AST/ASTContext.h"
#include "clang/AST/Mangle.h"
#include "clang/AST/TypeVisitor.h"
#include "clang/Basic/DiagnosticSema.h"
#include "clang/Basic/TargetInfo.h"
#include "clang/CodeGen/CodeGenAction.h"
#include "clang/CodeGen/ModuleBuilder.h"
#include "clang/CodeGen/ObjectFilePCHContainerOperations.h"
#include "clang/Driver/Compilation.h"
#include "clang/Driver/Driver.h"
#include "clang/Driver/Job.h"
#include "clang/Driver/Options.h"
#include "clang/Driver/Tool.h"
#include "clang/Frontend/CompilerInstance.h"
#include "clang/Frontend/TextDiagnosticBuffer.h"
#include "clang/Interpreter/Interpreter.h"
#include "clang/Interpreter/Value.h"
#include "clang/Lex/PreprocessorOptions.h"
#include "clang/Sema/Lookup.h"
#include "llvm/ExecutionEngine/JITSymbol.h"
#include "llvm/ExecutionEngine/Orc/LLJIT.h"
#include "llvm/IR/Module.h"
#include "llvm/Support/Errc.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/TargetParser/Host.h"
using namespace clang;

// FIXME: Figure out how to unify with namespace init_convenience from
//        tools/clang-import-test/clang-import-test.cpp
namespace {
/// Retrieves the clang CC1 specific flags out of the compilation's jobs.
/// \returns NULL on error.
static llvm::Expected<const llvm::opt::ArgStringList *>
GetCC1Arguments(DiagnosticsEngine *Diagnostics,
                driver::Compilation *Compilation) {
  // We expect to get back exactly one Command job, if we didn't something
  // failed. Extract that job from the Compilation.
  const driver::JobList &Jobs = Compilation->getJobs();
  if (!Jobs.size() || !isa<driver::Command>(*Jobs.begin()))
    return llvm::createStringError(llvm::errc::not_supported,
                                   "Driver initialization failed. "
                                   "Unable to create a driver job");

  // The one job we find should be to invoke clang again.
  const driver::Command *Cmd = cast<driver::Command>(&(*Jobs.begin()));
  if (llvm::StringRef(Cmd->getCreator().getName()) != "clang")
    return llvm::createStringError(llvm::errc::not_supported,
                                   "Driver initialization failed");

  return &Cmd->getArguments();
}

static llvm::Expected<std::unique_ptr<CompilerInstance>>
CreateCI(const llvm::opt::ArgStringList &Argv) {
  std::unique_ptr<CompilerInstance> Clang(new CompilerInstance());
  IntrusiveRefCntPtr<DiagnosticIDs> DiagID(new DiagnosticIDs());

  // Register the support for object-file-wrapped Clang modules.
  // FIXME: Clang should register these container operations automatically.
  auto PCHOps = Clang->getPCHContainerOperations();
  PCHOps->registerWriter(std::make_unique<ObjectFilePCHContainerWriter>());
  PCHOps->registerReader(std::make_unique<ObjectFilePCHContainerReader>());

  // Buffer diagnostics from argument parsing so that we can output them using
  // a well formed diagnostic object.
  IntrusiveRefCntPtr<DiagnosticOptions> DiagOpts = new DiagnosticOptions();
  TextDiagnosticBuffer *DiagsBuffer = new TextDiagnosticBuffer;
  DiagnosticsEngine Diags(DiagID, &*DiagOpts, DiagsBuffer);
  bool Success = CompilerInvocation::CreateFromArgs(
      Clang->getInvocation(), llvm::ArrayRef(Argv.begin(), Argv.size()), Diags);

  // Infer the builtin include path if unspecified.
  if (Clang->getHeaderSearchOpts().UseBuiltinIncludes &&
      Clang->getHeaderSearchOpts().ResourceDir.empty())
    Clang->getHeaderSearchOpts().ResourceDir =
        CompilerInvocation::GetResourcesPath(Argv[0], nullptr);

  // Create the actual diagnostics engine.
  Clang->createDiagnostics();
  if (!Clang->hasDiagnostics())
    return llvm::createStringError(llvm::errc::not_supported,
                                   "Initialization failed. "
                                   "Unable to create diagnostics engine");

  DiagsBuffer->FlushDiagnostics(Clang->getDiagnostics());
  if (!Success)
    return llvm::createStringError(llvm::errc::not_supported,
                                   "Initialization failed. "
                                   "Unable to flush diagnostics");

  // FIXME: Merge with CompilerInstance::ExecuteAction.
  llvm::MemoryBuffer *MB = llvm::MemoryBuffer::getMemBuffer("").release();
  Clang->getPreprocessorOpts().addRemappedFile("<<< inputs >>>", MB);

  Clang->setTarget(TargetInfo::CreateTargetInfo(
      Clang->getDiagnostics(), Clang->getInvocation().TargetOpts));
  if (!Clang->hasTarget())
    return llvm::createStringError(llvm::errc::not_supported,
                                   "Initialization failed. "
                                   "Target is missing");

  Clang->getTarget().adjust(Clang->getDiagnostics(), Clang->getLangOpts());

  // Don't clear the AST before backend codegen since we do codegen multiple
  // times, reusing the same AST.
  Clang->getCodeGenOpts().ClearASTBeforeBackend = false;

  Clang->getFrontendOpts().DisableFree = false;
  Clang->getCodeGenOpts().DisableFree = false;
  return std::move(Clang);
}

} // anonymous namespace

llvm::Expected<std::unique_ptr<CompilerInstance>>
IncrementalCompilerBuilder::create(std::string TT,
                                   std::vector<const char *> &ClangArgv) {

  // If we don't know ClangArgv0 or the address of main() at this point, try
  // to guess it anyway (it's possible on some platforms).
  std::string MainExecutableName =
      llvm::sys::fs::getMainExecutable(nullptr, nullptr);

  ClangArgv.insert(ClangArgv.begin(), MainExecutableName.c_str());

  // Prepending -c to force the driver to do something if no action was
  // specified. By prepending we allow users to override the default
  // action and use other actions in incremental mode.
  // FIXME: Print proper driver diagnostics if the driver flags are wrong.
  // We do C++ by default; append right after argv[0] if no "-x" given
  ClangArgv.insert(ClangArgv.end(), "-Xclang");
  ClangArgv.insert(ClangArgv.end(), "-fincremental-extensions");
  ClangArgv.insert(ClangArgv.end(), "-c");

  // Put a dummy C++ file on to ensure there's at least one compile job for the
  // driver to construct.
  ClangArgv.push_back("<<< inputs >>>");

  // Buffer diagnostics from argument parsing so that we can output them using a
  // well formed diagnostic object.
  IntrusiveRefCntPtr<DiagnosticIDs> DiagID(new DiagnosticIDs());
  IntrusiveRefCntPtr<DiagnosticOptions> DiagOpts =
      CreateAndPopulateDiagOpts(ClangArgv);
  TextDiagnosticBuffer *DiagsBuffer = new TextDiagnosticBuffer;
  DiagnosticsEngine Diags(DiagID, &*DiagOpts, DiagsBuffer);

  driver::Driver Driver(/*MainBinaryName=*/ClangArgv[0], TT, Diags);
  Driver.setCheckInputsExist(false); // the input comes from mem buffers
  llvm::ArrayRef<const char *> RF = llvm::ArrayRef(ClangArgv);
  std::unique_ptr<driver::Compilation> Compilation(Driver.BuildCompilation(RF));

  if (Compilation->getArgs().hasArg(driver::options::OPT_v))
    Compilation->getJobs().Print(llvm::errs(), "\n", /*Quote=*/false);

  auto ErrOrCC1Args = GetCC1Arguments(&Diags, Compilation.get());
  if (auto Err = ErrOrCC1Args.takeError())
    return std::move(Err);

  return CreateCI(**ErrOrCC1Args);
}

llvm::Expected<std::unique_ptr<CompilerInstance>>
IncrementalCompilerBuilder::CreateCpp() {
  std::vector<const char *> Argv;
  Argv.reserve(5 + 1 + UserArgs.size());
  Argv.push_back("-xc++");
  Argv.insert(Argv.end(), UserArgs.begin(), UserArgs.end());

  std::string TT = TargetTriple ? *TargetTriple : llvm::sys::getProcessTriple();
  return IncrementalCompilerBuilder::create(TT, Argv);
}

llvm::Expected<std::unique_ptr<CompilerInstance>>
IncrementalCompilerBuilder::createCuda(bool device) {
  std::vector<const char *> Argv;
  Argv.reserve(5 + 4 + UserArgs.size());

  Argv.push_back("-xcuda");
  if (device)
    Argv.push_back("--cuda-device-only");
  else
    Argv.push_back("--cuda-host-only");

  std::string SDKPathArg = "--cuda-path=";
  if (!CudaSDKPath.empty()) {
    SDKPathArg += CudaSDKPath;
    Argv.push_back(SDKPathArg.c_str());
  }

  std::string ArchArg = "--offload-arch=";
  if (!OffloadArch.empty()) {
    ArchArg += OffloadArch;
    Argv.push_back(ArchArg.c_str());
  }

  Argv.insert(Argv.end(), UserArgs.begin(), UserArgs.end());

  std::string TT = TargetTriple ? *TargetTriple : llvm::sys::getProcessTriple();
  return IncrementalCompilerBuilder::create(TT, Argv);
}

llvm::Expected<std::unique_ptr<CompilerInstance>>
IncrementalCompilerBuilder::CreateCudaDevice() {
  return IncrementalCompilerBuilder::createCuda(true);
}

llvm::Expected<std::unique_ptr<CompilerInstance>>
IncrementalCompilerBuilder::CreateCudaHost() {
  return IncrementalCompilerBuilder::createCuda(false);
}

Interpreter::Interpreter(std::unique_ptr<CompilerInstance> CI,
                         llvm::Error &Err) {
  llvm::ErrorAsOutParameter EAO(&Err);
  auto LLVMCtx = std::make_unique<llvm::LLVMContext>();
  TSCtx = std::make_unique<llvm::orc::ThreadSafeContext>(std::move(LLVMCtx));
  IncrParser = std::make_unique<IncrementalParser>(*this, std::move(CI),
                                                   *TSCtx->getContext(), Err);
}

Interpreter::~Interpreter() {
  if (IncrExecutor) {
    if (llvm::Error Err = IncrExecutor->cleanUp())
      llvm::report_fatal_error(
          llvm::Twine("Failed to clean up IncrementalExecutor: ") +
          toString(std::move(Err)));
  }
}

// These better to put in a runtime header but we can't. This is because we
// can't find the precise resource directory in unittests so we have to hard
// code them.
const char *const Runtimes = R"(
#ifdef __cplusplus
    void *__clang_Interpreter_SetValueWithAlloc(void*, void*, void*);
    void __clang_Interpreter_SetValueNoAlloc(void*, void*, void*);
    void __clang_Interpreter_SetValueNoAlloc(void*, void*, void*, void*);
    void __clang_Interpreter_SetValueNoAlloc(void*, void*, void*, float);
    void __clang_Interpreter_SetValueNoAlloc(void*, void*, void*, double);
    void __clang_Interpreter_SetValueNoAlloc(void*, void*, void*, long double);
    void __clang_Interpreter_SetValueNoAlloc(void*,void*,void*,unsigned long long);
    struct __clang_Interpreter_NewTag{} __ci_newtag;
    void* operator new(__SIZE_TYPE__, void* __p, __clang_Interpreter_NewTag) noexcept;
    template <class T, class = T (*)() /*disable for arrays*/>
    void __clang_Interpreter_SetValueCopyArr(T* Src, void* Placement, unsigned long Size) {
      for (auto Idx = 0; Idx < Size; ++Idx)
        new ((void*)(((T*)Placement) + Idx), __ci_newtag) T(Src[Idx]);
    }
    template <class T, unsigned long N>
    void __clang_Interpreter_SetValueCopyArr(const T (*Src)[N], void* Placement, unsigned long Size) {
      __clang_Interpreter_SetValueCopyArr(Src[0], Placement, Size);
    }
#endif // __cplusplus
)";

llvm::Expected<std::unique_ptr<Interpreter>>
Interpreter::create(std::unique_ptr<CompilerInstance> CI) {
  llvm::Error Err = llvm::Error::success();
  auto Interp =
      std::unique_ptr<Interpreter>(new Interpreter(std::move(CI), Err));
  if (Err)
    return std::move(Err);

  // Add runtime code and set a marker to hide it from user code. Undo will not
  // go through that.
  auto PTU = Interp->Parse(Runtimes);
  if (!PTU)
    return PTU.takeError();
  Interp->markUserCodeStart();

  Interp->ValuePrintingInfo.resize(4);
  return std::move(Interp);
}

llvm::Expected<std::unique_ptr<Interpreter>>
Interpreter::createWithCUDA(std::unique_ptr<CompilerInstance> CI,
                            std::unique_ptr<CompilerInstance> DCI) {
  // avoid writing fat binary to disk using an in-memory virtual file system
  llvm::IntrusiveRefCntPtr<llvm::vfs::InMemoryFileSystem> IMVFS =
      std::make_unique<llvm::vfs::InMemoryFileSystem>();
  llvm::IntrusiveRefCntPtr<llvm::vfs::OverlayFileSystem> OverlayVFS =
      std::make_unique<llvm::vfs::OverlayFileSystem>(
          llvm::vfs::getRealFileSystem());
  OverlayVFS->pushOverlay(IMVFS);
  CI->createFileManager(OverlayVFS);

  auto Interp = Interpreter::create(std::move(CI));
  if (auto E = Interp.takeError())
    return std::move(E);

  llvm::Error Err = llvm::Error::success();
  auto DeviceParser = std::make_unique<IncrementalCUDADeviceParser>(
      **Interp, std::move(DCI), *(*Interp)->IncrParser.get(),
      *(*Interp)->TSCtx->getContext(), IMVFS, Err);
  if (Err)
    return std::move(Err);

  (*Interp)->DeviceParser = std::move(DeviceParser);

  return Interp;
}

const CompilerInstance *Interpreter::getCompilerInstance() const {
  return IncrParser->getCI();
}

CompilerInstance *Interpreter::getCompilerInstance() {
  return IncrParser->getCI();
}

llvm::Expected<llvm::orc::LLJIT &> Interpreter::getExecutionEngine() {
  if (!IncrExecutor) {
    if (auto Err = CreateExecutor())
      return std::move(Err);
  }

  return IncrExecutor->GetExecutionEngine();
}

ASTContext &Interpreter::getASTContext() {
  return getCompilerInstance()->getASTContext();
}

const ASTContext &Interpreter::getASTContext() const {
  return getCompilerInstance()->getASTContext();
}

void Interpreter::markUserCodeStart() {
  assert(!InitPTUSize && "We only do this once");
  InitPTUSize = IncrParser->getPTUs().size();
}

size_t Interpreter::getEffectivePTUSize() const {
  std::list<PartialTranslationUnit> &PTUs = IncrParser->getPTUs();
  assert(PTUs.size() >= InitPTUSize && "empty PTU list?");
  return PTUs.size() - InitPTUSize;
}

llvm::Expected<PartialTranslationUnit &>
Interpreter::Parse(llvm::StringRef Code) {
  // If we have a device parser, parse it first.
  // The generated code will be included in the host compilation
  if (DeviceParser) {
    auto DevicePTU = DeviceParser->Parse(Code);
    if (auto E = DevicePTU.takeError())
      return std::move(E);
  }

  // Tell the interpreter sliently ignore unused expressions since value
  // printing could cause it.
  getCompilerInstance()->getDiagnostics().setSeverity(
      clang::diag::warn_unused_expr, diag::Severity::Ignored, SourceLocation());
  return IncrParser->Parse(Code);
}

static llvm::Expected<llvm::orc::JITTargetMachineBuilder>
createJITTargetMachineBuilder(const std::string &TT) {
  if (TT == llvm::sys::getProcessTriple())
    // This fails immediately if the target backend is not registered
    return llvm::orc::JITTargetMachineBuilder::detectHost();

  // If the target backend is not registered, LLJITBuilder::create() will fail
  return llvm::orc::JITTargetMachineBuilder(llvm::Triple(TT));
}

llvm::Expected<std::unique_ptr<llvm::orc::LLJITBuilder>>
Interpreter::CreateJITBuilder(CompilerInstance &CI) {
  auto JTMB = createJITTargetMachineBuilder(CI.getTargetOpts().Triple);
  if (!JTMB)
    return JTMB.takeError();
  return IncrementalExecutor::createDefaultJITBuilder(std::move(*JTMB));
}

llvm::Error Interpreter::CreateExecutor() {
  if (IncrExecutor)
    return llvm::make_error<llvm::StringError>("Operation failed. "
                                               "Execution engine exists",
                                               std::error_code());
  llvm::Expected<std::unique_ptr<llvm::orc::LLJITBuilder>> JB =
      CreateJITBuilder(*getCompilerInstance());
  if (!JB)
    return JB.takeError();
  llvm::Error Err = llvm::Error::success();
  auto Executor = std::make_unique<IncrementalExecutor>(*TSCtx, **JB, Err);
  if (!Err)
    IncrExecutor = std::move(Executor);

  return Err;
}

void Interpreter::ResetExecutor() { IncrExecutor.reset(); }

llvm::Error Interpreter::Execute(PartialTranslationUnit &T) {
  assert(T.TheModule);
  if (!IncrExecutor) {
    auto Err = CreateExecutor();
    if (Err)
      return Err;
  }
  // FIXME: Add a callback to retain the llvm::Module once the JIT is done.
  if (auto Err = IncrExecutor->addModule(T))
    return Err;

  if (auto Err = IncrExecutor->runCtors())
    return Err;

  return llvm::Error::success();
}

llvm::Error Interpreter::ParseAndExecute(llvm::StringRef Code, Value *V) {

  auto PTU = Parse(Code);
  if (!PTU)
    return PTU.takeError();
  if (PTU->TheModule)
    if (llvm::Error Err = Execute(*PTU))
      return Err;

  if (LastValue.isValid()) {
    if (!V) {
      LastValue.dump();
      LastValue.clear();
    } else
      *V = std::move(LastValue);
  }
  return llvm::Error::success();
}

llvm::Expected<llvm::orc::ExecutorAddr>
Interpreter::getSymbolAddress(GlobalDecl GD) const {
  if (!IncrExecutor)
    return llvm::make_error<llvm::StringError>("Operation failed. "
                                               "No execution engine",
                                               std::error_code());
  llvm::StringRef MangledName = IncrParser->GetMangledName(GD);
  return getSymbolAddress(MangledName);
}

llvm::Expected<llvm::orc::ExecutorAddr>
Interpreter::getSymbolAddress(llvm::StringRef IRName) const {
  if (!IncrExecutor)
    return llvm::make_error<llvm::StringError>("Operation failed. "
                                               "No execution engine",
                                               std::error_code());

  return IncrExecutor->getSymbolAddress(IRName, IncrementalExecutor::IRName);
}

llvm::Expected<llvm::orc::ExecutorAddr>
Interpreter::getSymbolAddressFromLinkerName(llvm::StringRef Name) const {
  if (!IncrExecutor)
    return llvm::make_error<llvm::StringError>("Operation failed. "
                                               "No execution engine",
                                               std::error_code());

  return IncrExecutor->getSymbolAddress(Name, IncrementalExecutor::LinkerName);
}

llvm::Error Interpreter::Undo(unsigned N) {

  std::list<PartialTranslationUnit> &PTUs = IncrParser->getPTUs();
  if (N > getEffectivePTUSize())
    return llvm::make_error<llvm::StringError>("Operation failed. "
                                               "Too many undos",
                                               std::error_code());
  for (unsigned I = 0; I < N; I++) {
    if (IncrExecutor) {
      if (llvm::Error Err = IncrExecutor->removeModule(PTUs.back()))
        return Err;
    }

    IncrParser->CleanUpPTU(PTUs.back());
    PTUs.pop_back();
  }
  return llvm::Error::success();
}

llvm::Error Interpreter::LoadDynamicLibrary(const char *name) {
  auto EE = getExecutionEngine();
  if (!EE)
    return EE.takeError();

  auto &DL = EE->getDataLayout();

  if (auto DLSG = llvm::orc::DynamicLibrarySearchGenerator::Load(
          name, DL.getGlobalPrefix()))
    EE->getMainJITDylib().addGenerator(std::move(*DLSG));
  else
    return DLSG.takeError();

  return llvm::Error::success();
}

llvm::Expected<llvm::orc::ExecutorAddr>
Interpreter::CompileDtorCall(CXXRecordDecl *CXXRD) {
  assert(CXXRD && "Cannot compile a destructor for a nullptr");
  if (auto Dtor = Dtors.find(CXXRD); Dtor != Dtors.end())
    return Dtor->getSecond();

  if (CXXRD->hasIrrelevantDestructor())
    return llvm::orc::ExecutorAddr{};

  CXXDestructorDecl *DtorRD =
      getCompilerInstance()->getSema().LookupDestructor(CXXRD);

  llvm::StringRef Name =
      IncrParser->GetMangledName(GlobalDecl(DtorRD, Dtor_Base));
  auto AddrOrErr = getSymbolAddress(Name);
  if (!AddrOrErr)
    return AddrOrErr.takeError();

  Dtors[CXXRD] = *AddrOrErr;
  return AddrOrErr;
}

static constexpr llvm::StringRef MagicRuntimeInterface[] = {
    "__clang_Interpreter_SetValueNoAlloc",
    "__clang_Interpreter_SetValueWithAlloc",
    "__clang_Interpreter_SetValueCopyArr", "__ci_newtag"};

static std::unique_ptr<RuntimeInterfaceBuilder>
createInProcessRuntimeInterfaceBuilder(Interpreter &Interp, ASTContext &Ctx,
                                       Sema &S);

std::unique_ptr<RuntimeInterfaceBuilder> Interpreter::FindRuntimeInterface() {
  if (llvm::all_of(ValuePrintingInfo, [](Expr *E) { return E != nullptr; }))
    return nullptr;

  Sema &S = getCompilerInstance()->getSema();
  ASTContext &Ctx = S.getASTContext();

  auto LookupInterface = [&](Expr *&Interface, llvm::StringRef Name) {
    LookupResult R(S, &Ctx.Idents.get(Name), SourceLocation(),
                   Sema::LookupOrdinaryName, Sema::ForVisibleRedeclaration);
    S.LookupQualifiedName(R, Ctx.getTranslationUnitDecl());
    if (R.empty())
      return false;

    CXXScopeSpec CSS;
    Interface = S.BuildDeclarationNameExpr(CSS, R, /*ADL=*/false).get();
    return true;
  };

  if (!LookupInterface(ValuePrintingInfo[NoAlloc],
                       MagicRuntimeInterface[NoAlloc]))
    return nullptr;
  if (!LookupInterface(ValuePrintingInfo[WithAlloc],
                       MagicRuntimeInterface[WithAlloc]))
    return nullptr;
  if (!LookupInterface(ValuePrintingInfo[CopyArray],
                       MagicRuntimeInterface[CopyArray]))
    return nullptr;
  if (!LookupInterface(ValuePrintingInfo[NewTag],
                       MagicRuntimeInterface[NewTag]))
    return nullptr;

  return createInProcessRuntimeInterfaceBuilder(*this, Ctx, S);
}

namespace {

class InterfaceKindVisitor
    : public TypeVisitor<InterfaceKindVisitor, Interpreter::InterfaceKind> {
  friend class InProcessRuntimeInterfaceBuilder;

  ASTContext &Ctx;
  Sema &S;
  Expr *E;
  llvm::SmallVector<Expr *, 3> Args;

public:
  InterfaceKindVisitor(ASTContext &Ctx, Sema &S, Expr *E)
      : Ctx(Ctx), S(S), E(E) {}

  Interpreter::InterfaceKind VisitRecordType(const RecordType *Ty) {
    return Interpreter::InterfaceKind::WithAlloc;
  }

  Interpreter::InterfaceKind
  VisitMemberPointerType(const MemberPointerType *Ty) {
    return Interpreter::InterfaceKind::WithAlloc;
  }

  Interpreter::InterfaceKind
  VisitConstantArrayType(const ConstantArrayType *Ty) {
    return Interpreter::InterfaceKind::CopyArray;
  }

  Interpreter::InterfaceKind
  VisitFunctionProtoType(const FunctionProtoType *Ty) {
    HandlePtrType(Ty);
    return Interpreter::InterfaceKind::NoAlloc;
  }

  Interpreter::InterfaceKind VisitPointerType(const PointerType *Ty) {
    HandlePtrType(Ty);
    return Interpreter::InterfaceKind::NoAlloc;
  }

  Interpreter::InterfaceKind VisitReferenceType(const ReferenceType *Ty) {
    ExprResult AddrOfE = S.CreateBuiltinUnaryOp(SourceLocation(), UO_AddrOf, E);
    assert(!AddrOfE.isInvalid() && "Can not create unary expression");
    Args.push_back(AddrOfE.get());
    return Interpreter::InterfaceKind::NoAlloc;
  }

  Interpreter::InterfaceKind VisitBuiltinType(const BuiltinType *Ty) {
    if (Ty->isNullPtrType())
      Args.push_back(E);
    else if (Ty->isFloatingType())
      Args.push_back(E);
    else if (Ty->isIntegralOrEnumerationType())
      HandleIntegralOrEnumType(Ty);
    else if (Ty->isVoidType()) {
      // Do we need to still run `E`?
    }

    return Interpreter::InterfaceKind::NoAlloc;
  }

  Interpreter::InterfaceKind VisitEnumType(const EnumType *Ty) {
    HandleIntegralOrEnumType(Ty);
    return Interpreter::InterfaceKind::NoAlloc;
  }

private:
  // Force cast these types to uint64 to reduce the number of overloads of
  // `__clang_Interpreter_SetValueNoAlloc`.
  void HandleIntegralOrEnumType(const Type *Ty) {
    TypeSourceInfo *TSI = Ctx.getTrivialTypeSourceInfo(Ctx.UnsignedLongLongTy);
    ExprResult CastedExpr =
        S.BuildCStyleCastExpr(SourceLocation(), TSI, SourceLocation(), E);
    assert(!CastedExpr.isInvalid() && "Cannot create cstyle cast expr");
    Args.push_back(CastedExpr.get());
  }

  void HandlePtrType(const Type *Ty) {
    TypeSourceInfo *TSI = Ctx.getTrivialTypeSourceInfo(Ctx.VoidPtrTy);
    ExprResult CastedExpr =
        S.BuildCStyleCastExpr(SourceLocation(), TSI, SourceLocation(), E);
    assert(!CastedExpr.isInvalid() && "Can not create cstyle cast expression");
    Args.push_back(CastedExpr.get());
  }
};

class InProcessRuntimeInterfaceBuilder : public RuntimeInterfaceBuilder {
  Interpreter &Interp;
  ASTContext &Ctx;
  Sema &S;

public:
  InProcessRuntimeInterfaceBuilder(Interpreter &Interp, ASTContext &C, Sema &S)
      : Interp(Interp), Ctx(C), S(S) {}

  TransformExprFunction *getPrintValueTransformer() override {
    return &transformForValuePrinting;
  }

private:
  static ExprResult transformForValuePrinting(RuntimeInterfaceBuilder *Builder,
                                              Expr *E,
                                              ArrayRef<Expr *> FixedArgs) {
    auto *B = static_cast<InProcessRuntimeInterfaceBuilder *>(Builder);

    // Get rid of ExprWithCleanups.
    if (auto *EWC = llvm::dyn_cast_if_present<ExprWithCleanups>(E))
      E = EWC->getSubExpr();

    InterfaceKindVisitor Visitor(B->Ctx, B->S, E);

    // The Interpreter* parameter and the out parameter `OutVal`.
    for (Expr *E : FixedArgs)
      Visitor.Args.push_back(E);

    QualType Ty = E->getType();
    QualType DesugaredTy = Ty.getDesugaredType(B->Ctx);

    // For lvalue struct, we treat it as a reference.
    if (DesugaredTy->isRecordType() && E->isLValue()) {
      DesugaredTy = B->Ctx.getLValueReferenceType(DesugaredTy);
      Ty = B->Ctx.getLValueReferenceType(Ty);
    }

    Expr *TypeArg = CStyleCastPtrExpr(B->S, B->Ctx.VoidPtrTy,
                                      (uintptr_t)Ty.getAsOpaquePtr());
    // The QualType parameter `OpaqueType`, represented as `void*`.
    Visitor.Args.push_back(TypeArg);

    // We push the last parameter based on the type of the Expr. Note we need
    // special care for rvalue struct.
    Interpreter::InterfaceKind Kind = Visitor.Visit(&*DesugaredTy);
    switch (Kind) {
    case Interpreter::InterfaceKind::WithAlloc:
    case Interpreter::InterfaceKind::CopyArray: {
      // __clang_Interpreter_SetValueWithAlloc.
      ExprResult AllocCall = B->S.ActOnCallExpr(
          /*Scope=*/nullptr,
          B->Interp
              .getValuePrintingInfo()[Interpreter::InterfaceKind::WithAlloc],
          E->getBeginLoc(), Visitor.Args, E->getEndLoc());
      assert(!AllocCall.isInvalid() && "Can't create runtime interface call!");

      TypeSourceInfo *TSI =
          B->Ctx.getTrivialTypeSourceInfo(Ty, SourceLocation());

      // Force CodeGen to emit destructor.
      if (auto *RD = Ty->getAsCXXRecordDecl()) {
        auto *Dtor = B->S.LookupDestructor(RD);
        Dtor->addAttr(UsedAttr::CreateImplicit(B->Ctx));
        B->Interp.getCompilerInstance()->getASTConsumer().HandleTopLevelDecl(
            DeclGroupRef(Dtor));
      }

      // __clang_Interpreter_SetValueCopyArr.
      if (Kind == Interpreter::InterfaceKind::CopyArray) {
        const auto *ConstantArrTy =
            cast<ConstantArrayType>(DesugaredTy.getTypePtr());
        size_t ArrSize = B->Ctx.getConstantArrayElementCount(ConstantArrTy);
        Expr *ArrSizeExpr = IntegerLiteralExpr(B->Ctx, ArrSize);
        Expr *Args[] = {E, AllocCall.get(), ArrSizeExpr};
        return B->S.ActOnCallExpr(
            /*Scope *=*/nullptr,
            B->Interp
                .getValuePrintingInfo()[Interpreter::InterfaceKind::CopyArray],
            SourceLocation(), Args, SourceLocation());
      }
      Expr *Args[] = {
          AllocCall.get(),
          B->Interp.getValuePrintingInfo()[Interpreter::InterfaceKind::NewTag]};
      ExprResult CXXNewCall = B->S.BuildCXXNew(
          E->getSourceRange(),
          /*UseGlobal=*/true, /*PlacementLParen=*/SourceLocation(), Args,
          /*PlacementRParen=*/SourceLocation(),
          /*TypeIdParens=*/SourceRange(), TSI->getType(), TSI, std::nullopt,
          E->getSourceRange(), E);

      assert(!CXXNewCall.isInvalid() &&
             "Can't create runtime placement new call!");

      return B->S.ActOnFinishFullExpr(CXXNewCall.get(),
                                      /*DiscardedValue=*/false);
    }
      // __clang_Interpreter_SetValueNoAlloc.
    case Interpreter::InterfaceKind::NoAlloc: {
      return B->S.ActOnCallExpr(
          /*Scope=*/nullptr,
          B->Interp.getValuePrintingInfo()[Interpreter::InterfaceKind::NoAlloc],
          E->getBeginLoc(), Visitor.Args, E->getEndLoc());
    }
    default:
      llvm_unreachable("Unhandled Interpreter::InterfaceKind");
    }
  }
};
} // namespace

static std::unique_ptr<RuntimeInterfaceBuilder>
createInProcessRuntimeInterfaceBuilder(Interpreter &Interp, ASTContext &Ctx,
                                       Sema &S) {
  return std::make_unique<InProcessRuntimeInterfaceBuilder>(Interp, Ctx, S);
}

// This synthesizes a call expression to a speciall
// function that is responsible for generating the Value.
// In general, we transform:
//   clang-repl> x
// To:
//   // 1. If x is a built-in type like int, float.
//   __clang_Interpreter_SetValueNoAlloc(ThisInterp, OpaqueValue, xQualType, x);
//   // 2. If x is a struct, and a lvalue.
//   __clang_Interpreter_SetValueNoAlloc(ThisInterp, OpaqueValue, xQualType,
//   &x);
//   // 3. If x is a struct, but a rvalue.
//   new (__clang_Interpreter_SetValueWithAlloc(ThisInterp, OpaqueValue,
//   xQualType)) (x);

Expr *Interpreter::SynthesizeExpr(Expr *E) {
  Sema &S = getCompilerInstance()->getSema();
  ASTContext &Ctx = S.getASTContext();

  if (!RuntimeIB) {
    RuntimeIB = FindRuntimeInterface();
    AddPrintValueCall = RuntimeIB->getPrintValueTransformer();
  }

  assert(AddPrintValueCall &&
         "We don't have a runtime interface for pretty print!");

  // Create parameter `ThisInterp`.
  auto *ThisInterp = CStyleCastPtrExpr(S, Ctx.VoidPtrTy, (uintptr_t)this);

  // Create parameter `OutVal`.
  auto *OutValue = CStyleCastPtrExpr(S, Ctx.VoidPtrTy, (uintptr_t)&LastValue);

  // Build `__clang_Interpreter_SetValue*` call.
  ExprResult Result =
      AddPrintValueCall(RuntimeIB.get(), E, {ThisInterp, OutValue});

  // It could fail, like printing an array type in C. (not supported)
  if (Result.isInvalid())
    return E;
  return Result.get();
}

// Temporary rvalue struct that need special care.
REPL_EXTERNAL_VISIBILITY void *
__clang_Interpreter_SetValueWithAlloc(void *This, void *OutVal,
                                      void *OpaqueType) {
  Value &VRef = *(Value *)OutVal;
  VRef = Value(static_cast<Interpreter *>(This), OpaqueType);
  return VRef.getPtr();
}

// Pointers, lvalue struct that can take as a reference.
REPL_EXTERNAL_VISIBILITY void
__clang_Interpreter_SetValueNoAlloc(void *This, void *OutVal, void *OpaqueType,
                                    void *Val) {
  Value &VRef = *(Value *)OutVal;
  VRef = Value(static_cast<Interpreter *>(This), OpaqueType);
  VRef.setPtr(Val);
}

REPL_EXTERNAL_VISIBILITY void
__clang_Interpreter_SetValueNoAlloc(void *This, void *OutVal,
                                    void *OpaqueType) {
  Value &VRef = *(Value *)OutVal;
  VRef = Value(static_cast<Interpreter *>(This), OpaqueType);
}

static void SetValueDataBasedOnQualType(Value &V, unsigned long long Data) {
  QualType QT = V.getType();
  if (const auto *ET = QT->getAs<EnumType>())
    QT = ET->getDecl()->getIntegerType();

  switch (QT->castAs<BuiltinType>()->getKind()) {
  default:
    llvm_unreachable("unknown type kind!");
#define X(type, name)                                                          \
  case BuiltinType::name:                                                      \
    V.set##name(Data);                                                         \
    break;
    REPL_BUILTIN_TYPES
#undef X
  }
}

REPL_EXTERNAL_VISIBILITY void
__clang_Interpreter_SetValueNoAlloc(void *This, void *OutVal, void *OpaqueType,
                                    unsigned long long Val) {
  Value &VRef = *(Value *)OutVal;
  VRef = Value(static_cast<Interpreter *>(This), OpaqueType);
  SetValueDataBasedOnQualType(VRef, Val);
}

REPL_EXTERNAL_VISIBILITY void
__clang_Interpreter_SetValueNoAlloc(void *This, void *OutVal, void *OpaqueType,
                                    float Val) {
  Value &VRef = *(Value *)OutVal;
  VRef = Value(static_cast<Interpreter *>(This), OpaqueType);
  VRef.setFloat(Val);
}

REPL_EXTERNAL_VISIBILITY void
__clang_Interpreter_SetValueNoAlloc(void *This, void *OutVal, void *OpaqueType,
                                    double Val) {
  Value &VRef = *(Value *)OutVal;
  VRef = Value(static_cast<Interpreter *>(This), OpaqueType);
  VRef.setDouble(Val);
}

REPL_EXTERNAL_VISIBILITY void
__clang_Interpreter_SetValueNoAlloc(void *This, void *OutVal, void *OpaqueType,
                                    long double Val) {
  Value &VRef = *(Value *)OutVal;
  VRef = Value(static_cast<Interpreter *>(This), OpaqueType);
  VRef.setLongDouble(Val);
}

// A trampoline to work around the fact that operator placement new cannot
// really be forward declared due to libc++ and libstdc++ declaration mismatch.
// FIXME: __clang_Interpreter_NewTag is ODR violation because we get the same
// definition in the interpreter runtime. We should move it in a runtime header
// which gets included by the interpreter and here.
struct __clang_Interpreter_NewTag {};
REPL_EXTERNAL_VISIBILITY void *
operator new(size_t __sz, void *__p, __clang_Interpreter_NewTag) noexcept {
  // Just forward to the standard operator placement new.
  return operator new(__sz, __p);
}
