//===-- Scalar.cpp --------------------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//

#include "lldb/Utility/Scalar.h"
#include "lldb/Utility/DataBufferHeap.h"
#include "lldb/Utility/DataExtractor.h"
#include "lldb/Utility/Endian.h"
#include "lldb/Utility/Status.h"
#include "lldb/Utility/Stream.h"
#include "lldb/Utility/StreamString.h"
#include "lldb/lldb-types.h"
#include "llvm/ADT/APSInt.h"
#include "llvm/ADT/SmallString.h"

#include <cinttypes>
#include <cstdio>

using namespace lldb;
using namespace lldb_private;

using llvm::APFloat;
using llvm::APInt;
using llvm::APSInt;

Scalar::PromotionKey Scalar::GetPromoKey() const {
  switch (m_type) {
  case e_void:
    return PromotionKey{e_void, 0, false};
  case e_int:
    return PromotionKey{e_int, m_integer.getBitWidth(), m_integer.isUnsigned()};
  case e_float:
    return GetFloatPromoKey(m_float.getSemantics());
  }
  llvm_unreachable("Unhandled category!");
}

Scalar::PromotionKey Scalar::GetFloatPromoKey(const llvm::fltSemantics &sem) {
  static const llvm::fltSemantics *const order[] = {
      &APFloat::IEEEsingle(), &APFloat::IEEEdouble(),
      &APFloat::x87DoubleExtended()};
  for (const auto &entry : llvm::enumerate(order)) {
    if (entry.value() == &sem)
      return PromotionKey{e_float, entry.index(), false};
  }
  llvm_unreachable("Unsupported semantics!");
}

// Promote to max type currently follows the ANSI C rule for type promotion in
// expressions.
Scalar::Type Scalar::PromoteToMaxType(Scalar &lhs, Scalar &rhs) {
  const auto &Promote = [](Scalar &a, const Scalar &b) {
    switch (b.GetType()) {
    case e_void:
      break;
    case e_int:
      a.IntegralPromote(b.m_integer.getBitWidth(), b.m_integer.isSigned());
      break;
    case e_float:
      a.FloatPromote(b.m_float.getSemantics());
    }
  };

  PromotionKey lhs_key = lhs.GetPromoKey();
  PromotionKey rhs_key = rhs.GetPromoKey();

  if (lhs_key > rhs_key)
    Promote(rhs, lhs);
  else if (rhs_key > lhs_key)
    Promote(lhs, rhs);

  // Make sure our type promotion worked as expected
  if (lhs.GetPromoKey() == rhs.GetPromoKey())
    return lhs.GetType(); // Return the resulting type

  // Return the void type (zero) if we fail to promote either of the values.
  return Scalar::e_void;
}

bool Scalar::GetData(DataExtractor &data, size_t limit_byte_size) const {
  size_t byte_size = GetByteSize();
  if (byte_size == 0) {
    data.Clear();
    return false;
  }
  auto buffer_up = std::make_unique<DataBufferHeap>(byte_size, 0);
  GetBytes(buffer_up->GetData());
  lldb::offset_t offset = 0;

  if (limit_byte_size < byte_size) {
    if (endian::InlHostByteOrder() == eByteOrderLittle) {
      // On little endian systems if we want fewer bytes from the current
      // type we just specify fewer bytes since the LSByte is first...
      byte_size = limit_byte_size;
    } else if (endian::InlHostByteOrder() == eByteOrderBig) {
      // On big endian systems if we want fewer bytes from the current type
      // have to advance our initial byte pointer and trim down the number of
      // bytes since the MSByte is first
      offset = byte_size - limit_byte_size;
      byte_size = limit_byte_size;
    }
  }

  data.SetData(std::move(buffer_up), offset, byte_size);
  data.SetByteOrder(endian::InlHostByteOrder());
  return true;
}

void Scalar::GetBytes(llvm::MutableArrayRef<uint8_t> storage) const {
  assert(storage.size() >= GetByteSize());

  const auto &store = [&](const llvm::APInt &val) {
    StoreIntToMemory(val, storage.data(), (val.getBitWidth() + 7) / 8);
  };
  switch (m_type) {
  case e_void:
    break;
  case e_int:
    store(m_integer);
    break;
  case e_float:
    store(m_float.bitcastToAPInt());
    break;
  }
}

size_t Scalar::GetByteSize() const {
  switch (m_type) {
  case e_void:
    break;
  case e_int:
    return (m_integer.getBitWidth() / 8);
  case e_float:
    return m_float.bitcastToAPInt().getBitWidth() / 8;
  }
  return 0;
}

bool Scalar::IsZero() const {
  switch (m_type) {
  case e_void:
    break;
  case e_int:
    return m_integer.isZero();
  case e_float:
    return m_float.isZero();
  }
  return false;
}

void Scalar::GetValue(Stream *s, bool show_type) const {
  if (show_type)
    s->Printf("(%s) ", GetTypeAsCString());

  switch (m_type) {
  case e_void:
    break;
  case e_int:
    s->PutCString(llvm::toString(m_integer, 10));
    break;
  case e_float:
    llvm::SmallString<24> string;
    m_float.toString(string);
    s->PutCString(string);
    break;
  }
}

void Scalar::TruncOrExtendTo(uint16_t bits, bool sign) {
  m_integer.setIsSigned(sign);
  m_integer = m_integer.extOrTrunc(bits);
}

bool Scalar::IntegralPromote(uint16_t bits, bool sign) {
  switch (m_type) {
  case e_void:
  case e_float:
    break;
  case e_int:
    if (GetPromoKey() > PromotionKey(e_int, bits, !sign))
      break;
    m_integer = m_integer.extOrTrunc(bits);
    m_integer.setIsSigned(sign);
    return true;
  }
  return false;
}

bool Scalar::FloatPromote(const llvm::fltSemantics &semantics) {
  bool success = false;
  switch (m_type) {
  case e_void:
    break;
  case e_int:
    m_float = llvm::APFloat(semantics);
    m_float.convertFromAPInt(m_integer, m_integer.isSigned(),
                             llvm::APFloat::rmNearestTiesToEven);
    success = true;
    break;
  case e_float:
    if (GetFloatPromoKey(semantics) < GetFloatPromoKey(m_float.getSemantics()))
      break;
    bool ignore;
    success = true;
    m_float.convert(semantics, llvm::APFloat::rmNearestTiesToEven, &ignore);
  }

  if (success)
    m_type = e_float;
  return success;
}

const char *Scalar::GetValueTypeAsCString(Scalar::Type type) {
  switch (type) {
  case e_void:
    return "void";
  case e_int:
    return "int";
  case e_float:
    return "float";
  }
  return "???";
}

bool Scalar::IsSigned() const {
  switch (m_type) {
  case e_void:
    return false;
  case e_int:
    return m_integer.isSigned();
  case e_float:
    return true;
  }
  llvm_unreachable("Unrecognized type!");
}

bool Scalar::MakeSigned() {
  bool success = false;

  switch (m_type) {
  case e_void:
    break;
  case e_int:
    m_integer.setIsSigned(true);
    success = true;
    break;
  case e_float:
    success = true;
    break;
  }

  return success;
}

bool Scalar::MakeUnsigned() {
  bool success = false;

  switch (m_type) {
  case e_void:
    break;
  case e_int:
    m_integer.setIsUnsigned(true);
    success = true;
    break;
  case e_float:
    success = true;
    break;
  }

  return success;
}

static llvm::APInt ToAPInt(const llvm::APFloat &f, unsigned bits,
                           bool is_unsigned) {
  llvm::APSInt result(bits, is_unsigned);
  bool isExact;
  f.convertToInteger(result, llvm::APFloat::rmTowardZero, &isExact);
  return std::move(result);
}

template <typename T> T Scalar::GetAs(T fail_value) const {
  switch (m_type) {
  case e_void:
    break;
  case e_int: {
    APSInt ext = m_integer.extOrTrunc(sizeof(T) * 8);
    if (ext.isSigned())
      return ext.getSExtValue();
    return ext.getZExtValue();
  }
  case e_float:
    return ToAPInt(m_float, sizeof(T) * 8, std::is_unsigned<T>::value)
        .getSExtValue();
  }
  return fail_value;
}

signed char Scalar::SChar(signed char fail_value) const {
  return GetAs<signed char>(fail_value);
}

unsigned char Scalar::UChar(unsigned char fail_value) const {
  return GetAs<unsigned char>(fail_value);
}

short Scalar::SShort(short fail_value) const {
  return GetAs<short>(fail_value);
}

unsigned short Scalar::UShort(unsigned short fail_value) const {
  return GetAs<unsigned short>(fail_value);
}

int Scalar::SInt(int fail_value) const { return GetAs<int>(fail_value); }

unsigned int Scalar::UInt(unsigned int fail_value) const {
  return GetAs<unsigned int>(fail_value);
}

long Scalar::SLong(long fail_value) const { return GetAs<long>(fail_value); }

unsigned long Scalar::ULong(unsigned long fail_value) const {
  return GetAs<unsigned long>(fail_value);
}

long long Scalar::SLongLong(long long fail_value) const {
  return GetAs<long long>(fail_value);
}

unsigned long long Scalar::ULongLong(unsigned long long fail_value) const {
  return GetAs<unsigned long long>(fail_value);
}

llvm::APInt Scalar::SInt128(const llvm::APInt &fail_value) const {
  switch (m_type) {
  case e_void:
    break;
  case e_int:
    return m_integer;
  case e_float:
    return ToAPInt(m_float, 128, /*is_unsigned=*/false);
  }
  return fail_value;
}

llvm::APInt Scalar::UInt128(const llvm::APInt &fail_value) const {
  switch (m_type) {
  case e_void:
    break;
  case e_int:
    return m_integer;
  case e_float:
    return ToAPInt(m_float, 128, /*is_unsigned=*/true);
  }
  return fail_value;
}

float Scalar::Float(float fail_value) const {
  switch (m_type) {
  case e_void:
    break;
  case e_int:
    if (m_integer.isSigned())
      return llvm::APIntOps::RoundSignedAPIntToFloat(m_integer);
    return llvm::APIntOps::RoundAPIntToFloat(m_integer);

  case e_float: {
    APFloat result = m_float;
    bool losesInfo;
    result.convert(APFloat::IEEEsingle(), APFloat::rmNearestTiesToEven,
                   &losesInfo);
    return result.convertToFloat();
  }
  }
  return fail_value;
}

double Scalar::Double(double fail_value) const {
  switch (m_type) {
  case e_void:
    break;
  case e_int:
    if (m_integer.isSigned())
      return llvm::APIntOps::RoundSignedAPIntToDouble(m_integer);
    return llvm::APIntOps::RoundAPIntToDouble(m_integer);

  case e_float: {
    APFloat result = m_float;
    bool losesInfo;
    result.convert(APFloat::IEEEdouble(), APFloat::rmNearestTiesToEven,
                   &losesInfo);
    return result.convertToDouble();
  }
  }
  return fail_value;
}

long double Scalar::LongDouble(long double fail_value) const {
  /// No way to get more precision at the moment.
  return static_cast<long double>(Double(fail_value));
}

Scalar &Scalar::operator+=(Scalar rhs) {
  Scalar copy = *this;
  if ((m_type = PromoteToMaxType(copy, rhs)) != Scalar::e_void) {
    switch (m_type) {
    case e_void:
      break;
    case e_int:
      m_integer = copy.m_integer + rhs.m_integer;
      break;

    case e_float:
      m_float = copy.m_float + rhs.m_float;
      break;
    }
  }
  return *this;
}

Scalar &Scalar::operator<<=(const Scalar &rhs) {
  if (m_type == e_int && rhs.m_type == e_int)
    static_cast<APInt &>(m_integer) <<= rhs.m_integer;
  else
    m_type = e_void;
  return *this;
}

bool Scalar::ShiftRightLogical(const Scalar &rhs) {
  if (m_type == e_int && rhs.m_type == e_int) {
    m_integer = m_integer.lshr(rhs.m_integer);
    return true;
  }
  m_type = e_void;
  return false;
}

Scalar &Scalar::operator>>=(const Scalar &rhs) {
  switch (m_type) {
  case e_void:
  case e_float:
    m_type = e_void;
    break;

  case e_int:
    switch (rhs.m_type) {
    case e_void:
    case e_float:
      m_type = e_void;
      break;
    case e_int:
      m_integer = m_integer.ashr(rhs.m_integer);
      break;
    }
    break;
  }
  return *this;
}

Scalar &Scalar::operator&=(const Scalar &rhs) {
  if (m_type == e_int && rhs.m_type == e_int)
    m_integer &= rhs.m_integer;
  else
    m_type = e_void;
  return *this;
}

bool Scalar::AbsoluteValue() {
  switch (m_type) {
  case e_void:
    break;

  case e_int:
    if (m_integer.isNegative())
      m_integer = -m_integer;
    return true;

  case e_float:
    m_float.clearSign();
    return true;
  }
  return false;
}

bool Scalar::UnaryNegate() {
  switch (m_type) {
  case e_void:
    break;
  case e_int:
    m_integer = -m_integer;
    return true;
  case e_float:
    m_float.changeSign();
    return true;
  }
  return false;
}

bool Scalar::OnesComplement() {
  if (m_type == e_int) {
    m_integer = ~m_integer;
    return true;
  }

  return false;
}

const Scalar lldb_private::operator+(const Scalar &lhs, const Scalar &rhs) {
  Scalar result = lhs;
  result += rhs;
  return result;
}

const Scalar lldb_private::operator-(Scalar lhs, Scalar rhs) {
  Scalar result;
  if ((result.m_type = Scalar::PromoteToMaxType(lhs, rhs)) != Scalar::e_void) {
    switch (result.m_type) {
    case Scalar::e_void:
      break;
    case Scalar::e_int:
      result.m_integer = lhs.m_integer - rhs.m_integer;
      break;
    case Scalar::e_float:
      result.m_float = lhs.m_float - rhs.m_float;
      break;
    }
  }
  return result;
}

const Scalar lldb_private::operator/(Scalar lhs, Scalar rhs) {
  Scalar result;
  if ((result.m_type = Scalar::PromoteToMaxType(lhs, rhs)) != Scalar::e_void &&
      !rhs.IsZero()) {
    switch (result.m_type) {
    case Scalar::e_void:
      break;
    case Scalar::e_int:
      result.m_integer = lhs.m_integer / rhs.m_integer;
      return result;
    case Scalar::e_float:
      result.m_float = lhs.m_float / rhs.m_float;
      return result;
    }
  }
  // For division only, the only way it should make it here is if a promotion
  // failed, or if we are trying to do a divide by zero.
  result.m_type = Scalar::e_void;
  return result;
}

const Scalar lldb_private::operator*(Scalar lhs, Scalar rhs) {
  Scalar result;
  if ((result.m_type = Scalar::PromoteToMaxType(lhs, rhs)) != Scalar::e_void) {
    switch (result.m_type) {
    case Scalar::e_void:
      break;
    case Scalar::e_int:
      result.m_integer = lhs.m_integer * rhs.m_integer;
      break;
    case Scalar::e_float:
      result.m_float = lhs.m_float * rhs.m_float;
      break;
    }
  }
  return result;
}

const Scalar lldb_private::operator&(Scalar lhs, Scalar rhs) {
  Scalar result;
  if ((result.m_type = Scalar::PromoteToMaxType(lhs, rhs)) != Scalar::e_void) {
    if (result.m_type == Scalar::e_int)
      result.m_integer = lhs.m_integer & rhs.m_integer;
    else
      result.m_type = Scalar::e_void;
  }
  return result;
}

const Scalar lldb_private::operator|(Scalar lhs, Scalar rhs) {
  Scalar result;
  if ((result.m_type = Scalar::PromoteToMaxType(lhs, rhs)) != Scalar::e_void) {
    if (result.m_type == Scalar::e_int)
      result.m_integer = lhs.m_integer | rhs.m_integer;
    else
      result.m_type = Scalar::e_void;
  }
  return result;
}

const Scalar lldb_private::operator%(Scalar lhs, Scalar rhs) {
  Scalar result;
  if ((result.m_type = Scalar::PromoteToMaxType(lhs, rhs)) != Scalar::e_void) {
    if (!rhs.IsZero() && result.m_type == Scalar::e_int) {
      result.m_integer = lhs.m_integer % rhs.m_integer;
      return result;
    }
  }
  result.m_type = Scalar::e_void;
  return result;
}

const Scalar lldb_private::operator^(Scalar lhs, Scalar rhs) {
  Scalar result;
  if ((result.m_type = Scalar::PromoteToMaxType(lhs, rhs)) != Scalar::e_void) {
    if (result.m_type == Scalar::e_int)
      result.m_integer = lhs.m_integer ^ rhs.m_integer;
    else
      result.m_type = Scalar::e_void;
  }
  return result;
}

const Scalar lldb_private::operator<<(const Scalar &lhs, const Scalar &rhs) {
  Scalar result = lhs;
  result <<= rhs;
  return result;
}

const Scalar lldb_private::operator>>(const Scalar &lhs, const Scalar &rhs) {
  Scalar result = lhs;
  result >>= rhs;
  return result;
}

Status Scalar::SetValueFromCString(const char *value_str, Encoding encoding,
                                   size_t byte_size) {
  Status error;
  if (value_str == nullptr || value_str[0] == '\0') {
    error.SetErrorString("Invalid c-string value string.");
    return error;
  }
  switch (encoding) {
  case eEncodingInvalid:
    error.SetErrorString("Invalid encoding.");
    break;

  case eEncodingSint:
  case eEncodingUint: {
    llvm::StringRef str = value_str;
    bool is_signed = encoding == eEncodingSint;
    bool is_negative = is_signed && str.consume_front("-");
    APInt integer;
    if (str.getAsInteger(0, integer)) {
      error.SetErrorStringWithFormatv(
          "'{0}' is not a valid integer string value", value_str);
      break;
    }
    bool fits;
    if (is_signed) {
      integer = integer.zext(integer.getBitWidth() + 1);
      if (is_negative)
        integer.negate();
      fits = integer.isSignedIntN(byte_size * 8);
    } else
      fits = integer.isIntN(byte_size * 8);
    if (!fits) {
      error.SetErrorStringWithFormatv(
          "value {0} is too large to fit in a {1} byte integer value",
          value_str, byte_size);
      break;
    }
    m_type = e_int;
    m_integer =
        APSInt(std::move(integer), !is_signed).extOrTrunc(8 * byte_size);
    break;
  }

  case eEncodingIEEE754: {
    // FIXME: It's not possible to unambiguously map a byte size to a floating
    // point type. This function should be refactored to take an explicit
    // semantics argument.
    const llvm::fltSemantics &sem =
        byte_size <= 4 ? APFloat::IEEEsingle()
                       : byte_size <= 8 ? APFloat::IEEEdouble()
                                        : APFloat::x87DoubleExtended();
    APFloat f(sem);
    if (llvm::Expected<APFloat::opStatus> op =
            f.convertFromString(value_str, APFloat::rmNearestTiesToEven)) {
      m_type = e_float;
      m_float = std::move(f);
    } else
      error = op.takeError();
    break;
  }

  case eEncodingVector:
    error.SetErrorString("vector encoding unsupported.");
    break;
  }
  if (error.Fail())
    m_type = e_void;

  return error;
}

Status Scalar::SetValueFromData(const DataExtractor &data,
                                lldb::Encoding encoding, size_t byte_size) {
  Status error;
  switch (encoding) {
  case lldb::eEncodingInvalid:
    error.SetErrorString("invalid encoding");
    break;
  case lldb::eEncodingVector:
    error.SetErrorString("vector encoding unsupported");
    break;
  case lldb::eEncodingUint:
  case lldb::eEncodingSint: {
    if (data.GetByteSize() < byte_size)
      return Status("insufficient data");
    m_type = e_int;
    m_integer =
        APSInt(APInt::getZero(8 * byte_size), encoding == eEncodingUint);
    if (data.GetByteOrder() == endian::InlHostByteOrder()) {
      llvm::LoadIntFromMemory(m_integer, data.GetDataStart(), byte_size);
    } else {
      std::vector<uint8_t> buffer(byte_size);
      std::copy_n(data.GetDataStart(), byte_size, buffer.rbegin());
      llvm::LoadIntFromMemory(m_integer, buffer.data(), byte_size);
    }
    break;
  }
  case lldb::eEncodingIEEE754: {
    lldb::offset_t offset = 0;

    if (byte_size == sizeof(float))
      operator=(data.GetFloat(&offset));
    else if (byte_size == sizeof(double))
      operator=(data.GetDouble(&offset));
    else if (byte_size == sizeof(long double))
      operator=(data.GetLongDouble(&offset));
    else
      error.SetErrorStringWithFormat("unsupported float byte size: %" PRIu64 "",
                                     static_cast<uint64_t>(byte_size));
  } break;
  }

  return error;
}

bool Scalar::SignExtend(uint32_t sign_bit_pos) {
  const uint32_t max_bit_pos = GetByteSize() * 8;

  if (sign_bit_pos < max_bit_pos) {
    switch (m_type) {
    case Scalar::e_void:
    case Scalar::e_float:
      return false;

    case Scalar::e_int:
      if (max_bit_pos == sign_bit_pos)
        return true;
      else if (sign_bit_pos < (max_bit_pos - 1)) {
        llvm::APInt sign_bit = llvm::APInt::getSignMask(sign_bit_pos + 1);
        llvm::APInt bitwize_and = m_integer & sign_bit;
        if (bitwize_and.getBoolValue()) {
          llvm::APInt mask =
              ~(sign_bit) + llvm::APInt(m_integer.getBitWidth(), 1);
          m_integer |= APSInt(std::move(mask), m_integer.isUnsigned());
        }
        return true;
      }
      break;
    }
  }
  return false;
}

size_t Scalar::GetAsMemoryData(void *dst, size_t dst_len,
                               lldb::ByteOrder dst_byte_order,
                               Status &error) const {
  // Get a data extractor that points to the native scalar data
  DataExtractor data;
  if (!GetData(data)) {
    error.SetErrorString("invalid scalar value");
    return 0;
  }

  const size_t src_len = data.GetByteSize();

  // Prepare a memory buffer that contains some or all of the register value
  const size_t bytes_copied =
      data.CopyByteOrderedData(0,               // src offset
                               src_len,         // src length
                               dst,             // dst buffer
                               dst_len,         // dst length
                               dst_byte_order); // dst byte order
  if (bytes_copied == 0)
    error.SetErrorString("failed to copy data");

  return bytes_copied;
}

bool Scalar::ExtractBitfield(uint32_t bit_size, uint32_t bit_offset) {
  if (bit_size == 0)
    return true;

  switch (m_type) {
  case Scalar::e_void:
  case Scalar::e_float:
    break;

  case Scalar::e_int:
    m_integer >>= bit_offset;
    m_integer = m_integer.extOrTrunc(bit_size).extOrTrunc(8 * GetByteSize());
    return true;
  }
  return false;
}

bool lldb_private::operator==(Scalar lhs, Scalar rhs) {
  // If either entry is void then we can just compare the types
  if (lhs.m_type == Scalar::e_void || rhs.m_type == Scalar::e_void)
    return lhs.m_type == rhs.m_type;

  llvm::APFloat::cmpResult result;
  switch (Scalar::PromoteToMaxType(lhs, rhs)) {
  case Scalar::e_void:
    break;
  case Scalar::e_int:
    return lhs.m_integer == rhs.m_integer;
  case Scalar::e_float:
    result = lhs.m_float.compare(rhs.m_float);
    if (result == llvm::APFloat::cmpEqual)
      return true;
  }
  return false;
}

bool lldb_private::operator!=(const Scalar &lhs, const Scalar &rhs) {
  return !(lhs == rhs);
}

bool lldb_private::operator<(Scalar lhs, Scalar rhs) {
  if (lhs.m_type == Scalar::e_void || rhs.m_type == Scalar::e_void)
    return false;

  llvm::APFloat::cmpResult result;
  switch (Scalar::PromoteToMaxType(lhs, rhs)) {
  case Scalar::e_void:
    break;
  case Scalar::e_int:
    return lhs.m_integer < rhs.m_integer;
  case Scalar::e_float:
    result = lhs.m_float.compare(rhs.m_float);
    if (result == llvm::APFloat::cmpLessThan)
      return true;
  }
  return false;
}

bool lldb_private::operator<=(const Scalar &lhs, const Scalar &rhs) {
  return !(rhs < lhs);
}

bool lldb_private::operator>(const Scalar &lhs, const Scalar &rhs) {
  return rhs < lhs;
}

bool lldb_private::operator>=(const Scalar &lhs, const Scalar &rhs) {
  return !(lhs < rhs);
}

bool Scalar::ClearBit(uint32_t bit) {
  switch (m_type) {
  case e_void:
    break;
  case e_int:
    m_integer.clearBit(bit);
    return true;
  case e_float:
    break;
  }
  return false;
}

bool Scalar::SetBit(uint32_t bit) {
  switch (m_type) {
  case e_void:
    break;
  case e_int:
    m_integer.setBit(bit);
    return true;
  case e_float:
    break;
  }
  return false;
}

llvm::raw_ostream &lldb_private::operator<<(llvm::raw_ostream &os, const Scalar &scalar) {
  StreamString s;
  scalar.GetValue(&s, /*show_type*/ true);
  return os << s.GetString();
}
