//===-- SBTarget.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 "lldb/API/SBTarget.h"
#include "SBReproducerPrivate.h"

#include "lldb/lldb-public.h"

#include "lldb/API/SBBreakpoint.h"
#include "lldb/API/SBDebugger.h"
#include "lldb/API/SBEvent.h"
#include "lldb/API/SBExpressionOptions.h"
#include "lldb/API/SBFileSpec.h"
#include "lldb/API/SBListener.h"
#include "lldb/API/SBModule.h"
#include "lldb/API/SBModuleSpec.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/SBSymbolContextList.h"
#include "lldb/Breakpoint/BreakpointID.h"
#include "lldb/Breakpoint/BreakpointIDList.h"
#include "lldb/Breakpoint/BreakpointList.h"
#include "lldb/Breakpoint/BreakpointLocation.h"
#include "lldb/Core/Address.h"
#include "lldb/Core/AddressResolver.h"
#include "lldb/Core/AddressResolverName.h"
#include "lldb/Core/Debugger.h"
#include "lldb/Core/Disassembler.h"
#include "lldb/Core/Module.h"
#include "lldb/Core/ModuleSpec.h"
#include "lldb/Core/STLUtils.h"
#include "lldb/Core/SearchFilter.h"
#include "lldb/Core/Section.h"
#include "lldb/Core/StructuredDataImpl.h"
#include "lldb/Core/ValueObjectConstResult.h"
#include "lldb/Core/ValueObjectList.h"
#include "lldb/Core/ValueObjectVariable.h"
#include "lldb/Host/Host.h"
#include "lldb/Symbol/ClangASTContext.h"
#include "lldb/Symbol/DeclVendor.h"
#include "lldb/Symbol/ObjectFile.h"
#include "lldb/Symbol/SymbolFile.h"
#include "lldb/Symbol/SymbolVendor.h"
#include "lldb/Symbol/VariableList.h"
#include "lldb/Target/ABI.h"
#include "lldb/Target/Language.h"
#include "lldb/Target/LanguageRuntime.h"
#include "lldb/Target/ObjCLanguageRuntime.h"
#include "lldb/Target/Process.h"
#include "lldb/Target/StackFrame.h"
#include "lldb/Target/Target.h"
#include "lldb/Target/TargetList.h"
#include "lldb/Utility/ArchSpec.h"
#include "lldb/Utility/Args.h"
#include "lldb/Utility/FileSpec.h"
#include "lldb/Utility/ProcessInfo.h"
#include "lldb/Utility/RegularExpression.h"

#include "Commands/CommandObjectBreakpoint.h"
#include "lldb/Interpreter/CommandReturnObject.h"
#include "llvm/Support/PrettyStackTrace.h"
#include "llvm/Support/Regex.h"

using namespace lldb;
using namespace lldb_private;

#define DEFAULT_DISASM_BYTE_SIZE 32

namespace {

Status AttachToProcess(ProcessAttachInfo &attach_info, Target &target) {
  std::lock_guard<std::recursive_mutex> guard(target.GetAPIMutex());

  auto process_sp = target.GetProcessSP();
  if (process_sp) {
    const auto state = process_sp->GetState();
    if (process_sp->IsAlive() && state == eStateConnected) {
      // If we are already connected, then we have already specified the
      // listener, so if a valid listener is supplied, we need to error out to
      // let the client know.
      if (attach_info.GetListener())
        return Status("process is connected and already has a listener, pass "
                      "empty listener");
    }
  }

  return target.Attach(attach_info, nullptr);
}

} // namespace

// SBTarget constructor
SBTarget::SBTarget() : m_opaque_sp() {
  LLDB_RECORD_CONSTRUCTOR_NO_ARGS(SBTarget);
}

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

SBTarget::SBTarget(const TargetSP &target_sp) : m_opaque_sp(target_sp) {
  LLDB_RECORD_CONSTRUCTOR(SBTarget, (const lldb::TargetSP &), target_sp);
}

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

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

// Destructor
SBTarget::~SBTarget() {}

bool SBTarget::EventIsTargetEvent(const SBEvent &event) {
  LLDB_RECORD_STATIC_METHOD(bool, SBTarget, EventIsTargetEvent,
                            (const lldb::SBEvent &), event);

  return Target::TargetEventData::GetEventDataFromEvent(event.get()) != NULL;
}

SBTarget SBTarget::GetTargetFromEvent(const SBEvent &event) {
  LLDB_RECORD_STATIC_METHOD(lldb::SBTarget, SBTarget, GetTargetFromEvent,
                            (const lldb::SBEvent &), event);

  return LLDB_RECORD_RESULT(
      Target::TargetEventData::GetTargetFromEvent(event.get()));
}

uint32_t SBTarget::GetNumModulesFromEvent(const SBEvent &event) {
  LLDB_RECORD_STATIC_METHOD(uint32_t, SBTarget, GetNumModulesFromEvent,
                            (const lldb::SBEvent &), event);

  const ModuleList module_list =
      Target::TargetEventData::GetModuleListFromEvent(event.get());
  return module_list.GetSize();
}

SBModule SBTarget::GetModuleAtIndexFromEvent(const uint32_t idx,
                                             const SBEvent &event) {
  LLDB_RECORD_STATIC_METHOD(lldb::SBModule, SBTarget, GetModuleAtIndexFromEvent,
                            (const uint32_t, const lldb::SBEvent &), idx,
                            event);

  const ModuleList module_list =
      Target::TargetEventData::GetModuleListFromEvent(event.get());
  return LLDB_RECORD_RESULT(SBModule(module_list.GetModuleAtIndex(idx)));
}

const char *SBTarget::GetBroadcasterClassName() {
  LLDB_RECORD_STATIC_METHOD_NO_ARGS(const char *, SBTarget,
                                    GetBroadcasterClassName);

  return Target::GetStaticBroadcasterClass().AsCString();
}

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

  return m_opaque_sp.get() != NULL && m_opaque_sp->IsValid();
}

SBProcess SBTarget::GetProcess() {
  LLDB_RECORD_METHOD_NO_ARGS(lldb::SBProcess, SBTarget, GetProcess);

  SBProcess sb_process;
  ProcessSP process_sp;
  TargetSP target_sp(GetSP());
  if (target_sp) {
    process_sp = target_sp->GetProcessSP();
    sb_process.SetSP(process_sp);
  }

  return LLDB_RECORD_RESULT(sb_process);
}

SBPlatform SBTarget::GetPlatform() {
  LLDB_RECORD_METHOD_NO_ARGS(lldb::SBPlatform, SBTarget, GetPlatform);

  TargetSP target_sp(GetSP());
  if (!target_sp)
    return LLDB_RECORD_RESULT(SBPlatform());

  SBPlatform platform;
  platform.m_opaque_sp = target_sp->GetPlatform();

  return LLDB_RECORD_RESULT(platform);
}

SBDebugger SBTarget::GetDebugger() const {
  LLDB_RECORD_METHOD_CONST_NO_ARGS(lldb::SBDebugger, SBTarget, GetDebugger);

  SBDebugger debugger;
  TargetSP target_sp(GetSP());
  if (target_sp)
    debugger.reset(target_sp->GetDebugger().shared_from_this());
  return LLDB_RECORD_RESULT(debugger);
}

SBStructuredData SBTarget::GetStatistics() {
  LLDB_RECORD_METHOD_NO_ARGS(lldb::SBStructuredData, SBTarget, GetStatistics);

  SBStructuredData data;
  TargetSP target_sp(GetSP());
  if (!target_sp)
    return LLDB_RECORD_RESULT(data);

  auto stats_up = llvm::make_unique<StructuredData::Dictionary>();
  int i = 0;
  for (auto &Entry : target_sp->GetStatistics()) {
    std::string Desc = lldb_private::GetStatDescription(
        static_cast<lldb_private::StatisticKind>(i));
    stats_up->AddIntegerItem(Desc, Entry);
    i += 1;
  }

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

void SBTarget::SetCollectingStats(bool v) {
  LLDB_RECORD_METHOD(void, SBTarget, SetCollectingStats, (bool), v);

  TargetSP target_sp(GetSP());
  if (!target_sp)
    return;
  return target_sp->SetCollectingStats(v);
}

bool SBTarget::GetCollectingStats() {
  LLDB_RECORD_METHOD_NO_ARGS(bool, SBTarget, GetCollectingStats);

  TargetSP target_sp(GetSP());
  if (!target_sp)
    return false;
  return target_sp->GetCollectingStats();
}

SBProcess SBTarget::LoadCore(const char *core_file) {
  LLDB_RECORD_METHOD(lldb::SBProcess, SBTarget, LoadCore, (const char *),
                     core_file);

  lldb::SBError error; // Ignored
  return LLDB_RECORD_RESULT(LoadCore(core_file, error));
}

SBProcess SBTarget::LoadCore(const char *core_file, lldb::SBError &error) {
  LLDB_RECORD_METHOD(lldb::SBProcess, SBTarget, LoadCore,
                     (const char *, lldb::SBError &), core_file, error);

  SBProcess sb_process;
  TargetSP target_sp(GetSP());
  if (target_sp) {
    FileSpec filespec(core_file);
    FileSystem::Instance().Resolve(filespec);
    ProcessSP process_sp(target_sp->CreateProcess(
        target_sp->GetDebugger().GetListener(), "", &filespec));
    if (process_sp) {
      error.SetError(process_sp->LoadCore());
      if (error.Success())
        sb_process.SetSP(process_sp);
    } else {
      error.SetErrorString("Failed to create the process");
    }
  } else {
    error.SetErrorString("SBTarget is invalid");
  }
  return LLDB_RECORD_RESULT(sb_process);
}

SBProcess SBTarget::LaunchSimple(char const **argv, char const **envp,
                                 const char *working_directory) {
  LLDB_RECORD_METHOD(lldb::SBProcess, SBTarget, LaunchSimple,
                     (const char **, const char **, const char *), argv, envp,
                     working_directory);

  char *stdin_path = NULL;
  char *stdout_path = NULL;
  char *stderr_path = NULL;
  uint32_t launch_flags = 0;
  bool stop_at_entry = false;
  SBError error;
  SBListener listener = GetDebugger().GetListener();
  return LLDB_RECORD_RESULT(Launch(listener, argv, envp, stdin_path,
                                   stdout_path, stderr_path, working_directory,
                                   launch_flags, stop_at_entry, error));
}

SBError SBTarget::Install() {
  LLDB_RECORD_METHOD_NO_ARGS(lldb::SBError, SBTarget, Install);

  SBError sb_error;
  TargetSP target_sp(GetSP());
  if (target_sp) {
    std::lock_guard<std::recursive_mutex> guard(target_sp->GetAPIMutex());
    sb_error.ref() = target_sp->Install(NULL);
  }
  return LLDB_RECORD_RESULT(sb_error);
}

SBProcess SBTarget::Launch(SBListener &listener, char const **argv,
                           char const **envp, const char *stdin_path,
                           const char *stdout_path, const char *stderr_path,
                           const char *working_directory,
                           uint32_t launch_flags, // See LaunchFlags
                           bool stop_at_entry, lldb::SBError &error) {
  LLDB_RECORD_METHOD(lldb::SBProcess, SBTarget, Launch,
                     (lldb::SBListener &, const char **, const char **,
                      const char *, const char *, const char *, const char *,
                      uint32_t, bool, lldb::SBError &),
                     listener, argv, envp, stdin_path, stdout_path, stderr_path,
                     working_directory, launch_flags, stop_at_entry, error);

  SBProcess sb_process;
  ProcessSP process_sp;
  TargetSP target_sp(GetSP());

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

    if (stop_at_entry)
      launch_flags |= eLaunchFlagStopAtEntry;

    if (getenv("LLDB_LAUNCH_FLAG_DISABLE_ASLR"))
      launch_flags |= eLaunchFlagDisableASLR;

    StateType state = eStateInvalid;
    process_sp = target_sp->GetProcessSP();
    if (process_sp) {
      state = process_sp->GetState();

      if (process_sp->IsAlive() && state != eStateConnected) {
        if (state == eStateAttaching)
          error.SetErrorString("process attach is in progress");
        else
          error.SetErrorString("a process is already being debugged");
        return LLDB_RECORD_RESULT(sb_process);
      }
    }

    if (state == eStateConnected) {
      // If we are already connected, then we have already specified the
      // listener, so if a valid listener is supplied, we need to error out to
      // let the client know.
      if (listener.IsValid()) {
        error.SetErrorString("process is connected and already has a listener, "
                             "pass empty listener");
        return LLDB_RECORD_RESULT(sb_process);
      }
    }

    if (getenv("LLDB_LAUNCH_FLAG_DISABLE_STDIO"))
      launch_flags |= eLaunchFlagDisableSTDIO;

    ProcessLaunchInfo launch_info(FileSpec(stdin_path), FileSpec(stdout_path),
                                  FileSpec(stderr_path),
                                  FileSpec(working_directory), launch_flags);

    Module *exe_module = target_sp->GetExecutableModulePointer();
    if (exe_module)
      launch_info.SetExecutableFile(exe_module->GetPlatformFileSpec(), true);
    if (argv)
      launch_info.GetArguments().AppendArguments(argv);
    if (envp)
      launch_info.GetEnvironment() = Environment(envp);

    if (listener.IsValid())
      launch_info.SetListener(listener.GetSP());

    error.SetError(target_sp->Launch(launch_info, NULL));

    sb_process.SetSP(target_sp->GetProcessSP());
  } else {
    error.SetErrorString("SBTarget is invalid");
  }

  return LLDB_RECORD_RESULT(sb_process);
}

SBProcess SBTarget::Launch(SBLaunchInfo &sb_launch_info, SBError &error) {
  LLDB_RECORD_METHOD(lldb::SBProcess, SBTarget, Launch,
                     (lldb::SBLaunchInfo &, lldb::SBError &), sb_launch_info,
                     error);


  SBProcess sb_process;
  TargetSP target_sp(GetSP());

  if (target_sp) {
    std::lock_guard<std::recursive_mutex> guard(target_sp->GetAPIMutex());
    StateType state = eStateInvalid;
    {
      ProcessSP process_sp = target_sp->GetProcessSP();
      if (process_sp) {
        state = process_sp->GetState();

        if (process_sp->IsAlive() && state != eStateConnected) {
          if (state == eStateAttaching)
            error.SetErrorString("process attach is in progress");
          else
            error.SetErrorString("a process is already being debugged");
          return LLDB_RECORD_RESULT(sb_process);
        }
      }
    }

    lldb_private::ProcessLaunchInfo launch_info = sb_launch_info.ref();

    if (!launch_info.GetExecutableFile()) {
      Module *exe_module = target_sp->GetExecutableModulePointer();
      if (exe_module)
        launch_info.SetExecutableFile(exe_module->GetPlatformFileSpec(), true);
    }

    const ArchSpec &arch_spec = target_sp->GetArchitecture();
    if (arch_spec.IsValid())
      launch_info.GetArchitecture() = arch_spec;

    error.SetError(target_sp->Launch(launch_info, NULL));
    sb_launch_info.set_ref(launch_info);
    sb_process.SetSP(target_sp->GetProcessSP());
  } else {
    error.SetErrorString("SBTarget is invalid");
  }

  return LLDB_RECORD_RESULT(sb_process);
}

lldb::SBProcess SBTarget::Attach(SBAttachInfo &sb_attach_info, SBError &error) {
  LLDB_RECORD_METHOD(lldb::SBProcess, SBTarget, Attach,
                     (lldb::SBAttachInfo &, lldb::SBError &), sb_attach_info,
                     error);

  SBProcess sb_process;
  TargetSP target_sp(GetSP());

  if (target_sp) {
    ProcessAttachInfo &attach_info = sb_attach_info.ref();
    if (attach_info.ProcessIDIsValid() && !attach_info.UserIDIsValid()) {
      PlatformSP platform_sp = target_sp->GetPlatform();
      // See if we can pre-verify if a process exists or not
      if (platform_sp && platform_sp->IsConnected()) {
        lldb::pid_t attach_pid = attach_info.GetProcessID();
        ProcessInstanceInfo instance_info;
        if (platform_sp->GetProcessInfo(attach_pid, instance_info)) {
          attach_info.SetUserID(instance_info.GetEffectiveUserID());
        } else {
          error.ref().SetErrorStringWithFormat(
              "no process found with process ID %" PRIu64, attach_pid);
          return LLDB_RECORD_RESULT(sb_process);
        }
      }
    }
    error.SetError(AttachToProcess(attach_info, *target_sp));
    if (error.Success())
      sb_process.SetSP(target_sp->GetProcessSP());
  } else {
    error.SetErrorString("SBTarget is invalid");
  }

  return LLDB_RECORD_RESULT(sb_process);
}

lldb::SBProcess SBTarget::AttachToProcessWithID(
    SBListener &listener,
    lldb::pid_t pid, // The process ID to attach to
    SBError &error   // An error explaining what went wrong if attach fails
) {
  LLDB_RECORD_METHOD(lldb::SBProcess, SBTarget, AttachToProcessWithID,
                     (lldb::SBListener &, lldb::pid_t, lldb::SBError &),
                     listener, pid, error);

  SBProcess sb_process;
  TargetSP target_sp(GetSP());

  if (target_sp) {
    ProcessAttachInfo attach_info;
    attach_info.SetProcessID(pid);
    if (listener.IsValid())
      attach_info.SetListener(listener.GetSP());

    ProcessInstanceInfo instance_info;
    if (target_sp->GetPlatform()->GetProcessInfo(pid, instance_info))
      attach_info.SetUserID(instance_info.GetEffectiveUserID());

    error.SetError(AttachToProcess(attach_info, *target_sp));
    if (error.Success())
      sb_process.SetSP(target_sp->GetProcessSP());
  } else
    error.SetErrorString("SBTarget is invalid");

  return LLDB_RECORD_RESULT(sb_process);
}

lldb::SBProcess SBTarget::AttachToProcessWithName(
    SBListener &listener,
    const char *name, // basename of process to attach to
    bool wait_for, // if true wait for a new instance of "name" to be launched
    SBError &error // An error explaining what went wrong if attach fails
) {
  LLDB_RECORD_METHOD(lldb::SBProcess, SBTarget, AttachToProcessWithName,
                     (lldb::SBListener &, const char *, bool, lldb::SBError &),
                     listener, name, wait_for, error);

  SBProcess sb_process;
  TargetSP target_sp(GetSP());

  if (name && target_sp) {
    ProcessAttachInfo attach_info;
    attach_info.GetExecutableFile().SetFile(name, FileSpec::Style::native);
    attach_info.SetWaitForLaunch(wait_for);
    if (listener.IsValid())
      attach_info.SetListener(listener.GetSP());

    error.SetError(AttachToProcess(attach_info, *target_sp));
    if (error.Success())
      sb_process.SetSP(target_sp->GetProcessSP());
  } else
    error.SetErrorString("SBTarget is invalid");

  return LLDB_RECORD_RESULT(sb_process);
}

lldb::SBProcess SBTarget::ConnectRemote(SBListener &listener, const char *url,
                                        const char *plugin_name,
                                        SBError &error) {
  LLDB_RECORD_METHOD(
      lldb::SBProcess, SBTarget, ConnectRemote,
      (lldb::SBListener &, const char *, const char *, lldb::SBError &),
      listener, url, plugin_name, error);

  SBProcess sb_process;
  ProcessSP process_sp;
  TargetSP target_sp(GetSP());

  if (target_sp) {
    std::lock_guard<std::recursive_mutex> guard(target_sp->GetAPIMutex());
    if (listener.IsValid())
      process_sp =
          target_sp->CreateProcess(listener.m_opaque_sp, plugin_name, NULL);
    else
      process_sp = target_sp->CreateProcess(
          target_sp->GetDebugger().GetListener(), plugin_name, NULL);

    if (process_sp) {
      sb_process.SetSP(process_sp);
      error.SetError(process_sp->ConnectRemote(NULL, url));
    } else {
      error.SetErrorString("unable to create lldb_private::Process");
    }
  } else {
    error.SetErrorString("SBTarget is invalid");
  }

  return LLDB_RECORD_RESULT(sb_process);
}

SBFileSpec SBTarget::GetExecutable() {
  LLDB_RECORD_METHOD_NO_ARGS(lldb::SBFileSpec, SBTarget, GetExecutable);

  SBFileSpec exe_file_spec;
  TargetSP target_sp(GetSP());
  if (target_sp) {
    Module *exe_module = target_sp->GetExecutableModulePointer();
    if (exe_module)
      exe_file_spec.SetFileSpec(exe_module->GetFileSpec());
  }

  return LLDB_RECORD_RESULT(exe_file_spec);
}

bool SBTarget::operator==(const SBTarget &rhs) const {
  LLDB_RECORD_METHOD_CONST(bool, SBTarget, operator==,(const lldb::SBTarget &),
                           rhs);

  return m_opaque_sp.get() == rhs.m_opaque_sp.get();
}

bool SBTarget::operator!=(const SBTarget &rhs) const {
  LLDB_RECORD_METHOD_CONST(bool, SBTarget, operator!=,(const lldb::SBTarget &),
                           rhs);

  return m_opaque_sp.get() != rhs.m_opaque_sp.get();
}

lldb::TargetSP SBTarget::GetSP() const { return m_opaque_sp; }

void SBTarget::SetSP(const lldb::TargetSP &target_sp) {
  m_opaque_sp = target_sp;
}

lldb::SBAddress SBTarget::ResolveLoadAddress(lldb::addr_t vm_addr) {
  LLDB_RECORD_METHOD(lldb::SBAddress, SBTarget, ResolveLoadAddress,
                     (lldb::addr_t), vm_addr);

  lldb::SBAddress sb_addr;
  Address &addr = sb_addr.ref();
  TargetSP target_sp(GetSP());
  if (target_sp) {
    std::lock_guard<std::recursive_mutex> guard(target_sp->GetAPIMutex());
    if (target_sp->ResolveLoadAddress(vm_addr, addr))
      return LLDB_RECORD_RESULT(sb_addr);
  }

  // We have a load address that isn't in a section, just return an address
  // with the offset filled in (the address) and the section set to NULL
  addr.SetRawAddress(vm_addr);
  return LLDB_RECORD_RESULT(sb_addr);
}

lldb::SBAddress SBTarget::ResolveFileAddress(lldb::addr_t file_addr) {
  LLDB_RECORD_METHOD(lldb::SBAddress, SBTarget, ResolveFileAddress,
                     (lldb::addr_t), file_addr);

  lldb::SBAddress sb_addr;
  Address &addr = sb_addr.ref();
  TargetSP target_sp(GetSP());
  if (target_sp) {
    std::lock_guard<std::recursive_mutex> guard(target_sp->GetAPIMutex());
    if (target_sp->ResolveFileAddress(file_addr, addr))
      return LLDB_RECORD_RESULT(sb_addr);
  }

  addr.SetRawAddress(file_addr);
  return LLDB_RECORD_RESULT(sb_addr);
}

lldb::SBAddress SBTarget::ResolvePastLoadAddress(uint32_t stop_id,
                                                 lldb::addr_t vm_addr) {
  LLDB_RECORD_METHOD(lldb::SBAddress, SBTarget, ResolvePastLoadAddress,
                     (uint32_t, lldb::addr_t), stop_id, vm_addr);

  lldb::SBAddress sb_addr;
  Address &addr = sb_addr.ref();
  TargetSP target_sp(GetSP());
  if (target_sp) {
    std::lock_guard<std::recursive_mutex> guard(target_sp->GetAPIMutex());
    if (target_sp->ResolveLoadAddress(vm_addr, addr))
      return LLDB_RECORD_RESULT(sb_addr);
  }

  // We have a load address that isn't in a section, just return an address
  // with the offset filled in (the address) and the section set to NULL
  addr.SetRawAddress(vm_addr);
  return LLDB_RECORD_RESULT(sb_addr);
}

SBSymbolContext
SBTarget::ResolveSymbolContextForAddress(const SBAddress &addr,
                                         uint32_t resolve_scope) {
  LLDB_RECORD_METHOD(lldb::SBSymbolContext, SBTarget,
                     ResolveSymbolContextForAddress,
                     (const lldb::SBAddress &, uint32_t), addr, resolve_scope);

  SBSymbolContext sc;
  SymbolContextItem scope = static_cast<SymbolContextItem>(resolve_scope);
  if (addr.IsValid()) {
    TargetSP target_sp(GetSP());
    if (target_sp)
      target_sp->GetImages().ResolveSymbolContextForAddress(addr.ref(), scope,
                                                            sc.ref());
  }
  return LLDB_RECORD_RESULT(sc);
}

size_t SBTarget::ReadMemory(const SBAddress addr, void *buf, size_t size,
                            lldb::SBError &error) {
  LLDB_RECORD_DUMMY(size_t, SBTarget, ReadMemory,
                    (const lldb::SBAddress, void *, size_t, lldb::SBError &),
                    addr, buf, size, error);

  SBError sb_error;
  size_t bytes_read = 0;
  TargetSP target_sp(GetSP());
  if (target_sp) {
    std::lock_guard<std::recursive_mutex> guard(target_sp->GetAPIMutex());
    bytes_read =
        target_sp->ReadMemory(addr.ref(), false, buf, size, sb_error.ref());
  } else {
    sb_error.SetErrorString("invalid target");
  }

  return bytes_read;
}

SBBreakpoint SBTarget::BreakpointCreateByLocation(const char *file,
                                                  uint32_t line) {
  LLDB_RECORD_METHOD(lldb::SBBreakpoint, SBTarget, BreakpointCreateByLocation,
                     (const char *, uint32_t), file, line);

  return LLDB_RECORD_RESULT(
      SBBreakpoint(BreakpointCreateByLocation(SBFileSpec(file, false), line)));
}

SBBreakpoint
SBTarget::BreakpointCreateByLocation(const SBFileSpec &sb_file_spec,
                                     uint32_t line) {
  LLDB_RECORD_METHOD(lldb::SBBreakpoint, SBTarget, BreakpointCreateByLocation,
                     (const lldb::SBFileSpec &, uint32_t), sb_file_spec, line);

  return LLDB_RECORD_RESULT(BreakpointCreateByLocation(sb_file_spec, line, 0));
}

SBBreakpoint
SBTarget::BreakpointCreateByLocation(const SBFileSpec &sb_file_spec,
                                     uint32_t line, lldb::addr_t offset) {
  LLDB_RECORD_METHOD(lldb::SBBreakpoint, SBTarget, BreakpointCreateByLocation,
                     (const lldb::SBFileSpec &, uint32_t, lldb::addr_t),
                     sb_file_spec, line, offset);

  SBFileSpecList empty_list;
  return LLDB_RECORD_RESULT(
      BreakpointCreateByLocation(sb_file_spec, line, offset, empty_list));
}

SBBreakpoint
SBTarget::BreakpointCreateByLocation(const SBFileSpec &sb_file_spec,
                                     uint32_t line, lldb::addr_t offset,
                                     SBFileSpecList &sb_module_list) {
  LLDB_RECORD_METHOD(lldb::SBBreakpoint, SBTarget, BreakpointCreateByLocation,
                     (const lldb::SBFileSpec &, uint32_t, lldb::addr_t,
                      lldb::SBFileSpecList &),
                     sb_file_spec, line, offset, sb_module_list);

  return LLDB_RECORD_RESULT(BreakpointCreateByLocation(sb_file_spec, line, 0,
                                                       offset, sb_module_list));
}

SBBreakpoint SBTarget::BreakpointCreateByLocation(
    const SBFileSpec &sb_file_spec, uint32_t line, uint32_t column,
    lldb::addr_t offset, SBFileSpecList &sb_module_list) {
  LLDB_RECORD_METHOD(lldb::SBBreakpoint, SBTarget, BreakpointCreateByLocation,
                     (const lldb::SBFileSpec &, uint32_t, uint32_t,
                      lldb::addr_t, lldb::SBFileSpecList &),
                     sb_file_spec, line, column, offset, sb_module_list);

  SBBreakpoint sb_bp;
  TargetSP target_sp(GetSP());
  if (target_sp && line != 0) {
    std::lock_guard<std::recursive_mutex> guard(target_sp->GetAPIMutex());

    const LazyBool check_inlines = eLazyBoolCalculate;
    const LazyBool skip_prologue = eLazyBoolCalculate;
    const bool internal = false;
    const bool hardware = false;
    const LazyBool move_to_nearest_code = eLazyBoolCalculate;
    const FileSpecList *module_list = nullptr;
    if (sb_module_list.GetSize() > 0) {
      module_list = sb_module_list.get();
    }
    sb_bp = target_sp->CreateBreakpoint(
        module_list, *sb_file_spec, line, column, offset, check_inlines,
        skip_prologue, internal, hardware, move_to_nearest_code);
  }

  return LLDB_RECORD_RESULT(sb_bp);
}

SBBreakpoint SBTarget::BreakpointCreateByName(const char *symbol_name,
                                              const char *module_name) {
  LLDB_RECORD_METHOD(lldb::SBBreakpoint, SBTarget, BreakpointCreateByName,
                     (const char *, const char *), symbol_name, module_name);

  SBBreakpoint sb_bp;
  TargetSP target_sp(GetSP());
  if (target_sp.get()) {
    std::lock_guard<std::recursive_mutex> guard(target_sp->GetAPIMutex());

    const bool internal = false;
    const bool hardware = false;
    const LazyBool skip_prologue = eLazyBoolCalculate;
    const lldb::addr_t offset = 0;
    if (module_name && module_name[0]) {
      FileSpecList module_spec_list;
      module_spec_list.Append(FileSpec(module_name));
      sb_bp = target_sp->CreateBreakpoint(
          &module_spec_list, NULL, symbol_name, eFunctionNameTypeAuto,
          eLanguageTypeUnknown, offset, skip_prologue, internal, hardware);
    } else {
      sb_bp = target_sp->CreateBreakpoint(
          NULL, NULL, symbol_name, eFunctionNameTypeAuto, eLanguageTypeUnknown,
          offset, skip_prologue, internal, hardware);
    }
  }

  return LLDB_RECORD_RESULT(sb_bp);
}

lldb::SBBreakpoint
SBTarget::BreakpointCreateByName(const char *symbol_name,
                                 const SBFileSpecList &module_list,
                                 const SBFileSpecList &comp_unit_list) {
  LLDB_RECORD_METHOD(lldb::SBBreakpoint, SBTarget, BreakpointCreateByName,
                     (const char *, const lldb::SBFileSpecList &,
                      const lldb::SBFileSpecList &),
                     symbol_name, module_list, comp_unit_list);

  lldb::FunctionNameType name_type_mask = eFunctionNameTypeAuto;
  return LLDB_RECORD_RESULT(
      BreakpointCreateByName(symbol_name, name_type_mask, eLanguageTypeUnknown,
                             module_list, comp_unit_list));
}

lldb::SBBreakpoint SBTarget::BreakpointCreateByName(
    const char *symbol_name, uint32_t name_type_mask,
    const SBFileSpecList &module_list, const SBFileSpecList &comp_unit_list) {
  LLDB_RECORD_METHOD(lldb::SBBreakpoint, SBTarget, BreakpointCreateByName,
                     (const char *, uint32_t, const lldb::SBFileSpecList &,
                      const lldb::SBFileSpecList &),
                     symbol_name, name_type_mask, module_list, comp_unit_list);

  return LLDB_RECORD_RESULT(
      BreakpointCreateByName(symbol_name, name_type_mask, eLanguageTypeUnknown,
                             module_list, comp_unit_list));
}

lldb::SBBreakpoint SBTarget::BreakpointCreateByName(
    const char *symbol_name, uint32_t name_type_mask,
    LanguageType symbol_language, const SBFileSpecList &module_list,
    const SBFileSpecList &comp_unit_list) {
  LLDB_RECORD_METHOD(lldb::SBBreakpoint, SBTarget, BreakpointCreateByName,
                     (const char *, uint32_t, lldb::LanguageType,
                      const lldb::SBFileSpecList &,
                      const lldb::SBFileSpecList &),
                     symbol_name, name_type_mask, symbol_language, module_list,
                     comp_unit_list);

  SBBreakpoint sb_bp;
  TargetSP target_sp(GetSP());
  if (target_sp && symbol_name && symbol_name[0]) {
    const bool internal = false;
    const bool hardware = false;
    const LazyBool skip_prologue = eLazyBoolCalculate;
    std::lock_guard<std::recursive_mutex> guard(target_sp->GetAPIMutex());
    FunctionNameType mask = static_cast<FunctionNameType>(name_type_mask);
    sb_bp = target_sp->CreateBreakpoint(module_list.get(), comp_unit_list.get(),
                                        symbol_name, mask, symbol_language, 0,
                                        skip_prologue, internal, hardware);
  }

  return LLDB_RECORD_RESULT(sb_bp);
}

lldb::SBBreakpoint SBTarget::BreakpointCreateByNames(
    const char *symbol_names[], uint32_t num_names, uint32_t name_type_mask,
    const SBFileSpecList &module_list, const SBFileSpecList &comp_unit_list) {
  LLDB_RECORD_METHOD(
      lldb::SBBreakpoint, SBTarget, BreakpointCreateByNames,
      (const char **, uint32_t, uint32_t, const lldb::SBFileSpecList &,
       const lldb::SBFileSpecList &),
      symbol_names, num_names, name_type_mask, module_list, comp_unit_list);

  return LLDB_RECORD_RESULT(BreakpointCreateByNames(
      symbol_names, num_names, name_type_mask, eLanguageTypeUnknown,
      module_list, comp_unit_list));
}

lldb::SBBreakpoint SBTarget::BreakpointCreateByNames(
    const char *symbol_names[], uint32_t num_names, uint32_t name_type_mask,
    LanguageType symbol_language, const SBFileSpecList &module_list,
    const SBFileSpecList &comp_unit_list) {
  LLDB_RECORD_METHOD(lldb::SBBreakpoint, SBTarget, BreakpointCreateByNames,
                     (const char **, uint32_t, uint32_t, lldb::LanguageType,
                      const lldb::SBFileSpecList &,
                      const lldb::SBFileSpecList &),
                     symbol_names, num_names, name_type_mask, symbol_language,
                     module_list, comp_unit_list);

  return LLDB_RECORD_RESULT(BreakpointCreateByNames(
      symbol_names, num_names, name_type_mask, eLanguageTypeUnknown, 0,
      module_list, comp_unit_list));
}

lldb::SBBreakpoint SBTarget::BreakpointCreateByNames(
    const char *symbol_names[], uint32_t num_names, uint32_t name_type_mask,
    LanguageType symbol_language, lldb::addr_t offset,
    const SBFileSpecList &module_list, const SBFileSpecList &comp_unit_list) {
  LLDB_RECORD_METHOD(lldb::SBBreakpoint, SBTarget, BreakpointCreateByNames,
                     (const char **, uint32_t, uint32_t, lldb::LanguageType,
                      lldb::addr_t, const lldb::SBFileSpecList &,
                      const lldb::SBFileSpecList &),
                     symbol_names, num_names, name_type_mask, symbol_language,
                     offset, module_list, comp_unit_list);

  SBBreakpoint sb_bp;
  TargetSP target_sp(GetSP());
  if (target_sp && num_names > 0) {
    std::lock_guard<std::recursive_mutex> guard(target_sp->GetAPIMutex());
    const bool internal = false;
    const bool hardware = false;
    FunctionNameType mask = static_cast<FunctionNameType>(name_type_mask);
    const LazyBool skip_prologue = eLazyBoolCalculate;
    sb_bp = target_sp->CreateBreakpoint(
        module_list.get(), comp_unit_list.get(), symbol_names, num_names, mask,
        symbol_language, offset, skip_prologue, internal, hardware);
  }

  return LLDB_RECORD_RESULT(sb_bp);
}

SBBreakpoint SBTarget::BreakpointCreateByRegex(const char *symbol_name_regex,
                                               const char *module_name) {
  LLDB_RECORD_METHOD(lldb::SBBreakpoint, SBTarget, BreakpointCreateByRegex,
                     (const char *, const char *), symbol_name_regex,
                     module_name);

  SBFileSpecList module_spec_list;
  SBFileSpecList comp_unit_list;
  if (module_name && module_name[0]) {
    module_spec_list.Append(FileSpec(module_name));
  }
  return LLDB_RECORD_RESULT(
      BreakpointCreateByRegex(symbol_name_regex, eLanguageTypeUnknown,
                              module_spec_list, comp_unit_list));
}

lldb::SBBreakpoint
SBTarget::BreakpointCreateByRegex(const char *symbol_name_regex,
                                  const SBFileSpecList &module_list,
                                  const SBFileSpecList &comp_unit_list) {
  LLDB_RECORD_METHOD(lldb::SBBreakpoint, SBTarget, BreakpointCreateByRegex,
                     (const char *, const lldb::SBFileSpecList &,
                      const lldb::SBFileSpecList &),
                     symbol_name_regex, module_list, comp_unit_list);

  return LLDB_RECORD_RESULT(BreakpointCreateByRegex(
      symbol_name_regex, eLanguageTypeUnknown, module_list, comp_unit_list));
}

lldb::SBBreakpoint SBTarget::BreakpointCreateByRegex(
    const char *symbol_name_regex, LanguageType symbol_language,
    const SBFileSpecList &module_list, const SBFileSpecList &comp_unit_list) {
  LLDB_RECORD_METHOD(
      lldb::SBBreakpoint, SBTarget, BreakpointCreateByRegex,
      (const char *, lldb::LanguageType, const lldb::SBFileSpecList &,
       const lldb::SBFileSpecList &),
      symbol_name_regex, symbol_language, module_list, comp_unit_list);


  SBBreakpoint sb_bp;
  TargetSP target_sp(GetSP());
  if (target_sp && symbol_name_regex && symbol_name_regex[0]) {
    std::lock_guard<std::recursive_mutex> guard(target_sp->GetAPIMutex());
    RegularExpression regexp((llvm::StringRef(symbol_name_regex)));
    const bool internal = false;
    const bool hardware = false;
    const LazyBool skip_prologue = eLazyBoolCalculate;

    sb_bp = target_sp->CreateFuncRegexBreakpoint(
        module_list.get(), comp_unit_list.get(), regexp, symbol_language,
        skip_prologue, internal, hardware);
  }

  return LLDB_RECORD_RESULT(sb_bp);
}

SBBreakpoint SBTarget::BreakpointCreateByAddress(addr_t address) {
  LLDB_RECORD_METHOD(lldb::SBBreakpoint, SBTarget, BreakpointCreateByAddress,
                     (lldb::addr_t), address);

  SBBreakpoint sb_bp;
  TargetSP target_sp(GetSP());
  if (target_sp) {
    std::lock_guard<std::recursive_mutex> guard(target_sp->GetAPIMutex());
    const bool hardware = false;
    sb_bp = target_sp->CreateBreakpoint(address, false, hardware);
  }

  return LLDB_RECORD_RESULT(sb_bp);
}

SBBreakpoint SBTarget::BreakpointCreateBySBAddress(SBAddress &sb_address) {
  LLDB_RECORD_METHOD(lldb::SBBreakpoint, SBTarget, BreakpointCreateBySBAddress,
                     (lldb::SBAddress &), sb_address);

  SBBreakpoint sb_bp;
  TargetSP target_sp(GetSP());
  if (!sb_address.IsValid()) {
    return LLDB_RECORD_RESULT(sb_bp);
  }

  if (target_sp) {
    std::lock_guard<std::recursive_mutex> guard(target_sp->GetAPIMutex());
    const bool hardware = false;
    sb_bp = target_sp->CreateBreakpoint(sb_address.ref(), false, hardware);
  }

  return LLDB_RECORD_RESULT(sb_bp);
}

lldb::SBBreakpoint
SBTarget::BreakpointCreateBySourceRegex(const char *source_regex,
                                        const lldb::SBFileSpec &source_file,
                                        const char *module_name) {
  LLDB_RECORD_METHOD(lldb::SBBreakpoint, SBTarget,
                     BreakpointCreateBySourceRegex,
                     (const char *, const lldb::SBFileSpec &, const char *),
                     source_regex, source_file, module_name);

  SBFileSpecList module_spec_list;

  if (module_name && module_name[0]) {
    module_spec_list.Append(FileSpec(module_name));
  }

  SBFileSpecList source_file_list;
  if (source_file.IsValid()) {
    source_file_list.Append(source_file);
  }

  return LLDB_RECORD_RESULT(BreakpointCreateBySourceRegex(
      source_regex, module_spec_list, source_file_list));
}

lldb::SBBreakpoint SBTarget::BreakpointCreateBySourceRegex(
    const char *source_regex, const SBFileSpecList &module_list,
    const lldb::SBFileSpecList &source_file_list) {
  LLDB_RECORD_METHOD(lldb::SBBreakpoint, SBTarget,
                     BreakpointCreateBySourceRegex,
                     (const char *, const lldb::SBFileSpecList &,
                      const lldb::SBFileSpecList &),
                     source_regex, module_list, source_file_list);

  return LLDB_RECORD_RESULT(BreakpointCreateBySourceRegex(
      source_regex, module_list, source_file_list, SBStringList()));
}

lldb::SBBreakpoint SBTarget::BreakpointCreateBySourceRegex(
    const char *source_regex, const SBFileSpecList &module_list,
    const lldb::SBFileSpecList &source_file_list,
    const SBStringList &func_names) {
  LLDB_RECORD_METHOD(lldb::SBBreakpoint, SBTarget,
                     BreakpointCreateBySourceRegex,
                     (const char *, const lldb::SBFileSpecList &,
                      const lldb::SBFileSpecList &, const lldb::SBStringList &),
                     source_regex, module_list, source_file_list, func_names);

  SBBreakpoint sb_bp;
  TargetSP target_sp(GetSP());
  if (target_sp && source_regex && source_regex[0]) {
    std::lock_guard<std::recursive_mutex> guard(target_sp->GetAPIMutex());
    const bool hardware = false;
    const LazyBool move_to_nearest_code = eLazyBoolCalculate;
    RegularExpression regexp((llvm::StringRef(source_regex)));
    std::unordered_set<std::string> func_names_set;
    for (size_t i = 0; i < func_names.GetSize(); i++) {
      func_names_set.insert(func_names.GetStringAtIndex(i));
    }

    sb_bp = target_sp->CreateSourceRegexBreakpoint(
        module_list.get(), source_file_list.get(), func_names_set, regexp,
        false, hardware, move_to_nearest_code);
  }

  return LLDB_RECORD_RESULT(sb_bp);
}

lldb::SBBreakpoint
SBTarget::BreakpointCreateForException(lldb::LanguageType language,
                                       bool catch_bp, bool throw_bp) {
  LLDB_RECORD_METHOD(lldb::SBBreakpoint, SBTarget, BreakpointCreateForException,
                     (lldb::LanguageType, bool, bool), language, catch_bp,
                     throw_bp);

  SBBreakpoint sb_bp;
  TargetSP target_sp(GetSP());
  if (target_sp) {
    std::lock_guard<std::recursive_mutex> guard(target_sp->GetAPIMutex());
    const bool hardware = false;
    sb_bp = target_sp->CreateExceptionBreakpoint(language, catch_bp, throw_bp,
                                                  hardware);
  }

  return LLDB_RECORD_RESULT(sb_bp);
}

lldb::SBBreakpoint SBTarget::BreakpointCreateFromScript(
    const char *class_name, SBStructuredData &extra_args,
    const SBFileSpecList &module_list, const SBFileSpecList &file_list,
    bool request_hardware) {
  LLDB_RECORD_METHOD(
      lldb::SBBreakpoint, SBTarget, BreakpointCreateFromScript,
      (const char *, lldb::SBStructuredData &, const lldb::SBFileSpecList &,
       const lldb::SBFileSpecList &, bool),
      class_name, extra_args, module_list, file_list, request_hardware);

  SBBreakpoint sb_bp;
  TargetSP target_sp(GetSP());
  if (target_sp) {
    std::lock_guard<std::recursive_mutex> guard(target_sp->GetAPIMutex());
    Status error;

    StructuredData::ObjectSP obj_sp = extra_args.m_impl_up->GetObjectSP();
    sb_bp =
        target_sp->CreateScriptedBreakpoint(class_name,
                                            module_list.get(),
                                            file_list.get(),
                                            false, /* internal */
                                            request_hardware,
                                            obj_sp,
                                            &error);
  }

  return LLDB_RECORD_RESULT(sb_bp);
}

uint32_t SBTarget::GetNumBreakpoints() const {
  LLDB_RECORD_METHOD_CONST_NO_ARGS(uint32_t, SBTarget, GetNumBreakpoints);

  TargetSP target_sp(GetSP());
  if (target_sp) {
    // The breakpoint list is thread safe, no need to lock
    return target_sp->GetBreakpointList().GetSize();
  }
  return 0;
}

SBBreakpoint SBTarget::GetBreakpointAtIndex(uint32_t idx) const {
  LLDB_RECORD_METHOD_CONST(lldb::SBBreakpoint, SBTarget, GetBreakpointAtIndex,
                           (uint32_t), idx);

  SBBreakpoint sb_breakpoint;
  TargetSP target_sp(GetSP());
  if (target_sp) {
    // The breakpoint list is thread safe, no need to lock
    sb_breakpoint = target_sp->GetBreakpointList().GetBreakpointAtIndex(idx);
  }
  return LLDB_RECORD_RESULT(sb_breakpoint);
}

bool SBTarget::BreakpointDelete(break_id_t bp_id) {
  LLDB_RECORD_METHOD(bool, SBTarget, BreakpointDelete, (lldb::break_id_t),
                     bp_id);

  bool result = false;
  TargetSP target_sp(GetSP());
  if (target_sp) {
    std::lock_guard<std::recursive_mutex> guard(target_sp->GetAPIMutex());
    result = target_sp->RemoveBreakpointByID(bp_id);
  }

  return result;
}

SBBreakpoint SBTarget::FindBreakpointByID(break_id_t bp_id) {
  LLDB_RECORD_METHOD(lldb::SBBreakpoint, SBTarget, FindBreakpointByID,
                     (lldb::break_id_t), bp_id);

  SBBreakpoint sb_breakpoint;
  TargetSP target_sp(GetSP());
  if (target_sp && bp_id != LLDB_INVALID_BREAK_ID) {
    std::lock_guard<std::recursive_mutex> guard(target_sp->GetAPIMutex());
    sb_breakpoint = target_sp->GetBreakpointByID(bp_id);
  }

  return LLDB_RECORD_RESULT(sb_breakpoint);
}

bool SBTarget::FindBreakpointsByName(const char *name,
                                     SBBreakpointList &bkpts) {
  LLDB_RECORD_METHOD(bool, SBTarget, FindBreakpointsByName,
                     (const char *, lldb::SBBreakpointList &), name, bkpts);

  TargetSP target_sp(GetSP());
  if (target_sp) {
    std::lock_guard<std::recursive_mutex> guard(target_sp->GetAPIMutex());
    BreakpointList bkpt_list(false);
    bool is_valid =
        target_sp->GetBreakpointList().FindBreakpointsByName(name, bkpt_list);
    if (!is_valid)
      return false;
    for (BreakpointSP bkpt_sp : bkpt_list.Breakpoints()) {
      bkpts.AppendByID(bkpt_sp->GetID());
    }
  }
  return true;
}

void SBTarget::GetBreakpointNames(SBStringList &names) {
  LLDB_RECORD_METHOD(void, SBTarget, GetBreakpointNames, (lldb::SBStringList &),
                     names);

  names.Clear();

  TargetSP target_sp(GetSP());
  if (target_sp) {
    std::lock_guard<std::recursive_mutex> guard(target_sp->GetAPIMutex());

    std::vector<std::string> name_vec;
    target_sp->GetBreakpointNames(name_vec);
    for (auto name : name_vec)
      names.AppendString(name.c_str());
  }
}

void SBTarget::DeleteBreakpointName(const char *name) {
  LLDB_RECORD_METHOD(void, SBTarget, DeleteBreakpointName, (const char *),
                     name);

  TargetSP target_sp(GetSP());
  if (target_sp) {
    std::lock_guard<std::recursive_mutex> guard(target_sp->GetAPIMutex());
    target_sp->DeleteBreakpointName(ConstString(name));
  }
}

bool SBTarget::EnableAllBreakpoints() {
  LLDB_RECORD_METHOD_NO_ARGS(bool, SBTarget, EnableAllBreakpoints);

  TargetSP target_sp(GetSP());
  if (target_sp) {
    std::lock_guard<std::recursive_mutex> guard(target_sp->GetAPIMutex());
    target_sp->EnableAllowedBreakpoints();
    return true;
  }
  return false;
}

bool SBTarget::DisableAllBreakpoints() {
  LLDB_RECORD_METHOD_NO_ARGS(bool, SBTarget, DisableAllBreakpoints);

  TargetSP target_sp(GetSP());
  if (target_sp) {
    std::lock_guard<std::recursive_mutex> guard(target_sp->GetAPIMutex());
    target_sp->DisableAllowedBreakpoints();
    return true;
  }
  return false;
}

bool SBTarget::DeleteAllBreakpoints() {
  LLDB_RECORD_METHOD_NO_ARGS(bool, SBTarget, DeleteAllBreakpoints);

  TargetSP target_sp(GetSP());
  if (target_sp) {
    std::lock_guard<std::recursive_mutex> guard(target_sp->GetAPIMutex());
    target_sp->RemoveAllowedBreakpoints();
    return true;
  }
  return false;
}

lldb::SBError SBTarget::BreakpointsCreateFromFile(SBFileSpec &source_file,
                                                  SBBreakpointList &new_bps) {
  LLDB_RECORD_METHOD(lldb::SBError, SBTarget, BreakpointsCreateFromFile,
                     (lldb::SBFileSpec &, lldb::SBBreakpointList &),
                     source_file, new_bps);

  SBStringList empty_name_list;
  return LLDB_RECORD_RESULT(
      BreakpointsCreateFromFile(source_file, empty_name_list, new_bps));
}

lldb::SBError SBTarget::BreakpointsCreateFromFile(SBFileSpec &source_file,
                                                  SBStringList &matching_names,
                                                  SBBreakpointList &new_bps) {
  LLDB_RECORD_METHOD(
      lldb::SBError, SBTarget, BreakpointsCreateFromFile,
      (lldb::SBFileSpec &, lldb::SBStringList &, lldb::SBBreakpointList &),
      source_file, matching_names, new_bps);

  SBError sberr;
  TargetSP target_sp(GetSP());
  if (!target_sp) {
    sberr.SetErrorString(
        "BreakpointCreateFromFile called with invalid target.");
    return LLDB_RECORD_RESULT(sberr);
  }
  std::lock_guard<std::recursive_mutex> guard(target_sp->GetAPIMutex());

  BreakpointIDList bp_ids;

  std::vector<std::string> name_vector;
  size_t num_names = matching_names.GetSize();
  for (size_t i = 0; i < num_names; i++)
    name_vector.push_back(matching_names.GetStringAtIndex(i));

  sberr.ref() = target_sp->CreateBreakpointsFromFile(source_file.ref(),
                                                     name_vector, bp_ids);
  if (sberr.Fail())
    return LLDB_RECORD_RESULT(sberr);

  size_t num_bkpts = bp_ids.GetSize();
  for (size_t i = 0; i < num_bkpts; i++) {
    BreakpointID bp_id = bp_ids.GetBreakpointIDAtIndex(i);
    new_bps.AppendByID(bp_id.GetBreakpointID());
  }
  return LLDB_RECORD_RESULT(sberr);
}

lldb::SBError SBTarget::BreakpointsWriteToFile(SBFileSpec &dest_file) {
  LLDB_RECORD_METHOD(lldb::SBError, SBTarget, BreakpointsWriteToFile,
                     (lldb::SBFileSpec &), dest_file);

  SBError sberr;
  TargetSP target_sp(GetSP());
  if (!target_sp) {
    sberr.SetErrorString("BreakpointWriteToFile called with invalid target.");
    return LLDB_RECORD_RESULT(sberr);
  }
  SBBreakpointList bkpt_list(*this);
  return LLDB_RECORD_RESULT(BreakpointsWriteToFile(dest_file, bkpt_list));
}

lldb::SBError SBTarget::BreakpointsWriteToFile(SBFileSpec &dest_file,
                                               SBBreakpointList &bkpt_list,
                                               bool append) {
  LLDB_RECORD_METHOD(lldb::SBError, SBTarget, BreakpointsWriteToFile,
                     (lldb::SBFileSpec &, lldb::SBBreakpointList &, bool),
                     dest_file, bkpt_list, append);

  SBError sberr;
  TargetSP target_sp(GetSP());
  if (!target_sp) {
    sberr.SetErrorString("BreakpointWriteToFile called with invalid target.");
    return LLDB_RECORD_RESULT(sberr);
  }

  std::lock_guard<std::recursive_mutex> guard(target_sp->GetAPIMutex());
  BreakpointIDList bp_id_list;
  bkpt_list.CopyToBreakpointIDList(bp_id_list);
  sberr.ref() = target_sp->SerializeBreakpointsToFile(dest_file.ref(),
                                                      bp_id_list, append);
  return LLDB_RECORD_RESULT(sberr);
}

uint32_t SBTarget::GetNumWatchpoints() const {
  LLDB_RECORD_METHOD_CONST_NO_ARGS(uint32_t, SBTarget, GetNumWatchpoints);

  TargetSP target_sp(GetSP());
  if (target_sp) {
    // The watchpoint list is thread safe, no need to lock
    return target_sp->GetWatchpointList().GetSize();
  }
  return 0;
}

SBWatchpoint SBTarget::GetWatchpointAtIndex(uint32_t idx) const {
  LLDB_RECORD_METHOD_CONST(lldb::SBWatchpoint, SBTarget, GetWatchpointAtIndex,
                           (uint32_t), idx);

  SBWatchpoint sb_watchpoint;
  TargetSP target_sp(GetSP());
  if (target_sp) {
    // The watchpoint list is thread safe, no need to lock
    sb_watchpoint.SetSP(target_sp->GetWatchpointList().GetByIndex(idx));
  }
  return LLDB_RECORD_RESULT(sb_watchpoint);
}

bool SBTarget::DeleteWatchpoint(watch_id_t wp_id) {
  LLDB_RECORD_METHOD(bool, SBTarget, DeleteWatchpoint, (lldb::watch_id_t),
                     wp_id);


  bool result = false;
  TargetSP target_sp(GetSP());
  if (target_sp) {
    std::lock_guard<std::recursive_mutex> guard(target_sp->GetAPIMutex());
    std::unique_lock<std::recursive_mutex> lock;
    target_sp->GetWatchpointList().GetListMutex(lock);
    result = target_sp->RemoveWatchpointByID(wp_id);
  }

  return result;
}

SBWatchpoint SBTarget::FindWatchpointByID(lldb::watch_id_t wp_id) {
  LLDB_RECORD_METHOD(lldb::SBWatchpoint, SBTarget, FindWatchpointByID,
                     (lldb::watch_id_t), wp_id);


  SBWatchpoint sb_watchpoint;
  lldb::WatchpointSP watchpoint_sp;
  TargetSP target_sp(GetSP());
  if (target_sp && wp_id != LLDB_INVALID_WATCH_ID) {
    std::lock_guard<std::recursive_mutex> guard(target_sp->GetAPIMutex());
    std::unique_lock<std::recursive_mutex> lock;
    target_sp->GetWatchpointList().GetListMutex(lock);
    watchpoint_sp = target_sp->GetWatchpointList().FindByID(wp_id);
    sb_watchpoint.SetSP(watchpoint_sp);
  }

  return LLDB_RECORD_RESULT(sb_watchpoint);
}

lldb::SBWatchpoint SBTarget::WatchAddress(lldb::addr_t addr, size_t size,
                                          bool read, bool write,
                                          SBError &error) {
  LLDB_RECORD_METHOD(lldb::SBWatchpoint, SBTarget, WatchAddress,
                     (lldb::addr_t, size_t, bool, bool, lldb::SBError &), addr,
                     size, read, write, error);

  SBWatchpoint sb_watchpoint;
  lldb::WatchpointSP watchpoint_sp;
  TargetSP target_sp(GetSP());
  if (target_sp && (read || write) && addr != LLDB_INVALID_ADDRESS &&
      size > 0) {
    std::lock_guard<std::recursive_mutex> guard(target_sp->GetAPIMutex());
    uint32_t watch_type = 0;
    if (read)
      watch_type |= LLDB_WATCH_TYPE_READ;
    if (write)
      watch_type |= LLDB_WATCH_TYPE_WRITE;
    if (watch_type == 0) {
      error.SetErrorString(
          "Can't create a watchpoint that is neither read nor write.");
      return LLDB_RECORD_RESULT(sb_watchpoint);
    }

    // Target::CreateWatchpoint() is thread safe.
    Status cw_error;
    // This API doesn't take in a type, so we can't figure out what it is.
    CompilerType *type = NULL;
    watchpoint_sp =
        target_sp->CreateWatchpoint(addr, size, type, watch_type, cw_error);
    error.SetError(cw_error);
    sb_watchpoint.SetSP(watchpoint_sp);
  }

  return LLDB_RECORD_RESULT(sb_watchpoint);
}

bool SBTarget::EnableAllWatchpoints() {
  LLDB_RECORD_METHOD_NO_ARGS(bool, SBTarget, EnableAllWatchpoints);

  TargetSP target_sp(GetSP());
  if (target_sp) {
    std::lock_guard<std::recursive_mutex> guard(target_sp->GetAPIMutex());
    std::unique_lock<std::recursive_mutex> lock;
    target_sp->GetWatchpointList().GetListMutex(lock);
    target_sp->EnableAllWatchpoints();
    return true;
  }
  return false;
}

bool SBTarget::DisableAllWatchpoints() {
  LLDB_RECORD_METHOD_NO_ARGS(bool, SBTarget, DisableAllWatchpoints);

  TargetSP target_sp(GetSP());
  if (target_sp) {
    std::lock_guard<std::recursive_mutex> guard(target_sp->GetAPIMutex());
    std::unique_lock<std::recursive_mutex> lock;
    target_sp->GetWatchpointList().GetListMutex(lock);
    target_sp->DisableAllWatchpoints();
    return true;
  }
  return false;
}

SBValue SBTarget::CreateValueFromAddress(const char *name, SBAddress addr,
                                         SBType type) {
  LLDB_RECORD_METHOD(lldb::SBValue, SBTarget, CreateValueFromAddress,
                     (const char *, lldb::SBAddress, lldb::SBType), name, addr,
                     type);

  SBValue sb_value;
  lldb::ValueObjectSP new_value_sp;
  if (IsValid() && name && *name && addr.IsValid() && type.IsValid()) {
    lldb::addr_t load_addr(addr.GetLoadAddress(*this));
    ExecutionContext exe_ctx(
        ExecutionContextRef(ExecutionContext(m_opaque_sp.get(), false)));
    CompilerType ast_type(type.GetSP()->GetCompilerType(true));
    new_value_sp = ValueObject::CreateValueObjectFromAddress(name, load_addr,
                                                             exe_ctx, ast_type);
  }
  sb_value.SetSP(new_value_sp);
  return LLDB_RECORD_RESULT(sb_value);
}

lldb::SBValue SBTarget::CreateValueFromData(const char *name, lldb::SBData data,
                                            lldb::SBType type) {
  LLDB_RECORD_METHOD(lldb::SBValue, SBTarget, CreateValueFromData,
                     (const char *, lldb::SBData, lldb::SBType), name, data,
                     type);

  SBValue sb_value;
  lldb::ValueObjectSP new_value_sp;
  if (IsValid() && name && *name && data.IsValid() && type.IsValid()) {
    DataExtractorSP extractor(*data);
    ExecutionContext exe_ctx(
        ExecutionContextRef(ExecutionContext(m_opaque_sp.get(), false)));
    CompilerType ast_type(type.GetSP()->GetCompilerType(true));
    new_value_sp = ValueObject::CreateValueObjectFromData(name, *extractor,
                                                          exe_ctx, ast_type);
  }
  sb_value.SetSP(new_value_sp);
  return LLDB_RECORD_RESULT(sb_value);
}

lldb::SBValue SBTarget::CreateValueFromExpression(const char *name,
                                                  const char *expr) {
  LLDB_RECORD_METHOD(lldb::SBValue, SBTarget, CreateValueFromExpression,
                     (const char *, const char *), name, expr);

  SBValue sb_value;
  lldb::ValueObjectSP new_value_sp;
  if (IsValid() && name && *name && expr && *expr) {
    ExecutionContext exe_ctx(
        ExecutionContextRef(ExecutionContext(m_opaque_sp.get(), false)));
    new_value_sp =
        ValueObject::CreateValueObjectFromExpression(name, expr, exe_ctx);
  }
  sb_value.SetSP(new_value_sp);
  return LLDB_RECORD_RESULT(sb_value);
}

bool SBTarget::DeleteAllWatchpoints() {
  LLDB_RECORD_METHOD_NO_ARGS(bool, SBTarget, DeleteAllWatchpoints);

  TargetSP target_sp(GetSP());
  if (target_sp) {
    std::lock_guard<std::recursive_mutex> guard(target_sp->GetAPIMutex());
    std::unique_lock<std::recursive_mutex> lock;
    target_sp->GetWatchpointList().GetListMutex(lock);
    target_sp->RemoveAllWatchpoints();
    return true;
  }
  return false;
}

void SBTarget::AppendImageSearchPath(const char *from, const char *to,
                                     lldb::SBError &error) {
  LLDB_RECORD_METHOD(void, SBTarget, AppendImageSearchPath,
                     (const char *, const char *, lldb::SBError &), from, to,
                     error);

  TargetSP target_sp(GetSP());
  if (!target_sp)
    return error.SetErrorString("invalid target");

  const ConstString csFrom(from), csTo(to);
  if (!csFrom)
    return error.SetErrorString("<from> path can't be empty");
  if (!csTo)
    return error.SetErrorString("<to> path can't be empty");

  target_sp->GetImageSearchPathList().Append(csFrom, csTo, true);
}

lldb::SBModule SBTarget::AddModule(const char *path, const char *triple,
                                   const char *uuid_cstr) {
  LLDB_RECORD_METHOD(lldb::SBModule, SBTarget, AddModule,
                     (const char *, const char *, const char *), path, triple,
                     uuid_cstr);

  return LLDB_RECORD_RESULT(AddModule(path, triple, uuid_cstr, NULL));
}

lldb::SBModule SBTarget::AddModule(const char *path, const char *triple,
                                   const char *uuid_cstr, const char *symfile) {
  LLDB_RECORD_METHOD(lldb::SBModule, SBTarget, AddModule,
                     (const char *, const char *, const char *, const char *),
                     path, triple, uuid_cstr, symfile);

  lldb::SBModule sb_module;
  TargetSP target_sp(GetSP());
  if (target_sp) {
    ModuleSpec module_spec;
    if (path)
      module_spec.GetFileSpec().SetFile(path, FileSpec::Style::native);

    if (uuid_cstr)
      module_spec.GetUUID().SetFromStringRef(uuid_cstr);

    if (triple)
      module_spec.GetArchitecture() = Platform::GetAugmentedArchSpec(
          target_sp->GetPlatform().get(), triple);
    else
      module_spec.GetArchitecture() = target_sp->GetArchitecture();

    if (symfile)
      module_spec.GetSymbolFileSpec().SetFile(symfile, FileSpec::Style::native);

    sb_module.SetSP(target_sp->GetOrCreateModule(module_spec, true /* notify */));
  }
  return LLDB_RECORD_RESULT(sb_module);
}

lldb::SBModule SBTarget::AddModule(const SBModuleSpec &module_spec) {
  LLDB_RECORD_METHOD(lldb::SBModule, SBTarget, AddModule,
                     (const lldb::SBModuleSpec &), module_spec);

  lldb::SBModule sb_module;
  TargetSP target_sp(GetSP());
  if (target_sp)
    sb_module.SetSP(target_sp->GetOrCreateModule(*module_spec.m_opaque_up, 
                                                 true /* notify */));
  return LLDB_RECORD_RESULT(sb_module);
}

bool SBTarget::AddModule(lldb::SBModule &module) {
  LLDB_RECORD_METHOD(bool, SBTarget, AddModule, (lldb::SBModule &), module);

  TargetSP target_sp(GetSP());
  if (target_sp) {
    target_sp->GetImages().AppendIfNeeded(module.GetSP());
    return true;
  }
  return false;
}

uint32_t SBTarget::GetNumModules() const {
  LLDB_RECORD_METHOD_CONST_NO_ARGS(uint32_t, SBTarget, GetNumModules);

  uint32_t num = 0;
  TargetSP target_sp(GetSP());
  if (target_sp) {
    // The module list is thread safe, no need to lock
    num = target_sp->GetImages().GetSize();
  }

  return num;
}

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

  m_opaque_sp.reset();
}

SBModule SBTarget::FindModule(const SBFileSpec &sb_file_spec) {
  LLDB_RECORD_METHOD(lldb::SBModule, SBTarget, FindModule,
                     (const lldb::SBFileSpec &), sb_file_spec);

  SBModule sb_module;
  TargetSP target_sp(GetSP());
  if (target_sp && sb_file_spec.IsValid()) {
    ModuleSpec module_spec(*sb_file_spec);
    // The module list is thread safe, no need to lock
    sb_module.SetSP(target_sp->GetImages().FindFirstModule(module_spec));
  }
  return LLDB_RECORD_RESULT(sb_module);
}

SBSymbolContextList SBTarget::FindCompileUnits(const SBFileSpec &sb_file_spec) {
  LLDB_RECORD_METHOD(lldb::SBSymbolContextList, SBTarget, FindCompileUnits,
                     (const lldb::SBFileSpec &), sb_file_spec);

  SBSymbolContextList sb_sc_list;
  const TargetSP target_sp(GetSP());
  if (target_sp && sb_file_spec.IsValid()) {
    const bool append = true;
    target_sp->GetImages().FindCompileUnits(*sb_file_spec,
                                            append, *sb_sc_list);
  }
  return LLDB_RECORD_RESULT(sb_sc_list);
}

lldb::ByteOrder SBTarget::GetByteOrder() {
  LLDB_RECORD_METHOD_NO_ARGS(lldb::ByteOrder, SBTarget, GetByteOrder);

  TargetSP target_sp(GetSP());
  if (target_sp)
    return target_sp->GetArchitecture().GetByteOrder();
  return eByteOrderInvalid;
}

const char *SBTarget::GetTriple() {
  LLDB_RECORD_METHOD_NO_ARGS(const char *, SBTarget, GetTriple);

  TargetSP target_sp(GetSP());
  if (target_sp) {
    std::string triple(target_sp->GetArchitecture().GetTriple().str());
    // Unique the string so we don't run into ownership issues since the const
    // strings put the string into the string pool once and the strings never
    // comes out
    ConstString const_triple(triple.c_str());
    return const_triple.GetCString();
  }
  return NULL;
}

uint32_t SBTarget::GetDataByteSize() {
  LLDB_RECORD_METHOD_NO_ARGS(uint32_t, SBTarget, GetDataByteSize);

  TargetSP target_sp(GetSP());
  if (target_sp) {
    return target_sp->GetArchitecture().GetDataByteSize();
  }
  return 0;
}

uint32_t SBTarget::GetCodeByteSize() {
  LLDB_RECORD_METHOD_NO_ARGS(uint32_t, SBTarget, GetCodeByteSize);

  TargetSP target_sp(GetSP());
  if (target_sp) {
    return target_sp->GetArchitecture().GetCodeByteSize();
  }
  return 0;
}

uint32_t SBTarget::GetAddressByteSize() {
  LLDB_RECORD_METHOD_NO_ARGS(uint32_t, SBTarget, GetAddressByteSize);

  TargetSP target_sp(GetSP());
  if (target_sp)
    return target_sp->GetArchitecture().GetAddressByteSize();
  return sizeof(void *);
}

SBModule SBTarget::GetModuleAtIndex(uint32_t idx) {
  LLDB_RECORD_METHOD(lldb::SBModule, SBTarget, GetModuleAtIndex, (uint32_t),
                     idx);

  SBModule sb_module;
  ModuleSP module_sp;
  TargetSP target_sp(GetSP());
  if (target_sp) {
    // The module list is thread safe, no need to lock
    module_sp = target_sp->GetImages().GetModuleAtIndex(idx);
    sb_module.SetSP(module_sp);
  }

  return LLDB_RECORD_RESULT(sb_module);
}

bool SBTarget::RemoveModule(lldb::SBModule module) {
  LLDB_RECORD_METHOD(bool, SBTarget, RemoveModule, (lldb::SBModule), module);

  TargetSP target_sp(GetSP());
  if (target_sp)
    return target_sp->GetImages().Remove(module.GetSP());
  return false;
}

SBBroadcaster SBTarget::GetBroadcaster() const {
  LLDB_RECORD_METHOD_CONST_NO_ARGS(lldb::SBBroadcaster, SBTarget,
                                   GetBroadcaster);


  TargetSP target_sp(GetSP());
  SBBroadcaster broadcaster(target_sp.get(), false);


  return LLDB_RECORD_RESULT(broadcaster);
}

bool SBTarget::GetDescription(SBStream &description,
                              lldb::DescriptionLevel description_level) {
  LLDB_RECORD_METHOD(bool, SBTarget, GetDescription,
                     (lldb::SBStream &, lldb::DescriptionLevel), description,
                     description_level);

  Stream &strm = description.ref();

  TargetSP target_sp(GetSP());
  if (target_sp) {
    target_sp->Dump(&strm, description_level);
  } else
    strm.PutCString("No value");

  return true;
}

lldb::SBSymbolContextList SBTarget::FindFunctions(const char *name,
                                                  uint32_t name_type_mask) {
  LLDB_RECORD_METHOD(lldb::SBSymbolContextList, SBTarget, FindFunctions,
                     (const char *, uint32_t), name, name_type_mask);

  lldb::SBSymbolContextList sb_sc_list;
  if (!name | !name[0])
    return LLDB_RECORD_RESULT(sb_sc_list);

  TargetSP target_sp(GetSP());
  if (!target_sp)
    return LLDB_RECORD_RESULT(sb_sc_list);

  const bool symbols_ok = true;
  const bool inlines_ok = true;
  const bool append = true;
  FunctionNameType mask = static_cast<FunctionNameType>(name_type_mask);
  target_sp->GetImages().FindFunctions(ConstString(name), mask, symbols_ok,
                                       inlines_ok, append, *sb_sc_list);
  return LLDB_RECORD_RESULT(sb_sc_list);
}

lldb::SBSymbolContextList SBTarget::FindGlobalFunctions(const char *name,
                                                        uint32_t max_matches,
                                                        MatchType matchtype) {
  LLDB_RECORD_METHOD(lldb::SBSymbolContextList, SBTarget, FindGlobalFunctions,
                     (const char *, uint32_t, lldb::MatchType), name,
                     max_matches, matchtype);

  lldb::SBSymbolContextList sb_sc_list;
  if (name && name[0]) {
    llvm::StringRef name_ref(name);
    TargetSP target_sp(GetSP());
    if (target_sp) {
      std::string regexstr;
      switch (matchtype) {
      case eMatchTypeRegex:
        target_sp->GetImages().FindFunctions(RegularExpression(name_ref), true,
                                             true, true, *sb_sc_list);
        break;
      case eMatchTypeStartsWith:
        regexstr = llvm::Regex::escape(name) + ".*";
        target_sp->GetImages().FindFunctions(RegularExpression(regexstr), true,
                                             true, true, *sb_sc_list);
        break;
      default:
        target_sp->GetImages().FindFunctions(ConstString(name),
                                             eFunctionNameTypeAny, true, true,
                                             true, *sb_sc_list);
        break;
      }
    }
  }
  return LLDB_RECORD_RESULT(sb_sc_list);
}

lldb::SBType SBTarget::FindFirstType(const char *typename_cstr) {
  LLDB_RECORD_METHOD(lldb::SBType, SBTarget, FindFirstType, (const char *),
                     typename_cstr);

  TargetSP target_sp(GetSP());
  if (typename_cstr && typename_cstr[0] && target_sp) {
    ConstString const_typename(typename_cstr);
    SymbolContext sc;
    const bool exact_match = false;

    const ModuleList &module_list = target_sp->GetImages();
    size_t count = module_list.GetSize();
    for (size_t idx = 0; idx < count; idx++) {
      ModuleSP module_sp(module_list.GetModuleAtIndex(idx));
      if (module_sp) {
        TypeSP type_sp(
            module_sp->FindFirstType(sc, const_typename, exact_match));
        if (type_sp)
          return LLDB_RECORD_RESULT(SBType(type_sp));
      }
    }

    // Didn't find the type in the symbols; try the Objective-C runtime if one
    // is installed

    ProcessSP process_sp(target_sp->GetProcessSP());

    if (process_sp) {
      ObjCLanguageRuntime *objc_language_runtime =
          process_sp->GetObjCLanguageRuntime();

      if (objc_language_runtime) {
        DeclVendor *objc_decl_vendor = objc_language_runtime->GetDeclVendor();

        if (objc_decl_vendor) {
          std::vector<clang::NamedDecl *> decls;

          if (objc_decl_vendor->FindDecls(const_typename, true, 1, decls) > 0) {
            if (CompilerType type = ClangASTContext::GetTypeForDecl(decls[0])) {
              return LLDB_RECORD_RESULT(SBType(type));
            }
          }
        }
      }
    }

    // No matches, search for basic typename matches
    ClangASTContext *clang_ast = target_sp->GetScratchClangASTContext();
    if (clang_ast)
      return LLDB_RECORD_RESULT(SBType(ClangASTContext::GetBasicType(
          clang_ast->getASTContext(), const_typename)));
  }
  return LLDB_RECORD_RESULT(SBType());
}

SBType SBTarget::GetBasicType(lldb::BasicType type) {
  LLDB_RECORD_METHOD(lldb::SBType, SBTarget, GetBasicType, (lldb::BasicType),
                     type);

  TargetSP target_sp(GetSP());
  if (target_sp) {
    ClangASTContext *clang_ast = target_sp->GetScratchClangASTContext();
    if (clang_ast)
      return LLDB_RECORD_RESULT(SBType(
          ClangASTContext::GetBasicType(clang_ast->getASTContext(), type)));
  }
  return LLDB_RECORD_RESULT(SBType());
}

lldb::SBTypeList SBTarget::FindTypes(const char *typename_cstr) {
  LLDB_RECORD_METHOD(lldb::SBTypeList, SBTarget, FindTypes, (const char *),
                     typename_cstr);

  SBTypeList sb_type_list;
  TargetSP target_sp(GetSP());
  if (typename_cstr && typename_cstr[0] && target_sp) {
    ModuleList &images = target_sp->GetImages();
    ConstString const_typename(typename_cstr);
    bool exact_match = false;
    TypeList type_list;
    llvm::DenseSet<SymbolFile *> searched_symbol_files;
    uint32_t num_matches =
        images.FindTypes(nullptr, const_typename, exact_match, UINT32_MAX,
                         searched_symbol_files, type_list);

    if (num_matches > 0) {
      for (size_t idx = 0; idx < num_matches; idx++) {
        TypeSP type_sp(type_list.GetTypeAtIndex(idx));
        if (type_sp)
          sb_type_list.Append(SBType(type_sp));
      }
    }

    // Try the Objective-C runtime if one is installed

    ProcessSP process_sp(target_sp->GetProcessSP());

    if (process_sp) {
      ObjCLanguageRuntime *objc_language_runtime =
          process_sp->GetObjCLanguageRuntime();

      if (objc_language_runtime) {
        DeclVendor *objc_decl_vendor = objc_language_runtime->GetDeclVendor();

        if (objc_decl_vendor) {
          std::vector<clang::NamedDecl *> decls;

          if (objc_decl_vendor->FindDecls(const_typename, true, 1, decls) > 0) {
            for (clang::NamedDecl *decl : decls) {
              if (CompilerType type = ClangASTContext::GetTypeForDecl(decl)) {
                sb_type_list.Append(SBType(type));
              }
            }
          }
        }
      }
    }

    if (sb_type_list.GetSize() == 0) {
      // No matches, search for basic typename matches
      ClangASTContext *clang_ast = target_sp->GetScratchClangASTContext();
      if (clang_ast)
        sb_type_list.Append(SBType(ClangASTContext::GetBasicType(
            clang_ast->getASTContext(), const_typename)));
    }
  }
  return LLDB_RECORD_RESULT(sb_type_list);
}

SBValueList SBTarget::FindGlobalVariables(const char *name,
                                          uint32_t max_matches) {
  LLDB_RECORD_METHOD(lldb::SBValueList, SBTarget, FindGlobalVariables,
                     (const char *, uint32_t), name, max_matches);

  SBValueList sb_value_list;

  TargetSP target_sp(GetSP());
  if (name && target_sp) {
    VariableList variable_list;
    const uint32_t match_count = target_sp->GetImages().FindGlobalVariables(
        ConstString(name), max_matches, variable_list);

    if (match_count > 0) {
      ExecutionContextScope *exe_scope = target_sp->GetProcessSP().get();
      if (exe_scope == NULL)
        exe_scope = target_sp.get();
      for (uint32_t i = 0; i < match_count; ++i) {
        lldb::ValueObjectSP valobj_sp(ValueObjectVariable::Create(
            exe_scope, variable_list.GetVariableAtIndex(i)));
        if (valobj_sp)
          sb_value_list.Append(SBValue(valobj_sp));
      }
    }
  }

  return LLDB_RECORD_RESULT(sb_value_list);
}

SBValueList SBTarget::FindGlobalVariables(const char *name,
                                          uint32_t max_matches,
                                          MatchType matchtype) {
  LLDB_RECORD_METHOD(lldb::SBValueList, SBTarget, FindGlobalVariables,
                     (const char *, uint32_t, lldb::MatchType), name,
                     max_matches, matchtype);

  SBValueList sb_value_list;

  TargetSP target_sp(GetSP());
  if (name && target_sp) {
    llvm::StringRef name_ref(name);
    VariableList variable_list;

    std::string regexstr;
    uint32_t match_count;
    switch (matchtype) {
    case eMatchTypeNormal:
      match_count = target_sp->GetImages().FindGlobalVariables(
          ConstString(name), max_matches, variable_list);
      break;
    case eMatchTypeRegex:
      match_count = target_sp->GetImages().FindGlobalVariables(
          RegularExpression(name_ref), max_matches, variable_list);
      break;
    case eMatchTypeStartsWith:
      regexstr = llvm::Regex::escape(name) + ".*";
      match_count = target_sp->GetImages().FindGlobalVariables(
          RegularExpression(regexstr), max_matches, variable_list);
      break;
    }

    if (match_count > 0) {
      ExecutionContextScope *exe_scope = target_sp->GetProcessSP().get();
      if (exe_scope == NULL)
        exe_scope = target_sp.get();
      for (uint32_t i = 0; i < match_count; ++i) {
        lldb::ValueObjectSP valobj_sp(ValueObjectVariable::Create(
            exe_scope, variable_list.GetVariableAtIndex(i)));
        if (valobj_sp)
          sb_value_list.Append(SBValue(valobj_sp));
      }
    }
  }

  return LLDB_RECORD_RESULT(sb_value_list);
}

lldb::SBValue SBTarget::FindFirstGlobalVariable(const char *name) {
  LLDB_RECORD_METHOD(lldb::SBValue, SBTarget, FindFirstGlobalVariable,
                     (const char *), name);

  SBValueList sb_value_list(FindGlobalVariables(name, 1));
  if (sb_value_list.IsValid() && sb_value_list.GetSize() > 0)
    return LLDB_RECORD_RESULT(sb_value_list.GetValueAtIndex(0));
  return LLDB_RECORD_RESULT(SBValue());
}

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

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

lldb::SBInstructionList SBTarget::ReadInstructions(lldb::SBAddress base_addr,
                                                   uint32_t count) {
  LLDB_RECORD_METHOD(lldb::SBInstructionList, SBTarget, ReadInstructions,
                     (lldb::SBAddress, uint32_t), base_addr, count);

  return LLDB_RECORD_RESULT(ReadInstructions(base_addr, count, NULL));
}

lldb::SBInstructionList SBTarget::ReadInstructions(lldb::SBAddress base_addr,
                                                   uint32_t count,
                                                   const char *flavor_string) {
  LLDB_RECORD_METHOD(lldb::SBInstructionList, SBTarget, ReadInstructions,
                     (lldb::SBAddress, uint32_t, const char *), base_addr,
                     count, flavor_string);

  SBInstructionList sb_instructions;

  TargetSP target_sp(GetSP());
  if (target_sp) {
    Address *addr_ptr = base_addr.get();

    if (addr_ptr) {
      DataBufferHeap data(
          target_sp->GetArchitecture().GetMaximumOpcodeByteSize() * count, 0);
      bool prefer_file_cache = false;
      lldb_private::Status error;
      lldb::addr_t load_addr = LLDB_INVALID_ADDRESS;
      const size_t bytes_read =
          target_sp->ReadMemory(*addr_ptr, prefer_file_cache, data.GetBytes(),
                                data.GetByteSize(), error, &load_addr);
      const bool data_from_file = load_addr == LLDB_INVALID_ADDRESS;
      sb_instructions.SetDisassembler(Disassembler::DisassembleBytes(
          target_sp->GetArchitecture(), NULL, flavor_string, *addr_ptr,
          data.GetBytes(), bytes_read, count, data_from_file));
    }
  }

  return LLDB_RECORD_RESULT(sb_instructions);
}

lldb::SBInstructionList SBTarget::GetInstructions(lldb::SBAddress base_addr,
                                                  const void *buf,
                                                  size_t size) {
  LLDB_RECORD_DUMMY(lldb::SBInstructionList, SBTarget, GetInstructions,
                    (lldb::SBAddress, const void *, size_t), base_addr, buf,
                    size);

  return GetInstructionsWithFlavor(base_addr, NULL, buf, size);
}

lldb::SBInstructionList
SBTarget::GetInstructionsWithFlavor(lldb::SBAddress base_addr,
                                    const char *flavor_string, const void *buf,
                                    size_t size) {
  LLDB_RECORD_DUMMY(lldb::SBInstructionList, SBTarget,
                    GetInstructionsWithFlavor,
                    (lldb::SBAddress, const char *, const void *, size_t),
                    base_addr, flavor_string, buf, size);

  SBInstructionList sb_instructions;

  TargetSP target_sp(GetSP());
  if (target_sp) {
    Address addr;

    if (base_addr.get())
      addr = *base_addr.get();

    const bool data_from_file = true;

    sb_instructions.SetDisassembler(Disassembler::DisassembleBytes(
        target_sp->GetArchitecture(), NULL, flavor_string, addr, buf, size,
        UINT32_MAX, data_from_file));
  }

  return sb_instructions;
}

lldb::SBInstructionList SBTarget::GetInstructions(lldb::addr_t base_addr,
                                                  const void *buf,
                                                  size_t size) {
  LLDB_RECORD_DUMMY(lldb::SBInstructionList, SBTarget, GetInstructions,
                    (lldb::addr_t, const void *, size_t), base_addr, buf, size);

  return GetInstructionsWithFlavor(ResolveLoadAddress(base_addr), NULL, buf,
                                   size);
}

lldb::SBInstructionList
SBTarget::GetInstructionsWithFlavor(lldb::addr_t base_addr,
                                    const char *flavor_string, const void *buf,
                                    size_t size) {
  LLDB_RECORD_DUMMY(lldb::SBInstructionList, SBTarget,
                    GetInstructionsWithFlavor,
                    (lldb::addr_t, const char *, const void *, size_t),
                    base_addr, flavor_string, buf, size);

  return GetInstructionsWithFlavor(ResolveLoadAddress(base_addr), flavor_string,
                                   buf, size);
}

SBError SBTarget::SetSectionLoadAddress(lldb::SBSection section,
                                        lldb::addr_t section_base_addr) {
  LLDB_RECORD_METHOD(lldb::SBError, SBTarget, SetSectionLoadAddress,
                     (lldb::SBSection, lldb::addr_t), section,
                     section_base_addr);

  SBError sb_error;
  TargetSP target_sp(GetSP());
  if (target_sp) {
    if (!section.IsValid()) {
      sb_error.SetErrorStringWithFormat("invalid section");
    } else {
      SectionSP section_sp(section.GetSP());
      if (section_sp) {
        if (section_sp->IsThreadSpecific()) {
          sb_error.SetErrorString(
              "thread specific sections are not yet supported");
        } else {
          ProcessSP process_sp(target_sp->GetProcessSP());
          if (target_sp->SetSectionLoadAddress(section_sp, section_base_addr)) {
            ModuleSP module_sp(section_sp->GetModule());
            if (module_sp) {
              ModuleList module_list;
              module_list.Append(module_sp);
              target_sp->ModulesDidLoad(module_list);
            }
            // Flush info in the process (stack frames, etc)
            if (process_sp)
              process_sp->Flush();
          }
        }
      }
    }
  } else {
    sb_error.SetErrorString("invalid target");
  }
  return LLDB_RECORD_RESULT(sb_error);
}

SBError SBTarget::ClearSectionLoadAddress(lldb::SBSection section) {
  LLDB_RECORD_METHOD(lldb::SBError, SBTarget, ClearSectionLoadAddress,
                     (lldb::SBSection), section);

  SBError sb_error;

  TargetSP target_sp(GetSP());
  if (target_sp) {
    if (!section.IsValid()) {
      sb_error.SetErrorStringWithFormat("invalid section");
    } else {
      SectionSP section_sp(section.GetSP());
      if (section_sp) {
        ProcessSP process_sp(target_sp->GetProcessSP());
        if (target_sp->SetSectionUnloaded(section_sp)) {
          ModuleSP module_sp(section_sp->GetModule());
          if (module_sp) {
            ModuleList module_list;
            module_list.Append(module_sp);
            target_sp->ModulesDidUnload(module_list, false);
          }
          // Flush info in the process (stack frames, etc)
          if (process_sp)
            process_sp->Flush();
        }
      } else {
        sb_error.SetErrorStringWithFormat("invalid section");
      }
    }
  } else {
    sb_error.SetErrorStringWithFormat("invalid target");
  }
  return LLDB_RECORD_RESULT(sb_error);
}

SBError SBTarget::SetModuleLoadAddress(lldb::SBModule module,
                                       int64_t slide_offset) {
  LLDB_RECORD_METHOD(lldb::SBError, SBTarget, SetModuleLoadAddress,
                     (lldb::SBModule, int64_t), module, slide_offset);

  SBError sb_error;

  TargetSP target_sp(GetSP());
  if (target_sp) {
    ModuleSP module_sp(module.GetSP());
    if (module_sp) {
      bool changed = false;
      if (module_sp->SetLoadAddress(*target_sp, slide_offset, true, changed)) {
        // The load was successful, make sure that at least some sections
        // changed before we notify that our module was loaded.
        if (changed) {
          ModuleList module_list;
          module_list.Append(module_sp);
          target_sp->ModulesDidLoad(module_list);
          // Flush info in the process (stack frames, etc)
          ProcessSP process_sp(target_sp->GetProcessSP());
          if (process_sp)
            process_sp->Flush();
        }
      }
    } else {
      sb_error.SetErrorStringWithFormat("invalid module");
    }

  } else {
    sb_error.SetErrorStringWithFormat("invalid target");
  }
  return LLDB_RECORD_RESULT(sb_error);
}

SBError SBTarget::ClearModuleLoadAddress(lldb::SBModule module) {
  LLDB_RECORD_METHOD(lldb::SBError, SBTarget, ClearModuleLoadAddress,
                     (lldb::SBModule), module);

  SBError sb_error;

  char path[PATH_MAX];
  TargetSP target_sp(GetSP());
  if (target_sp) {
    ModuleSP module_sp(module.GetSP());
    if (module_sp) {
      ObjectFile *objfile = module_sp->GetObjectFile();
      if (objfile) {
        SectionList *section_list = objfile->GetSectionList();
        if (section_list) {
          ProcessSP process_sp(target_sp->GetProcessSP());

          bool changed = false;
          const size_t num_sections = section_list->GetSize();
          for (size_t sect_idx = 0; sect_idx < num_sections; ++sect_idx) {
            SectionSP section_sp(section_list->GetSectionAtIndex(sect_idx));
            if (section_sp)
              changed |= target_sp->SetSectionUnloaded(section_sp);
          }
          if (changed) {
            ModuleList module_list;
            module_list.Append(module_sp);
            target_sp->ModulesDidUnload(module_list, false);
            // Flush info in the process (stack frames, etc)
            ProcessSP process_sp(target_sp->GetProcessSP());
            if (process_sp)
              process_sp->Flush();
          }
        } else {
          module_sp->GetFileSpec().GetPath(path, sizeof(path));
          sb_error.SetErrorStringWithFormat("no sections in object file '%s'",
                                            path);
        }
      } else {
        module_sp->GetFileSpec().GetPath(path, sizeof(path));
        sb_error.SetErrorStringWithFormat("no object file for module '%s'",
                                          path);
      }
    } else {
      sb_error.SetErrorStringWithFormat("invalid module");
    }
  } else {
    sb_error.SetErrorStringWithFormat("invalid target");
  }
  return LLDB_RECORD_RESULT(sb_error);
}

lldb::SBSymbolContextList SBTarget::FindSymbols(const char *name,
                                                lldb::SymbolType symbol_type) {
  LLDB_RECORD_METHOD(lldb::SBSymbolContextList, SBTarget, FindSymbols,
                     (const char *, lldb::SymbolType), name, symbol_type);

  SBSymbolContextList sb_sc_list;
  if (name && name[0]) {
    TargetSP target_sp(GetSP());
    if (target_sp) {
      bool append = true;
      target_sp->GetImages().FindSymbolsWithNameAndType(
          ConstString(name), symbol_type, *sb_sc_list, append);
    }
  }
  return LLDB_RECORD_RESULT(sb_sc_list);
}

lldb::SBValue SBTarget::EvaluateExpression(const char *expr) {
  LLDB_RECORD_METHOD(lldb::SBValue, SBTarget, EvaluateExpression,
                     (const char *), expr);

  TargetSP target_sp(GetSP());
  if (!target_sp)
    return LLDB_RECORD_RESULT(SBValue());

  SBExpressionOptions options;
  lldb::DynamicValueType fetch_dynamic_value =
      target_sp->GetPreferDynamicValue();
  options.SetFetchDynamicValue(fetch_dynamic_value);
  options.SetUnwindOnError(true);
  return LLDB_RECORD_RESULT(EvaluateExpression(expr, options));
}

lldb::SBValue SBTarget::EvaluateExpression(const char *expr,
                                           const SBExpressionOptions &options) {
  LLDB_RECORD_METHOD(lldb::SBValue, SBTarget, EvaluateExpression,
                     (const char *, const lldb::SBExpressionOptions &), expr,
                     options);

  Log *expr_log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS));
  SBValue expr_result;
  ValueObjectSP expr_value_sp;
  TargetSP target_sp(GetSP());
  StackFrame *frame = NULL;
  if (target_sp) {
    if (expr == NULL || expr[0] == '\0') {
      return LLDB_RECORD_RESULT(expr_result);
    }

    std::lock_guard<std::recursive_mutex> guard(target_sp->GetAPIMutex());
    ExecutionContext exe_ctx(m_opaque_sp.get());


    frame = exe_ctx.GetFramePtr();
    Target *target = exe_ctx.GetTargetPtr();

    if (target) {
#ifdef LLDB_CONFIGURATION_DEBUG
      StreamString frame_description;
      if (frame)
        frame->DumpUsingSettingsFormat(&frame_description);
      llvm::PrettyStackTraceFormat stack_trace(
          "SBTarget::EvaluateExpression (expr = \"%s\", fetch_dynamic_value = "
          "%u) %s",
          expr, options.GetFetchDynamicValue(),
          frame_description.GetString().str().c_str());
#endif
      target->EvaluateExpression(expr, frame, expr_value_sp, options.ref());

      expr_result.SetSP(expr_value_sp, options.GetFetchDynamicValue());
    }
  }
  if (expr_log)
    expr_log->Printf("** [SBTarget::EvaluateExpression] Expression result is "
                     "%s, summary %s **",
                     expr_result.GetValue(), expr_result.GetSummary());
  return LLDB_RECORD_RESULT(expr_result);
}

lldb::addr_t SBTarget::GetStackRedZoneSize() {
  LLDB_RECORD_METHOD_NO_ARGS(lldb::addr_t, SBTarget, GetStackRedZoneSize);

  TargetSP target_sp(GetSP());
  if (target_sp) {
    ABISP abi_sp;
    ProcessSP process_sp(target_sp->GetProcessSP());
    if (process_sp)
      abi_sp = process_sp->GetABI();
    else
      abi_sp = ABI::FindPlugin(ProcessSP(), target_sp->GetArchitecture());
    if (abi_sp)
      return abi_sp->GetRedZoneSize();
  }
  return 0;
}

lldb::SBLaunchInfo SBTarget::GetLaunchInfo() const {
  LLDB_RECORD_METHOD_CONST_NO_ARGS(lldb::SBLaunchInfo, SBTarget, GetLaunchInfo);

  lldb::SBLaunchInfo launch_info(NULL);
  TargetSP target_sp(GetSP());
  if (target_sp)
    launch_info.set_ref(m_opaque_sp->GetProcessLaunchInfo());
  return LLDB_RECORD_RESULT(launch_info);
}

void SBTarget::SetLaunchInfo(const lldb::SBLaunchInfo &launch_info) {
  LLDB_RECORD_METHOD(void, SBTarget, SetLaunchInfo,
                     (const lldb::SBLaunchInfo &), launch_info);

  TargetSP target_sp(GetSP());
  if (target_sp)
    m_opaque_sp->SetProcessLaunchInfo(launch_info.ref());
}

namespace lldb_private {
namespace repro {

template <>
void RegisterMethods<SBTarget>(Registry &R) {
  LLDB_REGISTER_CONSTRUCTOR(SBTarget, ());
  LLDB_REGISTER_CONSTRUCTOR(SBTarget, (const lldb::SBTarget &));
  LLDB_REGISTER_CONSTRUCTOR(SBTarget, (const lldb::TargetSP &));
  LLDB_REGISTER_METHOD(const lldb::SBTarget &,
                       SBTarget, operator=,(const lldb::SBTarget &));
  LLDB_REGISTER_STATIC_METHOD(bool, SBTarget, EventIsTargetEvent,
                              (const lldb::SBEvent &));
  LLDB_REGISTER_STATIC_METHOD(lldb::SBTarget, SBTarget, GetTargetFromEvent,
                              (const lldb::SBEvent &));
  LLDB_REGISTER_STATIC_METHOD(uint32_t, SBTarget, GetNumModulesFromEvent,
                              (const lldb::SBEvent &));
  LLDB_REGISTER_STATIC_METHOD(lldb::SBModule, SBTarget,
                              GetModuleAtIndexFromEvent,
                              (const uint32_t, const lldb::SBEvent &));
  LLDB_REGISTER_STATIC_METHOD(const char *, SBTarget, GetBroadcasterClassName,
                              ());
  LLDB_REGISTER_METHOD_CONST(bool, SBTarget, IsValid, ());
  LLDB_REGISTER_METHOD_CONST(bool, SBTarget, operator bool, ());
  LLDB_REGISTER_METHOD(lldb::SBProcess, SBTarget, GetProcess, ());
  LLDB_REGISTER_METHOD(lldb::SBPlatform, SBTarget, GetPlatform, ());
  LLDB_REGISTER_METHOD_CONST(lldb::SBDebugger, SBTarget, GetDebugger, ());
  LLDB_REGISTER_METHOD(lldb::SBStructuredData, SBTarget, GetStatistics, ());
  LLDB_REGISTER_METHOD(void, SBTarget, SetCollectingStats, (bool));
  LLDB_REGISTER_METHOD(bool, SBTarget, GetCollectingStats, ());
  LLDB_REGISTER_METHOD(lldb::SBProcess, SBTarget, LoadCore, (const char *));
  LLDB_REGISTER_METHOD(lldb::SBProcess, SBTarget, LoadCore,
                       (const char *, lldb::SBError &));
  LLDB_REGISTER_METHOD(lldb::SBProcess, SBTarget, LaunchSimple,
                       (const char **, const char **, const char *));
  LLDB_REGISTER_METHOD(lldb::SBError, SBTarget, Install, ());
  LLDB_REGISTER_METHOD(lldb::SBProcess, SBTarget, Launch,
                       (lldb::SBListener &, const char **, const char **,
                        const char *, const char *, const char *,
                        const char *, uint32_t, bool, lldb::SBError &));
  LLDB_REGISTER_METHOD(lldb::SBProcess, SBTarget, Launch,
                       (lldb::SBLaunchInfo &, lldb::SBError &));
  LLDB_REGISTER_METHOD(lldb::SBProcess, SBTarget, Attach,
                       (lldb::SBAttachInfo &, lldb::SBError &));
  LLDB_REGISTER_METHOD(lldb::SBProcess, SBTarget, AttachToProcessWithID,
                       (lldb::SBListener &, lldb::pid_t, lldb::SBError &));
  LLDB_REGISTER_METHOD(
      lldb::SBProcess, SBTarget, AttachToProcessWithName,
      (lldb::SBListener &, const char *, bool, lldb::SBError &));
  LLDB_REGISTER_METHOD(
      lldb::SBProcess, SBTarget, ConnectRemote,
      (lldb::SBListener &, const char *, const char *, lldb::SBError &));
  LLDB_REGISTER_METHOD(lldb::SBFileSpec, SBTarget, GetExecutable, ());
  LLDB_REGISTER_METHOD_CONST(bool,
                             SBTarget, operator==,(const lldb::SBTarget &));
  LLDB_REGISTER_METHOD_CONST(bool,
                             SBTarget, operator!=,(const lldb::SBTarget &));
  LLDB_REGISTER_METHOD(lldb::SBAddress, SBTarget, ResolveLoadAddress,
                       (lldb::addr_t));
  LLDB_REGISTER_METHOD(lldb::SBAddress, SBTarget, ResolveFileAddress,
                       (lldb::addr_t));
  LLDB_REGISTER_METHOD(lldb::SBAddress, SBTarget, ResolvePastLoadAddress,
                       (uint32_t, lldb::addr_t));
  LLDB_REGISTER_METHOD(lldb::SBSymbolContext, SBTarget,
                       ResolveSymbolContextForAddress,
                       (const lldb::SBAddress &, uint32_t));
  LLDB_REGISTER_METHOD(lldb::SBBreakpoint, SBTarget,
                       BreakpointCreateByLocation, (const char *, uint32_t));
  LLDB_REGISTER_METHOD(lldb::SBBreakpoint, SBTarget,
                       BreakpointCreateByLocation,
                       (const lldb::SBFileSpec &, uint32_t));
  LLDB_REGISTER_METHOD(lldb::SBBreakpoint, SBTarget,
                       BreakpointCreateByLocation,
                       (const lldb::SBFileSpec &, uint32_t, lldb::addr_t));
  LLDB_REGISTER_METHOD(lldb::SBBreakpoint, SBTarget,
                       BreakpointCreateByLocation,
                       (const lldb::SBFileSpec &, uint32_t, lldb::addr_t,
                        lldb::SBFileSpecList &));
  LLDB_REGISTER_METHOD(lldb::SBBreakpoint, SBTarget,
                       BreakpointCreateByLocation,
                       (const lldb::SBFileSpec &, uint32_t, uint32_t,
                        lldb::addr_t, lldb::SBFileSpecList &));
  LLDB_REGISTER_METHOD(lldb::SBBreakpoint, SBTarget, BreakpointCreateByName,
                       (const char *, const char *));
  LLDB_REGISTER_METHOD(lldb::SBBreakpoint, SBTarget, BreakpointCreateByName,
                       (const char *, const lldb::SBFileSpecList &,
                        const lldb::SBFileSpecList &));
  LLDB_REGISTER_METHOD(lldb::SBBreakpoint, SBTarget, BreakpointCreateByName,
                       (const char *, uint32_t, const lldb::SBFileSpecList &,
                        const lldb::SBFileSpecList &));
  LLDB_REGISTER_METHOD(lldb::SBBreakpoint, SBTarget, BreakpointCreateByName,
                       (const char *, uint32_t, lldb::LanguageType,
                        const lldb::SBFileSpecList &,
                        const lldb::SBFileSpecList &));
  LLDB_REGISTER_METHOD(lldb::SBBreakpoint, SBTarget, BreakpointCreateByNames,
                       (const char **, uint32_t, uint32_t,
                        const lldb::SBFileSpecList &,
                        const lldb::SBFileSpecList &));
  LLDB_REGISTER_METHOD(lldb::SBBreakpoint, SBTarget, BreakpointCreateByNames,
                       (const char **, uint32_t, uint32_t, lldb::LanguageType,
                        const lldb::SBFileSpecList &,
                        const lldb::SBFileSpecList &));
  LLDB_REGISTER_METHOD(lldb::SBBreakpoint, SBTarget, BreakpointCreateByNames,
                       (const char **, uint32_t, uint32_t, lldb::LanguageType,
                        lldb::addr_t, const lldb::SBFileSpecList &,
                        const lldb::SBFileSpecList &));
  LLDB_REGISTER_METHOD(lldb::SBBreakpoint, SBTarget, BreakpointCreateByRegex,
                       (const char *, const char *));
  LLDB_REGISTER_METHOD(lldb::SBBreakpoint, SBTarget, BreakpointCreateByRegex,
                       (const char *, const lldb::SBFileSpecList &,
                        const lldb::SBFileSpecList &));
  LLDB_REGISTER_METHOD(lldb::SBBreakpoint, SBTarget, BreakpointCreateByRegex,
                       (const char *, lldb::LanguageType,
                        const lldb::SBFileSpecList &,
                        const lldb::SBFileSpecList &));
  LLDB_REGISTER_METHOD(lldb::SBBreakpoint, SBTarget,
                       BreakpointCreateByAddress, (lldb::addr_t));
  LLDB_REGISTER_METHOD(lldb::SBBreakpoint, SBTarget,
                       BreakpointCreateBySBAddress, (lldb::SBAddress &));
  LLDB_REGISTER_METHOD(
      lldb::SBBreakpoint, SBTarget, BreakpointCreateBySourceRegex,
      (const char *, const lldb::SBFileSpec &, const char *));
  LLDB_REGISTER_METHOD(lldb::SBBreakpoint, SBTarget,
                       BreakpointCreateBySourceRegex,
                       (const char *, const lldb::SBFileSpecList &,
                        const lldb::SBFileSpecList &));
  LLDB_REGISTER_METHOD(
      lldb::SBBreakpoint, SBTarget, BreakpointCreateBySourceRegex,
      (const char *, const lldb::SBFileSpecList &,
       const lldb::SBFileSpecList &, const lldb::SBStringList &));
  LLDB_REGISTER_METHOD(lldb::SBBreakpoint, SBTarget,
                       BreakpointCreateForException,
                       (lldb::LanguageType, bool, bool));
  LLDB_REGISTER_METHOD(
      lldb::SBBreakpoint, SBTarget, BreakpointCreateFromScript,
      (const char *, lldb::SBStructuredData &, const lldb::SBFileSpecList &,
       const lldb::SBFileSpecList &, bool));
  LLDB_REGISTER_METHOD_CONST(uint32_t, SBTarget, GetNumBreakpoints, ());
  LLDB_REGISTER_METHOD_CONST(lldb::SBBreakpoint, SBTarget,
                             GetBreakpointAtIndex, (uint32_t));
  LLDB_REGISTER_METHOD(bool, SBTarget, BreakpointDelete, (lldb::break_id_t));
  LLDB_REGISTER_METHOD(lldb::SBBreakpoint, SBTarget, FindBreakpointByID,
                       (lldb::break_id_t));
  LLDB_REGISTER_METHOD(bool, SBTarget, FindBreakpointsByName,
                       (const char *, lldb::SBBreakpointList &));
  LLDB_REGISTER_METHOD(void, SBTarget, GetBreakpointNames,
                       (lldb::SBStringList &));
  LLDB_REGISTER_METHOD(void, SBTarget, DeleteBreakpointName, (const char *));
  LLDB_REGISTER_METHOD(bool, SBTarget, EnableAllBreakpoints, ());
  LLDB_REGISTER_METHOD(bool, SBTarget, DisableAllBreakpoints, ());
  LLDB_REGISTER_METHOD(bool, SBTarget, DeleteAllBreakpoints, ());
  LLDB_REGISTER_METHOD(lldb::SBError, SBTarget, BreakpointsCreateFromFile,
                       (lldb::SBFileSpec &, lldb::SBBreakpointList &));
  LLDB_REGISTER_METHOD(
      lldb::SBError, SBTarget, BreakpointsCreateFromFile,
      (lldb::SBFileSpec &, lldb::SBStringList &, lldb::SBBreakpointList &));
  LLDB_REGISTER_METHOD(lldb::SBError, SBTarget, BreakpointsWriteToFile,
                       (lldb::SBFileSpec &));
  LLDB_REGISTER_METHOD(lldb::SBError, SBTarget, BreakpointsWriteToFile,
                       (lldb::SBFileSpec &, lldb::SBBreakpointList &, bool));
  LLDB_REGISTER_METHOD_CONST(uint32_t, SBTarget, GetNumWatchpoints, ());
  LLDB_REGISTER_METHOD_CONST(lldb::SBWatchpoint, SBTarget,
                             GetWatchpointAtIndex, (uint32_t));
  LLDB_REGISTER_METHOD(bool, SBTarget, DeleteWatchpoint, (lldb::watch_id_t));
  LLDB_REGISTER_METHOD(lldb::SBWatchpoint, SBTarget, FindWatchpointByID,
                       (lldb::watch_id_t));
  LLDB_REGISTER_METHOD(lldb::SBWatchpoint, SBTarget, WatchAddress,
                       (lldb::addr_t, size_t, bool, bool, lldb::SBError &));
  LLDB_REGISTER_METHOD(bool, SBTarget, EnableAllWatchpoints, ());
  LLDB_REGISTER_METHOD(bool, SBTarget, DisableAllWatchpoints, ());
  LLDB_REGISTER_METHOD(lldb::SBValue, SBTarget, CreateValueFromAddress,
                       (const char *, lldb::SBAddress, lldb::SBType));
  LLDB_REGISTER_METHOD(lldb::SBValue, SBTarget, CreateValueFromData,
                       (const char *, lldb::SBData, lldb::SBType));
  LLDB_REGISTER_METHOD(lldb::SBValue, SBTarget, CreateValueFromExpression,
                       (const char *, const char *));
  LLDB_REGISTER_METHOD(bool, SBTarget, DeleteAllWatchpoints, ());
  LLDB_REGISTER_METHOD(void, SBTarget, AppendImageSearchPath,
                       (const char *, const char *, lldb::SBError &));
  LLDB_REGISTER_METHOD(lldb::SBModule, SBTarget, AddModule,
                       (const char *, const char *, const char *));
  LLDB_REGISTER_METHOD(
      lldb::SBModule, SBTarget, AddModule,
      (const char *, const char *, const char *, const char *));
  LLDB_REGISTER_METHOD(lldb::SBModule, SBTarget, AddModule,
                       (const lldb::SBModuleSpec &));
  LLDB_REGISTER_METHOD(bool, SBTarget, AddModule, (lldb::SBModule &));
  LLDB_REGISTER_METHOD_CONST(uint32_t, SBTarget, GetNumModules, ());
  LLDB_REGISTER_METHOD(void, SBTarget, Clear, ());
  LLDB_REGISTER_METHOD(lldb::SBModule, SBTarget, FindModule,
                       (const lldb::SBFileSpec &));
  LLDB_REGISTER_METHOD(lldb::SBSymbolContextList, SBTarget, FindCompileUnits,
                       (const lldb::SBFileSpec &));
  LLDB_REGISTER_METHOD(lldb::ByteOrder, SBTarget, GetByteOrder, ());
  LLDB_REGISTER_METHOD(const char *, SBTarget, GetTriple, ());
  LLDB_REGISTER_METHOD(uint32_t, SBTarget, GetDataByteSize, ());
  LLDB_REGISTER_METHOD(uint32_t, SBTarget, GetCodeByteSize, ());
  LLDB_REGISTER_METHOD(uint32_t, SBTarget, GetAddressByteSize, ());
  LLDB_REGISTER_METHOD(lldb::SBModule, SBTarget, GetModuleAtIndex,
                       (uint32_t));
  LLDB_REGISTER_METHOD(bool, SBTarget, RemoveModule, (lldb::SBModule));
  LLDB_REGISTER_METHOD_CONST(lldb::SBBroadcaster, SBTarget, GetBroadcaster,
                             ());
  LLDB_REGISTER_METHOD(bool, SBTarget, GetDescription,
                       (lldb::SBStream &, lldb::DescriptionLevel));
  LLDB_REGISTER_METHOD(lldb::SBSymbolContextList, SBTarget, FindFunctions,
                       (const char *, uint32_t));
  LLDB_REGISTER_METHOD(lldb::SBSymbolContextList, SBTarget,
                       FindGlobalFunctions,
                       (const char *, uint32_t, lldb::MatchType));
  LLDB_REGISTER_METHOD(lldb::SBType, SBTarget, FindFirstType, (const char *));
  LLDB_REGISTER_METHOD(lldb::SBType, SBTarget, GetBasicType,
                       (lldb::BasicType));
  LLDB_REGISTER_METHOD(lldb::SBTypeList, SBTarget, FindTypes, (const char *));
  LLDB_REGISTER_METHOD(lldb::SBValueList, SBTarget, FindGlobalVariables,
                       (const char *, uint32_t));
  LLDB_REGISTER_METHOD(lldb::SBValueList, SBTarget, FindGlobalVariables,
                       (const char *, uint32_t, lldb::MatchType));
  LLDB_REGISTER_METHOD(lldb::SBValue, SBTarget, FindFirstGlobalVariable,
                       (const char *));
  LLDB_REGISTER_METHOD(lldb::SBSourceManager, SBTarget, GetSourceManager, ());
  LLDB_REGISTER_METHOD(lldb::SBInstructionList, SBTarget, ReadInstructions,
                       (lldb::SBAddress, uint32_t));
  LLDB_REGISTER_METHOD(lldb::SBInstructionList, SBTarget, ReadInstructions,
                       (lldb::SBAddress, uint32_t, const char *));
  LLDB_REGISTER_METHOD(lldb::SBError, SBTarget, SetSectionLoadAddress,
                       (lldb::SBSection, lldb::addr_t));
  LLDB_REGISTER_METHOD(lldb::SBError, SBTarget, ClearSectionLoadAddress,
                       (lldb::SBSection));
  LLDB_REGISTER_METHOD(lldb::SBError, SBTarget, SetModuleLoadAddress,
                       (lldb::SBModule, int64_t));
  LLDB_REGISTER_METHOD(lldb::SBError, SBTarget, ClearModuleLoadAddress,
                       (lldb::SBModule));
  LLDB_REGISTER_METHOD(lldb::SBSymbolContextList, SBTarget, FindSymbols,
                       (const char *, lldb::SymbolType));
  LLDB_REGISTER_METHOD(lldb::SBValue, SBTarget, EvaluateExpression,
                       (const char *));
  LLDB_REGISTER_METHOD(lldb::SBValue, SBTarget, EvaluateExpression,
                       (const char *, const lldb::SBExpressionOptions &));
  LLDB_REGISTER_METHOD(lldb::addr_t, SBTarget, GetStackRedZoneSize, ());
  LLDB_REGISTER_METHOD_CONST(lldb::SBLaunchInfo, SBTarget, GetLaunchInfo, ());
  LLDB_REGISTER_METHOD(void, SBTarget, SetLaunchInfo,
                       (const lldb::SBLaunchInfo &));
}

}
}
