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

#include "lldb/Core/DumpDataExtractor.h"
#include "lldb/Utility/DataBufferHeap.h"
#include "lldb/Utility/DataExtractor.h"
#include "lldb/Utility/Stream.h"

#include <cinttypes>
#include <memory>

using namespace lldb;
using namespace lldb_private;

SBData::SBData() : m_opaque_sp(new DataExtractor()) {
  LLDB_RECORD_CONSTRUCTOR_NO_ARGS(SBData);
}

SBData::SBData(const lldb::DataExtractorSP &data_sp) : m_opaque_sp(data_sp) {}

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

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

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

SBData::~SBData() {}

void SBData::SetOpaque(const lldb::DataExtractorSP &data_sp) {
  m_opaque_sp = data_sp;
}

lldb_private::DataExtractor *SBData::get() const { return m_opaque_sp.get(); }

lldb_private::DataExtractor *SBData::operator->() const {
  return m_opaque_sp.operator->();
}

lldb::DataExtractorSP &SBData::operator*() { return m_opaque_sp; }

const lldb::DataExtractorSP &SBData::operator*() const { return m_opaque_sp; }

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

  return m_opaque_sp.get() != nullptr;
}

uint8_t SBData::GetAddressByteSize() {
  LLDB_RECORD_METHOD_NO_ARGS(uint8_t, SBData, GetAddressByteSize);

  uint8_t value = 0;
  if (m_opaque_sp.get())
    value = m_opaque_sp->GetAddressByteSize();
  return value;
}

void SBData::SetAddressByteSize(uint8_t addr_byte_size) {
  LLDB_RECORD_METHOD(void, SBData, SetAddressByteSize, (uint8_t),
                     addr_byte_size);

  if (m_opaque_sp.get())
    m_opaque_sp->SetAddressByteSize(addr_byte_size);
}

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

  if (m_opaque_sp.get())
    m_opaque_sp->Clear();
}

size_t SBData::GetByteSize() {
  LLDB_RECORD_METHOD_NO_ARGS(size_t, SBData, GetByteSize);

  size_t value = 0;
  if (m_opaque_sp.get())
    value = m_opaque_sp->GetByteSize();
  return value;
}

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

  lldb::ByteOrder value = eByteOrderInvalid;
  if (m_opaque_sp.get())
    value = m_opaque_sp->GetByteOrder();
  return value;
}

void SBData::SetByteOrder(lldb::ByteOrder endian) {
  LLDB_RECORD_METHOD(void, SBData, SetByteOrder, (lldb::ByteOrder), endian);

  if (m_opaque_sp.get())
    m_opaque_sp->SetByteOrder(endian);
}

float SBData::GetFloat(lldb::SBError &error, lldb::offset_t offset) {
  LLDB_RECORD_METHOD(float, SBData, GetFloat, (lldb::SBError &, lldb::offset_t),
                     error, offset);

  float value = 0;
  if (!m_opaque_sp.get()) {
    error.SetErrorString("no value to read from");
  } else {
    uint32_t old_offset = offset;
    value = m_opaque_sp->GetFloat(&offset);
    if (offset == old_offset)
      error.SetErrorString("unable to read data");
  }
  return value;
}

double SBData::GetDouble(lldb::SBError &error, lldb::offset_t offset) {
  LLDB_RECORD_METHOD(double, SBData, GetDouble,
                     (lldb::SBError &, lldb::offset_t), error, offset);

  double value = 0;
  if (!m_opaque_sp.get()) {
    error.SetErrorString("no value to read from");
  } else {
    uint32_t old_offset = offset;
    value = m_opaque_sp->GetDouble(&offset);
    if (offset == old_offset)
      error.SetErrorString("unable to read data");
  }
  return value;
}

long double SBData::GetLongDouble(lldb::SBError &error, lldb::offset_t offset) {
  LLDB_RECORD_METHOD(long double, SBData, GetLongDouble,
                     (lldb::SBError &, lldb::offset_t), error, offset);

  long double value = 0;
  if (!m_opaque_sp.get()) {
    error.SetErrorString("no value to read from");
  } else {
    uint32_t old_offset = offset;
    value = m_opaque_sp->GetLongDouble(&offset);
    if (offset == old_offset)
      error.SetErrorString("unable to read data");
  }
  return value;
}

lldb::addr_t SBData::GetAddress(lldb::SBError &error, lldb::offset_t offset) {
  LLDB_RECORD_METHOD(lldb::addr_t, SBData, GetAddress,
                     (lldb::SBError &, lldb::offset_t), error, offset);

  lldb::addr_t value = 0;
  if (!m_opaque_sp.get()) {
    error.SetErrorString("no value to read from");
  } else {
    uint32_t old_offset = offset;
    value = m_opaque_sp->GetAddress(&offset);
    if (offset == old_offset)
      error.SetErrorString("unable to read data");
  }
  return value;
}

uint8_t SBData::GetUnsignedInt8(lldb::SBError &error, lldb::offset_t offset) {
  LLDB_RECORD_METHOD(uint8_t, SBData, GetUnsignedInt8,
                     (lldb::SBError &, lldb::offset_t), error, offset);

  uint8_t value = 0;
  if (!m_opaque_sp.get()) {
    error.SetErrorString("no value to read from");
  } else {
    uint32_t old_offset = offset;
    value = m_opaque_sp->GetU8(&offset);
    if (offset == old_offset)
      error.SetErrorString("unable to read data");
  }
  return value;
}

uint16_t SBData::GetUnsignedInt16(lldb::SBError &error, lldb::offset_t offset) {
  LLDB_RECORD_METHOD(uint16_t, SBData, GetUnsignedInt16,
                     (lldb::SBError &, lldb::offset_t), error, offset);

  uint16_t value = 0;
  if (!m_opaque_sp.get()) {
    error.SetErrorString("no value to read from");
  } else {
    uint32_t old_offset = offset;
    value = m_opaque_sp->GetU16(&offset);
    if (offset == old_offset)
      error.SetErrorString("unable to read data");
  }
  return value;
}

uint32_t SBData::GetUnsignedInt32(lldb::SBError &error, lldb::offset_t offset) {
  LLDB_RECORD_METHOD(uint32_t, SBData, GetUnsignedInt32,
                     (lldb::SBError &, lldb::offset_t), error, offset);

  uint32_t value = 0;
  if (!m_opaque_sp.get()) {
    error.SetErrorString("no value to read from");
  } else {
    uint32_t old_offset = offset;
    value = m_opaque_sp->GetU32(&offset);
    if (offset == old_offset)
      error.SetErrorString("unable to read data");
  }
  return value;
}

uint64_t SBData::GetUnsignedInt64(lldb::SBError &error, lldb::offset_t offset) {
  LLDB_RECORD_METHOD(uint64_t, SBData, GetUnsignedInt64,
                     (lldb::SBError &, lldb::offset_t), error, offset);

  uint64_t value = 0;
  if (!m_opaque_sp.get()) {
    error.SetErrorString("no value to read from");
  } else {
    uint32_t old_offset = offset;
    value = m_opaque_sp->GetU64(&offset);
    if (offset == old_offset)
      error.SetErrorString("unable to read data");
  }
  return value;
}

int8_t SBData::GetSignedInt8(lldb::SBError &error, lldb::offset_t offset) {
  LLDB_RECORD_METHOD(int8_t, SBData, GetSignedInt8,
                     (lldb::SBError &, lldb::offset_t), error, offset);

  int8_t value = 0;
  if (!m_opaque_sp.get()) {
    error.SetErrorString("no value to read from");
  } else {
    uint32_t old_offset = offset;
    value = (int8_t)m_opaque_sp->GetMaxS64(&offset, 1);
    if (offset == old_offset)
      error.SetErrorString("unable to read data");
  }
  return value;
}

int16_t SBData::GetSignedInt16(lldb::SBError &error, lldb::offset_t offset) {
  LLDB_RECORD_METHOD(int16_t, SBData, GetSignedInt16,
                     (lldb::SBError &, lldb::offset_t), error, offset);

  int16_t value = 0;
  if (!m_opaque_sp.get()) {
    error.SetErrorString("no value to read from");
  } else {
    uint32_t old_offset = offset;
    value = (int16_t)m_opaque_sp->GetMaxS64(&offset, 2);
    if (offset == old_offset)
      error.SetErrorString("unable to read data");
  }
  return value;
}

int32_t SBData::GetSignedInt32(lldb::SBError &error, lldb::offset_t offset) {
  LLDB_RECORD_METHOD(int32_t, SBData, GetSignedInt32,
                     (lldb::SBError &, lldb::offset_t), error, offset);

  int32_t value = 0;
  if (!m_opaque_sp.get()) {
    error.SetErrorString("no value to read from");
  } else {
    uint32_t old_offset = offset;
    value = (int32_t)m_opaque_sp->GetMaxS64(&offset, 4);
    if (offset == old_offset)
      error.SetErrorString("unable to read data");
  }
  return value;
}

int64_t SBData::GetSignedInt64(lldb::SBError &error, lldb::offset_t offset) {
  LLDB_RECORD_METHOD(int64_t, SBData, GetSignedInt64,
                     (lldb::SBError &, lldb::offset_t), error, offset);

  int64_t value = 0;
  if (!m_opaque_sp.get()) {
    error.SetErrorString("no value to read from");
  } else {
    uint32_t old_offset = offset;
    value = (int64_t)m_opaque_sp->GetMaxS64(&offset, 8);
    if (offset == old_offset)
      error.SetErrorString("unable to read data");
  }
  return value;
}

const char *SBData::GetString(lldb::SBError &error, lldb::offset_t offset) {
  LLDB_RECORD_METHOD(const char *, SBData, GetString,
                     (lldb::SBError &, lldb::offset_t), error, offset);

  const char *value = nullptr;
  if (!m_opaque_sp.get()) {
    error.SetErrorString("no value to read from");
  } else {
    uint32_t old_offset = offset;
    value = m_opaque_sp->GetCStr(&offset);
    if (offset == old_offset || (value == nullptr))
      error.SetErrorString("unable to read data");
  }
  return value;
}

bool SBData::GetDescription(lldb::SBStream &description,
                            lldb::addr_t base_addr) {
  LLDB_RECORD_METHOD(bool, SBData, GetDescription,
                     (lldb::SBStream &, lldb::addr_t), description, base_addr);

  Stream &strm = description.ref();

  if (m_opaque_sp) {
    DumpDataExtractor(*m_opaque_sp, &strm, 0, lldb::eFormatBytesWithASCII, 1,
                      m_opaque_sp->GetByteSize(), 16, base_addr, 0, 0);
  } else
    strm.PutCString("No value");

  return true;
}

size_t SBData::ReadRawData(lldb::SBError &error, lldb::offset_t offset,
                           void *buf, size_t size) {
  LLDB_RECORD_DUMMY(size_t, SBData, ReadRawData,
                    (lldb::SBError &, lldb::offset_t, void *, size_t), error,
                    offset, buf, size);

  void *ok = nullptr;
  if (!m_opaque_sp.get()) {
    error.SetErrorString("no value to read from");
  } else {
    uint32_t old_offset = offset;
    ok = m_opaque_sp->GetU8(&offset, buf, size);
    if ((offset == old_offset) || (ok == nullptr))
      error.SetErrorString("unable to read data");
  }
  return ok ? size : 0;
}

void SBData::SetData(lldb::SBError &error, const void *buf, size_t size,
                     lldb::ByteOrder endian, uint8_t addr_size) {
  LLDB_RECORD_DUMMY(
      void, SBData, SetData,
      (lldb::SBError &, const void *, size_t, lldb::ByteOrder, uint8_t), error,
      buf, size, endian, addr_size);

  if (!m_opaque_sp.get())
    m_opaque_sp = std::make_shared<DataExtractor>(buf, size, endian, addr_size);
  else
  {
    m_opaque_sp->SetData(buf, size, endian);
    m_opaque_sp->SetAddressByteSize(addr_size);
  }
}

bool SBData::Append(const SBData &rhs) {
  LLDB_RECORD_METHOD(bool, SBData, Append, (const lldb::SBData &), rhs);

  bool value = false;
  if (m_opaque_sp.get() && rhs.m_opaque_sp.get())
    value = m_opaque_sp.get()->Append(*rhs.m_opaque_sp);
  return value;
}

lldb::SBData SBData::CreateDataFromCString(lldb::ByteOrder endian,
                                           uint32_t addr_byte_size,
                                           const char *data) {
  LLDB_RECORD_STATIC_METHOD(lldb::SBData, SBData, CreateDataFromCString,
                            (lldb::ByteOrder, uint32_t, const char *), endian,
                            addr_byte_size, data);

  if (!data || !data[0])
    return LLDB_RECORD_RESULT(SBData());

  uint32_t data_len = strlen(data);

  lldb::DataBufferSP buffer_sp(new DataBufferHeap(data, data_len));
  lldb::DataExtractorSP data_sp(
      new DataExtractor(buffer_sp, endian, addr_byte_size));

  SBData ret(data_sp);

  return LLDB_RECORD_RESULT(ret);
}

lldb::SBData SBData::CreateDataFromUInt64Array(lldb::ByteOrder endian,
                                               uint32_t addr_byte_size,
                                               uint64_t *array,
                                               size_t array_len) {
  LLDB_RECORD_STATIC_METHOD(lldb::SBData, SBData, CreateDataFromUInt64Array,
                            (lldb::ByteOrder, uint32_t, uint64_t *, size_t),
                            endian, addr_byte_size, array, array_len);

  if (!array || array_len == 0)
    return LLDB_RECORD_RESULT(SBData());

  size_t data_len = array_len * sizeof(uint64_t);

  lldb::DataBufferSP buffer_sp(new DataBufferHeap(array, data_len));
  lldb::DataExtractorSP data_sp(
      new DataExtractor(buffer_sp, endian, addr_byte_size));

  SBData ret(data_sp);

  return LLDB_RECORD_RESULT(ret);
}

lldb::SBData SBData::CreateDataFromUInt32Array(lldb::ByteOrder endian,
                                               uint32_t addr_byte_size,
                                               uint32_t *array,
                                               size_t array_len) {
  LLDB_RECORD_STATIC_METHOD(lldb::SBData, SBData, CreateDataFromUInt32Array,
                            (lldb::ByteOrder, uint32_t, uint32_t *, size_t),
                            endian, addr_byte_size, array, array_len);

  if (!array || array_len == 0)
    return LLDB_RECORD_RESULT(SBData());

  size_t data_len = array_len * sizeof(uint32_t);

  lldb::DataBufferSP buffer_sp(new DataBufferHeap(array, data_len));
  lldb::DataExtractorSP data_sp(
      new DataExtractor(buffer_sp, endian, addr_byte_size));

  SBData ret(data_sp);

  return LLDB_RECORD_RESULT(ret);
}

lldb::SBData SBData::CreateDataFromSInt64Array(lldb::ByteOrder endian,
                                               uint32_t addr_byte_size,
                                               int64_t *array,
                                               size_t array_len) {
  LLDB_RECORD_STATIC_METHOD(lldb::SBData, SBData, CreateDataFromSInt64Array,
                            (lldb::ByteOrder, uint32_t, int64_t *, size_t),
                            endian, addr_byte_size, array, array_len);

  if (!array || array_len == 0)
    return LLDB_RECORD_RESULT(SBData());

  size_t data_len = array_len * sizeof(int64_t);

  lldb::DataBufferSP buffer_sp(new DataBufferHeap(array, data_len));
  lldb::DataExtractorSP data_sp(
      new DataExtractor(buffer_sp, endian, addr_byte_size));

  SBData ret(data_sp);

  return LLDB_RECORD_RESULT(ret);
}

lldb::SBData SBData::CreateDataFromSInt32Array(lldb::ByteOrder endian,
                                               uint32_t addr_byte_size,
                                               int32_t *array,
                                               size_t array_len) {
  LLDB_RECORD_STATIC_METHOD(lldb::SBData, SBData, CreateDataFromSInt32Array,
                            (lldb::ByteOrder, uint32_t, int32_t *, size_t),
                            endian, addr_byte_size, array, array_len);

  if (!array || array_len == 0)
    return LLDB_RECORD_RESULT(SBData());

  size_t data_len = array_len * sizeof(int32_t);

  lldb::DataBufferSP buffer_sp(new DataBufferHeap(array, data_len));
  lldb::DataExtractorSP data_sp(
      new DataExtractor(buffer_sp, endian, addr_byte_size));

  SBData ret(data_sp);

  return LLDB_RECORD_RESULT(ret);
}

lldb::SBData SBData::CreateDataFromDoubleArray(lldb::ByteOrder endian,
                                               uint32_t addr_byte_size,
                                               double *array,
                                               size_t array_len) {
  LLDB_RECORD_STATIC_METHOD(lldb::SBData, SBData, CreateDataFromDoubleArray,
                            (lldb::ByteOrder, uint32_t, double *, size_t),
                            endian, addr_byte_size, array, array_len);

  if (!array || array_len == 0)
    return LLDB_RECORD_RESULT(SBData());

  size_t data_len = array_len * sizeof(double);

  lldb::DataBufferSP buffer_sp(new DataBufferHeap(array, data_len));
  lldb::DataExtractorSP data_sp(
      new DataExtractor(buffer_sp, endian, addr_byte_size));

  SBData ret(data_sp);

  return LLDB_RECORD_RESULT(ret);
}

bool SBData::SetDataFromCString(const char *data) {
  LLDB_RECORD_METHOD(bool, SBData, SetDataFromCString, (const char *), data);


  if (!data) {
    return false;
  }

  size_t data_len = strlen(data);

  lldb::DataBufferSP buffer_sp(new DataBufferHeap(data, data_len));

  if (!m_opaque_sp.get())
    m_opaque_sp = std::make_shared<DataExtractor>(buffer_sp, GetByteOrder(),
                                                  GetAddressByteSize());
  else
    m_opaque_sp->SetData(buffer_sp);


  return true;
}

bool SBData::SetDataFromUInt64Array(uint64_t *array, size_t array_len) {
  LLDB_RECORD_METHOD(bool, SBData, SetDataFromUInt64Array, (uint64_t *, size_t),
                     array, array_len);


  if (!array || array_len == 0) {
    return false;
  }

  size_t data_len = array_len * sizeof(uint64_t);

  lldb::DataBufferSP buffer_sp(new DataBufferHeap(array, data_len));

  if (!m_opaque_sp.get())
    m_opaque_sp = std::make_shared<DataExtractor>(buffer_sp, GetByteOrder(),
                                                  GetAddressByteSize());
  else
    m_opaque_sp->SetData(buffer_sp);


  return true;
}

bool SBData::SetDataFromUInt32Array(uint32_t *array, size_t array_len) {
  LLDB_RECORD_METHOD(bool, SBData, SetDataFromUInt32Array, (uint32_t *, size_t),
                     array, array_len);


  if (!array || array_len == 0) {
    return false;
  }

  size_t data_len = array_len * sizeof(uint32_t);

  lldb::DataBufferSP buffer_sp(new DataBufferHeap(array, data_len));

  if (!m_opaque_sp.get())
    m_opaque_sp = std::make_shared<DataExtractor>(buffer_sp, GetByteOrder(),
                                                  GetAddressByteSize());
  else
    m_opaque_sp->SetData(buffer_sp);

  return true;
}

bool SBData::SetDataFromSInt64Array(int64_t *array, size_t array_len) {
  LLDB_RECORD_METHOD(bool, SBData, SetDataFromSInt64Array, (int64_t *, size_t),
                     array, array_len);


  if (!array || array_len == 0) {
    return false;
  }

  size_t data_len = array_len * sizeof(int64_t);

  lldb::DataBufferSP buffer_sp(new DataBufferHeap(array, data_len));

  if (!m_opaque_sp.get())
    m_opaque_sp = std::make_shared<DataExtractor>(buffer_sp, GetByteOrder(),
                                                  GetAddressByteSize());
  else
    m_opaque_sp->SetData(buffer_sp);

  return true;
}

bool SBData::SetDataFromSInt32Array(int32_t *array, size_t array_len) {
  LLDB_RECORD_METHOD(bool, SBData, SetDataFromSInt32Array, (int32_t *, size_t),
                     array, array_len);


  if (!array || array_len == 0) {
    return false;
  }

  size_t data_len = array_len * sizeof(int32_t);

  lldb::DataBufferSP buffer_sp(new DataBufferHeap(array, data_len));

  if (!m_opaque_sp.get())
    m_opaque_sp = std::make_shared<DataExtractor>(buffer_sp, GetByteOrder(),
                                                  GetAddressByteSize());
  else
    m_opaque_sp->SetData(buffer_sp);

  return true;
}

bool SBData::SetDataFromDoubleArray(double *array, size_t array_len) {
  LLDB_RECORD_METHOD(bool, SBData, SetDataFromDoubleArray, (double *, size_t),
                     array, array_len);


  if (!array || array_len == 0) {
    return false;
  }

  size_t data_len = array_len * sizeof(double);

  lldb::DataBufferSP buffer_sp(new DataBufferHeap(array, data_len));

  if (!m_opaque_sp.get())
    m_opaque_sp = std::make_shared<DataExtractor>(buffer_sp, GetByteOrder(),
                                                  GetAddressByteSize());
  else
    m_opaque_sp->SetData(buffer_sp);

  return true;
}

namespace lldb_private {
namespace repro {

template <>
void RegisterMethods<SBData>(Registry &R) {
  LLDB_REGISTER_CONSTRUCTOR(SBData, ());
  LLDB_REGISTER_CONSTRUCTOR(SBData, (const lldb::SBData &));
  LLDB_REGISTER_METHOD(const lldb::SBData &,
                       SBData, operator=,(const lldb::SBData &));
  LLDB_REGISTER_METHOD(bool, SBData, IsValid, ());
  LLDB_REGISTER_METHOD_CONST(bool, SBData, operator bool, ());
  LLDB_REGISTER_METHOD(uint8_t, SBData, GetAddressByteSize, ());
  LLDB_REGISTER_METHOD(void, SBData, SetAddressByteSize, (uint8_t));
  LLDB_REGISTER_METHOD(void, SBData, Clear, ());
  LLDB_REGISTER_METHOD(size_t, SBData, GetByteSize, ());
  LLDB_REGISTER_METHOD(lldb::ByteOrder, SBData, GetByteOrder, ());
  LLDB_REGISTER_METHOD(void, SBData, SetByteOrder, (lldb::ByteOrder));
  LLDB_REGISTER_METHOD(float, SBData, GetFloat,
                       (lldb::SBError &, lldb::offset_t));
  LLDB_REGISTER_METHOD(double, SBData, GetDouble,
                       (lldb::SBError &, lldb::offset_t));
  LLDB_REGISTER_METHOD(long double, SBData, GetLongDouble,
                       (lldb::SBError &, lldb::offset_t));
  LLDB_REGISTER_METHOD(lldb::addr_t, SBData, GetAddress,
                       (lldb::SBError &, lldb::offset_t));
  LLDB_REGISTER_METHOD(uint8_t, SBData, GetUnsignedInt8,
                       (lldb::SBError &, lldb::offset_t));
  LLDB_REGISTER_METHOD(uint16_t, SBData, GetUnsignedInt16,
                       (lldb::SBError &, lldb::offset_t));
  LLDB_REGISTER_METHOD(uint32_t, SBData, GetUnsignedInt32,
                       (lldb::SBError &, lldb::offset_t));
  LLDB_REGISTER_METHOD(uint64_t, SBData, GetUnsignedInt64,
                       (lldb::SBError &, lldb::offset_t));
  LLDB_REGISTER_METHOD(int8_t, SBData, GetSignedInt8,
                       (lldb::SBError &, lldb::offset_t));
  LLDB_REGISTER_METHOD(int16_t, SBData, GetSignedInt16,
                       (lldb::SBError &, lldb::offset_t));
  LLDB_REGISTER_METHOD(int32_t, SBData, GetSignedInt32,
                       (lldb::SBError &, lldb::offset_t));
  LLDB_REGISTER_METHOD(int64_t, SBData, GetSignedInt64,
                       (lldb::SBError &, lldb::offset_t));
  LLDB_REGISTER_METHOD(const char *, SBData, GetString,
                       (lldb::SBError &, lldb::offset_t));
  LLDB_REGISTER_METHOD(bool, SBData, GetDescription,
                       (lldb::SBStream &, lldb::addr_t));
  LLDB_REGISTER_METHOD(bool, SBData, Append, (const lldb::SBData &));
  LLDB_REGISTER_STATIC_METHOD(lldb::SBData, SBData, CreateDataFromCString,
                              (lldb::ByteOrder, uint32_t, const char *));
  LLDB_REGISTER_STATIC_METHOD(
      lldb::SBData, SBData, CreateDataFromUInt64Array,
      (lldb::ByteOrder, uint32_t, uint64_t *, size_t));
  LLDB_REGISTER_STATIC_METHOD(
      lldb::SBData, SBData, CreateDataFromUInt32Array,
      (lldb::ByteOrder, uint32_t, uint32_t *, size_t));
  LLDB_REGISTER_STATIC_METHOD(lldb::SBData, SBData, CreateDataFromSInt64Array,
                              (lldb::ByteOrder, uint32_t, int64_t *, size_t));
  LLDB_REGISTER_STATIC_METHOD(lldb::SBData, SBData, CreateDataFromSInt32Array,
                              (lldb::ByteOrder, uint32_t, int32_t *, size_t));
  LLDB_REGISTER_STATIC_METHOD(lldb::SBData, SBData, CreateDataFromDoubleArray,
                              (lldb::ByteOrder, uint32_t, double *, size_t));
  LLDB_REGISTER_METHOD(bool, SBData, SetDataFromCString, (const char *));
  LLDB_REGISTER_METHOD(bool, SBData, SetDataFromUInt64Array,
                       (uint64_t *, size_t));
  LLDB_REGISTER_METHOD(bool, SBData, SetDataFromUInt32Array,
                       (uint32_t *, size_t));
  LLDB_REGISTER_METHOD(bool, SBData, SetDataFromSInt64Array,
                       (int64_t *, size_t));
  LLDB_REGISTER_METHOD(bool, SBData, SetDataFromSInt32Array,
                       (int32_t *, size_t));
  LLDB_REGISTER_METHOD(bool, SBData, SetDataFromDoubleArray,
                       (double *, size_t));
}

}
}
