LLDB mainline
Cocoa.cpp
Go to the documentation of this file.
1//===-- Cocoa.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
9#include "Cocoa.h"
10#include "NSString.h"
11#include "ObjCConstants.h"
12
15#include "lldb/Core/Mangled.h"
19#include "lldb/Host/Time.h"
21#include "lldb/Target/Process.h"
22#include "lldb/Target/Target.h"
24#include "lldb/Utility/Endian.h"
26#include "lldb/Utility/Status.h"
27#include "lldb/Utility/Stream.h"
30
31#include "llvm/ADT/APInt.h"
32#include "llvm/ADT/bit.h"
33
34using namespace lldb;
35using namespace lldb_private;
36using namespace lldb_private::formatters;
37
39 ValueObject &valobj, Stream &stream, const TypeSummaryOptions &options) {
40 ProcessSP process_sp = valobj.GetProcessSP();
41 if (!process_sp)
42 return false;
43
44 ObjCLanguageRuntime *runtime = ObjCLanguageRuntime::Get(*process_sp);
45
46 if (!runtime)
47 return false;
48
50 runtime->GetClassDescriptor(valobj));
51
52 if (!descriptor || !descriptor->IsValid())
53 return false;
54
55 uint32_t ptr_size = process_sp->GetAddressByteSize();
56
57 lldb::addr_t valobj_addr = valobj.GetValueAsUnsigned(0);
58
59 if (!valobj_addr)
60 return false;
61
62 llvm::StringRef class_name(descriptor->GetClassName().GetCString());
63
64 if (class_name.empty())
65 return false;
66
67 if (class_name == "NSBundle") {
68 uint64_t offset = 5 * ptr_size;
70 offset,
72 true));
73
74 if (!text)
75 return false;
76
77 StreamString summary_stream;
78 bool was_nsstring_ok =
79 NSStringSummaryProvider(*text, summary_stream, options);
80 if (was_nsstring_ok && summary_stream.GetSize() > 0) {
81 stream.Printf("%s", summary_stream.GetData());
82 return true;
83 }
84 }
85
86 return false;
87}
88
90 ValueObject &valobj, Stream &stream, const TypeSummaryOptions &options) {
91 ProcessSP process_sp = valobj.GetProcessSP();
92 if (!process_sp)
93 return false;
94
95 ObjCLanguageRuntime *runtime = ObjCLanguageRuntime::Get(*process_sp);
96
97 if (!runtime)
98 return false;
99
101 runtime->GetClassDescriptor(valobj));
102
103 if (!descriptor || !descriptor->IsValid())
104 return false;
105
106 uint32_t ptr_size = process_sp->GetAddressByteSize();
107
108 lldb::addr_t valobj_addr = valobj.GetValueAsUnsigned(0);
109
110 if (!valobj_addr)
111 return false;
112
113 llvm::StringRef class_name(descriptor->GetClassName().GetCString());
114
115 if (class_name.empty())
116 return false;
117
118 if (class_name == "__NSTimeZone") {
119 uint64_t offset = ptr_size;
121 offset, valobj.GetCompilerType(), true));
122
123 if (!text)
124 return false;
125
126 StreamString summary_stream;
127 bool was_nsstring_ok =
128 NSStringSummaryProvider(*text, summary_stream, options);
129 if (was_nsstring_ok && summary_stream.GetSize() > 0) {
130 stream.Printf("%s", summary_stream.GetData());
131 return true;
132 }
133 }
134
135 return false;
136}
137
139 ValueObject &valobj, Stream &stream, const TypeSummaryOptions &options) {
140 ProcessSP process_sp = valobj.GetProcessSP();
141 if (!process_sp)
142 return false;
143
144 ObjCLanguageRuntime *runtime = ObjCLanguageRuntime::Get(*process_sp);
145
146 if (!runtime)
147 return false;
148
150 runtime->GetClassDescriptor(valobj));
151
152 if (!descriptor || !descriptor->IsValid())
153 return false;
154
155 uint32_t ptr_size = process_sp->GetAddressByteSize();
156
157 lldb::addr_t valobj_addr = valobj.GetValueAsUnsigned(0);
158
159 if (!valobj_addr)
160 return false;
161
162 llvm::StringRef class_name(descriptor->GetClassName().GetCString());
163
164 if (class_name.empty())
165 return false;
166
167 if (class_name == "NSConcreteNotification") {
168 uint64_t offset = ptr_size;
170 offset, valobj.GetCompilerType(), true));
171
172 if (!text)
173 return false;
174
175 StreamString summary_stream;
176 bool was_nsstring_ok =
177 NSStringSummaryProvider(*text, summary_stream, options);
178 if (was_nsstring_ok && summary_stream.GetSize() > 0) {
179 stream.Printf("%s", summary_stream.GetData());
180 return true;
181 }
182 }
183
184 return false;
185}
186
188 ValueObject &valobj, Stream &stream, const TypeSummaryOptions &options) {
189 ProcessSP process_sp = valobj.GetProcessSP();
190 if (!process_sp)
191 return false;
192
193 ObjCLanguageRuntime *runtime = ObjCLanguageRuntime::Get(*process_sp);
194
195 if (!runtime)
196 return false;
197
199 runtime->GetClassDescriptor(valobj));
200
201 if (!descriptor || !descriptor->IsValid())
202 return false;
203
204 uint32_t ptr_size = process_sp->GetAddressByteSize();
205
206 lldb::addr_t valobj_addr = valobj.GetValueAsUnsigned(0);
207
208 if (!valobj_addr)
209 return false;
210
211 llvm::StringRef class_name(descriptor->GetClassName().GetCString());
212
213 if (class_name.empty())
214 return false;
215
216 uint64_t port_number = 0;
217
218 if (class_name == "NSMachPort") {
219 uint64_t offset = (ptr_size == 4 ? 12 : 20);
221 port_number = process_sp->ReadUnsignedIntegerFromMemory(
222 offset + valobj_addr, 4, 0, error);
223 if (error.Success()) {
224 stream.Printf("mach port: %u",
225 (uint32_t)(port_number & 0x00000000FFFFFFFF));
226 return true;
227 }
228 }
229
230 return false;
231}
232
234 ValueObject &valobj, Stream &stream, const TypeSummaryOptions &options) {
235 ProcessSP process_sp = valobj.GetProcessSP();
236 if (!process_sp)
237 return false;
238
239 AppleObjCRuntime *runtime = llvm::dyn_cast_or_null<AppleObjCRuntime>(
240 ObjCLanguageRuntime::Get(*process_sp));
241
242 if (!runtime)
243 return false;
244
246 runtime->GetClassDescriptor(valobj));
247
248 if (!descriptor || !descriptor->IsValid())
249 return false;
250
251 uint32_t ptr_size = process_sp->GetAddressByteSize();
252
253 lldb::addr_t valobj_addr = valobj.GetValueAsUnsigned(0);
254
255 if (!valobj_addr)
256 return false;
257
258 llvm::StringRef class_name(descriptor->GetClassName().GetCString());
259
260 if (class_name.empty())
261 return false;
262
263 uint64_t count = 0;
264
265 do {
266 if (class_name == "NSIndexSet" || class_name == "NSMutableIndexSet") {
267 // Foundation version 2000 added a bitmask if the index set fit in 64 bits
268 // and a Tagged Pointer version if the bitmask is small enough to fit in
269 // the tagged pointer payload.
270 // It also changed the layout (but not the size) of the set descriptor.
271
272 // First check whether this is a tagged pointer. The bitmask will be in
273 // the payload of the tagged pointer.
274 uint64_t payload;
275 if (runtime->GetFoundationVersion() >= 2000 &&
276 descriptor->GetTaggedPointerInfo(nullptr, nullptr, &payload)) {
277 count = llvm::popcount(payload);
278 break;
279 }
280 // The first 32 bits describe the index set in all cases:
282 uint32_t mode = process_sp->ReadUnsignedIntegerFromMemory(
283 valobj_addr + ptr_size, 4, 0, error);
284 if (error.Fail())
285 return false;
286 // Now check if the index is held in a bitmask in the object:
287 if (runtime->GetFoundationVersion() >= 2000) {
288 // The first two bits are "isSingleRange" and "isBitfield". If this is
289 // a bitfield we handle it here, otherwise set mode appropriately and
290 // the rest of the treatment is in common.
291 if ((mode & 2) == 2) {
292 // The bitfield is a 64 bit uint at the beginning of the data var.
293 uint64_t bitfield = process_sp->ReadUnsignedIntegerFromMemory(
294 valobj_addr + 2 * ptr_size, 8, 0, error);
295 if (error.Fail())
296 return false;
297 count = llvm::popcount(bitfield);
298 break;
299 }
300 // It wasn't a bitfield, so read the isSingleRange from its new loc:
301 if ((mode & 1) == 1)
302 mode = 1; // this means the set only has one range
303 else
304 mode = 2; // this means the set has multiple ranges
305 } else {
306 // this means the set is empty - count = 0
307 if ((mode & 1) == 1) {
308 count = 0;
309 break;
310 }
311
312 if ((mode & 2) == 2)
313 mode = 1; // this means the set only has one range
314 else
315 mode = 2; // this means the set has multiple ranges
316 }
317 if (mode == 1) {
318 count = process_sp->ReadUnsignedIntegerFromMemory(
319 valobj_addr + 3 * ptr_size, ptr_size, 0, error);
320 if (error.Fail())
321 return false;
322 } else {
323 // read a pointer to the data at 2*ptr_size
324 count = process_sp->ReadUnsignedIntegerFromMemory(
325 valobj_addr + 2 * ptr_size, ptr_size, 0, error);
326 if (error.Fail())
327 return false;
328 // read the data at 2*ptr_size from the first location
329 count = process_sp->ReadUnsignedIntegerFromMemory(count + 2 * ptr_size,
330 ptr_size, 0, error);
331 if (error.Fail())
332 return false;
333 }
334 } else
335 return false;
336 } while (false);
337 stream.Printf("%" PRIu64 " index%s", count, (count == 1 ? "" : "es"));
338 return true;
339}
340
341static void NSNumber_FormatChar(ValueObject &valobj, Stream &stream, char value,
342 lldb::LanguageType lang) {
343 static constexpr llvm::StringLiteral g_TypeHint("NSNumber:char");
344
345 llvm::StringRef prefix, suffix;
346 if (Language *language = Language::FindPlugin(lang))
347 std::tie(prefix, suffix) = language->GetFormatterPrefixSuffix(g_TypeHint);
348
349 stream << prefix;
350 stream.Printf("%hhd", value);
351 stream << suffix;
352}
353
354static void NSNumber_FormatShort(ValueObject &valobj, Stream &stream,
355 short value, lldb::LanguageType lang) {
356 static constexpr llvm::StringLiteral g_TypeHint("NSNumber:short");
357
358 llvm::StringRef prefix, suffix;
359 if (Language *language = Language::FindPlugin(lang))
360 std::tie(prefix, suffix) = language->GetFormatterPrefixSuffix(g_TypeHint);
361
362 stream << prefix;
363 stream.Printf("%hd", value);
364 stream << suffix;
365}
366
367static void NSNumber_FormatInt(ValueObject &valobj, Stream &stream, int value,
368 lldb::LanguageType lang) {
369 static constexpr llvm::StringLiteral g_TypeHint("NSNumber:int");
370
371 llvm::StringRef prefix, suffix;
372 if (Language *language = Language::FindPlugin(lang))
373 std::tie(prefix, suffix) = language->GetFormatterPrefixSuffix(g_TypeHint);
374
375 stream << prefix;
376 stream.Printf("%d", value);
377 stream << suffix;
378}
379
380static void NSNumber_FormatLong(ValueObject &valobj, Stream &stream,
381 int64_t value, lldb::LanguageType lang) {
382 static constexpr llvm::StringLiteral g_TypeHint("NSNumber:long");
383
384 llvm::StringRef prefix, suffix;
385 if (Language *language = Language::FindPlugin(lang))
386 std::tie(prefix, suffix) = language->GetFormatterPrefixSuffix(g_TypeHint);
387
388 stream << prefix;
389 stream.Printf("%" PRId64 "", value);
390 stream << suffix;
391}
392
393static void NSNumber_FormatInt128(ValueObject &valobj, Stream &stream,
394 const llvm::APInt &value,
395 lldb::LanguageType lang) {
396 static constexpr llvm::StringLiteral g_TypeHint("NSNumber:int128_t");
397
398 llvm::StringRef prefix, suffix;
399 if (Language *language = Language::FindPlugin(lang))
400 std::tie(prefix, suffix) = language->GetFormatterPrefixSuffix(g_TypeHint);
401
402 stream << prefix;
403 const int radix = 10;
404 const bool isSigned = true;
405 std::string str = llvm::toString(value, radix, isSigned);
406 stream.PutCString(str.c_str());
407 stream << suffix;
408}
409
410static void NSNumber_FormatFloat(ValueObject &valobj, Stream &stream,
411 float value, lldb::LanguageType lang) {
412 static constexpr llvm::StringLiteral g_TypeHint("NSNumber:float");
413
414 llvm::StringRef prefix, suffix;
415 if (Language *language = Language::FindPlugin(lang))
416 std::tie(prefix, suffix) = language->GetFormatterPrefixSuffix(g_TypeHint);
417
418 stream << prefix;
419 stream.Printf("%f", value);
420 stream << suffix;
421}
422
423static void NSNumber_FormatDouble(ValueObject &valobj, Stream &stream,
424 double value, lldb::LanguageType lang) {
425 static constexpr llvm::StringLiteral g_TypeHint("NSNumber:double");
426
427 llvm::StringRef prefix, suffix;
428 if (Language *language = Language::FindPlugin(lang))
429 std::tie(prefix, suffix) = language->GetFormatterPrefixSuffix(g_TypeHint);
430
431 stream << prefix;
432 stream.Printf("%g", value);
433 stream << suffix;
434}
435
437 ValueObject &valobj, Stream &stream, const TypeSummaryOptions &options) {
438 ProcessSP process_sp = valobj.GetProcessSP();
439 if (!process_sp)
440 return false;
441
442 Log *log = GetLog(LLDBLog::DataFormatters);
443 ObjCLanguageRuntime *runtime = ObjCLanguageRuntime::Get(*process_sp);
444
445 if (!runtime)
446 return false;
447
449 runtime->GetClassDescriptor(valobj));
450
451 if (!descriptor || !descriptor->IsValid())
452 return false;
453
454 uint32_t ptr_size = process_sp->GetAddressByteSize();
455
456 lldb::addr_t valobj_addr = valobj.GetValueAsUnsigned(0);
457
458 if (!valobj_addr)
459 return false;
460
461 llvm::StringRef class_name(descriptor->GetClassName().GetCString());
462
463 if (class_name.empty())
464 return false;
465
466 if (class_name == "__NSCFBoolean")
467 return ObjCBooleanSummaryProvider(valobj, stream, options);
468
469 if (class_name == "NSDecimalNumber")
470 return NSDecimalNumberSummaryProvider(valobj, stream, options);
471
472 if (class_name == "NSConstantIntegerNumber") {
474 int64_t value = process_sp->ReadSignedIntegerFromMemory(
475 valobj_addr + 2 * ptr_size, 8, 0, error);
476 if (error.Fail())
477 return false;
478 uint64_t encoding_addr = process_sp->ReadUnsignedIntegerFromMemory(
479 valobj_addr + ptr_size, ptr_size, 0, error);
480 if (error.Fail())
481 return false;
482 char encoding =
483 process_sp->ReadUnsignedIntegerFromMemory(encoding_addr, 1, 0, error);
484 if (error.Fail())
485 return false;
486
487 switch (encoding) {
488 case _C_CHR:
489 NSNumber_FormatChar(valobj, stream, (char)value, options.GetLanguage());
490 return true;
491 case _C_SHT:
492 NSNumber_FormatShort(valobj, stream, (short)value, options.GetLanguage());
493 return true;
494 case _C_INT:
495 NSNumber_FormatInt(valobj, stream, (int)value, options.GetLanguage());
496 return true;
497 case _C_LNG:
498 case _C_LNG_LNG:
499 NSNumber_FormatLong(valobj, stream, value, options.GetLanguage());
500 return true;
501
502 case _C_UCHR:
503 case _C_USHT:
504 case _C_UINT:
505 case _C_ULNG:
506 case _C_ULNG_LNG:
507 stream.Printf("%" PRIu64, value);
508 return true;
509 }
510
511 return false;
512 }
513
514 if (class_name == "NSConstantFloatNumber") {
516 uint32_t flt_as_int = process_sp->ReadUnsignedIntegerFromMemory(
517 valobj_addr + ptr_size, 4, 0, error);
518 if (error.Fail())
519 return false;
520 float flt_value = 0.0f;
521 memcpy(&flt_value, &flt_as_int, sizeof(flt_as_int));
522 NSNumber_FormatFloat(valobj, stream, flt_value, options.GetLanguage());
523 return true;
524 }
525
526 if (class_name == "NSConstantDoubleNumber") {
528 uint64_t dbl_as_lng = process_sp->ReadUnsignedIntegerFromMemory(
529 valobj_addr + ptr_size, 8, 0, error);
530 if (error.Fail())
531 return false;
532 double dbl_value = 0.0;
533 memcpy(&dbl_value, &dbl_as_lng, sizeof(dbl_as_lng));
534 NSNumber_FormatDouble(valobj, stream, dbl_value, options.GetLanguage());
535 return true;
536 }
537
538 if (class_name == "NSNumber" || class_name == "__NSCFNumber") {
539 int64_t value = 0;
540 uint64_t i_bits = 0;
541 if (descriptor->GetTaggedPointerInfoSigned(&i_bits, &value)) {
542 // Check for "preserved" numbers. We still don't support them yet.
543 if (i_bits & 0x8) {
544 if (log)
545 log->Printf(
546 "Unsupported (preserved) NSNumber tagged pointer 0x%" PRIu64,
547 valobj_addr);
548 return false;
549 }
550
551 switch (i_bits) {
552 case 0:
553 NSNumber_FormatChar(valobj, stream, (char)value, options.GetLanguage());
554 break;
555 case 1:
556 case 4:
557 NSNumber_FormatShort(valobj, stream, (short)value,
558 options.GetLanguage());
559 break;
560 case 2:
561 case 8:
562 NSNumber_FormatInt(valobj, stream, (int)value, options.GetLanguage());
563 break;
564 case 3:
565 case 12:
566 NSNumber_FormatLong(valobj, stream, value, options.GetLanguage());
567 break;
568 default:
569 return false;
570 }
571 return true;
572 } else {
574
575 AppleObjCRuntime *runtime = llvm::dyn_cast_or_null<AppleObjCRuntime>(
576 ObjCLanguageRuntime::Get(*process_sp));
577
578 const bool new_format =
579 (runtime && runtime->GetFoundationVersion() >= 1400);
580
581 enum class TypeCodes : int {
582 sint8 = 0x0,
583 sint16 = 0x1,
584 sint32 = 0x2,
585 sint64 = 0x3,
586 f32 = 0x4,
587 f64 = 0x5,
588 sint128 = 0x6
589 };
590
591 uint64_t data_location = valobj_addr + 2 * ptr_size;
592 TypeCodes type_code;
593
594 if (new_format) {
595 uint64_t cfinfoa = process_sp->ReadUnsignedIntegerFromMemory(
596 valobj_addr + ptr_size, ptr_size, 0, error);
597
598 if (error.Fail())
599 return false;
600
601 bool is_preserved_number = cfinfoa & 0x8;
602 if (is_preserved_number) {
603 if (log)
604 log->Printf(
605 "Unsupported preserved NSNumber tagged pointer 0x%" PRIu64,
606 valobj_addr);
607 return false;
608 }
609
610 type_code = static_cast<TypeCodes>(cfinfoa & 0x7);
611 } else {
612 uint8_t data_type = process_sp->ReadUnsignedIntegerFromMemory(
613 valobj_addr + ptr_size, 1, 0, error) &
614 0x1F;
615
616 if (error.Fail())
617 return false;
618
619 switch (data_type) {
620 case 1:
621 type_code = TypeCodes::sint8;
622 break;
623 case 2:
624 type_code = TypeCodes::sint16;
625 break;
626 case 3:
627 type_code = TypeCodes::sint32;
628 break;
629 case 17:
630 data_location += 8;
631 [[fallthrough]];
632 case 4:
633 type_code = TypeCodes::sint64;
634 break;
635 case 5:
636 type_code = TypeCodes::f32;
637 break;
638 case 6:
639 type_code = TypeCodes::f64;
640 break;
641 default:
642 return false;
643 }
644 }
645
646 uint64_t value = 0;
647 bool success = false;
648 switch (type_code) {
649 case TypeCodes::sint8:
650 value = process_sp->ReadUnsignedIntegerFromMemory(data_location, 1, 0,
651 error);
652 if (error.Fail())
653 return false;
654 NSNumber_FormatChar(valobj, stream, (char)value, options.GetLanguage());
655 success = true;
656 break;
657 case TypeCodes::sint16:
658 value = process_sp->ReadUnsignedIntegerFromMemory(data_location, 2, 0,
659 error);
660 if (error.Fail())
661 return false;
662 NSNumber_FormatShort(valobj, stream, (short)value,
663 options.GetLanguage());
664 success = true;
665 break;
666 case TypeCodes::sint32:
667 value = process_sp->ReadUnsignedIntegerFromMemory(data_location, 4, 0,
668 error);
669 if (error.Fail())
670 return false;
671 NSNumber_FormatInt(valobj, stream, (int)value, options.GetLanguage());
672 success = true;
673 break;
674 case TypeCodes::sint64:
675 value = process_sp->ReadUnsignedIntegerFromMemory(data_location, 8, 0,
676 error);
677 if (error.Fail())
678 return false;
679 NSNumber_FormatLong(valobj, stream, value, options.GetLanguage());
680 success = true;
681 break;
682 case TypeCodes::f32: {
683 uint32_t flt_as_int = process_sp->ReadUnsignedIntegerFromMemory(
684 data_location, 4, 0, error);
685 if (error.Fail())
686 return false;
687 float flt_value = 0.0f;
688 memcpy(&flt_value, &flt_as_int, sizeof(flt_as_int));
689 NSNumber_FormatFloat(valobj, stream, flt_value, options.GetLanguage());
690 success = true;
691 break;
692 }
693 case TypeCodes::f64: {
694 uint64_t dbl_as_lng = process_sp->ReadUnsignedIntegerFromMemory(
695 data_location, 8, 0, error);
696 if (error.Fail())
697 return false;
698 double dbl_value = 0.0;
699 memcpy(&dbl_value, &dbl_as_lng, sizeof(dbl_as_lng));
700 NSNumber_FormatDouble(valobj, stream, dbl_value, options.GetLanguage());
701 success = true;
702 break;
703 }
704 case TypeCodes::sint128: // internally, this is the same
705 {
706 uint64_t words[2];
707 words[1] = process_sp->ReadUnsignedIntegerFromMemory(data_location, 8,
708 0, error);
709 if (error.Fail())
710 return false;
711 words[0] = process_sp->ReadUnsignedIntegerFromMemory(data_location + 8,
712 8, 0, error);
713 if (error.Fail())
714 return false;
715 llvm::APInt i128_value(128, words);
716 NSNumber_FormatInt128(valobj, stream, i128_value,
717 options.GetLanguage());
718 success = true;
719 break;
720 }
721 }
722 return success;
723 }
724 }
725
726 return false;
727}
728
730 ValueObject &valobj, Stream &stream, const TypeSummaryOptions &options) {
731 ProcessSP process_sp = valobj.GetProcessSP();
732 if (!process_sp)
733 return false;
734
735 lldb::addr_t valobj_addr = valobj.GetValueAsUnsigned(0);
736 uint32_t ptr_size = process_sp->GetAddressByteSize();
737
739 int8_t exponent = process_sp->ReadUnsignedIntegerFromMemory(
740 valobj_addr + ptr_size, 1, 0, error);
741 if (error.Fail())
742 return false;
743
744 uint8_t length_and_negative = process_sp->ReadUnsignedIntegerFromMemory(
745 valobj_addr + ptr_size + 1, 1, 0, error);
746 if (error.Fail())
747 return false;
748
749 // Fifth bit marks negativity.
750 const bool is_negative = (length_and_negative >> 4) & 1;
751
752 // Zero length and negative means NaN.
753 uint8_t length = length_and_negative & 0xf;
754 const bool is_nan = is_negative && (length == 0);
755
756 if (is_nan) {
757 stream.Printf("NaN");
758 return true;
759 }
760
761 if (length == 0) {
762 stream.Printf("0");
763 return true;
764 }
765
766 uint64_t mantissa = process_sp->ReadUnsignedIntegerFromMemory(
767 valobj_addr + ptr_size + 4, 8, 0, error);
768 if (error.Fail())
769 return false;
770
771 if (is_negative)
772 stream.Printf("-");
773
774 stream.Printf("%" PRIu64 " x 10^%" PRIi8, mantissa, exponent);
775 return true;
776}
777
779 ValueObject &valobj, Stream &stream, const TypeSummaryOptions &options) {
780 ProcessSP process_sp = valobj.GetProcessSP();
781 if (!process_sp)
782 return false;
783
784 ObjCLanguageRuntime *runtime = ObjCLanguageRuntime::Get(*process_sp);
785
786 if (!runtime)
787 return false;
788
790 runtime->GetClassDescriptor(valobj));
791
792 if (!descriptor || !descriptor->IsValid())
793 return false;
794
795 uint32_t ptr_size = process_sp->GetAddressByteSize();
796
797 lldb::addr_t valobj_addr = valobj.GetValueAsUnsigned(0);
798
799 if (!valobj_addr)
800 return false;
801
802 llvm::StringRef class_name = descriptor->GetClassName().GetStringRef();
803
804 if (class_name != "NSURL")
805 return false;
806
807 uint64_t offset_text = ptr_size + ptr_size +
808 8; // ISA + pointer + 8 bytes of data (even on 32bit)
809 uint64_t offset_base = offset_text + ptr_size;
810 CompilerType type(valobj.GetCompilerType());
811 ValueObjectSP text(valobj.GetSyntheticChildAtOffset(offset_text, type, true));
812 ValueObjectSP base(valobj.GetSyntheticChildAtOffset(offset_base, type, true));
813 if (!text || text->GetValueAsUnsigned(0) == 0)
814 return false;
815
816 StreamString base_summary;
817 if (base && base->GetValueAsUnsigned(0)) {
818 if (!NSURLSummaryProvider(*base, base_summary, options))
819 base_summary.Clear();
820 }
821 if (base_summary.Empty())
822 return NSStringSummaryProvider(*text, stream, options);
823
824 StreamString summary;
825 if (!NSStringSummaryProvider(*text, summary, options) || summary.Empty())
826 return false;
827
828 static constexpr llvm::StringLiteral quote_char("\"");
829 static constexpr llvm::StringLiteral g_TypeHint("NSString");
830 llvm::StringRef prefix, suffix;
831 if (Language *language = Language::FindPlugin(options.GetLanguage()))
832 std::tie(prefix, suffix) = language->GetFormatterPrefixSuffix(g_TypeHint);
833
834 // @"A" -> @"A
835 llvm::StringRef summary_str = summary.GetString();
836 bool back_consumed =
837 summary_str.consume_back(suffix) && summary_str.consume_back(quote_char);
838 assert(back_consumed);
839 UNUSED_IF_ASSERT_DISABLED(back_consumed);
840 // @"B" -> B"
841 llvm::StringRef base_summary_str = base_summary.GetString();
842 bool front_consumed = base_summary_str.consume_front(prefix) &&
843 base_summary_str.consume_front(quote_char);
844 assert(front_consumed);
845 UNUSED_IF_ASSERT_DISABLED(front_consumed);
846 // @"A -- B"
847 if (!summary_str.empty() && !base_summary_str.empty()) {
848 stream << summary_str << " -- " << base_summary_str;
849 return true;
850 }
851
852 return false;
853}
854
855/// Bias value for tagged pointer exponents.
856/// Recommended values:
857/// 0x3e3: encodes all dates between distantPast and distantFuture
858/// except for the range within about 1e-28 second of the reference date.
859/// 0x3ef: encodes all dates for a few million years beyond distantPast and
860/// distantFuture, except within about 1e-25 second of the reference date.
862
864 uint64_t fraction : 52; // unsigned
865 uint64_t exponent : 11; // signed
866 uint64_t sign : 1;
867};
868
870 uint64_t fraction : 52; // unsigned
871 uint64_t exponent : 7; // signed
872 uint64_t sign : 1;
873 uint64_t unused : 4; // placeholder for pointer tag bits
874};
875
876static uint64_t decodeExponent(uint64_t exp) {
877 // Tagged exponent field is 7-bit signed. Sign-extend the value to 64 bits
878 // before performing arithmetic.
879 return llvm::SignExtend64<7>(exp) + TAGGED_DATE_EXPONENT_BIAS;
880}
881
882static double decodeTaggedTimeInterval(uint64_t encodedTimeInterval) {
883 if (encodedTimeInterval == 0)
884 return 0.0;
885 if (encodedTimeInterval == std::numeric_limits<uint64_t>::max())
886 return (uint64_t)-0.0;
887
888 TaggedDoubleBits encodedBits =
889 llvm::bit_cast<TaggedDoubleBits>(encodedTimeInterval);
890 assert(encodedBits.unused == 0);
891
892 // Sign and fraction are represented exactly.
893 // Exponent is encoded.
894 DoubleBits decodedBits;
895 decodedBits.sign = encodedBits.sign;
896 decodedBits.fraction = encodedBits.fraction;
897 decodedBits.exponent = decodeExponent(encodedBits.exponent);
898
899 return llvm::bit_cast<double>(decodedBits);
900}
901
903 ValueObject &valobj, Stream &stream, const TypeSummaryOptions &options) {
904 ProcessSP process_sp = valobj.GetProcessSP();
905 if (!process_sp)
906 return false;
907
908 ObjCLanguageRuntime *runtime = ObjCLanguageRuntime::Get(*process_sp);
909
910 if (!runtime)
911 return false;
912
914 runtime->GetClassDescriptor(valobj));
915
916 if (!descriptor || !descriptor->IsValid())
917 return false;
918
919 uint32_t ptr_size = process_sp->GetAddressByteSize();
920
921 lldb::addr_t valobj_addr = valobj.GetValueAsUnsigned(0);
922
923 if (!valobj_addr)
924 return false;
925
926 uint64_t date_value_bits = 0;
927 double date_value = 0.0;
928
929 ConstString class_name = descriptor->GetClassName();
930
931 static const ConstString g_NSDate("NSDate");
932 static const ConstString g_dunder_NSDate("__NSDate");
933 static const ConstString g_NSTaggedDate("__NSTaggedDate");
934 static const ConstString g_NSCalendarDate("NSCalendarDate");
935 static const ConstString g_NSConstantDate("NSConstantDate");
936
937 if (class_name.IsEmpty())
938 return false;
939
940 uint64_t info_bits = 0, value_bits = 0;
941 if ((class_name == g_NSDate) || (class_name == g_dunder_NSDate) ||
942 (class_name == g_NSTaggedDate) || (class_name == g_NSConstantDate)) {
943 if (descriptor->GetTaggedPointerInfo(&info_bits, &value_bits)) {
944 date_value_bits = ((value_bits << 8) | (info_bits << 4));
945 memcpy(&date_value, &date_value_bits, sizeof(date_value_bits));
946 } else {
947 llvm::Triple triple(
948 process_sp->GetTarget().GetArchitecture().GetTriple());
949 uint32_t delta =
950 (triple.isWatchOS() && triple.isWatchABI()) ? 8 : ptr_size;
952 date_value_bits = process_sp->ReadUnsignedIntegerFromMemory(
953 valobj_addr + delta, 8, 0, error);
954 memcpy(&date_value, &date_value_bits, sizeof(date_value_bits));
955 if (error.Fail())
956 return false;
957 }
958 } else if (class_name == g_NSCalendarDate) {
960 date_value_bits = process_sp->ReadUnsignedIntegerFromMemory(
961 valobj_addr + 2 * ptr_size, 8, 0, error);
962 memcpy(&date_value, &date_value_bits, sizeof(date_value_bits));
963 if (error.Fail())
964 return false;
965 } else
966 return false;
967
968 // FIXME: It seems old dates are not formatted according to NSDate's calendar
969 // so we hardcode distantPast's value so that it looks like LLDB is doing
970 // the right thing.
971
972 // The relative time in seconds from Cocoa Epoch to [NSDate distantPast].
973 const double RelSecondsFromCocoaEpochToNSDateDistantPast = -63114076800;
974 if (date_value == RelSecondsFromCocoaEpochToNSDateDistantPast) {
975 stream.Printf("0001-01-01 00:00:00 UTC");
976 return true;
977 }
978
979 // Accomodate for the __NSTaggedDate format introduced in Foundation 1600.
980 if (class_name == g_NSTaggedDate) {
981 auto *runtime = llvm::dyn_cast_or_null<AppleObjCRuntime>(
982 ObjCLanguageRuntime::Get(*process_sp));
983 if (runtime && runtime->GetFoundationVersion() >= 1600)
984 date_value = decodeTaggedTimeInterval(value_bits << 4);
985 }
986
987 // this snippet of code assumes that time_t == seconds since Jan-1-1970 this
988 // is generally true and POSIXly happy, but might break if a library vendor
989 // decides to get creative
990 time_t epoch = GetOSXEpoch();
991 epoch = epoch + static_cast<time_t>(std::floor(date_value));
992 tm *tm_date = gmtime(&epoch);
993 if (!tm_date)
994 return false;
995 std::string buffer(1024, 0);
996 if (strftime(&buffer[0], 1023, "%Z", tm_date) == 0)
997 return false;
998 stream.Printf("%04d-%02d-%02d %02d:%02d:%02d %s", tm_date->tm_year + 1900,
999 tm_date->tm_mon + 1, tm_date->tm_mday, tm_date->tm_hour,
1000 tm_date->tm_min, tm_date->tm_sec, buffer.c_str());
1001 return true;
1002}
1003
1005 ValueObject &valobj, Stream &stream, const TypeSummaryOptions &options) {
1006 ProcessSP process_sp = valobj.GetProcessSP();
1007 if (!process_sp)
1008 return false;
1009
1010 ObjCLanguageRuntime *runtime = ObjCLanguageRuntime::Get(*process_sp);
1011
1012 if (!runtime)
1013 return false;
1014
1016 runtime->GetClassDescriptorFromISA(valobj.GetValueAsUnsigned(0)));
1017
1018 if (!descriptor || !descriptor->IsValid())
1019 return false;
1020
1021 ConstString class_name = descriptor->GetClassName();
1022
1023 if (class_name.IsEmpty())
1024 return false;
1025
1026 if (ConstString cs = Mangled(class_name).GetDemangledName())
1027 class_name = cs;
1028
1029 stream.Printf("%s", class_name.AsCString("<unknown class>"));
1030 return true;
1031}
1032
1034public:
1036 : SyntheticChildrenFrontEnd(*valobj_sp) {}
1037
1039
1040 llvm::Expected<uint32_t> CalculateNumChildren() override { return 0; }
1041
1042 lldb::ValueObjectSP GetChildAtIndex(uint32_t idx) override {
1043 return lldb::ValueObjectSP();
1044 }
1045
1048 }
1049
1050 bool MightHaveChildren() override { return false; }
1051
1052 size_t GetIndexOfChildWithName(ConstString name) override {
1053 return UINT32_MAX;
1054 }
1055};
1056
1060 return new ObjCClassSyntheticChildrenFrontEnd(valobj_sp);
1061}
1062
1063template <bool needs_at>
1065 ValueObject &valobj, Stream &stream, const TypeSummaryOptions &options) {
1066 ProcessSP process_sp = valobj.GetProcessSP();
1067 if (!process_sp)
1068 return false;
1069
1070 ObjCLanguageRuntime *runtime = ObjCLanguageRuntime::Get(*process_sp);
1071
1072 if (!runtime)
1073 return false;
1074
1076 runtime->GetClassDescriptor(valobj));
1077
1078 if (!descriptor || !descriptor->IsValid())
1079 return false;
1080
1081 bool is_64bit = (process_sp->GetAddressByteSize() == 8);
1082 lldb::addr_t valobj_addr = valobj.GetValueAsUnsigned(0);
1083
1084 if (!valobj_addr)
1085 return false;
1086
1087 uint64_t value = 0;
1088
1089 llvm::StringRef class_name = descriptor->GetClassName().GetCString();
1090
1091 if (class_name.empty())
1092 return false;
1093
1094 bool isNSConcreteData = class_name == "NSConcreteData";
1095 bool isNSConcreteMutableData = class_name == "NSConcreteMutableData";
1096 bool isNSCFData = class_name == "__NSCFData";
1097 if (isNSConcreteData || isNSConcreteMutableData || isNSCFData) {
1098 uint32_t offset;
1099 if (isNSConcreteData)
1100 offset = is_64bit ? 8 : 4;
1101 else
1102 offset = is_64bit ? 16 : 8;
1103
1104 Status error;
1105 value = process_sp->ReadUnsignedIntegerFromMemory(
1106 valobj_addr + offset, is_64bit ? 8 : 4, 0, error);
1107 if (error.Fail())
1108 return false;
1109 } else if (class_name == "_NSInlineData") {
1110 uint32_t offset = (is_64bit ? 8 : 4);
1111 Status error;
1112 value = process_sp->ReadUnsignedIntegerFromMemory(valobj_addr + offset, 2,
1113 0, error);
1114 if (error.Fail())
1115 return false;
1116 } else if (class_name == "_NSZeroData") {
1117 value = 0;
1118 } else
1119 return false;
1120
1121 stream.Printf("%s%" PRIu64 " byte%s%s", (needs_at ? "@\"" : ""), value,
1122 (value != 1 ? "s" : ""), (needs_at ? "\"" : ""));
1123
1124 return true;
1125}
1126
1128 ValueObject &valobj, Stream &stream, const TypeSummaryOptions &options) {
1129 const uint32_t type_info = valobj.GetCompilerType().GetTypeInfo();
1130
1131 ValueObjectSP real_guy_sp = valobj.GetSP();
1132
1133 if (type_info & eTypeIsPointer) {
1134 Status err;
1135 real_guy_sp = valobj.Dereference(err);
1136 if (err.Fail() || !real_guy_sp)
1137 return false;
1138 } else if (type_info & eTypeIsReference) {
1139 real_guy_sp = valobj.GetChildAtIndex(0);
1140 if (!real_guy_sp)
1141 return false;
1142 }
1143 int8_t value = (real_guy_sp->GetValueAsSigned(0) & 0xFF);
1144 switch (value) {
1145 case 0:
1146 stream.Printf("NO");
1147 break;
1148 case 1:
1149 stream.Printf("YES");
1150 break;
1151 default:
1152 stream.Printf("%d", value);
1153 break;
1154 }
1155 return true;
1156}
1157
1159 ValueObject &valobj, Stream &stream, const TypeSummaryOptions &options) {
1160 lldb::addr_t valobj_ptr_value =
1162 if (valobj_ptr_value == LLDB_INVALID_ADDRESS)
1163 return false;
1164
1165 ProcessSP process_sp(valobj.GetProcessSP());
1166 if (!process_sp)
1167 return false;
1168
1169 if (AppleObjCRuntime *objc_runtime = llvm::dyn_cast_or_null<AppleObjCRuntime>(
1170 ObjCLanguageRuntime::Get(*process_sp))) {
1172 cf_false = LLDB_INVALID_ADDRESS;
1173 objc_runtime->GetValuesForGlobalCFBooleans(cf_true, cf_false);
1174 if (valobj_ptr_value == cf_true) {
1175 stream.PutCString("YES");
1176 return true;
1177 }
1178 if (valobj_ptr_value == cf_false) {
1179 stream.PutCString("NO");
1180 return true;
1181 }
1182 }
1183
1184 return false;
1185}
1186
1187template <bool is_sel_ptr>
1189 ValueObject &valobj, Stream &stream, const TypeSummaryOptions &options) {
1190 lldb::ValueObjectSP valobj_sp;
1191
1192 CompilerType charstar(valobj.GetCompilerType()
1194 .GetPointerType());
1195
1196 if (!charstar)
1197 return false;
1198
1199 ExecutionContext exe_ctx(valobj.GetExecutionContextRef());
1200
1201 if (is_sel_ptr) {
1203 if (data_address == LLDB_INVALID_ADDRESS)
1204 return false;
1205 valobj_sp = ValueObject::CreateValueObjectFromAddress("text", data_address,
1206 exe_ctx, charstar);
1207 } else {
1208 DataExtractor data;
1209 Status error;
1210 valobj.GetData(data, error);
1211 if (error.Fail())
1212 return false;
1213 valobj_sp =
1214 ValueObject::CreateValueObjectFromData("text", data, exe_ctx, charstar);
1215 }
1216
1217 if (!valobj_sp)
1218 return false;
1219
1220 stream.Printf("%s", valobj_sp->GetSummaryAsCString());
1221 return true;
1222}
1223
1224// POSIX has an epoch on Jan-1-1970, but Cocoa prefers Jan-1-2001
1225// this call gives the POSIX equivalent of the Cocoa epoch
1227 static time_t epoch = 0;
1228 if (!epoch) {
1229#ifndef _WIN32
1230 tzset();
1231 tm tm_epoch;
1232 tm_epoch.tm_sec = 0;
1233 tm_epoch.tm_hour = 0;
1234 tm_epoch.tm_min = 0;
1235 tm_epoch.tm_mon = 0;
1236 tm_epoch.tm_mday = 1;
1237 tm_epoch.tm_year = 2001 - 1900;
1238 tm_epoch.tm_isdst = -1;
1239 tm_epoch.tm_gmtoff = 0;
1240 tm_epoch.tm_zone = nullptr;
1241 epoch = timegm(&tm_epoch);
1242#endif
1243 }
1244 return epoch;
1245}
1246
1248 ValueObject &, Stream &, const TypeSummaryOptions &);
1249
1251 ValueObject &, Stream &, const TypeSummaryOptions &);
1252
1254 ValueObject &, Stream &, const TypeSummaryOptions &);
1255
1257 ValueObject &, Stream &, const TypeSummaryOptions &);
static void NSNumber_FormatLong(ValueObject &valobj, Stream &stream, int64_t value, lldb::LanguageType lang)
Definition: Cocoa.cpp:380
static void NSNumber_FormatChar(ValueObject &valobj, Stream &stream, char value, lldb::LanguageType lang)
Definition: Cocoa.cpp:341
static void NSNumber_FormatFloat(ValueObject &valobj, Stream &stream, float value, lldb::LanguageType lang)
Definition: Cocoa.cpp:410
static double decodeTaggedTimeInterval(uint64_t encodedTimeInterval)
Definition: Cocoa.cpp:882
static void NSNumber_FormatInt(ValueObject &valobj, Stream &stream, int value, lldb::LanguageType lang)
Definition: Cocoa.cpp:367
static uint64_t decodeExponent(uint64_t exp)
Definition: Cocoa.cpp:876
static void NSNumber_FormatInt128(ValueObject &valobj, Stream &stream, const llvm::APInt &value, lldb::LanguageType lang)
Definition: Cocoa.cpp:393
static void NSNumber_FormatDouble(ValueObject &valobj, Stream &stream, double value, lldb::LanguageType lang)
Definition: Cocoa.cpp:423
const int TAGGED_DATE_EXPONENT_BIAS
Bias value for tagged pointer exponents.
Definition: Cocoa.cpp:861
static void NSNumber_FormatShort(ValueObject &valobj, Stream &stream, short value, lldb::LanguageType lang)
Definition: Cocoa.cpp:354
static llvm::raw_ostream & error(Stream &strm)
#define _C_USHT
Definition: ObjCConstants.h:19
#define _C_ULNG
Definition: ObjCConstants.h:23
#define _C_INT
Definition: ObjCConstants.h:20
#define _C_UINT
Definition: ObjCConstants.h:21
#define _C_CHR
Definition: ObjCConstants.h:16
#define _C_ULNG_LNG
Definition: ObjCConstants.h:25
#define _C_UCHR
Definition: ObjCConstants.h:17
#define _C_LNG
Definition: ObjCConstants.h:22
#define _C_LNG_LNG
Definition: ObjCConstants.h:24
#define _C_SHT
Definition: ObjCConstants.h:18
time_t timegm(struct tm *t)
lldb::ValueObjectSP GetChildAtIndex(uint32_t idx) override
Definition: Cocoa.cpp:1042
llvm::Expected< uint32_t > CalculateNumChildren() override
Definition: Cocoa.cpp:1040
size_t GetIndexOfChildWithName(ConstString name) override
Definition: Cocoa.cpp:1052
lldb::ChildCacheState Update() override
This function is assumed to always succeed and if it fails, the front-end should know to deal with it...
Definition: Cocoa.cpp:1046
~ObjCClassSyntheticChildrenFrontEnd() override=default
bool MightHaveChildren() override
Definition: Cocoa.cpp:1050
ObjCClassSyntheticChildrenFrontEnd(lldb::ValueObjectSP valobj_sp)
Definition: Cocoa.cpp:1035
Generic representation of a type in a programming language.
Definition: CompilerType.h:36
CompilerType GetBasicTypeFromAST(lldb::BasicType basic_type) const
Create related types using the current type's AST.
CompilerType GetPointerType() const
Return a new CompilerType that is a pointer to this type.
uint32_t GetTypeInfo(CompilerType *pointee_or_element_compiler_type=nullptr) const
A uniqued constant string class.
Definition: ConstString.h:40
const char * AsCString(const char *value_if_empty=nullptr) const
Get the string value as a C string.
Definition: ConstString.h:188
bool IsEmpty() const
Test for empty string.
Definition: ConstString.h:304
An data extractor class.
Definition: DataExtractor.h:48
"lldb/Target/ExecutionContext.h" A class that contains an execution context.
static Language * FindPlugin(lldb::LanguageType language)
Definition: Language.cpp:84
void void Printf(const char *format,...) __attribute__((format(printf
Prefer using LLDB_LOGF whenever possible.
Definition: Log.cpp:156
A class that handles mangled names.
Definition: Mangled.h:33
std::shared_ptr< ClassDescriptor > ClassDescriptorSP
virtual ClassDescriptorSP GetClassDescriptorFromISA(ObjCISA isa)
static ObjCLanguageRuntime * Get(Process &process)
virtual ClassDescriptorSP GetClassDescriptor(ValueObject &in_value)
An error handling class.
Definition: Status.h:118
bool Fail() const
Test for error condition.
Definition: Status.cpp:294
const char * GetData() const
Definition: StreamString.h:45
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:134
size_t PutCString(llvm::StringRef cstr)
Output a C string to the stream.
Definition: Stream.cpp:65
lldb::LanguageType GetLanguage() const
Definition: TypeSummary.cpp:29
virtual uint64_t GetData(DataExtractor &data, Status &error)
virtual lldb::ValueObjectSP GetChildAtIndex(uint32_t idx, bool can_create=true)
CompilerType GetCompilerType()
Definition: ValueObject.h:352
lldb::ValueObjectSP GetSP()
Definition: ValueObject.h:569
lldb::ProcessSP GetProcessSP() const
Definition: ValueObject.h:338
virtual lldb::ValueObjectSP GetSyntheticChildAtOffset(uint32_t offset, const CompilerType &type, bool can_create, ConstString name_const_str=ConstString())
static lldb::ValueObjectSP CreateValueObjectFromAddress(llvm::StringRef name, uint64_t address, const ExecutionContext &exe_ctx, CompilerType type, bool do_deref=true)
Given an address either create a value object containing the value at that address,...
virtual uint64_t GetValueAsUnsigned(uint64_t fail_value, bool *success=nullptr)
static lldb::ValueObjectSP CreateValueObjectFromData(llvm::StringRef name, const DataExtractor &data, const ExecutionContext &exe_ctx, CompilerType type)
virtual lldb::ValueObjectSP Dereference(Status &error)
const ExecutionContextRef & GetExecutionContextRef() const
Definition: ValueObject.h:330
#define UNUSED_IF_ASSERT_DISABLED(x)
Definition: lldb-defines.h:140
#define LLDB_INVALID_ADDRESS
Definition: lldb-defines.h:82
#define UINT32_MAX
Definition: lldb-defines.h:19
bool NSURLSummaryProvider(ValueObject &valobj, Stream &stream, const TypeSummaryOptions &options)
Definition: Cocoa.cpp:778
template bool NSDataSummaryProvider< true >(ValueObject &, Stream &, const TypeSummaryOptions &)
bool ObjCBOOLSummaryProvider(ValueObject &valobj, Stream &stream, const TypeSummaryOptions &options)
Definition: Cocoa.cpp:1127
bool ObjCBooleanSummaryProvider(ValueObject &valobj, Stream &stream, const TypeSummaryOptions &options)
Definition: Cocoa.cpp:1158
bool NSBundleSummaryProvider(ValueObject &valobj, Stream &stream, const TypeSummaryOptions &options)
Definition: Cocoa.cpp:38
bool NSIndexSetSummaryProvider(ValueObject &valobj, Stream &stream, const TypeSummaryOptions &options)
Definition: Cocoa.cpp:233
bool NSDecimalNumberSummaryProvider(ValueObject &valobj, Stream &stream, const TypeSummaryOptions &options)
Definition: Cocoa.cpp:729
template bool ObjCSELSummaryProvider< true >(ValueObject &, Stream &, const TypeSummaryOptions &)
template bool ObjCSELSummaryProvider< false >(ValueObject &, Stream &, const TypeSummaryOptions &)
bool NSDataSummaryProvider(ValueObject &valobj, Stream &stream, const TypeSummaryOptions &options)
Definition: Cocoa.cpp:1064
bool NSDateSummaryProvider(ValueObject &valobj, Stream &stream, const TypeSummaryOptions &options)
Definition: Cocoa.cpp:902
bool NSNotificationSummaryProvider(ValueObject &valobj, Stream &stream, const TypeSummaryOptions &options)
Definition: Cocoa.cpp:138
bool NSMachPortSummaryProvider(ValueObject &valobj, Stream &stream, const TypeSummaryOptions &options)
Definition: Cocoa.cpp:187
template bool NSDataSummaryProvider< false >(ValueObject &, Stream &, const TypeSummaryOptions &)
bool ObjCSELSummaryProvider(ValueObject &valobj, Stream &stream, const TypeSummaryOptions &options)
Definition: Cocoa.cpp:1188
bool ObjCClassSummaryProvider(ValueObject &valobj, Stream &stream, const TypeSummaryOptions &options)
Definition: Cocoa.cpp:1004
bool NSNumberSummaryProvider(ValueObject &valobj, Stream &stream, const TypeSummaryOptions &options)
Definition: Cocoa.cpp:436
bool NSTimeZoneSummaryProvider(ValueObject &valobj, Stream &stream, const TypeSummaryOptions &options)
Definition: Cocoa.cpp:89
bool NSStringSummaryProvider(ValueObject &valobj, Stream &stream, const TypeSummaryOptions &options)
Definition: NSString.cpp:33
SyntheticChildrenFrontEnd * ObjCClassSyntheticFrontEndCreator(CXXSyntheticChildren *, lldb::ValueObjectSP)
Definition: Cocoa.cpp:1058
A class that represents a running process on the host machine.
Log * GetLog(Cat mask)
Retrieve the Log object for the channel associated with the given log enum.
Definition: Log.h:332
Definition: SBAddress.h:15
@ eBasicTypeObjCID
ChildCacheState
Specifies if children need to be re-computed after a call to SyntheticChildrenFrontEnd::Update.
@ eRefetch
Children need to be recomputed dynamically.
std::shared_ptr< lldb_private::ValueObject > ValueObjectSP
Definition: lldb-forward.h:484
LanguageType
Programming language type.
std::shared_ptr< lldb_private::Process > ProcessSP
Definition: lldb-forward.h:389
uint64_t addr_t
Definition: lldb-types.h:80
uint64_t sign
Definition: Cocoa.cpp:866
uint64_t exponent
Definition: Cocoa.cpp:865
uint64_t fraction
Definition: Cocoa.cpp:864
uint64_t unused
Definition: Cocoa.cpp:873
uint64_t sign
Definition: Cocoa.cpp:872
uint64_t exponent
Definition: Cocoa.cpp:871
uint64_t fraction
Definition: Cocoa.cpp:870