//===-- SBDebugger.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
//
//===----------------------------------------------------------------------===//

#include "SBReproducerPrivate.h"
#include "SystemInitializerFull.h"

#include "lldb/API/SBDebugger.h"

#include "lldb/lldb-private.h"

#include "lldb/API/SBBroadcaster.h"
#include "lldb/API/SBCommandInterpreter.h"
#include "lldb/API/SBCommandReturnObject.h"
#include "lldb/API/SBError.h"
#include "lldb/API/SBEvent.h"
#include "lldb/API/SBFile.h"
#include "lldb/API/SBFrame.h"
#include "lldb/API/SBListener.h"
#include "lldb/API/SBProcess.h"
#include "lldb/API/SBSourceManager.h"
#include "lldb/API/SBStream.h"
#include "lldb/API/SBStringList.h"
#include "lldb/API/SBStructuredData.h"
#include "lldb/API/SBTarget.h"
#include "lldb/API/SBThread.h"
#include "lldb/API/SBTypeCategory.h"
#include "lldb/API/SBTypeFilter.h"
#include "lldb/API/SBTypeFormat.h"
#include "lldb/API/SBTypeNameSpecifier.h"
#include "lldb/API/SBTypeSummary.h"
#include "lldb/API/SBTypeSynthetic.h"

#include "lldb/Core/Debugger.h"
#include "lldb/Core/PluginManager.h"
#include "lldb/Core/StreamFile.h"
#include "lldb/Core/StructuredDataImpl.h"
#include "lldb/DataFormatters/DataVisualization.h"
#include "lldb/Host/Config.h"
#include "lldb/Host/XML.h"
#include "lldb/Initialization/SystemLifetimeManager.h"
#include "lldb/Interpreter/CommandInterpreter.h"
#include "lldb/Interpreter/OptionArgParser.h"
#include "lldb/Interpreter/OptionGroupPlatform.h"
#include "lldb/Target/Process.h"
#include "lldb/Target/TargetList.h"
#include "lldb/Utility/Args.h"
#include "lldb/Utility/State.h"

#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/Support/DynamicLibrary.h"
#include "llvm/Support/ManagedStatic.h"

using namespace lldb;
using namespace lldb_private;

static llvm::sys::DynamicLibrary LoadPlugin(const lldb::DebuggerSP &debugger_sp,
                                            const FileSpec &spec,
                                            Status &error) {
  llvm::sys::DynamicLibrary dynlib =
      llvm::sys::DynamicLibrary::getPermanentLibrary(spec.GetPath().c_str());
  if (dynlib.isValid()) {
    typedef bool (*LLDBCommandPluginInit)(lldb::SBDebugger & debugger);

    lldb::SBDebugger debugger_sb(debugger_sp);
    // This calls the bool lldb::PluginInitialize(lldb::SBDebugger debugger)
    // function.
    // TODO: mangle this differently for your system - on OSX, the first
    // underscore needs to be removed and the second one stays
    LLDBCommandPluginInit init_func =
        (LLDBCommandPluginInit)(uintptr_t)dynlib.getAddressOfSymbol(
            "_ZN4lldb16PluginInitializeENS_10SBDebuggerE");
    if (init_func) {
      if (init_func(debugger_sb))
        return dynlib;
      else
        error.SetErrorString("plug-in refused to load "
                             "(lldb::PluginInitialize(lldb::SBDebugger) "
                             "returned false)");
    } else {
      error.SetErrorString("plug-in is missing the required initialization: "
                           "lldb::PluginInitialize(lldb::SBDebugger)");
    }
  } else {
    if (FileSystem::Instance().Exists(spec))
      error.SetErrorString("this file does not represent a loadable dylib");
    else
      error.SetErrorString("no such file");
  }
  return llvm::sys::DynamicLibrary();
}

static llvm::ManagedStatic<SystemLifetimeManager> g_debugger_lifetime;

SBError SBInputReader::Initialize(
    lldb::SBDebugger &sb_debugger,
    unsigned long (*callback)(void *, lldb::SBInputReader *,
                              lldb::InputReaderAction, char const *,
                              unsigned long),
    void *a, lldb::InputReaderGranularity b, char const *c, char const *d,
    bool e) {
  LLDB_RECORD_DUMMY(
      lldb::SBError, SBInputReader, Initialize,
      (lldb::SBDebugger &,
       unsigned long (*)(void *, lldb::SBInputReader *, lldb::InputReaderAction,
                         const char *, unsigned long),
       void *, lldb::InputReaderGranularity, const char *, const char *, bool),
      sb_debugger, callback, a, b, c, d, e);

  return SBError();
}

void SBInputReader::SetIsDone(bool b) {
  LLDB_RECORD_METHOD(void, SBInputReader, SetIsDone, (bool), b);
}

bool SBInputReader::IsActive() const {
  LLDB_RECORD_METHOD_CONST_NO_ARGS(bool, SBInputReader, IsActive);

  return false;
}

SBDebugger::SBDebugger() { LLDB_RECORD_CONSTRUCTOR_NO_ARGS(SBDebugger); }

SBDebugger::SBDebugger(const lldb::DebuggerSP &debugger_sp)
    : m_opaque_sp(debugger_sp) {
  LLDB_RECORD_CONSTRUCTOR(SBDebugger, (const lldb::DebuggerSP &), debugger_sp);
}

SBDebugger::SBDebugger(const SBDebugger &rhs) : m_opaque_sp(rhs.m_opaque_sp) {
  LLDB_RECORD_CONSTRUCTOR(SBDebugger, (const lldb::SBDebugger &), rhs);
}

SBDebugger::~SBDebugger() = default;

SBDebugger &SBDebugger::operator=(const SBDebugger &rhs) {
  LLDB_RECORD_METHOD(lldb::SBDebugger &,
                     SBDebugger, operator=,(const lldb::SBDebugger &), rhs);

  if (this != &rhs) {
    m_opaque_sp = rhs.m_opaque_sp;
  }
  return LLDB_RECORD_RESULT(*this);
}

void SBDebugger::Initialize() {
  LLDB_RECORD_STATIC_METHOD_NO_ARGS(void, SBDebugger, Initialize);
  SBError ignored = SBDebugger::InitializeWithErrorHandling();
}

lldb::SBError SBDebugger::InitializeWithErrorHandling() {
  LLDB_RECORD_STATIC_METHOD_NO_ARGS(lldb::SBError, SBDebugger,
                                    InitializeWithErrorHandling);

  SBError error;
  if (auto e = g_debugger_lifetime->Initialize(
          std::make_unique<SystemInitializerFull>(), LoadPlugin)) {
    error.SetError(Status(std::move(e)));
  }
  return LLDB_RECORD_RESULT(error);
}

void SBDebugger::Terminate() {
  LLDB_RECORD_STATIC_METHOD_NO_ARGS(void, SBDebugger, Terminate);

  g_debugger_lifetime->Terminate();
}

void SBDebugger::Clear() {
  LLDB_RECORD_METHOD_NO_ARGS(void, SBDebugger, Clear);

  if (m_opaque_sp)
    m_opaque_sp->ClearIOHandlers();

  m_opaque_sp.reset();
}

SBDebugger SBDebugger::Create() {
  LLDB_RECORD_STATIC_METHOD_NO_ARGS(lldb::SBDebugger, SBDebugger, Create);

  return LLDB_RECORD_RESULT(SBDebugger::Create(false, nullptr, nullptr));
}

SBDebugger SBDebugger::Create(bool source_init_files) {
  LLDB_RECORD_STATIC_METHOD(lldb::SBDebugger, SBDebugger, Create, (bool),
                            source_init_files);

  return LLDB_RECORD_RESULT(
      SBDebugger::Create(source_init_files, nullptr, nullptr));
}

SBDebugger SBDebugger::Create(bool source_init_files,
                              lldb::LogOutputCallback callback, void *baton)

{
  LLDB_RECORD_DUMMY(lldb::SBDebugger, SBDebugger, Create,
                    (bool, lldb::LogOutputCallback, void *), source_init_files,
                    callback, baton);

  SBDebugger debugger;

  // Currently we have issues if this function is called simultaneously on two
  // different threads. The issues mainly revolve around the fact that the
  // lldb_private::FormatManager uses global collections and having two threads
  // parsing the .lldbinit files can cause mayhem. So to get around this for
  // now we need to use a mutex to prevent bad things from happening.
  static std::recursive_mutex g_mutex;
  std::lock_guard<std::recursive_mutex> guard(g_mutex);

  debugger.reset(Debugger::CreateInstance(callback, baton));

  SBCommandInterpreter interp = debugger.GetCommandInterpreter();
  if (source_init_files) {
    interp.get()->SkipLLDBInitFiles(false);
    interp.get()->SkipAppInitFiles(false);
    SBCommandReturnObject result;
    interp.SourceInitFileInHomeDirectory(result);
  } else {
    interp.get()->SkipLLDBInitFiles(true);
    interp.get()->SkipAppInitFiles(true);
  }
  return debugger;
}

void SBDebugger::Destroy(SBDebugger &debugger) {
  LLDB_RECORD_STATIC_METHOD(void, SBDebugger, Destroy, (lldb::SBDebugger &),
                            debugger);

  Debugger::Destroy(debugger.m_opaque_sp);

  if (debugger.m_opaque_sp.get() != nullptr)
    debugger.m_opaque_sp.reset();
}

void SBDebugger::MemoryPressureDetected() {
  LLDB_RECORD_STATIC_METHOD_NO_ARGS(void, SBDebugger, MemoryPressureDetected);

  // Since this function can be call asynchronously, we allow it to be non-
  // mandatory. We have seen deadlocks with this function when called so we
  // need to safeguard against this until we can determine what is causing the
  // deadlocks.

  const bool mandatory = false;

  ModuleList::RemoveOrphanSharedModules(mandatory);
}

bool SBDebugger::IsValid() const {
  LLDB_RECORD_METHOD_CONST_NO_ARGS(bool, SBDebugger, IsValid);
  return this->operator bool();
}
SBDebugger::operator bool() const {
  LLDB_RECORD_METHOD_CONST_NO_ARGS(bool, SBDebugger, operator bool);

  return m_opaque_sp.get() != nullptr;
}

void SBDebugger::SetAsync(bool b) {
  LLDB_RECORD_METHOD(void, SBDebugger, SetAsync, (bool), b);

  if (m_opaque_sp)
    m_opaque_sp->SetAsyncExecution(b);
}

bool SBDebugger::GetAsync() {
  LLDB_RECORD_METHOD_NO_ARGS(bool, SBDebugger, GetAsync);

  return (m_opaque_sp ? m_opaque_sp->GetAsyncExecution() : false);
}

void SBDebugger::SkipLLDBInitFiles(bool b) {
  LLDB_RECORD_METHOD(void, SBDebugger, SkipLLDBInitFiles, (bool), b);

  if (m_opaque_sp)
    m_opaque_sp->GetCommandInterpreter().SkipLLDBInitFiles(b);
}

void SBDebugger::SkipAppInitFiles(bool b) {
  LLDB_RECORD_METHOD(void, SBDebugger, SkipAppInitFiles, (bool), b);

  if (m_opaque_sp)
    m_opaque_sp->GetCommandInterpreter().SkipAppInitFiles(b);
}

void SBDebugger::SetInputFileHandle(FILE *fh, bool transfer_ownership) {
  LLDB_RECORD_METHOD(void, SBDebugger, SetInputFileHandle, (FILE *, bool), fh,
                     transfer_ownership);
  SetInputFile((FileSP)std::make_shared<NativeFile>(fh, transfer_ownership));
}

SBError SBDebugger::SetInputFile(FileSP file_sp) {
  LLDB_RECORD_METHOD(SBError, SBDebugger, SetInputFile, (FileSP), file_sp);
  return LLDB_RECORD_RESULT(SetInputFile(SBFile(file_sp)));
}

// Shouldn't really be settable after initialization as this could cause lots
// of problems; don't want users trying to switch modes in the middle of a
// debugging session.
SBError SBDebugger::SetInputFile(SBFile file) {
  LLDB_RECORD_METHOD(SBError, SBDebugger, SetInputFile, (SBFile), file);

  SBError error;
  if (!m_opaque_sp) {
    error.ref().SetErrorString("invalid debugger");
    return LLDB_RECORD_RESULT(error);
  }

  repro::DataRecorder *recorder = nullptr;
  if (repro::Generator *g = repro::Reproducer::Instance().GetGenerator())
    recorder = g->GetOrCreate<repro::CommandProvider>().GetNewDataRecorder();

  FileSP file_sp = file.m_opaque_sp;

  static std::unique_ptr<repro::MultiLoader<repro::CommandProvider>> loader =
      repro::MultiLoader<repro::CommandProvider>::Create(
          repro::Reproducer::Instance().GetLoader());
  if (loader) {
    llvm::Optional<std::string> nextfile = loader->GetNextFile();
    FILE *fh = nextfile ? FileSystem::Instance().Fopen(nextfile->c_str(), "r")
                        : nullptr;
    // FIXME Jonas Devlieghere: shouldn't this error be propagated out to the
    // reproducer somehow if fh is NULL?
    if (fh) {
      file_sp = std::make_shared<NativeFile>(fh, true);
    }
  }

  if (!file_sp || !file_sp->IsValid()) {
    error.ref().SetErrorString("invalid file");
    return LLDB_RECORD_RESULT(error);
  }

  m_opaque_sp->SetInputFile(file_sp, recorder);
  return LLDB_RECORD_RESULT(error);
}

SBError SBDebugger::SetOutputFile(FileSP file_sp) {
  LLDB_RECORD_METHOD(SBError, SBDebugger, SetOutputFile, (FileSP), file_sp);
  return LLDB_RECORD_RESULT(SetOutputFile(SBFile(file_sp)));
}

void SBDebugger::SetOutputFileHandle(FILE *fh, bool transfer_ownership) {
  LLDB_RECORD_METHOD(void, SBDebugger, SetOutputFileHandle, (FILE *, bool), fh,
                     transfer_ownership);
  SetOutputFile((FileSP)std::make_shared<NativeFile>(fh, transfer_ownership));
}

SBError SBDebugger::SetOutputFile(SBFile file) {
  LLDB_RECORD_METHOD(SBError, SBDebugger, SetOutputFile, (SBFile file), file);
  SBError error;
  if (!m_opaque_sp) {
    error.ref().SetErrorString("invalid debugger");
    return LLDB_RECORD_RESULT(error);
  }
  if (!file) {
    error.ref().SetErrorString("invalid file");
    return LLDB_RECORD_RESULT(error);
  }
  m_opaque_sp->SetOutputFile(file.m_opaque_sp);
  return LLDB_RECORD_RESULT(error);
}

void SBDebugger::SetErrorFileHandle(FILE *fh, bool transfer_ownership) {
  LLDB_RECORD_METHOD(void, SBDebugger, SetErrorFileHandle, (FILE *, bool), fh,
                     transfer_ownership);
  SetErrorFile((FileSP)std::make_shared<NativeFile>(fh, transfer_ownership));
}

SBError SBDebugger::SetErrorFile(FileSP file_sp) {
  LLDB_RECORD_METHOD(SBError, SBDebugger, SetErrorFile, (FileSP), file_sp);
  return LLDB_RECORD_RESULT(SetErrorFile(SBFile(file_sp)));
}

SBError SBDebugger::SetErrorFile(SBFile file) {
  LLDB_RECORD_METHOD(SBError, SBDebugger, SetErrorFile, (SBFile file), file);
  SBError error;
  if (!m_opaque_sp) {
    error.ref().SetErrorString("invalid debugger");
    return LLDB_RECORD_RESULT(error);
  }
  if (!file) {
    error.ref().SetErrorString("invalid file");
    return LLDB_RECORD_RESULT(error);
  }
  m_opaque_sp->SetErrorFile(file.m_opaque_sp);
  return LLDB_RECORD_RESULT(error);
}

FILE *SBDebugger::GetInputFileHandle() {
  LLDB_RECORD_METHOD_NO_ARGS(FILE *, SBDebugger, GetInputFileHandle);
  if (m_opaque_sp) {
    File &file_sp = m_opaque_sp->GetInputFile();
    return LLDB_RECORD_RESULT(file_sp.GetStream());
  }
  return LLDB_RECORD_RESULT(nullptr);
}

SBFile SBDebugger::GetInputFile() {
  LLDB_RECORD_METHOD_NO_ARGS(SBFile, SBDebugger, GetInputFile);
  if (m_opaque_sp) {
    return LLDB_RECORD_RESULT(SBFile(m_opaque_sp->GetInputFileSP()));
  }
  return LLDB_RECORD_RESULT(SBFile());
}

FILE *SBDebugger::GetOutputFileHandle() {
  LLDB_RECORD_METHOD_NO_ARGS(FILE *, SBDebugger, GetOutputFileHandle);
  if (m_opaque_sp) {
    StreamFile &stream_file = m_opaque_sp->GetOutputStream();
    return LLDB_RECORD_RESULT(stream_file.GetFile().GetStream());
  }
  return LLDB_RECORD_RESULT(nullptr);
}

SBFile SBDebugger::GetOutputFile() {
  LLDB_RECORD_METHOD_NO_ARGS(SBFile, SBDebugger, GetOutputFile);
  if (m_opaque_sp) {
    SBFile file(m_opaque_sp->GetOutputStream().GetFileSP());
    return LLDB_RECORD_RESULT(file);
  }
  return LLDB_RECORD_RESULT(SBFile());
}

FILE *SBDebugger::GetErrorFileHandle() {
  LLDB_RECORD_METHOD_NO_ARGS(FILE *, SBDebugger, GetErrorFileHandle);

  if (m_opaque_sp) {
    StreamFile &stream_file = m_opaque_sp->GetErrorStream();
    return LLDB_RECORD_RESULT(stream_file.GetFile().GetStream());
  }
  return LLDB_RECORD_RESULT(nullptr);
}

SBFile SBDebugger::GetErrorFile() {
  LLDB_RECORD_METHOD_NO_ARGS(SBFile, SBDebugger, GetErrorFile);
  SBFile file;
  if (m_opaque_sp) {
    SBFile file(m_opaque_sp->GetErrorStream().GetFileSP());
    return LLDB_RECORD_RESULT(file);
  }
  return LLDB_RECORD_RESULT(SBFile());
}

void SBDebugger::SaveInputTerminalState() {
  LLDB_RECORD_DUMMY_NO_ARGS(void, SBDebugger, SaveInputTerminalState);

  if (m_opaque_sp)
    m_opaque_sp->SaveInputTerminalState();
}

void SBDebugger::RestoreInputTerminalState() {
  LLDB_RECORD_DUMMY_NO_ARGS(void, SBDebugger, RestoreInputTerminalState);

  if (m_opaque_sp)
    m_opaque_sp->RestoreInputTerminalState();
}
SBCommandInterpreter SBDebugger::GetCommandInterpreter() {
  LLDB_RECORD_METHOD_NO_ARGS(lldb::SBCommandInterpreter, SBDebugger,
                             GetCommandInterpreter);

  SBCommandInterpreter sb_interpreter;
  if (m_opaque_sp)
    sb_interpreter.reset(&m_opaque_sp->GetCommandInterpreter());

  return LLDB_RECORD_RESULT(sb_interpreter);
}

void SBDebugger::HandleCommand(const char *command) {
  LLDB_RECORD_METHOD(void, SBDebugger, HandleCommand, (const char *), command);

  if (m_opaque_sp) {
    TargetSP target_sp(m_opaque_sp->GetSelectedTarget());
    std::unique_lock<std::recursive_mutex> lock;
    if (target_sp)
      lock = std::unique_lock<std::recursive_mutex>(target_sp->GetAPIMutex());

    SBCommandInterpreter sb_interpreter(GetCommandInterpreter());
    SBCommandReturnObject result;

    sb_interpreter.HandleCommand(command, result, false);

    result.PutError(m_opaque_sp->GetErrorStream().GetFileSP());
    result.PutOutput(m_opaque_sp->GetOutputStream().GetFileSP());

    if (!m_opaque_sp->GetAsyncExecution()) {
      SBProcess process(GetCommandInterpreter().GetProcess());
      ProcessSP process_sp(process.GetSP());
      if (process_sp) {
        EventSP event_sp;
        ListenerSP lldb_listener_sp = m_opaque_sp->GetListener();
        while (lldb_listener_sp->GetEventForBroadcaster(
            process_sp.get(), event_sp, std::chrono::seconds(0))) {
          SBEvent event(event_sp);
          HandleProcessEvent(process, event, GetOutputFile(), GetErrorFile());
        }
      }
    }
  }
}

SBListener SBDebugger::GetListener() {
  LLDB_RECORD_METHOD_NO_ARGS(lldb::SBListener, SBDebugger, GetListener);

  SBListener sb_listener;
  if (m_opaque_sp)
    sb_listener.reset(m_opaque_sp->GetListener());

  return LLDB_RECORD_RESULT(sb_listener);
}

void SBDebugger::HandleProcessEvent(const SBProcess &process,
                                    const SBEvent &event, SBFile out,
                                    SBFile err) {
  LLDB_RECORD_METHOD(
      void, SBDebugger, HandleProcessEvent,
      (const lldb::SBProcess &, const lldb::SBEvent &, SBFile, SBFile), process,
      event, out, err);

  return HandleProcessEvent(process, event, out.m_opaque_sp, err.m_opaque_sp);
}

void SBDebugger::HandleProcessEvent(const SBProcess &process,
                                    const SBEvent &event, FILE *out,
                                    FILE *err) {
  LLDB_RECORD_METHOD(
      void, SBDebugger, HandleProcessEvent,
      (const lldb::SBProcess &, const lldb::SBEvent &, FILE *, FILE *), process,
      event, out, err);

  FileSP outfile = std::make_shared<NativeFile>(out, false);
  FileSP errfile = std::make_shared<NativeFile>(err, false);
  return HandleProcessEvent(process, event, outfile, errfile);
}

void SBDebugger::HandleProcessEvent(const SBProcess &process,
                                    const SBEvent &event, FileSP out_sp,
                                    FileSP err_sp) {

  LLDB_RECORD_METHOD(
      void, SBDebugger, HandleProcessEvent,
      (const lldb::SBProcess &, const lldb::SBEvent &, FileSP, FileSP), process,
      event, out_sp, err_sp);

  if (!process.IsValid())
    return;

  TargetSP target_sp(process.GetTarget().GetSP());
  if (!target_sp)
    return;

  const uint32_t event_type = event.GetType();
  char stdio_buffer[1024];
  size_t len;

  std::lock_guard<std::recursive_mutex> guard(target_sp->GetAPIMutex());

  if (event_type &
      (Process::eBroadcastBitSTDOUT | Process::eBroadcastBitStateChanged)) {
    // Drain stdout when we stop just in case we have any bytes
    while ((len = process.GetSTDOUT(stdio_buffer, sizeof(stdio_buffer))) > 0)
      if (out_sp)
        out_sp->Write(stdio_buffer, len);
  }

  if (event_type &
      (Process::eBroadcastBitSTDERR | Process::eBroadcastBitStateChanged)) {
    // Drain stderr when we stop just in case we have any bytes
    while ((len = process.GetSTDERR(stdio_buffer, sizeof(stdio_buffer))) > 0)
      if (err_sp)
        err_sp->Write(stdio_buffer, len);
  }

  if (event_type & Process::eBroadcastBitStateChanged) {
    StateType event_state = SBProcess::GetStateFromEvent(event);

    if (event_state == eStateInvalid)
      return;

    bool is_stopped = StateIsStoppedState(event_state);
    if (!is_stopped)
      process.ReportEventState(event, out_sp);
  }
}

SBSourceManager SBDebugger::GetSourceManager() {
  LLDB_RECORD_METHOD_NO_ARGS(lldb::SBSourceManager, SBDebugger,
                             GetSourceManager);

  SBSourceManager sb_source_manager(*this);
  return LLDB_RECORD_RESULT(sb_source_manager);
}

bool SBDebugger::GetDefaultArchitecture(char *arch_name, size_t arch_name_len) {
  LLDB_RECORD_STATIC_METHOD(bool, SBDebugger, GetDefaultArchitecture,
                            (char *, size_t), "", arch_name_len);

  if (arch_name && arch_name_len) {
    ArchSpec default_arch = Target::GetDefaultArchitecture();

    if (default_arch.IsValid()) {
      const std::string &triple_str = default_arch.GetTriple().str();
      if (!triple_str.empty())
        ::snprintf(arch_name, arch_name_len, "%s", triple_str.c_str());
      else
        ::snprintf(arch_name, arch_name_len, "%s",
                   default_arch.GetArchitectureName());
      return true;
    }
  }
  if (arch_name && arch_name_len)
    arch_name[0] = '\0';
  return false;
}

bool SBDebugger::SetDefaultArchitecture(const char *arch_name) {
  LLDB_RECORD_STATIC_METHOD(bool, SBDebugger, SetDefaultArchitecture,
                            (const char *), arch_name);

  if (arch_name) {
    ArchSpec arch(arch_name);
    if (arch.IsValid()) {
      Target::SetDefaultArchitecture(arch);
      return true;
    }
  }
  return false;
}

ScriptLanguage
SBDebugger::GetScriptingLanguage(const char *script_language_name) {
  LLDB_RECORD_METHOD(lldb::ScriptLanguage, SBDebugger, GetScriptingLanguage,
                     (const char *), script_language_name);

  if (!script_language_name)
    return eScriptLanguageDefault;
  return OptionArgParser::ToScriptLanguage(
      llvm::StringRef(script_language_name), eScriptLanguageDefault, nullptr);
}

const char *SBDebugger::GetVersionString() {
  LLDB_RECORD_STATIC_METHOD_NO_ARGS(const char *, SBDebugger, GetVersionString);

  return lldb_private::GetVersion();
}

const char *SBDebugger::StateAsCString(StateType state) {
  LLDB_RECORD_STATIC_METHOD(const char *, SBDebugger, StateAsCString,
                            (lldb::StateType), state);

  return lldb_private::StateAsCString(state);
}

static void AddBoolConfigEntry(StructuredData::Dictionary &dict,
                               llvm::StringRef name, bool value,
                               llvm::StringRef description) {
  auto entry_up = std::make_unique<StructuredData::Dictionary>();
  entry_up->AddBooleanItem("value", value);
  entry_up->AddStringItem("description", description);
  dict.AddItem(name, std::move(entry_up));
}

static void AddLLVMTargets(StructuredData::Dictionary &dict) {
  auto array_up = std::make_unique<StructuredData::Array>();
#define LLVM_TARGET(target)                                                    \
  array_up->AddItem(std::make_unique<StructuredData::String>(#target));
#include "llvm/Config/Targets.def"
  auto entry_up = std::make_unique<StructuredData::Dictionary>();
  entry_up->AddItem("value", std::move(array_up));
  entry_up->AddStringItem("description", "A list of configured LLVM targets.");
  dict.AddItem("targets", std::move(entry_up));
}

SBStructuredData SBDebugger::GetBuildConfiguration() {
  LLDB_RECORD_STATIC_METHOD_NO_ARGS(lldb::SBStructuredData, SBDebugger,
                                    GetBuildConfiguration);

  auto config_up = std::make_unique<StructuredData::Dictionary>();
  AddBoolConfigEntry(
      *config_up, "xml", XMLDocument::XMLEnabled(),
      "A boolean value that indicates if XML support is enabled in LLDB");
  AddBoolConfigEntry(
      *config_up, "curses", LLDB_ENABLE_CURSES,
      "A boolean value that indicates if curses support is enabled in LLDB");
  AddBoolConfigEntry(
      *config_up, "editline", LLDB_ENABLE_LIBEDIT,
      "A boolean value that indicates if editline support is enabled in LLDB");
  AddBoolConfigEntry(
      *config_up, "lzma", LLDB_ENABLE_LZMA,
      "A boolean value that indicates if lzma support is enabled in LLDB");
  AddBoolConfigEntry(
      *config_up, "python", LLDB_ENABLE_PYTHON,
      "A boolean value that indicates if python support is enabled in LLDB");
  AddBoolConfigEntry(
      *config_up, "lua", LLDB_ENABLE_LUA,
      "A boolean value that indicates if lua support is enabled in LLDB");
  AddLLVMTargets(*config_up);

  SBStructuredData data;
  data.m_impl_up->SetObjectSP(std::move(config_up));
  return LLDB_RECORD_RESULT(data);
}

bool SBDebugger::StateIsRunningState(StateType state) {
  LLDB_RECORD_STATIC_METHOD(bool, SBDebugger, StateIsRunningState,
                            (lldb::StateType), state);

  const bool result = lldb_private::StateIsRunningState(state);

  return result;
}

bool SBDebugger::StateIsStoppedState(StateType state) {
  LLDB_RECORD_STATIC_METHOD(bool, SBDebugger, StateIsStoppedState,
                            (lldb::StateType), state);

  const bool result = lldb_private::StateIsStoppedState(state, false);

  return result;
}

lldb::SBTarget SBDebugger::CreateTarget(const char *filename,
                                        const char *target_triple,
                                        const char *platform_name,
                                        bool add_dependent_modules,
                                        lldb::SBError &sb_error) {
  LLDB_RECORD_METHOD(
      lldb::SBTarget, SBDebugger, CreateTarget,
      (const char *, const char *, const char *, bool, lldb::SBError &),
      filename, target_triple, platform_name, add_dependent_modules, sb_error);

  SBTarget sb_target;
  TargetSP target_sp;
  if (m_opaque_sp) {
    sb_error.Clear();
    OptionGroupPlatform platform_options(false);
    platform_options.SetPlatformName(platform_name);

    sb_error.ref() = m_opaque_sp->GetTargetList().CreateTarget(
        *m_opaque_sp, filename, target_triple,
        add_dependent_modules ? eLoadDependentsYes : eLoadDependentsNo,
        &platform_options, target_sp);

    if (sb_error.Success())
      sb_target.SetSP(target_sp);
  } else {
    sb_error.SetErrorString("invalid debugger");
  }

  Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
  LLDB_LOGF(log,
            "SBDebugger(%p)::CreateTarget (filename=\"%s\", triple=%s, "
            "platform_name=%s, add_dependent_modules=%u, error=%s) => "
            "SBTarget(%p)",
            static_cast<void *>(m_opaque_sp.get()), filename, target_triple,
            platform_name, add_dependent_modules, sb_error.GetCString(),
            static_cast<void *>(target_sp.get()));

  return LLDB_RECORD_RESULT(sb_target);
}

SBTarget
SBDebugger::CreateTargetWithFileAndTargetTriple(const char *filename,
                                                const char *target_triple) {
  LLDB_RECORD_METHOD(lldb::SBTarget, SBDebugger,
                     CreateTargetWithFileAndTargetTriple,
                     (const char *, const char *), filename, target_triple);

  SBTarget sb_target;
  TargetSP target_sp;
  if (m_opaque_sp) {
    const bool add_dependent_modules = true;
    Status error(m_opaque_sp->GetTargetList().CreateTarget(
        *m_opaque_sp, filename, target_triple,
        add_dependent_modules ? eLoadDependentsYes : eLoadDependentsNo, nullptr,
        target_sp));
    sb_target.SetSP(target_sp);
  }

  Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
  LLDB_LOGF(log,
            "SBDebugger(%p)::CreateTargetWithFileAndTargetTriple "
            "(filename=\"%s\", triple=%s) => SBTarget(%p)",
            static_cast<void *>(m_opaque_sp.get()), filename, target_triple,
            static_cast<void *>(target_sp.get()));

  return LLDB_RECORD_RESULT(sb_target);
}

SBTarget SBDebugger::CreateTargetWithFileAndArch(const char *filename,
                                                 const char *arch_cstr) {
  LLDB_RECORD_METHOD(lldb::SBTarget, SBDebugger, CreateTargetWithFileAndArch,
                     (const char *, const char *), filename, arch_cstr);

  Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));

  SBTarget sb_target;
  TargetSP target_sp;
  if (m_opaque_sp) {
    Status error;
    const bool add_dependent_modules = true;

    error = m_opaque_sp->GetTargetList().CreateTarget(
        *m_opaque_sp, filename, arch_cstr,
        add_dependent_modules ? eLoadDependentsYes : eLoadDependentsNo, nullptr,
        target_sp);

    if (error.Success()) {
      m_opaque_sp->GetTargetList().SetSelectedTarget(target_sp.get());
      sb_target.SetSP(target_sp);
    }
  }

  LLDB_LOGF(log,
            "SBDebugger(%p)::CreateTargetWithFileAndArch (filename=\"%s\", "
            "arch=%s) => SBTarget(%p)",
            static_cast<void *>(m_opaque_sp.get()), filename, arch_cstr,
            static_cast<void *>(target_sp.get()));

  return LLDB_RECORD_RESULT(sb_target);
}

SBTarget SBDebugger::CreateTarget(const char *filename) {
  LLDB_RECORD_METHOD(lldb::SBTarget, SBDebugger, CreateTarget, (const char *),
                     filename);

  SBTarget sb_target;
  TargetSP target_sp;
  if (m_opaque_sp) {
    Status error;
    const bool add_dependent_modules = true;
    error = m_opaque_sp->GetTargetList().CreateTarget(
        *m_opaque_sp, filename, "",
        add_dependent_modules ? eLoadDependentsYes : eLoadDependentsNo, nullptr,
        target_sp);

    if (error.Success()) {
      m_opaque_sp->GetTargetList().SetSelectedTarget(target_sp.get());
      sb_target.SetSP(target_sp);
    }
  }
  Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
  LLDB_LOGF(log,
            "SBDebugger(%p)::CreateTarget (filename=\"%s\") => SBTarget(%p)",
            static_cast<void *>(m_opaque_sp.get()), filename,
            static_cast<void *>(target_sp.get()));
  return LLDB_RECORD_RESULT(sb_target);
}

SBTarget SBDebugger::GetDummyTarget() {
  LLDB_RECORD_METHOD_NO_ARGS(lldb::SBTarget, SBDebugger, GetDummyTarget);

  SBTarget sb_target;
  if (m_opaque_sp) {
    sb_target.SetSP(m_opaque_sp->GetDummyTarget()->shared_from_this());
  }
  Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
  LLDB_LOGF(log, "SBDebugger(%p)::GetDummyTarget() => SBTarget(%p)",
            static_cast<void *>(m_opaque_sp.get()),
            static_cast<void *>(sb_target.GetSP().get()));
  return LLDB_RECORD_RESULT(sb_target);
}

bool SBDebugger::DeleteTarget(lldb::SBTarget &target) {
  LLDB_RECORD_METHOD(bool, SBDebugger, DeleteTarget, (lldb::SBTarget &),
                     target);

  bool result = false;
  if (m_opaque_sp) {
    TargetSP target_sp(target.GetSP());
    if (target_sp) {
      // No need to lock, the target list is thread safe
      result = m_opaque_sp->GetTargetList().DeleteTarget(target_sp);
      target_sp->Destroy();
      target.Clear();
      const bool mandatory = true;
      ModuleList::RemoveOrphanSharedModules(mandatory);
    }
  }

  Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
  LLDB_LOGF(log, "SBDebugger(%p)::DeleteTarget (SBTarget(%p)) => %i",
            static_cast<void *>(m_opaque_sp.get()),
            static_cast<void *>(target.m_opaque_sp.get()), result);

  return result;
}

SBTarget SBDebugger::GetTargetAtIndex(uint32_t idx) {
  LLDB_RECORD_METHOD(lldb::SBTarget, SBDebugger, GetTargetAtIndex, (uint32_t),
                     idx);

  SBTarget sb_target;
  if (m_opaque_sp) {
    // No need to lock, the target list is thread safe
    sb_target.SetSP(m_opaque_sp->GetTargetList().GetTargetAtIndex(idx));
  }
  return LLDB_RECORD_RESULT(sb_target);
}

uint32_t SBDebugger::GetIndexOfTarget(lldb::SBTarget target) {
  LLDB_RECORD_METHOD(uint32_t, SBDebugger, GetIndexOfTarget, (lldb::SBTarget),
                     target);

  lldb::TargetSP target_sp = target.GetSP();
  if (!target_sp)
    return UINT32_MAX;

  if (!m_opaque_sp)
    return UINT32_MAX;

  return m_opaque_sp->GetTargetList().GetIndexOfTarget(target.GetSP());
}

SBTarget SBDebugger::FindTargetWithProcessID(lldb::pid_t pid) {
  LLDB_RECORD_METHOD(lldb::SBTarget, SBDebugger, FindTargetWithProcessID,
                     (lldb::pid_t), pid);

  SBTarget sb_target;
  if (m_opaque_sp) {
    // No need to lock, the target list is thread safe
    sb_target.SetSP(m_opaque_sp->GetTargetList().FindTargetWithProcessID(pid));
  }
  return LLDB_RECORD_RESULT(sb_target);
}

SBTarget SBDebugger::FindTargetWithFileAndArch(const char *filename,
                                               const char *arch_name) {
  LLDB_RECORD_METHOD(lldb::SBTarget, SBDebugger, FindTargetWithFileAndArch,
                     (const char *, const char *), filename, arch_name);

  SBTarget sb_target;
  if (m_opaque_sp && filename && filename[0]) {
    // No need to lock, the target list is thread safe
    ArchSpec arch = Platform::GetAugmentedArchSpec(
        m_opaque_sp->GetPlatformList().GetSelectedPlatform().get(), arch_name);
    TargetSP target_sp(
        m_opaque_sp->GetTargetList().FindTargetWithExecutableAndArchitecture(
            FileSpec(filename), arch_name ? &arch : nullptr));
    sb_target.SetSP(target_sp);
  }
  return LLDB_RECORD_RESULT(sb_target);
}

SBTarget SBDebugger::FindTargetWithLLDBProcess(const ProcessSP &process_sp) {
  SBTarget sb_target;
  if (m_opaque_sp) {
    // No need to lock, the target list is thread safe
    sb_target.SetSP(
        m_opaque_sp->GetTargetList().FindTargetWithProcess(process_sp.get()));
  }
  return sb_target;
}

uint32_t SBDebugger::GetNumTargets() {
  LLDB_RECORD_METHOD_NO_ARGS(uint32_t, SBDebugger, GetNumTargets);

  if (m_opaque_sp) {
    // No need to lock, the target list is thread safe
    return m_opaque_sp->GetTargetList().GetNumTargets();
  }
  return 0;
}

SBTarget SBDebugger::GetSelectedTarget() {
  LLDB_RECORD_METHOD_NO_ARGS(lldb::SBTarget, SBDebugger, GetSelectedTarget);

  Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));

  SBTarget sb_target;
  TargetSP target_sp;
  if (m_opaque_sp) {
    // No need to lock, the target list is thread safe
    target_sp = m_opaque_sp->GetTargetList().GetSelectedTarget();
    sb_target.SetSP(target_sp);
  }

  if (log) {
    SBStream sstr;
    sb_target.GetDescription(sstr, eDescriptionLevelBrief);
    LLDB_LOGF(log, "SBDebugger(%p)::GetSelectedTarget () => SBTarget(%p): %s",
              static_cast<void *>(m_opaque_sp.get()),
              static_cast<void *>(target_sp.get()), sstr.GetData());
  }

  return LLDB_RECORD_RESULT(sb_target);
}

void SBDebugger::SetSelectedTarget(SBTarget &sb_target) {
  LLDB_RECORD_METHOD(void, SBDebugger, SetSelectedTarget, (lldb::SBTarget &),
                     sb_target);

  Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));

  TargetSP target_sp(sb_target.GetSP());
  if (m_opaque_sp) {
    m_opaque_sp->GetTargetList().SetSelectedTarget(target_sp.get());
  }
  if (log) {
    SBStream sstr;
    sb_target.GetDescription(sstr, eDescriptionLevelBrief);
    LLDB_LOGF(log, "SBDebugger(%p)::SetSelectedTarget () => SBTarget(%p): %s",
              static_cast<void *>(m_opaque_sp.get()),
              static_cast<void *>(target_sp.get()), sstr.GetData());
  }
}

SBPlatform SBDebugger::GetSelectedPlatform() {
  LLDB_RECORD_METHOD_NO_ARGS(lldb::SBPlatform, SBDebugger, GetSelectedPlatform);

  Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));

  SBPlatform sb_platform;
  DebuggerSP debugger_sp(m_opaque_sp);
  if (debugger_sp) {
    sb_platform.SetSP(debugger_sp->GetPlatformList().GetSelectedPlatform());
  }
  LLDB_LOGF(log, "SBDebugger(%p)::GetSelectedPlatform () => SBPlatform(%p): %s",
            static_cast<void *>(m_opaque_sp.get()),
            static_cast<void *>(sb_platform.GetSP().get()),
            sb_platform.GetName());
  return LLDB_RECORD_RESULT(sb_platform);
}

void SBDebugger::SetSelectedPlatform(SBPlatform &sb_platform) {
  LLDB_RECORD_METHOD(void, SBDebugger, SetSelectedPlatform,
                     (lldb::SBPlatform &), sb_platform);

  Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));

  DebuggerSP debugger_sp(m_opaque_sp);
  if (debugger_sp) {
    debugger_sp->GetPlatformList().SetSelectedPlatform(sb_platform.GetSP());
  }

  LLDB_LOGF(log, "SBDebugger(%p)::SetSelectedPlatform (SBPlatform(%p) %s)",
            static_cast<void *>(m_opaque_sp.get()),
            static_cast<void *>(sb_platform.GetSP().get()),
            sb_platform.GetName());
}

uint32_t SBDebugger::GetNumPlatforms() {
  LLDB_RECORD_METHOD_NO_ARGS(uint32_t, SBDebugger, GetNumPlatforms);

  if (m_opaque_sp) {
    // No need to lock, the platform list is thread safe
    return m_opaque_sp->GetPlatformList().GetSize();
  }
  return 0;
}

SBPlatform SBDebugger::GetPlatformAtIndex(uint32_t idx) {
  LLDB_RECORD_METHOD(lldb::SBPlatform, SBDebugger, GetPlatformAtIndex,
                     (uint32_t), idx);

  SBPlatform sb_platform;
  if (m_opaque_sp) {
    // No need to lock, the platform list is thread safe
    sb_platform.SetSP(m_opaque_sp->GetPlatformList().GetAtIndex(idx));
  }
  return LLDB_RECORD_RESULT(sb_platform);
}

uint32_t SBDebugger::GetNumAvailablePlatforms() {
  LLDB_RECORD_METHOD_NO_ARGS(uint32_t, SBDebugger, GetNumAvailablePlatforms);

  uint32_t idx = 0;
  while (true) {
    if (!PluginManager::GetPlatformPluginNameAtIndex(idx)) {
      break;
    }
    ++idx;
  }
  // +1 for the host platform, which should always appear first in the list.
  return idx + 1;
}

SBStructuredData SBDebugger::GetAvailablePlatformInfoAtIndex(uint32_t idx) {
  LLDB_RECORD_METHOD(lldb::SBStructuredData, SBDebugger,
                     GetAvailablePlatformInfoAtIndex, (uint32_t), idx);

  SBStructuredData data;
  auto platform_dict = std::make_unique<StructuredData::Dictionary>();
  llvm::StringRef name_str("name"), desc_str("description");

  if (idx == 0) {
    PlatformSP host_platform_sp(Platform::GetHostPlatform());
    platform_dict->AddStringItem(
        name_str, host_platform_sp->GetPluginName().GetStringRef());
    platform_dict->AddStringItem(
        desc_str, llvm::StringRef(host_platform_sp->GetDescription()));
  } else if (idx > 0) {
    const char *plugin_name =
        PluginManager::GetPlatformPluginNameAtIndex(idx - 1);
    if (!plugin_name) {
      return LLDB_RECORD_RESULT(data);
    }
    platform_dict->AddStringItem(name_str, llvm::StringRef(plugin_name));

    const char *plugin_desc =
        PluginManager::GetPlatformPluginDescriptionAtIndex(idx - 1);
    if (!plugin_desc) {
      return LLDB_RECORD_RESULT(data);
    }
    platform_dict->AddStringItem(desc_str, llvm::StringRef(plugin_desc));
  }

  data.m_impl_up->SetObjectSP(
      StructuredData::ObjectSP(platform_dict.release()));
  return LLDB_RECORD_RESULT(data);
}

void SBDebugger::DispatchInput(void *baton, const void *data, size_t data_len) {
  LLDB_RECORD_DUMMY(void, SBDebugger, DispatchInput,
                    (void *, const void *, size_t), baton, data, data_len);

  DispatchInput(data, data_len);
}

void SBDebugger::DispatchInput(const void *data, size_t data_len) {
  LLDB_RECORD_DUMMY(void, SBDebugger, DispatchInput, (const void *, size_t),
                    data, data_len);

  //    Log *log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
  //
  //    if (log)
  //        LLDB_LOGF(log, "SBDebugger(%p)::DispatchInput (data=\"%.*s\",
  //        size_t=%" PRIu64 ")",
  //                     m_opaque_sp.get(),
  //                     (int) data_len,
  //                     (const char *) data,
  //                     (uint64_t)data_len);
  //
  //    if (m_opaque_sp)
  //        m_opaque_sp->DispatchInput ((const char *) data, data_len);
}

void SBDebugger::DispatchInputInterrupt() {
  LLDB_RECORD_DUMMY_NO_ARGS(void, SBDebugger, DispatchInputInterrupt);

  if (m_opaque_sp)
    m_opaque_sp->DispatchInputInterrupt();
}

void SBDebugger::DispatchInputEndOfFile() {
  LLDB_RECORD_METHOD_NO_ARGS(void, SBDebugger, DispatchInputEndOfFile);

  if (m_opaque_sp)
    m_opaque_sp->DispatchInputEndOfFile();
}

void SBDebugger::PushInputReader(SBInputReader &reader) {
  LLDB_RECORD_METHOD(void, SBDebugger, PushInputReader, (lldb::SBInputReader &),
                     reader);
}

void SBDebugger::RunCommandInterpreter(bool auto_handle_events,
                                       bool spawn_thread) {
  LLDB_RECORD_METHOD(void, SBDebugger, RunCommandInterpreter, (bool, bool),
                     auto_handle_events, spawn_thread);

  if (m_opaque_sp) {
    CommandInterpreterRunOptions options;

    m_opaque_sp->GetCommandInterpreter().RunCommandInterpreter(
        auto_handle_events, spawn_thread, options);
  }
}

void SBDebugger::RunCommandInterpreter(bool auto_handle_events,
                                       bool spawn_thread,
                                       SBCommandInterpreterRunOptions &options,
                                       int &num_errors, bool &quit_requested,
                                       bool &stopped_for_crash)

{
  LLDB_RECORD_METHOD(void, SBDebugger, RunCommandInterpreter,
                     (bool, bool, lldb::SBCommandInterpreterRunOptions &, int &,
                      bool &, bool &),
                     auto_handle_events, spawn_thread, options, num_errors,
                     quit_requested, stopped_for_crash);

  if (m_opaque_sp) {
    CommandInterpreter &interp = m_opaque_sp->GetCommandInterpreter();
    interp.RunCommandInterpreter(auto_handle_events, spawn_thread,
                                 options.ref());
    num_errors = interp.GetNumErrors();
    quit_requested = interp.GetQuitRequested();
    stopped_for_crash = interp.GetStoppedForCrash();
  }
}

SBError SBDebugger::RunREPL(lldb::LanguageType language,
                            const char *repl_options) {
  LLDB_RECORD_METHOD(lldb::SBError, SBDebugger, RunREPL,
                     (lldb::LanguageType, const char *), language,
                     repl_options);

  SBError error;
  if (m_opaque_sp)
    error.ref() = m_opaque_sp->RunREPL(language, repl_options);
  else
    error.SetErrorString("invalid debugger");
  return LLDB_RECORD_RESULT(error);
}

void SBDebugger::reset(const DebuggerSP &debugger_sp) {
  m_opaque_sp = debugger_sp;
}

Debugger *SBDebugger::get() const { return m_opaque_sp.get(); }

Debugger &SBDebugger::ref() const {
  assert(m_opaque_sp.get());
  return *m_opaque_sp;
}

const lldb::DebuggerSP &SBDebugger::get_sp() const { return m_opaque_sp; }

SBDebugger SBDebugger::FindDebuggerWithID(int id) {
  LLDB_RECORD_STATIC_METHOD(lldb::SBDebugger, SBDebugger, FindDebuggerWithID,
                            (int), id);

  // No need to lock, the debugger list is thread safe
  SBDebugger sb_debugger;
  DebuggerSP debugger_sp = Debugger::FindDebuggerWithID(id);
  if (debugger_sp)
    sb_debugger.reset(debugger_sp);
  return LLDB_RECORD_RESULT(sb_debugger);
}

const char *SBDebugger::GetInstanceName() {
  LLDB_RECORD_METHOD_NO_ARGS(const char *, SBDebugger, GetInstanceName);

  return (m_opaque_sp ? m_opaque_sp->GetInstanceName().AsCString() : nullptr);
}

SBError SBDebugger::SetInternalVariable(const char *var_name, const char *value,
                                        const char *debugger_instance_name) {
  LLDB_RECORD_STATIC_METHOD(lldb::SBError, SBDebugger, SetInternalVariable,
                            (const char *, const char *, const char *),
                            var_name, value, debugger_instance_name);

  SBError sb_error;
  DebuggerSP debugger_sp(Debugger::FindDebuggerWithInstanceName(
      ConstString(debugger_instance_name)));
  Status error;
  if (debugger_sp) {
    ExecutionContext exe_ctx(
        debugger_sp->GetCommandInterpreter().GetExecutionContext());
    error = debugger_sp->SetPropertyValue(&exe_ctx, eVarSetOperationAssign,
                                          var_name, value);
  } else {
    error.SetErrorStringWithFormat("invalid debugger instance name '%s'",
                                   debugger_instance_name);
  }
  if (error.Fail())
    sb_error.SetError(error);
  return LLDB_RECORD_RESULT(sb_error);
}

SBStringList
SBDebugger::GetInternalVariableValue(const char *var_name,
                                     const char *debugger_instance_name) {
  LLDB_RECORD_STATIC_METHOD(
      lldb::SBStringList, SBDebugger, GetInternalVariableValue,
      (const char *, const char *), var_name, debugger_instance_name);

  SBStringList ret_value;
  DebuggerSP debugger_sp(Debugger::FindDebuggerWithInstanceName(
      ConstString(debugger_instance_name)));
  Status error;
  if (debugger_sp) {
    ExecutionContext exe_ctx(
        debugger_sp->GetCommandInterpreter().GetExecutionContext());
    lldb::OptionValueSP value_sp(
        debugger_sp->GetPropertyValue(&exe_ctx, var_name, false, error));
    if (value_sp) {
      StreamString value_strm;
      value_sp->DumpValue(&exe_ctx, value_strm, OptionValue::eDumpOptionValue);
      const std::string &value_str = value_strm.GetString();
      if (!value_str.empty()) {
        StringList string_list;
        string_list.SplitIntoLines(value_str);
        return LLDB_RECORD_RESULT(SBStringList(&string_list));
      }
    }
  }
  return LLDB_RECORD_RESULT(SBStringList());
}

uint32_t SBDebugger::GetTerminalWidth() const {
  LLDB_RECORD_METHOD_CONST_NO_ARGS(uint32_t, SBDebugger, GetTerminalWidth);

  return (m_opaque_sp ? m_opaque_sp->GetTerminalWidth() : 0);
}

void SBDebugger::SetTerminalWidth(uint32_t term_width) {
  LLDB_RECORD_DUMMY(void, SBDebugger, SetTerminalWidth, (uint32_t), term_width);

  if (m_opaque_sp)
    m_opaque_sp->SetTerminalWidth(term_width);
}

const char *SBDebugger::GetPrompt() const {
  LLDB_RECORD_METHOD_CONST_NO_ARGS(const char *, SBDebugger, GetPrompt);

  Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));

  LLDB_LOGF(log, "SBDebugger(%p)::GetPrompt () => \"%s\"",
            static_cast<void *>(m_opaque_sp.get()),
            (m_opaque_sp ? m_opaque_sp->GetPrompt().str().c_str() : ""));

  return (m_opaque_sp ? ConstString(m_opaque_sp->GetPrompt()).GetCString()
                      : nullptr);
}

void SBDebugger::SetPrompt(const char *prompt) {
  LLDB_RECORD_METHOD(void, SBDebugger, SetPrompt, (const char *), prompt);

  if (m_opaque_sp)
    m_opaque_sp->SetPrompt(llvm::StringRef::withNullAsEmpty(prompt));
}

const char *SBDebugger::GetReproducerPath() const {
  LLDB_RECORD_METHOD_CONST_NO_ARGS(const char *, SBDebugger, GetReproducerPath);

  return (m_opaque_sp
              ? ConstString(m_opaque_sp->GetReproducerPath()).GetCString()
              : nullptr);
}

ScriptLanguage SBDebugger::GetScriptLanguage() const {
  LLDB_RECORD_METHOD_CONST_NO_ARGS(lldb::ScriptLanguage, SBDebugger,
                                   GetScriptLanguage);

  return (m_opaque_sp ? m_opaque_sp->GetScriptLanguage() : eScriptLanguageNone);
}

void SBDebugger::SetScriptLanguage(ScriptLanguage script_lang) {
  LLDB_RECORD_METHOD(void, SBDebugger, SetScriptLanguage,
                     (lldb::ScriptLanguage), script_lang);

  if (m_opaque_sp) {
    m_opaque_sp->SetScriptLanguage(script_lang);
  }
}

bool SBDebugger::SetUseExternalEditor(bool value) {
  LLDB_RECORD_METHOD(bool, SBDebugger, SetUseExternalEditor, (bool), value);

  return (m_opaque_sp ? m_opaque_sp->SetUseExternalEditor(value) : false);
}

bool SBDebugger::GetUseExternalEditor() {
  LLDB_RECORD_METHOD_NO_ARGS(bool, SBDebugger, GetUseExternalEditor);

  return (m_opaque_sp ? m_opaque_sp->GetUseExternalEditor() : false);
}

bool SBDebugger::SetUseColor(bool value) {
  LLDB_RECORD_METHOD(bool, SBDebugger, SetUseColor, (bool), value);

  return (m_opaque_sp ? m_opaque_sp->SetUseColor(value) : false);
}

bool SBDebugger::GetUseColor() const {
  LLDB_RECORD_METHOD_CONST_NO_ARGS(bool, SBDebugger, GetUseColor);

  return (m_opaque_sp ? m_opaque_sp->GetUseColor() : false);
}

bool SBDebugger::GetDescription(SBStream &description) {
  LLDB_RECORD_METHOD(bool, SBDebugger, GetDescription, (lldb::SBStream &),
                     description);

  Stream &strm = description.ref();

  if (m_opaque_sp) {
    const char *name = m_opaque_sp->GetInstanceName().AsCString();
    user_id_t id = m_opaque_sp->GetID();
    strm.Printf("Debugger (instance: \"%s\", id: %" PRIu64 ")", name, id);
  } else
    strm.PutCString("No value");

  return true;
}

user_id_t SBDebugger::GetID() {
  LLDB_RECORD_METHOD_NO_ARGS(lldb::user_id_t, SBDebugger, GetID);

  return (m_opaque_sp ? m_opaque_sp->GetID() : LLDB_INVALID_UID);
}

SBError SBDebugger::SetCurrentPlatform(const char *platform_name_cstr) {
  LLDB_RECORD_METHOD(lldb::SBError, SBDebugger, SetCurrentPlatform,
                     (const char *), platform_name_cstr);

  SBError sb_error;
  if (m_opaque_sp) {
    if (platform_name_cstr && platform_name_cstr[0]) {
      ConstString platform_name(platform_name_cstr);
      PlatformSP platform_sp(Platform::Find(platform_name));

      if (platform_sp) {
        // Already have a platform with this name, just select it
        m_opaque_sp->GetPlatformList().SetSelectedPlatform(platform_sp);
      } else {
        // We don't have a platform by this name yet, create one
        platform_sp = Platform::Create(platform_name, sb_error.ref());
        if (platform_sp) {
          // We created the platform, now append and select it
          bool make_selected = true;
          m_opaque_sp->GetPlatformList().Append(platform_sp, make_selected);
        }
      }
    } else {
      sb_error.ref().SetErrorString("invalid platform name");
    }
  } else {
    sb_error.ref().SetErrorString("invalid debugger");
  }
  return LLDB_RECORD_RESULT(sb_error);
}

bool SBDebugger::SetCurrentPlatformSDKRoot(const char *sysroot) {
  LLDB_RECORD_METHOD(bool, SBDebugger, SetCurrentPlatformSDKRoot,
                     (const char *), sysroot);

  Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
  if (m_opaque_sp) {
    PlatformSP platform_sp(
        m_opaque_sp->GetPlatformList().GetSelectedPlatform());

    if (platform_sp) {
      if (log && sysroot)
        LLDB_LOGF(log, "SBDebugger::SetCurrentPlatformSDKRoot (\"%s\")",
                  sysroot);
      platform_sp->SetSDKRootDirectory(ConstString(sysroot));
      return true;
    }
  }
  return false;
}

bool SBDebugger::GetCloseInputOnEOF() const {
  LLDB_RECORD_METHOD_CONST_NO_ARGS(bool, SBDebugger, GetCloseInputOnEOF);

  return (m_opaque_sp ? m_opaque_sp->GetCloseInputOnEOF() : false);
}

void SBDebugger::SetCloseInputOnEOF(bool b) {
  LLDB_RECORD_METHOD(void, SBDebugger, SetCloseInputOnEOF, (bool), b);

  if (m_opaque_sp)
    m_opaque_sp->SetCloseInputOnEOF(b);
}

SBTypeCategory SBDebugger::GetCategory(const char *category_name) {
  LLDB_RECORD_METHOD(lldb::SBTypeCategory, SBDebugger, GetCategory,
                     (const char *), category_name);

  if (!category_name || *category_name == 0)
    return LLDB_RECORD_RESULT(SBTypeCategory());

  TypeCategoryImplSP category_sp;

  if (DataVisualization::Categories::GetCategory(ConstString(category_name),
                                                 category_sp, false)) {
    return LLDB_RECORD_RESULT(SBTypeCategory(category_sp));
  } else {
    return LLDB_RECORD_RESULT(SBTypeCategory());
  }
}

SBTypeCategory SBDebugger::GetCategory(lldb::LanguageType lang_type) {
  LLDB_RECORD_METHOD(lldb::SBTypeCategory, SBDebugger, GetCategory,
                     (lldb::LanguageType), lang_type);

  TypeCategoryImplSP category_sp;
  if (DataVisualization::Categories::GetCategory(lang_type, category_sp)) {
    return LLDB_RECORD_RESULT(SBTypeCategory(category_sp));
  } else {
    return LLDB_RECORD_RESULT(SBTypeCategory());
  }
}

SBTypeCategory SBDebugger::CreateCategory(const char *category_name) {
  LLDB_RECORD_METHOD(lldb::SBTypeCategory, SBDebugger, CreateCategory,
                     (const char *), category_name);

  if (!category_name || *category_name == 0)
    return LLDB_RECORD_RESULT(SBTypeCategory());

  TypeCategoryImplSP category_sp;

  if (DataVisualization::Categories::GetCategory(ConstString(category_name),
                                                 category_sp, true)) {
    return LLDB_RECORD_RESULT(SBTypeCategory(category_sp));
  } else {
    return LLDB_RECORD_RESULT(SBTypeCategory());
  }
}

bool SBDebugger::DeleteCategory(const char *category_name) {
  LLDB_RECORD_METHOD(bool, SBDebugger, DeleteCategory, (const char *),
                     category_name);

  if (!category_name || *category_name == 0)
    return false;

  return DataVisualization::Categories::Delete(ConstString(category_name));
}

uint32_t SBDebugger::GetNumCategories() {
  LLDB_RECORD_METHOD_NO_ARGS(uint32_t, SBDebugger, GetNumCategories);

  return DataVisualization::Categories::GetCount();
}

SBTypeCategory SBDebugger::GetCategoryAtIndex(uint32_t index) {
  LLDB_RECORD_METHOD(lldb::SBTypeCategory, SBDebugger, GetCategoryAtIndex,
                     (uint32_t), index);

  return LLDB_RECORD_RESULT(
      SBTypeCategory(DataVisualization::Categories::GetCategoryAtIndex(index)));
}

SBTypeCategory SBDebugger::GetDefaultCategory() {
  LLDB_RECORD_METHOD_NO_ARGS(lldb::SBTypeCategory, SBDebugger,
                             GetDefaultCategory);

  return LLDB_RECORD_RESULT(GetCategory("default"));
}

SBTypeFormat SBDebugger::GetFormatForType(SBTypeNameSpecifier type_name) {
  LLDB_RECORD_METHOD(lldb::SBTypeFormat, SBDebugger, GetFormatForType,
                     (lldb::SBTypeNameSpecifier), type_name);

  SBTypeCategory default_category_sb = GetDefaultCategory();
  if (default_category_sb.GetEnabled())
    return LLDB_RECORD_RESULT(default_category_sb.GetFormatForType(type_name));
  return LLDB_RECORD_RESULT(SBTypeFormat());
}

SBTypeSummary SBDebugger::GetSummaryForType(SBTypeNameSpecifier type_name) {
  LLDB_RECORD_METHOD(lldb::SBTypeSummary, SBDebugger, GetSummaryForType,
                     (lldb::SBTypeNameSpecifier), type_name);

  if (!type_name.IsValid())
    return LLDB_RECORD_RESULT(SBTypeSummary());
  return LLDB_RECORD_RESULT(
      SBTypeSummary(DataVisualization::GetSummaryForType(type_name.GetSP())));
}

SBTypeFilter SBDebugger::GetFilterForType(SBTypeNameSpecifier type_name) {
  LLDB_RECORD_METHOD(lldb::SBTypeFilter, SBDebugger, GetFilterForType,
                     (lldb::SBTypeNameSpecifier), type_name);

  if (!type_name.IsValid())
    return LLDB_RECORD_RESULT(SBTypeFilter());
  return LLDB_RECORD_RESULT(
      SBTypeFilter(DataVisualization::GetFilterForType(type_name.GetSP())));
}

SBTypeSynthetic SBDebugger::GetSyntheticForType(SBTypeNameSpecifier type_name) {
  LLDB_RECORD_METHOD(lldb::SBTypeSynthetic, SBDebugger, GetSyntheticForType,
                     (lldb::SBTypeNameSpecifier), type_name);

  if (!type_name.IsValid())
    return LLDB_RECORD_RESULT(SBTypeSynthetic());
  return LLDB_RECORD_RESULT(SBTypeSynthetic(
      DataVisualization::GetSyntheticForType(type_name.GetSP())));
}

static llvm::ArrayRef<const char *> GetCategoryArray(const char **categories) {
  if (categories == nullptr)
    return {};
  size_t len = 0;
  while (categories[len] != nullptr)
    ++len;
  return llvm::makeArrayRef(categories, len);
}

bool SBDebugger::EnableLog(const char *channel, const char **categories) {
  LLDB_RECORD_METHOD(bool, SBDebugger, EnableLog, (const char *, const char **),
                     channel, categories);

  if (m_opaque_sp) {
    uint32_t log_options =
        LLDB_LOG_OPTION_PREPEND_TIMESTAMP | LLDB_LOG_OPTION_PREPEND_THREAD_NAME;
    std::string error;
    llvm::raw_string_ostream error_stream(error);
    return m_opaque_sp->EnableLog(channel, GetCategoryArray(categories), "",
                                  log_options, error_stream);
  } else
    return false;
}

void SBDebugger::SetLoggingCallback(lldb::LogOutputCallback log_callback,
                                    void *baton) {
  LLDB_RECORD_DUMMY(void, SBDebugger, SetLoggingCallback,
                    (lldb::LogOutputCallback, void *), log_callback, baton);

  if (m_opaque_sp) {
    return m_opaque_sp->SetLoggingCallback(log_callback, baton);
  }
}

namespace lldb_private {
namespace repro {

template <> void RegisterMethods<SBInputReader>(Registry &R) {
  LLDB_REGISTER_METHOD(void, SBInputReader, SetIsDone, (bool));
  LLDB_REGISTER_METHOD_CONST(bool, SBInputReader, IsActive, ());
}

static void SetFileHandleRedirect(SBDebugger *, FILE *, bool) {
  // Do nothing.
}

static SBError SetFileRedirect(SBDebugger *, SBFile file) { return SBError(); }

static SBError SetFileRedirect(SBDebugger *, FileSP file) { return SBError(); }

static bool GetDefaultArchitectureRedirect(char *arch_name,
                                           size_t arch_name_len) {
  // The function is writing to its argument. Without the redirect it would
  // write into the replay buffer.
  char buffer[1024];
  return SBDebugger::GetDefaultArchitecture(buffer, arch_name_len);
}

template <> void RegisterMethods<SBDebugger>(Registry &R) {
  // Custom implementation.
  R.Register(&invoke<void (SBDebugger::*)(
                 FILE *, bool)>::method<&SBDebugger::SetErrorFileHandle>::doit,
             &SetFileHandleRedirect);
  R.Register(&invoke<void (SBDebugger::*)(
                 FILE *, bool)>::method<&SBDebugger::SetOutputFileHandle>::doit,
             &SetFileHandleRedirect);
  R.Register<bool(char *, size_t)>(static_cast<bool (*)(char *, size_t)>(
                                       &SBDebugger::GetDefaultArchitecture),
                                   &GetDefaultArchitectureRedirect);

  R.Register(&invoke<SBError (SBDebugger::*)(
                 SBFile)>::method<&SBDebugger::SetInputFile>::doit,
             &SetFileRedirect);
  R.Register(&invoke<SBError (SBDebugger::*)(
                 SBFile)>::method<&SBDebugger::SetOutputFile>::doit,
             &SetFileRedirect);
  R.Register(&invoke<SBError (SBDebugger::*)(
                 SBFile)>::method<&SBDebugger::SetErrorFile>::doit,
             &SetFileRedirect);

  R.Register(&invoke<SBError (SBDebugger::*)(
                 FileSP)>::method<&SBDebugger::SetInputFile>::doit,
             &SetFileRedirect);
  R.Register(&invoke<SBError (SBDebugger::*)(
                 FileSP)>::method<&SBDebugger::SetOutputFile>::doit,
             &SetFileRedirect);
  R.Register(&invoke<SBError (SBDebugger::*)(
                 FileSP)>::method<&SBDebugger::SetErrorFile>::doit,
             &SetFileRedirect);

  LLDB_REGISTER_CONSTRUCTOR(SBDebugger, ());
  LLDB_REGISTER_CONSTRUCTOR(SBDebugger, (const lldb::DebuggerSP &));
  LLDB_REGISTER_CONSTRUCTOR(SBDebugger, (const lldb::SBDebugger &));
  LLDB_REGISTER_METHOD(lldb::SBDebugger &,
                       SBDebugger, operator=,(const lldb::SBDebugger &));
  LLDB_REGISTER_STATIC_METHOD(void, SBDebugger, Initialize, ());
  LLDB_REGISTER_STATIC_METHOD(lldb::SBError, SBDebugger,
                              InitializeWithErrorHandling, ());
  LLDB_REGISTER_STATIC_METHOD(void, SBDebugger, Terminate, ());
  LLDB_REGISTER_METHOD(void, SBDebugger, Clear, ());
  LLDB_REGISTER_STATIC_METHOD(lldb::SBDebugger, SBDebugger, Create, ());
  LLDB_REGISTER_STATIC_METHOD(lldb::SBDebugger, SBDebugger, Create, (bool));
  LLDB_REGISTER_STATIC_METHOD(void, SBDebugger, Destroy, (lldb::SBDebugger &));
  LLDB_REGISTER_STATIC_METHOD(void, SBDebugger, MemoryPressureDetected, ());
  LLDB_REGISTER_METHOD_CONST(bool, SBDebugger, IsValid, ());
  LLDB_REGISTER_METHOD_CONST(bool, SBDebugger, operator bool,());
  LLDB_REGISTER_METHOD(void, SBDebugger, SetAsync, (bool));
  LLDB_REGISTER_METHOD(bool, SBDebugger, GetAsync, ());
  LLDB_REGISTER_METHOD(void, SBDebugger, SkipLLDBInitFiles, (bool));
  LLDB_REGISTER_METHOD(void, SBDebugger, SkipAppInitFiles, (bool));
  LLDB_REGISTER_METHOD(void, SBDebugger, SetInputFileHandle, (FILE *, bool));
  LLDB_REGISTER_METHOD(FILE *, SBDebugger, GetInputFileHandle, ());
  LLDB_REGISTER_METHOD(FILE *, SBDebugger, GetOutputFileHandle, ());
  LLDB_REGISTER_METHOD(FILE *, SBDebugger, GetErrorFileHandle, ());
  LLDB_REGISTER_METHOD(SBFile, SBDebugger, GetInputFile, ());
  LLDB_REGISTER_METHOD(SBFile, SBDebugger, GetOutputFile, ());
  LLDB_REGISTER_METHOD(SBFile, SBDebugger, GetErrorFile, ());
  LLDB_REGISTER_METHOD(void, SBDebugger, SaveInputTerminalState, ());
  LLDB_REGISTER_METHOD(void, SBDebugger, RestoreInputTerminalState, ());
  LLDB_REGISTER_METHOD(lldb::SBCommandInterpreter, SBDebugger,
                       GetCommandInterpreter, ());
  LLDB_REGISTER_METHOD(void, SBDebugger, HandleCommand, (const char *));
  LLDB_REGISTER_METHOD(lldb::SBListener, SBDebugger, GetListener, ());
  LLDB_REGISTER_METHOD(
      void, SBDebugger, HandleProcessEvent,
      (const lldb::SBProcess &, const lldb::SBEvent &, FILE *, FILE *));
  LLDB_REGISTER_METHOD(
      void, SBDebugger, HandleProcessEvent,
      (const lldb::SBProcess &, const lldb::SBEvent &, SBFile, SBFile));
  LLDB_REGISTER_METHOD(
      void, SBDebugger, HandleProcessEvent,
      (const lldb::SBProcess &, const lldb::SBEvent &, FileSP, FileSP));
  LLDB_REGISTER_METHOD(lldb::SBSourceManager, SBDebugger, GetSourceManager, ());
  LLDB_REGISTER_STATIC_METHOD(bool, SBDebugger, SetDefaultArchitecture,
                              (const char *));
  LLDB_REGISTER_METHOD(lldb::ScriptLanguage, SBDebugger, GetScriptingLanguage,
                       (const char *));
  LLDB_REGISTER_STATIC_METHOD(const char *, SBDebugger, GetVersionString, ());
  LLDB_REGISTER_STATIC_METHOD(const char *, SBDebugger, StateAsCString,
                              (lldb::StateType));
  LLDB_REGISTER_STATIC_METHOD(lldb::SBStructuredData, SBDebugger,
                              GetBuildConfiguration, ());
  LLDB_REGISTER_STATIC_METHOD(bool, SBDebugger, StateIsRunningState,
                              (lldb::StateType));
  LLDB_REGISTER_STATIC_METHOD(bool, SBDebugger, StateIsStoppedState,
                              (lldb::StateType));
  LLDB_REGISTER_METHOD(
      lldb::SBTarget, SBDebugger, CreateTarget,
      (const char *, const char *, const char *, bool, lldb::SBError &));
  LLDB_REGISTER_METHOD(lldb::SBTarget, SBDebugger,
                       CreateTargetWithFileAndTargetTriple,
                       (const char *, const char *));
  LLDB_REGISTER_METHOD(lldb::SBTarget, SBDebugger, CreateTargetWithFileAndArch,
                       (const char *, const char *));
  LLDB_REGISTER_METHOD(lldb::SBTarget, SBDebugger, CreateTarget,
                       (const char *));
  LLDB_REGISTER_METHOD(lldb::SBTarget, SBDebugger, GetDummyTarget, ());
  LLDB_REGISTER_METHOD(bool, SBDebugger, DeleteTarget, (lldb::SBTarget &));
  LLDB_REGISTER_METHOD(lldb::SBTarget, SBDebugger, GetTargetAtIndex,
                       (uint32_t));
  LLDB_REGISTER_METHOD(uint32_t, SBDebugger, GetIndexOfTarget,
                       (lldb::SBTarget));
  LLDB_REGISTER_METHOD(lldb::SBTarget, SBDebugger, FindTargetWithProcessID,
                       (lldb::pid_t));
  LLDB_REGISTER_METHOD(lldb::SBTarget, SBDebugger, FindTargetWithFileAndArch,
                       (const char *, const char *));
  LLDB_REGISTER_METHOD(uint32_t, SBDebugger, GetNumTargets, ());
  LLDB_REGISTER_METHOD(lldb::SBTarget, SBDebugger, GetSelectedTarget, ());
  LLDB_REGISTER_METHOD(void, SBDebugger, SetSelectedTarget, (lldb::SBTarget &));
  LLDB_REGISTER_METHOD(lldb::SBPlatform, SBDebugger, GetSelectedPlatform, ());
  LLDB_REGISTER_METHOD(void, SBDebugger, SetSelectedPlatform,
                       (lldb::SBPlatform &));
  LLDB_REGISTER_METHOD(uint32_t, SBDebugger, GetNumPlatforms, ());
  LLDB_REGISTER_METHOD(lldb::SBPlatform, SBDebugger, GetPlatformAtIndex,
                       (uint32_t));
  LLDB_REGISTER_METHOD(uint32_t, SBDebugger, GetNumAvailablePlatforms, ());
  LLDB_REGISTER_METHOD(lldb::SBStructuredData, SBDebugger,
                       GetAvailablePlatformInfoAtIndex, (uint32_t));
  LLDB_REGISTER_METHOD(void, SBDebugger, DispatchInputInterrupt, ());
  LLDB_REGISTER_METHOD(void, SBDebugger, DispatchInputEndOfFile, ());
  LLDB_REGISTER_METHOD(void, SBDebugger, PushInputReader,
                       (lldb::SBInputReader &));
  LLDB_REGISTER_METHOD(void, SBDebugger, RunCommandInterpreter, (bool, bool));
  LLDB_REGISTER_METHOD(void, SBDebugger, RunCommandInterpreter,
                       (bool, bool, lldb::SBCommandInterpreterRunOptions &,
                        int &, bool &, bool &));
  LLDB_REGISTER_METHOD(lldb::SBError, SBDebugger, RunREPL,
                       (lldb::LanguageType, const char *));
  LLDB_REGISTER_STATIC_METHOD(lldb::SBDebugger, SBDebugger, FindDebuggerWithID,
                              (int));
  LLDB_REGISTER_METHOD(const char *, SBDebugger, GetInstanceName, ());
  LLDB_REGISTER_STATIC_METHOD(lldb::SBError, SBDebugger, SetInternalVariable,
                              (const char *, const char *, const char *));
  LLDB_REGISTER_STATIC_METHOD(lldb::SBStringList, SBDebugger,
                              GetInternalVariableValue,
                              (const char *, const char *));
  LLDB_REGISTER_METHOD_CONST(uint32_t, SBDebugger, GetTerminalWidth, ());
  LLDB_REGISTER_METHOD(void, SBDebugger, SetTerminalWidth, (uint32_t));
  LLDB_REGISTER_METHOD_CONST(const char *, SBDebugger, GetPrompt, ());
  LLDB_REGISTER_METHOD(void, SBDebugger, SetPrompt, (const char *));
  LLDB_REGISTER_METHOD_CONST(const char *, SBDebugger, GetReproducerPath, ());
  LLDB_REGISTER_METHOD_CONST(lldb::ScriptLanguage, SBDebugger,
                             GetScriptLanguage, ());
  LLDB_REGISTER_METHOD(void, SBDebugger, SetScriptLanguage,
                       (lldb::ScriptLanguage));
  LLDB_REGISTER_METHOD(bool, SBDebugger, SetUseExternalEditor, (bool));
  LLDB_REGISTER_METHOD(bool, SBDebugger, GetUseExternalEditor, ());
  LLDB_REGISTER_METHOD(bool, SBDebugger, SetUseColor, (bool));
  LLDB_REGISTER_METHOD_CONST(bool, SBDebugger, GetUseColor, ());
  LLDB_REGISTER_METHOD(bool, SBDebugger, GetDescription, (lldb::SBStream &));
  LLDB_REGISTER_METHOD(lldb::user_id_t, SBDebugger, GetID, ());
  LLDB_REGISTER_METHOD(lldb::SBError, SBDebugger, SetCurrentPlatform,
                       (const char *));
  LLDB_REGISTER_METHOD(bool, SBDebugger, SetCurrentPlatformSDKRoot,
                       (const char *));
  LLDB_REGISTER_METHOD_CONST(bool, SBDebugger, GetCloseInputOnEOF, ());
  LLDB_REGISTER_METHOD(void, SBDebugger, SetCloseInputOnEOF, (bool));
  LLDB_REGISTER_METHOD(lldb::SBTypeCategory, SBDebugger, GetCategory,
                       (const char *));
  LLDB_REGISTER_METHOD(lldb::SBTypeCategory, SBDebugger, GetCategory,
                       (lldb::LanguageType));
  LLDB_REGISTER_METHOD(lldb::SBTypeCategory, SBDebugger, CreateCategory,
                       (const char *));
  LLDB_REGISTER_METHOD(bool, SBDebugger, DeleteCategory, (const char *));
  LLDB_REGISTER_METHOD(uint32_t, SBDebugger, GetNumCategories, ());
  LLDB_REGISTER_METHOD(lldb::SBTypeCategory, SBDebugger, GetCategoryAtIndex,
                       (uint32_t));
  LLDB_REGISTER_METHOD(lldb::SBTypeCategory, SBDebugger, GetDefaultCategory,
                       ());
  LLDB_REGISTER_METHOD(lldb::SBTypeFormat, SBDebugger, GetFormatForType,
                       (lldb::SBTypeNameSpecifier));
  LLDB_REGISTER_METHOD(lldb::SBTypeSummary, SBDebugger, GetSummaryForType,
                       (lldb::SBTypeNameSpecifier));
  LLDB_REGISTER_METHOD(lldb::SBTypeSynthetic, SBDebugger, GetSyntheticForType,
                       (lldb::SBTypeNameSpecifier));
  LLDB_REGISTER_METHOD(lldb::SBTypeFilter, SBDebugger, GetFilterForType,
                       (lldb::SBTypeNameSpecifier));
  LLDB_REGISTER_METHOD(bool, SBDebugger, EnableLog,
                       (const char *, const char **));
}

} // namespace repro
} // namespace lldb_private
