Path: blob/main/contrib/llvm-project/lldb/source/Utility/Scalar.cpp
39587 views
//===-- Scalar.cpp --------------------------------------------------------===//1//2// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.3// See https://llvm.org/LICENSE.txt for license information.4// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception5//6//===----------------------------------------------------------------------===//78#include "lldb/Utility/Scalar.h"9#include "lldb/Utility/DataBufferHeap.h"10#include "lldb/Utility/DataExtractor.h"11#include "lldb/Utility/Endian.h"12#include "lldb/Utility/Status.h"13#include "lldb/Utility/Stream.h"14#include "lldb/Utility/StreamString.h"15#include "lldb/lldb-types.h"16#include "llvm/ADT/APSInt.h"17#include "llvm/ADT/SmallString.h"18#include "llvm/ADT/StringExtras.h"1920#include <cinttypes>21#include <cstdio>2223using namespace lldb;24using namespace lldb_private;2526using llvm::APFloat;27using llvm::APInt;28using llvm::APSInt;2930Scalar::PromotionKey Scalar::GetPromoKey() const {31switch (m_type) {32case e_void:33return PromotionKey{e_void, 0, false};34case e_int:35return PromotionKey{e_int, m_integer.getBitWidth(), m_integer.isUnsigned()};36case e_float:37return GetFloatPromoKey(m_float.getSemantics());38}39llvm_unreachable("Unhandled category!");40}4142Scalar::PromotionKey Scalar::GetFloatPromoKey(const llvm::fltSemantics &sem) {43static const llvm::fltSemantics *const order[] = {44&APFloat::IEEEsingle(), &APFloat::IEEEdouble(),45&APFloat::x87DoubleExtended()};46for (const auto &entry : llvm::enumerate(order)) {47if (entry.value() == &sem)48return PromotionKey{e_float, entry.index(), false};49}50llvm_unreachable("Unsupported semantics!");51}5253// Promote to max type currently follows the ANSI C rule for type promotion in54// expressions.55Scalar::Type Scalar::PromoteToMaxType(Scalar &lhs, Scalar &rhs) {56const auto &Promote = [](Scalar &a, const Scalar &b) {57switch (b.GetType()) {58case e_void:59break;60case e_int:61a.IntegralPromote(b.m_integer.getBitWidth(), b.m_integer.isSigned());62break;63case e_float:64a.FloatPromote(b.m_float.getSemantics());65}66};6768PromotionKey lhs_key = lhs.GetPromoKey();69PromotionKey rhs_key = rhs.GetPromoKey();7071if (lhs_key > rhs_key)72Promote(rhs, lhs);73else if (rhs_key > lhs_key)74Promote(lhs, rhs);7576// Make sure our type promotion worked as expected77if (lhs.GetPromoKey() == rhs.GetPromoKey())78return lhs.GetType(); // Return the resulting type7980// Return the void type (zero) if we fail to promote either of the values.81return Scalar::e_void;82}8384bool Scalar::GetData(DataExtractor &data, size_t limit_byte_size) const {85size_t byte_size = GetByteSize();86if (byte_size == 0) {87data.Clear();88return false;89}90auto buffer_up = std::make_unique<DataBufferHeap>(byte_size, 0);91GetBytes(buffer_up->GetData());92lldb::offset_t offset = 0;9394if (limit_byte_size < byte_size) {95if (endian::InlHostByteOrder() == eByteOrderLittle) {96// On little endian systems if we want fewer bytes from the current97// type we just specify fewer bytes since the LSByte is first...98byte_size = limit_byte_size;99} else if (endian::InlHostByteOrder() == eByteOrderBig) {100// On big endian systems if we want fewer bytes from the current type101// have to advance our initial byte pointer and trim down the number of102// bytes since the MSByte is first103offset = byte_size - limit_byte_size;104byte_size = limit_byte_size;105}106}107108data.SetData(std::move(buffer_up), offset, byte_size);109data.SetByteOrder(endian::InlHostByteOrder());110return true;111}112113void Scalar::GetBytes(llvm::MutableArrayRef<uint8_t> storage) const {114assert(storage.size() >= GetByteSize());115116const auto &store = [&](const llvm::APInt &val) {117StoreIntToMemory(val, storage.data(), (val.getBitWidth() + 7) / 8);118};119switch (m_type) {120case e_void:121break;122case e_int:123store(m_integer);124break;125case e_float:126store(m_float.bitcastToAPInt());127break;128}129}130131size_t Scalar::GetByteSize() const {132switch (m_type) {133case e_void:134break;135case e_int:136return (m_integer.getBitWidth() + 7) / 8;137case e_float:138return (m_float.bitcastToAPInt().getBitWidth() + 7) / 8;139}140return 0;141}142143bool Scalar::IsZero() const {144switch (m_type) {145case e_void:146break;147case e_int:148return m_integer.isZero();149case e_float:150return m_float.isZero();151}152return false;153}154155void Scalar::GetValue(Stream &s, bool show_type) const {156if (show_type)157s.Printf("(%s) ", GetTypeAsCString());158159switch (m_type) {160case e_void:161break;162case e_int:163s.PutCString(llvm::toString(m_integer, 10));164break;165case e_float:166llvm::SmallString<24> string;167m_float.toString(string);168s.PutCString(string);169break;170}171}172173void Scalar::TruncOrExtendTo(uint16_t bits, bool sign) {174m_integer.setIsSigned(sign);175m_integer = m_integer.extOrTrunc(bits);176}177178bool Scalar::IntegralPromote(uint16_t bits, bool sign) {179switch (m_type) {180case e_void:181case e_float:182break;183case e_int:184if (GetPromoKey() > PromotionKey(e_int, bits, !sign))185break;186m_integer = m_integer.extOrTrunc(bits);187m_integer.setIsSigned(sign);188return true;189}190return false;191}192193bool Scalar::FloatPromote(const llvm::fltSemantics &semantics) {194bool success = false;195switch (m_type) {196case e_void:197break;198case e_int:199m_float = llvm::APFloat(semantics);200m_float.convertFromAPInt(m_integer, m_integer.isSigned(),201llvm::APFloat::rmNearestTiesToEven);202success = true;203break;204case e_float:205if (GetFloatPromoKey(semantics) < GetFloatPromoKey(m_float.getSemantics()))206break;207bool ignore;208success = true;209m_float.convert(semantics, llvm::APFloat::rmNearestTiesToEven, &ignore);210}211212if (success)213m_type = e_float;214return success;215}216217const char *Scalar::GetValueTypeAsCString(Scalar::Type type) {218switch (type) {219case e_void:220return "void";221case e_int:222return "int";223case e_float:224return "float";225}226return "???";227}228229bool Scalar::IsSigned() const {230switch (m_type) {231case e_void:232return false;233case e_int:234return m_integer.isSigned();235case e_float:236return true;237}238llvm_unreachable("Unrecognized type!");239}240241bool Scalar::MakeSigned() {242bool success = false;243244switch (m_type) {245case e_void:246break;247case e_int:248m_integer.setIsSigned(true);249success = true;250break;251case e_float:252success = true;253break;254}255256return success;257}258259bool Scalar::MakeUnsigned() {260bool success = false;261262switch (m_type) {263case e_void:264break;265case e_int:266m_integer.setIsUnsigned(true);267success = true;268break;269case e_float:270success = true;271break;272}273274return success;275}276277static llvm::APInt ToAPInt(const llvm::APFloat &f, unsigned bits,278bool is_unsigned) {279llvm::APSInt result(bits, is_unsigned);280bool isExact;281f.convertToInteger(result, llvm::APFloat::rmTowardZero, &isExact);282return std::move(result);283}284285template <typename T> T Scalar::GetAs(T fail_value) const {286switch (m_type) {287case e_void:288break;289case e_int: {290APSInt ext = m_integer.extOrTrunc(sizeof(T) * 8);291if (ext.isSigned())292return ext.getSExtValue();293return ext.getZExtValue();294}295case e_float:296return ToAPInt(m_float, sizeof(T) * 8, std::is_unsigned<T>::value)297.getSExtValue();298}299return fail_value;300}301302signed char Scalar::SChar(signed char fail_value) const {303return GetAs<signed char>(fail_value);304}305306unsigned char Scalar::UChar(unsigned char fail_value) const {307return GetAs<unsigned char>(fail_value);308}309310short Scalar::SShort(short fail_value) const {311return GetAs<short>(fail_value);312}313314unsigned short Scalar::UShort(unsigned short fail_value) const {315return GetAs<unsigned short>(fail_value);316}317318int Scalar::SInt(int fail_value) const { return GetAs<int>(fail_value); }319320unsigned int Scalar::UInt(unsigned int fail_value) const {321return GetAs<unsigned int>(fail_value);322}323324long Scalar::SLong(long fail_value) const { return GetAs<long>(fail_value); }325326unsigned long Scalar::ULong(unsigned long fail_value) const {327return GetAs<unsigned long>(fail_value);328}329330long long Scalar::SLongLong(long long fail_value) const {331return GetAs<long long>(fail_value);332}333334unsigned long long Scalar::ULongLong(unsigned long long fail_value) const {335return GetAs<unsigned long long>(fail_value);336}337338llvm::APInt Scalar::SInt128(const llvm::APInt &fail_value) const {339switch (m_type) {340case e_void:341break;342case e_int:343return m_integer;344case e_float:345return ToAPInt(m_float, 128, /*is_unsigned=*/false);346}347return fail_value;348}349350llvm::APInt Scalar::UInt128(const llvm::APInt &fail_value) const {351switch (m_type) {352case e_void:353break;354case e_int:355return m_integer;356case e_float:357return ToAPInt(m_float, 128, /*is_unsigned=*/true);358}359return fail_value;360}361362float Scalar::Float(float fail_value) const {363switch (m_type) {364case e_void:365break;366case e_int:367if (m_integer.isSigned())368return llvm::APIntOps::RoundSignedAPIntToFloat(m_integer);369return llvm::APIntOps::RoundAPIntToFloat(m_integer);370371case e_float: {372APFloat result = m_float;373bool losesInfo;374result.convert(APFloat::IEEEsingle(), APFloat::rmNearestTiesToEven,375&losesInfo);376return result.convertToFloat();377}378}379return fail_value;380}381382double Scalar::Double(double fail_value) const {383switch (m_type) {384case e_void:385break;386case e_int:387if (m_integer.isSigned())388return llvm::APIntOps::RoundSignedAPIntToDouble(m_integer);389return llvm::APIntOps::RoundAPIntToDouble(m_integer);390391case e_float: {392APFloat result = m_float;393bool losesInfo;394result.convert(APFloat::IEEEdouble(), APFloat::rmNearestTiesToEven,395&losesInfo);396return result.convertToDouble();397}398}399return fail_value;400}401402long double Scalar::LongDouble(long double fail_value) const {403/// No way to get more precision at the moment.404return static_cast<long double>(Double(fail_value));405}406407Scalar &Scalar::operator+=(Scalar rhs) {408Scalar copy = *this;409if ((m_type = PromoteToMaxType(copy, rhs)) != Scalar::e_void) {410switch (m_type) {411case e_void:412break;413case e_int:414m_integer = copy.m_integer + rhs.m_integer;415break;416417case e_float:418m_float = copy.m_float + rhs.m_float;419break;420}421}422return *this;423}424425Scalar &Scalar::operator<<=(const Scalar &rhs) {426if (m_type == e_int && rhs.m_type == e_int)427static_cast<APInt &>(m_integer) <<= rhs.m_integer;428else429m_type = e_void;430return *this;431}432433bool Scalar::ShiftRightLogical(const Scalar &rhs) {434if (m_type == e_int && rhs.m_type == e_int) {435m_integer = m_integer.lshr(rhs.m_integer);436return true;437}438m_type = e_void;439return false;440}441442Scalar &Scalar::operator>>=(const Scalar &rhs) {443switch (m_type) {444case e_void:445case e_float:446m_type = e_void;447break;448449case e_int:450switch (rhs.m_type) {451case e_void:452case e_float:453m_type = e_void;454break;455case e_int:456m_integer = m_integer.ashr(rhs.m_integer);457break;458}459break;460}461return *this;462}463464Scalar &Scalar::operator&=(const Scalar &rhs) {465if (m_type == e_int && rhs.m_type == e_int)466m_integer &= rhs.m_integer;467else468m_type = e_void;469return *this;470}471472bool Scalar::AbsoluteValue() {473switch (m_type) {474case e_void:475break;476477case e_int:478if (m_integer.isNegative())479m_integer = -m_integer;480return true;481482case e_float:483m_float.clearSign();484return true;485}486return false;487}488489bool Scalar::UnaryNegate() {490switch (m_type) {491case e_void:492break;493case e_int:494m_integer = -m_integer;495return true;496case e_float:497m_float.changeSign();498return true;499}500return false;501}502503bool Scalar::OnesComplement() {504if (m_type == e_int) {505m_integer = ~m_integer;506return true;507}508509return false;510}511512const Scalar lldb_private::operator+(const Scalar &lhs, const Scalar &rhs) {513Scalar result = lhs;514result += rhs;515return result;516}517518const Scalar lldb_private::operator-(Scalar lhs, Scalar rhs) {519Scalar result;520if ((result.m_type = Scalar::PromoteToMaxType(lhs, rhs)) != Scalar::e_void) {521switch (result.m_type) {522case Scalar::e_void:523break;524case Scalar::e_int:525result.m_integer = lhs.m_integer - rhs.m_integer;526break;527case Scalar::e_float:528result.m_float = lhs.m_float - rhs.m_float;529break;530}531}532return result;533}534535const Scalar lldb_private::operator/(Scalar lhs, Scalar rhs) {536Scalar result;537if ((result.m_type = Scalar::PromoteToMaxType(lhs, rhs)) != Scalar::e_void &&538!rhs.IsZero()) {539switch (result.m_type) {540case Scalar::e_void:541break;542case Scalar::e_int:543result.m_integer = lhs.m_integer / rhs.m_integer;544return result;545case Scalar::e_float:546result.m_float = lhs.m_float / rhs.m_float;547return result;548}549}550// For division only, the only way it should make it here is if a promotion551// failed, or if we are trying to do a divide by zero.552result.m_type = Scalar::e_void;553return result;554}555556const Scalar lldb_private::operator*(Scalar lhs, Scalar rhs) {557Scalar result;558if ((result.m_type = Scalar::PromoteToMaxType(lhs, rhs)) != Scalar::e_void) {559switch (result.m_type) {560case Scalar::e_void:561break;562case Scalar::e_int:563result.m_integer = lhs.m_integer * rhs.m_integer;564break;565case Scalar::e_float:566result.m_float = lhs.m_float * rhs.m_float;567break;568}569}570return result;571}572573const Scalar lldb_private::operator&(Scalar lhs, Scalar rhs) {574Scalar result;575if ((result.m_type = Scalar::PromoteToMaxType(lhs, rhs)) != Scalar::e_void) {576if (result.m_type == Scalar::e_int)577result.m_integer = lhs.m_integer & rhs.m_integer;578else579result.m_type = Scalar::e_void;580}581return result;582}583584const Scalar lldb_private::operator|(Scalar lhs, Scalar rhs) {585Scalar result;586if ((result.m_type = Scalar::PromoteToMaxType(lhs, rhs)) != Scalar::e_void) {587if (result.m_type == Scalar::e_int)588result.m_integer = lhs.m_integer | rhs.m_integer;589else590result.m_type = Scalar::e_void;591}592return result;593}594595const Scalar lldb_private::operator%(Scalar lhs, Scalar rhs) {596Scalar result;597if ((result.m_type = Scalar::PromoteToMaxType(lhs, rhs)) != Scalar::e_void) {598if (!rhs.IsZero() && result.m_type == Scalar::e_int) {599result.m_integer = lhs.m_integer % rhs.m_integer;600return result;601}602}603result.m_type = Scalar::e_void;604return result;605}606607const Scalar lldb_private::operator^(Scalar lhs, Scalar rhs) {608Scalar result;609if ((result.m_type = Scalar::PromoteToMaxType(lhs, rhs)) != Scalar::e_void) {610if (result.m_type == Scalar::e_int)611result.m_integer = lhs.m_integer ^ rhs.m_integer;612else613result.m_type = Scalar::e_void;614}615return result;616}617618const Scalar lldb_private::operator<<(const Scalar &lhs, const Scalar &rhs) {619Scalar result = lhs;620result <<= rhs;621return result;622}623624const Scalar lldb_private::operator>>(const Scalar &lhs, const Scalar &rhs) {625Scalar result = lhs;626result >>= rhs;627return result;628}629630Status Scalar::SetValueFromCString(const char *value_str, Encoding encoding,631size_t byte_size) {632Status error;633if (value_str == nullptr || value_str[0] == '\0') {634error.SetErrorString("Invalid c-string value string.");635return error;636}637switch (encoding) {638case eEncodingInvalid:639error.SetErrorString("Invalid encoding.");640break;641642case eEncodingSint:643case eEncodingUint: {644llvm::StringRef str = value_str;645bool is_signed = encoding == eEncodingSint;646bool is_negative = is_signed && str.consume_front("-");647APInt integer;648if (str.getAsInteger(0, integer)) {649error.SetErrorStringWithFormatv(650"'{0}' is not a valid integer string value", value_str);651break;652}653bool fits;654if (is_signed) {655integer = integer.zext(integer.getBitWidth() + 1);656if (is_negative)657integer.negate();658fits = integer.isSignedIntN(byte_size * 8);659} else660fits = integer.isIntN(byte_size * 8);661if (!fits) {662error.SetErrorStringWithFormatv(663"value {0} is too large to fit in a {1} byte integer value",664value_str, byte_size);665break;666}667m_type = e_int;668m_integer =669APSInt(std::move(integer), !is_signed).extOrTrunc(8 * byte_size);670break;671}672673case eEncodingIEEE754: {674// FIXME: It's not possible to unambiguously map a byte size to a floating675// point type. This function should be refactored to take an explicit676// semantics argument.677const llvm::fltSemantics &sem =678byte_size <= 4 ? APFloat::IEEEsingle()679: byte_size <= 8 ? APFloat::IEEEdouble()680: APFloat::x87DoubleExtended();681APFloat f(sem);682if (llvm::Expected<APFloat::opStatus> op =683f.convertFromString(value_str, APFloat::rmNearestTiesToEven)) {684m_type = e_float;685m_float = std::move(f);686} else687error = op.takeError();688break;689}690691case eEncodingVector:692error.SetErrorString("vector encoding unsupported.");693break;694}695if (error.Fail())696m_type = e_void;697698return error;699}700701Status Scalar::SetValueFromData(const DataExtractor &data,702lldb::Encoding encoding, size_t byte_size) {703Status error;704switch (encoding) {705case lldb::eEncodingInvalid:706error.SetErrorString("invalid encoding");707break;708case lldb::eEncodingVector:709error.SetErrorString("vector encoding unsupported");710break;711case lldb::eEncodingUint:712case lldb::eEncodingSint: {713if (data.GetByteSize() < byte_size)714return Status("insufficient data");715m_type = e_int;716m_integer =717APSInt(APInt::getZero(8 * byte_size), encoding == eEncodingUint);718if (data.GetByteOrder() == endian::InlHostByteOrder()) {719llvm::LoadIntFromMemory(m_integer, data.GetDataStart(), byte_size);720} else {721std::vector<uint8_t> buffer(byte_size);722std::copy_n(data.GetDataStart(), byte_size, buffer.rbegin());723llvm::LoadIntFromMemory(m_integer, buffer.data(), byte_size);724}725break;726}727case lldb::eEncodingIEEE754: {728lldb::offset_t offset = 0;729730if (byte_size == sizeof(float))731operator=(data.GetFloat(&offset));732else if (byte_size == sizeof(double))733operator=(data.GetDouble(&offset));734else if (byte_size == sizeof(long double))735operator=(data.GetLongDouble(&offset));736else737error.SetErrorStringWithFormat("unsupported float byte size: %" PRIu64 "",738static_cast<uint64_t>(byte_size));739} break;740}741742return error;743}744745bool Scalar::SignExtend(uint32_t sign_bit_pos) {746const uint32_t max_bit_pos = GetByteSize() * 8;747748if (sign_bit_pos < max_bit_pos) {749switch (m_type) {750case Scalar::e_void:751case Scalar::e_float:752return false;753754case Scalar::e_int:755if (sign_bit_pos < (max_bit_pos - 1)) {756llvm::APInt sign_bit = llvm::APInt::getSignMask(sign_bit_pos + 1);757llvm::APInt bitwize_and = m_integer & sign_bit;758if (bitwize_and.getBoolValue()) {759llvm::APInt mask =760~(sign_bit) + llvm::APInt(m_integer.getBitWidth(), 1);761m_integer |= APSInt(std::move(mask), m_integer.isUnsigned());762}763return true;764}765break;766}767}768return false;769}770771size_t Scalar::GetAsMemoryData(void *dst, size_t dst_len,772lldb::ByteOrder dst_byte_order,773Status &error) const {774// Get a data extractor that points to the native scalar data775DataExtractor data;776if (!GetData(data)) {777error.SetErrorString("invalid scalar value");778return 0;779}780781const size_t src_len = data.GetByteSize();782783// Prepare a memory buffer that contains some or all of the register value784const size_t bytes_copied =785data.CopyByteOrderedData(0, // src offset786src_len, // src length787dst, // dst buffer788dst_len, // dst length789dst_byte_order); // dst byte order790if (bytes_copied == 0)791error.SetErrorString("failed to copy data");792793return bytes_copied;794}795796bool Scalar::ExtractBitfield(uint32_t bit_size, uint32_t bit_offset) {797if (bit_size == 0)798return true;799800switch (m_type) {801case Scalar::e_void:802case Scalar::e_float:803break;804805case Scalar::e_int:806m_integer >>= bit_offset;807m_integer = m_integer.extOrTrunc(bit_size).extOrTrunc(8 * GetByteSize());808return true;809}810return false;811}812813llvm::APFloat Scalar::CreateAPFloatFromAPSInt(lldb::BasicType basic_type) {814switch (basic_type) {815case lldb::eBasicTypeFloat:816return llvm::APFloat(817m_integer.isSigned()818? llvm::APIntOps::RoundSignedAPIntToFloat(m_integer)819: llvm::APIntOps::RoundAPIntToFloat(m_integer));820case lldb::eBasicTypeDouble:821// No way to get more precision at the moment.822case lldb::eBasicTypeLongDouble:823return llvm::APFloat(824m_integer.isSigned()825? llvm::APIntOps::RoundSignedAPIntToDouble(m_integer)826: llvm::APIntOps::RoundAPIntToDouble(m_integer));827default:828const llvm::fltSemantics &sem = APFloat::IEEEsingle();829return llvm::APFloat::getNaN(sem);830}831}832833llvm::APFloat Scalar::CreateAPFloatFromAPFloat(lldb::BasicType basic_type) {834switch (basic_type) {835case lldb::eBasicTypeFloat: {836bool loses_info;837m_float.convert(llvm::APFloat::IEEEsingle(),838llvm::APFloat::rmNearestTiesToEven, &loses_info);839return m_float;840}841case lldb::eBasicTypeDouble:842// No way to get more precision at the moment.843case lldb::eBasicTypeLongDouble: {844bool loses_info;845m_float.convert(llvm::APFloat::IEEEdouble(),846llvm::APFloat::rmNearestTiesToEven, &loses_info);847return m_float;848}849default:850const llvm::fltSemantics &sem = APFloat::IEEEsingle();851return llvm::APFloat::getNaN(sem);852}853}854855bool lldb_private::operator==(Scalar lhs, Scalar rhs) {856// If either entry is void then we can just compare the types857if (lhs.m_type == Scalar::e_void || rhs.m_type == Scalar::e_void)858return lhs.m_type == rhs.m_type;859860llvm::APFloat::cmpResult result;861switch (Scalar::PromoteToMaxType(lhs, rhs)) {862case Scalar::e_void:863break;864case Scalar::e_int:865return lhs.m_integer == rhs.m_integer;866case Scalar::e_float:867result = lhs.m_float.compare(rhs.m_float);868if (result == llvm::APFloat::cmpEqual)869return true;870}871return false;872}873874bool lldb_private::operator!=(const Scalar &lhs, const Scalar &rhs) {875return !(lhs == rhs);876}877878bool lldb_private::operator<(Scalar lhs, Scalar rhs) {879if (lhs.m_type == Scalar::e_void || rhs.m_type == Scalar::e_void)880return false;881882llvm::APFloat::cmpResult result;883switch (Scalar::PromoteToMaxType(lhs, rhs)) {884case Scalar::e_void:885break;886case Scalar::e_int:887return lhs.m_integer < rhs.m_integer;888case Scalar::e_float:889result = lhs.m_float.compare(rhs.m_float);890if (result == llvm::APFloat::cmpLessThan)891return true;892}893return false;894}895896bool lldb_private::operator<=(const Scalar &lhs, const Scalar &rhs) {897return !(rhs < lhs);898}899900bool lldb_private::operator>(const Scalar &lhs, const Scalar &rhs) {901return rhs < lhs;902}903904bool lldb_private::operator>=(const Scalar &lhs, const Scalar &rhs) {905return !(lhs < rhs);906}907908bool Scalar::ClearBit(uint32_t bit) {909switch (m_type) {910case e_void:911break;912case e_int:913m_integer.clearBit(bit);914return true;915case e_float:916break;917}918return false;919}920921bool Scalar::SetBit(uint32_t bit) {922switch (m_type) {923case e_void:924break;925case e_int:926m_integer.setBit(bit);927return true;928case e_float:929break;930}931return false;932}933934llvm::raw_ostream &lldb_private::operator<<(llvm::raw_ostream &os, const Scalar &scalar) {935StreamString s;936scalar.GetValue(s, /*show_type*/ true);937return os << s.GetString();938}939940941