//===-- SBDebugger.cpp ----------------------------------------------------===//
//
// 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/SBCommandInterpreterRunOptions.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, false);
  } 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>().GetNewRecorder();

  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_CHAR_PTR_STATIC_METHOD(bool, SBDebugger, GetDefaultArchitecture,
                                     (char *, size_t), arch_name, "",
                                     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();
    }
  }

  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;
    options.SetAutoHandleEvents(auto_handle_events);
    options.SetSpawnThread(spawn_thread);
    m_opaque_sp->GetCommandInterpreter().RunCommandInterpreter(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) {
    options.SetAutoHandleEvents(auto_handle_events);
    options.SetSpawnThread(spawn_thread);
    CommandInterpreter &interp = m_opaque_sp->GetCommandInterpreter();
    CommandInterpreterRunResult result =
        interp.RunCommandInterpreter(options.ref());
    num_errors = result.GetNumErrors();
    quit_requested =
        result.IsResult(lldb::eCommandInterpreterResultQuitRequested);
    stopped_for_crash =
        result.IsResult(lldb::eCommandInterpreterResultInferiorCrash);
  }
}

SBCommandInterpreterRunResult SBDebugger::RunCommandInterpreter(
    const SBCommandInterpreterRunOptions &options) {
  LLDB_RECORD_METHOD(lldb::SBCommandInterpreterRunResult, SBDebugger,
                     RunCommandInterpreter,
                     (const lldb::SBCommandInterpreterRunOptions &), options);

  if (!m_opaque_sp)
    return LLDB_RECORD_RESULT(SBCommandInterpreterRunResult());

  CommandInterpreter &interp = m_opaque_sp->GetCommandInterpreter();
  CommandInterpreterRunResult result =
      interp.RunCommandInterpreter(options.ref());

  return LLDB_RECORD_RESULT(SBCommandInterpreterRunResult(result));
}

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 = std::string(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::SetUseSourceCache(bool value) {
  LLDB_RECORD_METHOD(bool, SBDebugger, SetUseSourceCache, (bool), value);

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

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

  return (m_opaque_sp ? m_opaque_sp->GetUseSourceCache() : 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(); }

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

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

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

  LLDB_REGISTER_CHAR_PTR_METHOD_STATIC(bool, SBDebugger,
                                       GetDefaultArchitecture);

  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 **));
  LLDB_REGISTER_METHOD(lldb::SBCommandInterpreterRunResult, SBDebugger,
                       RunCommandInterpreter,
                       (const lldb::SBCommandInterpreterRunOptions &));
}

} // namespace repro
} // namespace lldb_private
