//===-- 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/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 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 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::CommandLoader> loader =
      repro::CommandLoader::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 error;
  }

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

SBError SBDebugger::SetOutputFile(FileSP file_sp) {
  LLDB_RECORD_METHOD(SBError, SBDebugger, SetOutputFile, (FileSP), file_sp);
  return 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 error;
  }
  if (!file) {
    error.ref().SetErrorString("invalid file");
    return error;
  }
  m_opaque_sp->SetOutputFile(file.m_opaque_sp);
  return 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 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 error;
  }
  if (!file) {
    error.ref().SetErrorString("invalid file");
    return error;
  }
  m_opaque_sp->SetErrorFile(file.m_opaque_sp);
  return 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 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 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 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");
  bool have_curses = true;
#ifdef LLDB_DISABLE_CURSES
  have_curses = false;
#endif
  AddBoolConfigEntry(
      *config_up, "curses", have_curses,
      "A boolean value that indicates if curses 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
