LLDB mainline
Scalar.cpp
Go to the documentation of this file.
1//===-- Scalar.cpp --------------------------------------------------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8
12#include "lldb/Utility/Endian.h"
13#include "lldb/Utility/Status.h"
14#include "lldb/Utility/Stream.h"
16#include "lldb/lldb-types.h"
17#include "llvm/ADT/APSInt.h"
18#include "llvm/ADT/SmallString.h"
19
20#include <cinttypes>
21#include <cstdio>
22
23using namespace lldb;
24using namespace lldb_private;
25
26using llvm::APFloat;
27using llvm::APInt;
28using llvm::APSInt;
29
31 switch (m_type) {
32 case e_void:
33 return PromotionKey{e_void, 0, false};
34 case e_int:
35 return PromotionKey{e_int, m_integer.getBitWidth(), m_integer.isUnsigned()};
36 case e_float:
37 return GetFloatPromoKey(m_float.getSemantics());
38 }
39 llvm_unreachable("Unhandled category!");
40}
41
42Scalar::PromotionKey Scalar::GetFloatPromoKey(const llvm::fltSemantics &sem) {
43 static const llvm::fltSemantics *const order[] = {
44 &APFloat::IEEEsingle(), &APFloat::IEEEdouble(),
45 &APFloat::x87DoubleExtended()};
46 for (const auto &entry : llvm::enumerate(order)) {
47 if (entry.value() == &sem)
48 return PromotionKey{e_float, entry.index(), false};
49 }
50 llvm_unreachable("Unsupported semantics!");
51}
52
53// Promote to max type currently follows the ANSI C rule for type promotion in
54// expressions.
56 const auto &Promote = [](Scalar &a, const Scalar &b) {
57 switch (b.GetType()) {
58 case e_void:
59 break;
60 case e_int:
61 a.IntegralPromote(b.m_integer.getBitWidth(), b.m_integer.isSigned());
62 break;
63 case e_float:
64 a.FloatPromote(b.m_float.getSemantics());
65 }
66 };
67
68 PromotionKey lhs_key = lhs.GetPromoKey();
69 PromotionKey rhs_key = rhs.GetPromoKey();
70
71 if (lhs_key > rhs_key)
72 Promote(rhs, lhs);
73 else if (rhs_key > lhs_key)
74 Promote(lhs, rhs);
75
76 // Make sure our type promotion worked as expected
77 if (lhs.GetPromoKey() == rhs.GetPromoKey())
78 return lhs.GetType(); // Return the resulting type
79
80 // Return the void type (zero) if we fail to promote either of the values.
81 return Scalar::e_void;
82}
83
84bool Scalar::GetData(DataExtractor &data, size_t limit_byte_size) const {
85 size_t byte_size = GetByteSize();
86 if (byte_size == 0) {
87 data.Clear();
88 return false;
89 }
90 auto buffer_up = std::make_unique<DataBufferHeap>(byte_size, 0);
91 GetBytes(buffer_up->GetData());
92 lldb::offset_t offset = 0;
93
94 if (limit_byte_size < byte_size) {
96 // On little endian systems if we want fewer bytes from the current
97 // type we just specify fewer bytes since the LSByte is first...
98 byte_size = limit_byte_size;
100 // On big endian systems if we want fewer bytes from the current type
101 // have to advance our initial byte pointer and trim down the number of
102 // bytes since the MSByte is first
103 offset = byte_size - limit_byte_size;
104 byte_size = limit_byte_size;
105 }
106 }
107
108 data.SetData(std::move(buffer_up), offset, byte_size);
110 return true;
111}
112
113void Scalar::GetBytes(llvm::MutableArrayRef<uint8_t> storage) const {
114 assert(storage.size() >= GetByteSize());
115
116 const auto &store = [&](const llvm::APInt &val) {
117 StoreIntToMemory(val, storage.data(), (val.getBitWidth() + 7) / 8);
118 };
119 switch (m_type) {
120 case e_void:
121 break;
122 case e_int:
123 store(m_integer);
124 break;
125 case e_float:
126 store(m_float.bitcastToAPInt());
127 break;
128 }
129}
130
131size_t Scalar::GetByteSize() const {
132 switch (m_type) {
133 case e_void:
134 break;
135 case e_int:
136 return (m_integer.getBitWidth() / 8);
137 case e_float:
138 return m_float.bitcastToAPInt().getBitWidth() / 8;
139 }
140 return 0;
141}
142
143bool Scalar::IsZero() const {
144 switch (m_type) {
145 case e_void:
146 break;
147 case e_int:
148 return m_integer.isZero();
149 case e_float:
150 return m_float.isZero();
151 }
152 return false;
153}
154
155void Scalar::GetValue(Stream *s, bool show_type) const {
156 if (show_type)
157 s->Printf("(%s) ", GetTypeAsCString());
158
159 switch (m_type) {
160 case e_void:
161 break;
162 case e_int:
163 s->PutCString(llvm::toString(m_integer, 10));
164 break;
165 case e_float:
166 llvm::SmallString<24> string;
167 m_float.toString(string);
168 s->PutCString(string);
169 break;
170 }
171}
172
174 m_integer.setIsSigned(sign);
175 m_integer = m_integer.extOrTrunc(bits);
176}
177
179 switch (m_type) {
180 case e_void:
181 case e_float:
182 break;
183 case e_int:
184 if (GetPromoKey() > PromotionKey(e_int, bits, !sign))
185 break;
186 m_integer = m_integer.extOrTrunc(bits);
187 m_integer.setIsSigned(sign);
188 return true;
189 }
190 return false;
191}
192
193bool Scalar::FloatPromote(const llvm::fltSemantics &semantics) {
194 bool success = false;
195 switch (m_type) {
196 case e_void:
197 break;
198 case e_int:
199 m_float = llvm::APFloat(semantics);
200 m_float.convertFromAPInt(m_integer, m_integer.isSigned(),
201 llvm::APFloat::rmNearestTiesToEven);
202 success = true;
203 break;
204 case e_float:
205 if (GetFloatPromoKey(semantics) < GetFloatPromoKey(m_float.getSemantics()))
206 break;
207 bool ignore;
208 success = true;
209 m_float.convert(semantics, llvm::APFloat::rmNearestTiesToEven, &ignore);
210 }
211
212 if (success)
213 m_type = e_float;
214 return success;
215}
216
218 switch (type) {
219 case e_void:
220 return "void";
221 case e_int:
222 return "int";
223 case e_float:
224 return "float";
225 }
226 return "???";
227}
228
229bool Scalar::IsSigned() const {
230 switch (m_type) {
231 case e_void:
232 return false;
233 case e_int:
234 return m_integer.isSigned();
235 case e_float:
236 return true;
237 }
238 llvm_unreachable("Unrecognized type!");
239}
240
242 bool success = false;
243
244 switch (m_type) {
245 case e_void:
246 break;
247 case e_int:
248 m_integer.setIsSigned(true);
249 success = true;
250 break;
251 case e_float:
252 success = true;
253 break;
254 }
255
256 return success;
257}
258
260 bool success = false;
261
262 switch (m_type) {
263 case e_void:
264 break;
265 case e_int:
266 m_integer.setIsUnsigned(true);
267 success = true;
268 break;
269 case e_float:
270 success = true;
271 break;
272 }
273
274 return success;
275}
276
277static llvm::APInt ToAPInt(const llvm::APFloat &f, unsigned bits,
278 bool is_unsigned) {
279 llvm::APSInt result(bits, is_unsigned);
280 bool isExact;
281 f.convertToInteger(result, llvm::APFloat::rmTowardZero, &isExact);
282 return std::move(result);
283}
284
285template <typename T> T Scalar::GetAs(T fail_value) const {
286 switch (m_type) {
287 case e_void:
288 break;
289 case e_int: {
290 APSInt ext = m_integer.extOrTrunc(sizeof(T) * 8);
291 if (ext.isSigned())
292 return ext.getSExtValue();
293 return ext.getZExtValue();
294 }
295 case e_float:
296 return ToAPInt(m_float, sizeof(T) * 8, std::is_unsigned<T>::value)
297 .getSExtValue();
298 }
299 return fail_value;
300}
301
302signed char Scalar::SChar(signed char fail_value) const {
303 return GetAs<signed char>(fail_value);
304}
305
306unsigned char Scalar::UChar(unsigned char fail_value) const {
307 return GetAs<unsigned char>(fail_value);
308}
309
310short Scalar::SShort(short fail_value) const {
311 return GetAs<short>(fail_value);
312}
313
314unsigned short Scalar::UShort(unsigned short fail_value) const {
315 return GetAs<unsigned short>(fail_value);
316}
317
318int Scalar::SInt(int fail_value) const { return GetAs<int>(fail_value); }
319
320unsigned int Scalar::UInt(unsigned int fail_value) const {
321 return GetAs<unsigned int>(fail_value);
322}
323
324long Scalar::SLong(long fail_value) const { return GetAs<long>(fail_value); }
325
326unsigned long Scalar::ULong(unsigned long fail_value) const {
327 return GetAs<unsigned long>(fail_value);
328}
329
330long long Scalar::SLongLong(long long fail_value) const {
331 return GetAs<long long>(fail_value);
332}
333
334unsigned long long Scalar::ULongLong(unsigned long long fail_value) const {
335 return GetAs<unsigned long long>(fail_value);
336}
337
338llvm::APInt Scalar::SInt128(const llvm::APInt &fail_value) const {
339 switch (m_type) {
340 case e_void:
341 break;
342 case e_int:
343 return m_integer;
344 case e_float:
345 return ToAPInt(m_float, 128, /*is_unsigned=*/false);
346 }
347 return fail_value;
348}
349
350llvm::APInt Scalar::UInt128(const llvm::APInt &fail_value) const {
351 switch (m_type) {
352 case e_void:
353 break;
354 case e_int:
355 return m_integer;
356 case e_float:
357 return ToAPInt(m_float, 128, /*is_unsigned=*/true);
358 }
359 return fail_value;
360}
361
362float Scalar::Float(float fail_value) const {
363 switch (m_type) {
364 case e_void:
365 break;
366 case e_int:
367 if (m_integer.isSigned())
368 return llvm::APIntOps::RoundSignedAPIntToFloat(m_integer);
369 return llvm::APIntOps::RoundAPIntToFloat(m_integer);
370
371 case e_float: {
372 APFloat result = m_float;
373 bool losesInfo;
374 result.convert(APFloat::IEEEsingle(), APFloat::rmNearestTiesToEven,
375 &losesInfo);
376 return result.convertToFloat();
377 }
378 }
379 return fail_value;
380}
381
382double Scalar::Double(double fail_value) const {
383 switch (m_type) {
384 case e_void:
385 break;
386 case e_int:
387 if (m_integer.isSigned())
388 return llvm::APIntOps::RoundSignedAPIntToDouble(m_integer);
389 return llvm::APIntOps::RoundAPIntToDouble(m_integer);
390
391 case e_float: {
392 APFloat result = m_float;
393 bool losesInfo;
394 result.convert(APFloat::IEEEdouble(), APFloat::rmNearestTiesToEven,
395 &losesInfo);
396 return result.convertToDouble();
397 }
398 }
399 return fail_value;
400}
401
402long double Scalar::LongDouble(long double fail_value) const {
403 /// No way to get more precision at the moment.
404 return static_cast<long double>(Double(fail_value));
405}
406
408 Scalar copy = *this;
409 if ((m_type = PromoteToMaxType(copy, rhs)) != Scalar::e_void) {
410 switch (m_type) {
411 case e_void:
412 break;
413 case e_int:
414 m_integer = copy.m_integer + rhs.m_integer;
415 break;
416
417 case e_float:
418 m_float = copy.m_float + rhs.m_float;
419 break;
420 }
421 }
422 return *this;
423}
424
426 if (m_type == e_int && rhs.m_type == e_int)
427 static_cast<APInt &>(m_integer) <<= rhs.m_integer;
428 else
429 m_type = e_void;
430 return *this;
431}
432
434 if (m_type == e_int && rhs.m_type == e_int) {
435 m_integer = m_integer.lshr(rhs.m_integer);
436 return true;
437 }
438 m_type = e_void;
439 return false;
440}
441
443 switch (m_type) {
444 case e_void:
445 case e_float:
446 m_type = e_void;
447 break;
448
449 case e_int:
450 switch (rhs.m_type) {
451 case e_void:
452 case e_float:
453 m_type = e_void;
454 break;
455 case e_int:
456 m_integer = m_integer.ashr(rhs.m_integer);
457 break;
458 }
459 break;
460 }
461 return *this;
462}
463
465 if (m_type == e_int && rhs.m_type == e_int)
466 m_integer &= rhs.m_integer;
467 else
468 m_type = e_void;
469 return *this;
470}
471
473 switch (m_type) {
474 case e_void:
475 break;
476
477 case e_int:
478 if (m_integer.isNegative())
480 return true;
481
482 case e_float:
483 m_float.clearSign();
484 return true;
485 }
486 return false;
487}
488
490 switch (m_type) {
491 case e_void:
492 break;
493 case e_int:
495 return true;
496 case e_float:
497 m_float.changeSign();
498 return true;
499 }
500 return false;
501}
502
504 if (m_type == e_int) {
505 m_integer = ~m_integer;
506 return true;
507 }
508
509 return false;
510}
511
512const Scalar lldb_private::operator+(const Scalar &lhs, const Scalar &rhs) {
513 Scalar result = lhs;
514 result += rhs;
515 return result;
516}
517
519 Scalar result;
520 if ((result.m_type = Scalar::PromoteToMaxType(lhs, rhs)) != Scalar::e_void) {
521 switch (result.m_type) {
522 case Scalar::e_void:
523 break;
524 case Scalar::e_int:
525 result.m_integer = lhs.m_integer - rhs.m_integer;
526 break;
527 case Scalar::e_float:
528 result.m_float = lhs.m_float - rhs.m_float;
529 break;
530 }
531 }
532 return result;
533}
534
536 Scalar result;
537 if ((result.m_type = Scalar::PromoteToMaxType(lhs, rhs)) != Scalar::e_void &&
538 !rhs.IsZero()) {
539 switch (result.m_type) {
540 case Scalar::e_void:
541 break;
542 case Scalar::e_int:
543 result.m_integer = lhs.m_integer / rhs.m_integer;
544 return result;
545 case Scalar::e_float:
546 result.m_float = lhs.m_float / rhs.m_float;
547 return result;
548 }
549 }
550 // For division only, the only way it should make it here is if a promotion
551 // failed, or if we are trying to do a divide by zero.
552 result.m_type = Scalar::e_void;
553 return result;
554}
555
557 Scalar result;
558 if ((result.m_type = Scalar::PromoteToMaxType(lhs, rhs)) != Scalar::e_void) {
559 switch (result.m_type) {
560 case Scalar::e_void:
561 break;
562 case Scalar::e_int:
563 result.m_integer = lhs.m_integer * rhs.m_integer;
564 break;
565 case Scalar::e_float:
566 result.m_float = lhs.m_float * rhs.m_float;
567 break;
568 }
569 }
570 return result;
571}
572
574 Scalar result;
575 if ((result.m_type = Scalar::PromoteToMaxType(lhs, rhs)) != Scalar::e_void) {
576 if (result.m_type == Scalar::e_int)
577 result.m_integer = lhs.m_integer & rhs.m_integer;
578 else
579 result.m_type = Scalar::e_void;
580 }
581 return result;
582}
583
585 Scalar result;
586 if ((result.m_type = Scalar::PromoteToMaxType(lhs, rhs)) != Scalar::e_void) {
587 if (result.m_type == Scalar::e_int)
588 result.m_integer = lhs.m_integer | rhs.m_integer;
589 else
590 result.m_type = Scalar::e_void;
591 }
592 return result;
593}
594
596 Scalar result;
597 if ((result.m_type = Scalar::PromoteToMaxType(lhs, rhs)) != Scalar::e_void) {
598 if (!rhs.IsZero() && result.m_type == Scalar::e_int) {
599 result.m_integer = lhs.m_integer % rhs.m_integer;
600 return result;
601 }
602 }
603 result.m_type = Scalar::e_void;
604 return result;
605}
606
608 Scalar result;
609 if ((result.m_type = Scalar::PromoteToMaxType(lhs, rhs)) != Scalar::e_void) {
610 if (result.m_type == Scalar::e_int)
611 result.m_integer = lhs.m_integer ^ rhs.m_integer;
612 else
613 result.m_type = Scalar::e_void;
614 }
615 return result;
616}
617
618const Scalar lldb_private::operator<<(const Scalar &lhs, const Scalar &rhs) {
619 Scalar result = lhs;
620 result <<= rhs;
621 return result;
622}
623
624const Scalar lldb_private::operator>>(const Scalar &lhs, const Scalar &rhs) {
625 Scalar result = lhs;
626 result >>= rhs;
627 return result;
628}
629
630Status Scalar::SetValueFromCString(const char *value_str, Encoding encoding,
631 size_t byte_size) {
633 if (value_str == nullptr || value_str[0] == '\0') {
634 error.SetErrorString("Invalid c-string value string.");
635 return error;
636 }
637 switch (encoding) {
638 case eEncodingInvalid:
639 error.SetErrorString("Invalid encoding.");
640 break;
641
642 case eEncodingSint:
643 case eEncodingUint: {
644 llvm::StringRef str = value_str;
645 bool is_signed = encoding == eEncodingSint;
646 bool is_negative = is_signed && str.consume_front("-");
647 APInt integer;
648 if (str.getAsInteger(0, integer)) {
649 error.SetErrorStringWithFormatv(
650 "'{0}' is not a valid integer string value", value_str);
651 break;
652 }
653 bool fits;
654 if (is_signed) {
655 integer = integer.zext(integer.getBitWidth() + 1);
656 if (is_negative)
657 integer.negate();
658 fits = integer.isSignedIntN(byte_size * 8);
659 } else
660 fits = integer.isIntN(byte_size * 8);
661 if (!fits) {
662 error.SetErrorStringWithFormatv(
663 "value {0} is too large to fit in a {1} byte integer value",
664 value_str, byte_size);
665 break;
666 }
667 m_type = e_int;
668 m_integer =
669 APSInt(std::move(integer), !is_signed).extOrTrunc(8 * byte_size);
670 break;
671 }
672
673 case eEncodingIEEE754: {
674 // FIXME: It's not possible to unambiguously map a byte size to a floating
675 // point type. This function should be refactored to take an explicit
676 // semantics argument.
677 const llvm::fltSemantics &sem =
678 byte_size <= 4 ? APFloat::IEEEsingle()
679 : byte_size <= 8 ? APFloat::IEEEdouble()
680 : APFloat::x87DoubleExtended();
681 APFloat f(sem);
682 if (llvm::Expected<APFloat::opStatus> op =
683 f.convertFromString(value_str, APFloat::rmNearestTiesToEven)) {
684 m_type = e_float;
685 m_float = std::move(f);
686 } else
687 error = op.takeError();
688 break;
689 }
690
691 case eEncodingVector:
692 error.SetErrorString("vector encoding unsupported.");
693 break;
694 }
695 if (error.Fail())
696 m_type = e_void;
697
698 return error;
699}
700
702 lldb::Encoding encoding, size_t byte_size) {
704 switch (encoding) {
706 error.SetErrorString("invalid encoding");
707 break;
709 error.SetErrorString("vector encoding unsupported");
710 break;
712 case lldb::eEncodingSint: {
713 if (data.GetByteSize() < byte_size)
714 return Status("insufficient data");
715 m_type = e_int;
716 m_integer =
717 APSInt(APInt::getZero(8 * byte_size), encoding == eEncodingUint);
718 if (data.GetByteOrder() == endian::InlHostByteOrder()) {
719 llvm::LoadIntFromMemory(m_integer, data.GetDataStart(), byte_size);
720 } else {
721 std::vector<uint8_t> buffer(byte_size);
722 std::copy_n(data.GetDataStart(), byte_size, buffer.rbegin());
723 llvm::LoadIntFromMemory(m_integer, buffer.data(), byte_size);
724 }
725 break;
726 }
728 lldb::offset_t offset = 0;
729
730 if (byte_size == sizeof(float))
731 operator=(data.GetFloat(&offset));
732 else if (byte_size == sizeof(double))
733 operator=(data.GetDouble(&offset));
734 else if (byte_size == sizeof(long double))
735 operator=(data.GetLongDouble(&offset));
736 else
737 error.SetErrorStringWithFormat("unsupported float byte size: %" PRIu64 "",
738 static_cast<uint64_t>(byte_size));
739 } break;
740 }
741
742 return error;
743}
744
745bool Scalar::SignExtend(uint32_t sign_bit_pos) {
746 const uint32_t max_bit_pos = GetByteSize() * 8;
747
748 if (sign_bit_pos < max_bit_pos) {
749 switch (m_type) {
750 case Scalar::e_void:
751 case Scalar::e_float:
752 return false;
753
754 case Scalar::e_int:
755 if (max_bit_pos == sign_bit_pos)
756 return true;
757 else if (sign_bit_pos < (max_bit_pos - 1)) {
758 llvm::APInt sign_bit = llvm::APInt::getSignMask(sign_bit_pos + 1);
759 llvm::APInt bitwize_and = m_integer & sign_bit;
760 if (bitwize_and.getBoolValue()) {
761 llvm::APInt mask =
762 ~(sign_bit) + llvm::APInt(m_integer.getBitWidth(), 1);
763 m_integer |= APSInt(std::move(mask), m_integer.isUnsigned());
764 }
765 return true;
766 }
767 break;
768 }
769 }
770 return false;
771}
772
773size_t Scalar::GetAsMemoryData(void *dst, size_t dst_len,
774 lldb::ByteOrder dst_byte_order,
775 Status &error) const {
776 // Get a data extractor that points to the native scalar data
777 DataExtractor data;
778 if (!GetData(data)) {
779 error.SetErrorString("invalid scalar value");
780 return 0;
781 }
782
783 const size_t src_len = data.GetByteSize();
784
785 // Prepare a memory buffer that contains some or all of the register value
786 const size_t bytes_copied =
787 data.CopyByteOrderedData(0, // src offset
788 src_len, // src length
789 dst, // dst buffer
790 dst_len, // dst length
791 dst_byte_order); // dst byte order
792 if (bytes_copied == 0)
793 error.SetErrorString("failed to copy data");
794
795 return bytes_copied;
796}
797
798bool Scalar::ExtractBitfield(uint32_t bit_size, uint32_t bit_offset) {
799 if (bit_size == 0)
800 return true;
801
802 switch (m_type) {
803 case Scalar::e_void:
804 case Scalar::e_float:
805 break;
806
807 case Scalar::e_int:
808 m_integer >>= bit_offset;
809 m_integer = m_integer.extOrTrunc(bit_size).extOrTrunc(8 * GetByteSize());
810 return true;
811 }
812 return false;
813}
814
816 // If either entry is void then we can just compare the types
817 if (lhs.m_type == Scalar::e_void || rhs.m_type == Scalar::e_void)
818 return lhs.m_type == rhs.m_type;
819
820 llvm::APFloat::cmpResult result;
821 switch (Scalar::PromoteToMaxType(lhs, rhs)) {
822 case Scalar::e_void:
823 break;
824 case Scalar::e_int:
825 return lhs.m_integer == rhs.m_integer;
826 case Scalar::e_float:
827 result = lhs.m_float.compare(rhs.m_float);
828 if (result == llvm::APFloat::cmpEqual)
829 return true;
830 }
831 return false;
832}
833
834bool lldb_private::operator!=(const Scalar &lhs, const Scalar &rhs) {
835 return !(lhs == rhs);
836}
837
839 if (lhs.m_type == Scalar::e_void || rhs.m_type == Scalar::e_void)
840 return false;
841
842 llvm::APFloat::cmpResult result;
843 switch (Scalar::PromoteToMaxType(lhs, rhs)) {
844 case Scalar::e_void:
845 break;
846 case Scalar::e_int:
847 return lhs.m_integer < rhs.m_integer;
848 case Scalar::e_float:
849 result = lhs.m_float.compare(rhs.m_float);
850 if (result == llvm::APFloat::cmpLessThan)
851 return true;
852 }
853 return false;
854}
855
856bool lldb_private::operator<=(const Scalar &lhs, const Scalar &rhs) {
857 return !(rhs < lhs);
858}
859
860bool lldb_private::operator>(const Scalar &lhs, const Scalar &rhs) {
861 return rhs < lhs;
862}
863
864bool lldb_private::operator>=(const Scalar &lhs, const Scalar &rhs) {
865 return !(lhs < rhs);
866}
867
869 switch (m_type) {
870 case e_void:
871 break;
872 case e_int:
873 m_integer.clearBit(bit);
874 return true;
875 case e_float:
876 break;
877 }
878 return false;
879}
880
882 switch (m_type) {
883 case e_void:
884 break;
885 case e_int:
886 m_integer.setBit(bit);
887 return true;
888 case e_float:
889 break;
890 }
891 return false;
892}
893
894llvm::raw_ostream &lldb_private::operator<<(llvm::raw_ostream &os, const Scalar &scalar) {
895 StreamString s;
896 scalar.GetValue(&s, /*show_type*/ true);
897 return os << s.GetString();
898}
static llvm::raw_ostream & error(Stream &strm)
#define bit
#define integer
static llvm::APInt ToAPInt(const llvm::APFloat &f, unsigned bits, bool is_unsigned)
Definition: Scalar.cpp:277
An data extractor class.
Definition: DataExtractor.h:48
float GetFloat(lldb::offset_t *offset_ptr) const
Extract a float from *offset_ptr.
long double GetLongDouble(lldb::offset_t *offset_ptr) const
void Clear()
Clears the object state.
void SetByteOrder(lldb::ByteOrder byte_order)
Set the byte_order value.
uint64_t GetByteSize() const
Get the number of bytes contained in this object.
const uint8_t * GetDataStart() const
Get the data start pointer.
lldb::offset_t SetData(const void *bytes, lldb::offset_t length, lldb::ByteOrder byte_order)
Set data with a buffer that is caller owned.
lldb::ByteOrder GetByteOrder() const
Get the current byte order value.
lldb::offset_t CopyByteOrderedData(lldb::offset_t src_offset, lldb::offset_t src_len, void *dst, lldb::offset_t dst_len, lldb::ByteOrder dst_byte_order) const
Copy dst_len bytes from *offset_ptr and ensure the copied data is treated as a value that can be swap...
double GetDouble(lldb::offset_t *offset_ptr) const
unsigned int UInt(unsigned int fail_value=0) const
Definition: Scalar.cpp:320
const char * GetTypeAsCString() const
Definition: Scalar.h:102
bool IntegralPromote(uint16_t bits, bool sign)
Definition: Scalar.cpp:178
bool SetBit(uint32_t bit)
Definition: Scalar.cpp:881
int SInt(int fail_value=0) const
Definition: Scalar.cpp:318
long SLong(long fail_value=0) const
Definition: Scalar.cpp:324
size_t GetByteSize() const
Definition: Scalar.cpp:131
unsigned char UChar(unsigned char fail_value=0) const
Definition: Scalar.cpp:306
Status SetValueFromData(const DataExtractor &data, lldb::Encoding encoding, size_t byte_size)
Definition: Scalar.cpp:701
llvm::APFloat m_float
Definition: Scalar.h:192
bool SignExtend(uint32_t bit_pos)
Definition: Scalar.cpp:745
short SShort(short fail_value=0) const
Definition: Scalar.cpp:310
bool IsZero() const
Definition: Scalar.cpp:143
T GetAs(T fail_value) const
Definition: Scalar.cpp:285
llvm::APSInt m_integer
Definition: Scalar.h:191
void TruncOrExtendTo(uint16_t bits, bool sign)
Convert to an integer with bits and the given signedness.
Definition: Scalar.cpp:173
unsigned long long ULongLong(unsigned long long fail_value=0) const
Definition: Scalar.cpp:334
Scalar::Type GetType() const
Definition: Scalar.h:148
unsigned long ULong(unsigned long fail_value=0) const
Definition: Scalar.cpp:326
bool IsSigned() const
Definition: Scalar.cpp:229
size_t GetAsMemoryData(void *dst, size_t dst_len, lldb::ByteOrder dst_byte_order, Status &error) const
Definition: Scalar.cpp:773
void GetBytes(llvm::MutableArrayRef< uint8_t > storage) const
Store the binary representation of this value into the given storage.
Definition: Scalar.cpp:113
bool GetData(DataExtractor &data, size_t limit_byte_size=UINT32_MAX) const
Definition: Scalar.cpp:84
signed char SChar(signed char fail_value=0) const
Definition: Scalar.cpp:302
bool FloatPromote(const llvm::fltSemantics &semantics)
Definition: Scalar.cpp:193
bool ClearBit(uint32_t bit)
Definition: Scalar.cpp:868
static PromotionKey GetFloatPromoKey(const llvm::fltSemantics &semantics)
Definition: Scalar.cpp:42
float Float(float fail_value=0.0f) const
Definition: Scalar.cpp:362
Scalar & operator&=(const Scalar &rhs)
Definition: Scalar.cpp:464
Scalar::Type m_type
Definition: Scalar.h:190
long long SLongLong(long long fail_value=0) const
Definition: Scalar.cpp:330
static const char * GetValueTypeAsCString(Scalar::Type value_type)
Definition: Scalar.cpp:217
bool ExtractBitfield(uint32_t bit_size, uint32_t bit_offset)
Definition: Scalar.cpp:798
std::tuple< Type, unsigned, bool > PromotionKey
Definition: Scalar.h:198
void GetValue(Stream *s, bool show_type) const
Definition: Scalar.cpp:155
double Double(double fail_value=0.0) const
Definition: Scalar.cpp:382
Scalar & operator<<=(const Scalar &rhs)
Definition: Scalar.cpp:425
Status SetValueFromCString(const char *s, lldb::Encoding encoding, size_t byte_size)
Definition: Scalar.cpp:630
static Type PromoteToMaxType(Scalar &lhs, Scalar &rhs)
Definition: Scalar.cpp:55
llvm::APInt SInt128(const llvm::APInt &fail_value) const
Definition: Scalar.cpp:338
unsigned short UShort(unsigned short fail_value=0) const
Definition: Scalar.cpp:314
Scalar & operator+=(Scalar rhs)
Definition: Scalar.cpp:407
bool ShiftRightLogical(const Scalar &rhs)
Definition: Scalar.cpp:433
PromotionKey GetPromoKey() const
Definition: Scalar.cpp:30
long double LongDouble(long double fail_value=0.0) const
Definition: Scalar.cpp:402
Scalar & operator>>=(const Scalar &rhs)
Definition: Scalar.cpp:442
llvm::APInt UInt128(const llvm::APInt &fail_value) const
Definition: Scalar.cpp:350
An error handling class.
Definition: Status.h:44
llvm::StringRef GetString() const
A stream class that can stream formatted output to a file.
Definition: Stream.h:28
size_t Printf(const char *format,...) __attribute__((format(printf
Output printf formatted output to the stream.
Definition: Stream.cpp:107
size_t PutCString(llvm::StringRef cstr)
Output a C string to the stream.
Definition: Stream.cpp:63
lldb::ByteOrder InlHostByteOrder()
Definition: Endian.h:25
A class that represents a running process on the host machine.
Definition: SBAttachInfo.h:14
const Scalar operator&(Scalar lhs, Scalar rhs)
Definition: Scalar.cpp:573
const Scalar operator*(Scalar lhs, Scalar rhs)
Definition: Scalar.cpp:556
bool operator<=(const Scalar &lhs, const Scalar &rhs)
Definition: Scalar.cpp:856
const Scalar operator/(Scalar lhs, Scalar rhs)
Definition: Scalar.cpp:535
bool operator!=(const Address &lhs, const Address &rhs)
Definition: Address.cpp:1022
bool operator>(const Address &lhs, const Address &rhs)
Definition: Address.cpp:1000
const Scalar operator>>(const Scalar &lhs, const Scalar &rhs)
Definition: Scalar.cpp:624
const Scalar operator%(Scalar lhs, Scalar rhs)
Definition: Scalar.cpp:595
AdaptedConstIterator< C, E, A > operator+(typename AdaptedConstIterator< C, E, A >::BackingIterator::difference_type offset, AdaptedConstIterator< C, E, A > &rhs)
Definition: Iterable.h:132
const Scalar operator^(Scalar lhs, Scalar rhs)
Definition: Scalar.cpp:607
bool operator==(const Address &lhs, const Address &rhs)
Definition: Address.cpp:1016
const Scalar operator|(Scalar lhs, Scalar rhs)
Definition: Scalar.cpp:584
bool operator<(const Address &lhs, const Address &rhs)
Definition: Address.cpp:985
static uint32_t bits(const uint32_t val, const uint32_t msbit, const uint32_t lsbit)
Definition: ARMUtils.h:265
bool operator>=(const Scalar &lhs, const Scalar &rhs)
Definition: Scalar.cpp:864
AdaptedConstIterator< C, E, A >::BackingIterator::difference_type operator-(AdaptedConstIterator< C, E, A > &lhs, AdaptedConstIterator< C, E, A > &rhs)
Definition: Iterable.h:141
Stream & operator<<(Stream &s, const SourceLocationSpec &loc)
Dump a SourceLocationSpec object to a stream.
Definition: SBAddress.h:15
uint64_t offset_t
Definition: lldb-types.h:83
Encoding
Register encoding definitions.
@ eEncodingIEEE754
float
@ eEncodingVector
vector registers
@ eEncodingUint
unsigned integer
@ eEncodingInvalid
@ eEncodingSint
signed integer
ByteOrder
Byte ordering definitions.
@ eByteOrderLittle