LLDB mainline
NSArray.cpp
Go to the documentation of this file.
1//===-- NSArray.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 "clang/AST/ASTContext.h"
10#include "clang/Basic/TargetInfo.h"
11
12#include "Cocoa.h"
13
16
20#include "lldb/Target/Target.h"
22#include "lldb/Utility/Endian.h"
23#include "lldb/Utility/Status.h"
24#include "lldb/Utility/Stream.h"
27
28using namespace lldb;
29using namespace lldb_private;
30using namespace lldb_private::formatters;
31
32namespace lldb_private {
33namespace formatters {
34std::map<ConstString, CXXFunctionSummaryFormat::Callback> &
36 static std::map<ConstString, CXXFunctionSummaryFormat::Callback> g_map;
37 return g_map;
38}
39
40std::map<ConstString, CXXSyntheticChildren::CreateFrontEndCallback> &
42 static std::map<ConstString, CXXSyntheticChildren::CreateFrontEndCallback>
43 g_map;
44 return g_map;
45}
46
48public:
50
51 ~NSArrayMSyntheticFrontEndBase() override = default;
52
53 llvm::Expected<uint32_t> CalculateNumChildren() override;
54
55 lldb::ValueObjectSP GetChildAtIndex(uint32_t idx) override;
56
58
59 llvm::Expected<size_t> GetIndexOfChildWithName(ConstString name) override;
60
61protected:
63
64 virtual uint64_t GetUsedCount() = 0;
65
66 virtual uint64_t GetOffset() = 0;
67
68 virtual uint64_t GetSize() = 0;
69
71 uint8_t m_ptr_size = 8;
73};
74
75template <typename D32, typename D64>
77public:
79
81
83
84protected:
86
87 uint64_t GetUsedCount() override;
88
89 uint64_t GetOffset() override;
90
91 uint64_t GetSize() override;
92
93private:
96};
97
98namespace Foundation1010 {
99 namespace {
100 struct DataDescriptor_32 {
101 uint32_t _used;
102 uint32_t _offset;
103 uint32_t _size : 28;
104 uint64_t _priv1 : 4;
105 uint32_t _priv2;
106 uint32_t _data;
107 };
108
109 struct DataDescriptor_64 {
110 uint64_t _used;
111 uint64_t _offset;
112 uint64_t _size : 60;
113 uint64_t _priv1 : 4;
114 uint32_t _priv2;
115 uint64_t _data;
116 };
117 }
118
121}
122
123namespace Foundation1428 {
124 namespace {
125 struct DataDescriptor_32 {
126 uint32_t _used;
127 uint32_t _offset;
128 uint32_t _size;
129 uint32_t _data;
130 };
131
132 struct DataDescriptor_64 {
133 uint64_t _used;
134 uint64_t _offset;
135 uint64_t _size;
136 uint64_t _data;
137 };
138 }
139
142}
143
144namespace Foundation1437 {
145 template <typename PtrType>
147 PtrType _cow;
148 // __deque
149 PtrType _data;
150 uint32_t _offset;
151 uint32_t _size;
152 uint32_t _muts;
153 uint32_t _used;
154 };
155
159
160 template <typename DD>
161 uint64_t
163 lldb::addr_t valobj_addr, Status &error) {
164 const lldb::addr_t start_of_descriptor =
165 valobj_addr + process.GetAddressByteSize();
166 DD descriptor = DD();
167 process.ReadMemory(start_of_descriptor, &descriptor,
168 sizeof(descriptor), error);
169 if (error.Fail()) {
170 return 0;
171 }
172 return descriptor._used;
173 }
174
175 uint64_t
177 Status &error) {
178 if (process.GetAddressByteSize() == 4) {
179 return __NSArrayMSize_Impl<DataDescriptor<uint32_t>>(process, valobj_addr,
180 error);
181 } else {
182 return __NSArrayMSize_Impl<DataDescriptor<uint64_t>>(process, valobj_addr,
183 error);
184 }
185 }
186
187}
188
189namespace CallStackArray {
191 uint32_t _data;
192 uint32_t _used;
193 uint32_t _offset;
194 const uint32_t _size = 0;
195};
196
198 uint64_t _data;
199 uint64_t _used;
200 uint64_t _offset;
201 const uint64_t _size = 0;
202};
203
206} // namespace CallStackArray
207
208template <typename D32, typename D64, bool Inline>
231
232namespace Foundation1300 {
233 struct IDD32 {
234 uint32_t used;
235 uint32_t list;
236 };
237
238 struct IDD64 {
239 uint64_t used;
240 uint64_t list;
241 };
242
245}
246
251
252namespace Foundation1436 {
253 struct IDD32 {
254 uint32_t used;
255 uint32_t list; // in Inline cases, this is the first element
256 };
257
258 struct IDD64 {
259 uint64_t used;
260 uint64_t list; // in Inline cases, this is the first element
261 };
262
265
268
271
272 uint64_t
274 Status &error) {
275 return Foundation1437::__NSArrayMSize(process, valobj_addr, error);
276 }
277}
278
279namespace ConstantArray {
280
282 uint64_t used;
283 uint32_t list;
284};
285
287 uint64_t used;
288 uint64_t list;
289};
290
293} // namespace ConstantArray
294
296public:
298
299 ~NSArray0SyntheticFrontEnd() override = default;
300
301 llvm::Expected<uint32_t> CalculateNumChildren() override;
302
303 lldb::ValueObjectSP GetChildAtIndex(uint32_t idx) override;
304
305 lldb::ChildCacheState Update() override;
306
307 bool MightHaveChildren() override;
308
309 llvm::Expected<size_t> GetIndexOfChildWithName(ConstString name) override;
310};
311
313public:
315
316 ~NSArray1SyntheticFrontEnd() override = default;
317
318 llvm::Expected<uint32_t> CalculateNumChildren() override;
319
320 lldb::ValueObjectSP GetChildAtIndex(uint32_t idx) override;
321
322 lldb::ChildCacheState Update() override;
323
324 llvm::Expected<size_t> GetIndexOfChildWithName(ConstString name) override;
325};
326} // namespace formatters
327} // namespace lldb_private
328
330 ValueObject &valobj, Stream &stream, const TypeSummaryOptions &options) {
331 static constexpr llvm::StringLiteral g_TypeHint("NSArray");
332
333 ProcessSP process_sp = valobj.GetProcessSP();
334 if (!process_sp)
335 return false;
336
337 ObjCLanguageRuntime *runtime = ObjCLanguageRuntime::Get(*process_sp);
338
339 if (!runtime)
340 return false;
341
343 runtime->GetClassDescriptor(valobj));
344
345 if (!descriptor || !descriptor->IsValid())
346 return false;
347
348 uint32_t ptr_size = process_sp->GetAddressByteSize();
349
350 lldb::addr_t valobj_addr = valobj.GetValueAsUnsigned(0);
351
352 if (!valobj_addr)
353 return false;
354
355 uint64_t value = 0;
356
357 ConstString class_name(descriptor->GetClassName());
358
359 static const ConstString g_NSArrayI("__NSArrayI");
360 static const ConstString g_NSArrayM("__NSArrayM");
361 static const ConstString g_NSArrayI_Transfer("__NSArrayI_Transfer");
362 static const ConstString g_NSFrozenArrayM("__NSFrozenArrayM");
363 static const ConstString g_NSArray0("__NSArray0");
364 static const ConstString g_NSArray1("__NSSingleObjectArrayI");
365 static const ConstString g_NSArrayCF("__NSCFArray");
366 static const ConstString g_NSArrayMLegacy("__NSArrayM_Legacy");
367 static const ConstString g_NSArrayMImmutable("__NSArrayM_Immutable");
368 static const ConstString g_NSCallStackArray("_NSCallStackArray");
369 static const ConstString g_NSConstantArray("NSConstantArray");
370
371 if (class_name.IsEmpty())
372 return false;
373
374 if (class_name == g_NSArrayI) {
376 value = process_sp->ReadUnsignedIntegerFromMemory(valobj_addr + ptr_size,
377 ptr_size, 0, error);
378 if (error.Fail())
379 return false;
380 } else if (class_name == g_NSConstantArray) {
382 value = process_sp->ReadUnsignedIntegerFromMemory(valobj_addr + ptr_size, 8,
383 0, error);
384 if (error.Fail())
385 return false;
386 } else if (class_name == g_NSArrayM) {
387 AppleObjCRuntime *apple_runtime =
388 llvm::dyn_cast_or_null<AppleObjCRuntime>(runtime);
390 if (apple_runtime && apple_runtime->GetFoundationVersion() >= 1437) {
391 value = Foundation1437::__NSArrayMSize(*process_sp, valobj_addr, error);
392 } else {
393 value = process_sp->ReadUnsignedIntegerFromMemory(valobj_addr + ptr_size,
394 ptr_size, 0, error);
395 }
396 if (error.Fail())
397 return false;
398 } else if (class_name == g_NSArrayI_Transfer) {
400 value = process_sp->ReadUnsignedIntegerFromMemory(valobj_addr + ptr_size,
401 ptr_size, 0, error);
402 if (error.Fail())
403 return false;
404 } else if (class_name == g_NSFrozenArrayM) {
406 value = Foundation1436::__NSFrozenArrayMSize(*process_sp, valobj_addr, error);
407 if (error.Fail())
408 return false;
409 } else if (class_name == g_NSArrayMLegacy) {
411 value = process_sp->ReadUnsignedIntegerFromMemory(valobj_addr + ptr_size,
412 ptr_size, 0, error);
413 if (error.Fail())
414 return false;
415 } else if (class_name == g_NSArrayMImmutable) {
417 value = process_sp->ReadUnsignedIntegerFromMemory(valobj_addr + ptr_size,
418 ptr_size, 0, error);
419 if (error.Fail())
420 return false;
421 } else if (class_name == g_NSArray0) {
422 value = 0;
423 } else if (class_name == g_NSArray1) {
424 value = 1;
425 } else if (class_name == g_NSArrayCF || class_name == g_NSCallStackArray) {
426 // __NSCFArray and _NSCallStackArray store the number of elements as a
427 // pointer-sized value at offset `2 * ptr_size`.
429 value = process_sp->ReadUnsignedIntegerFromMemory(
430 valobj_addr + 2 * ptr_size, ptr_size, 0, error);
431 if (error.Fail())
432 return false;
433 } else {
435 auto iter = map.find(class_name), end = map.end();
436 if (iter != end)
437 return iter->second(valobj, stream, options);
438 else
439 return false;
440 }
441
442 llvm::StringRef prefix, suffix;
443 if (Language *language = Language::FindPlugin(options.GetLanguage()))
444 std::tie(prefix, suffix) = language->GetFormatterPrefixSuffix(g_TypeHint);
445
446 stream << prefix;
447 stream.Printf("%" PRIu64 " %s%s", value, "element", value == 1 ? "" : "s");
448 stream << suffix;
449 return true;
450}
451
455 if (valobj_sp) {
457 *valobj_sp->GetExecutionContextRef().GetTargetSP());
458 if (scratch_ts_sp)
460 scratch_ts_sp->weak_from_this(),
461 scratch_ts_sp->getASTContext().ObjCBuiltinIdTy.getAsOpaquePtr());
462 if (valobj_sp->GetProcessSP())
463 m_ptr_size = valobj_sp->GetProcessSP()->GetAddressByteSize();
464 }
465}
466
467template <typename D32, typename D64>
473
478
481 uint32_t idx) {
483 return lldb::ValueObjectSP();
484 lldb::addr_t object_at_idx = GetDataAddress();
485 size_t pyhs_idx = idx;
486 pyhs_idx += GetOffset();
487 if (GetSize() <= pyhs_idx)
488 pyhs_idx -= GetSize();
489 object_at_idx += (pyhs_idx * m_ptr_size);
490 StreamString idx_name;
491 idx_name.Printf("[%" PRIu64 "]", (uint64_t)idx);
492 return CreateValueObjectFromAddress(idx_name.GetString(), object_at_idx,
494}
495
496template <typename D32, typename D64>
499 ValueObjectSP valobj_sp = m_backend.GetSP();
500 m_ptr_size = 0;
501 delete m_data_32;
502 m_data_32 = nullptr;
503 delete m_data_64;
504 m_data_64 = nullptr;
505 if (!valobj_sp)
507 m_exe_ctx_ref = valobj_sp->GetExecutionContextRef();
509 error.Clear();
510 lldb::ProcessSP process_sp(valobj_sp->GetProcessSP());
511 if (!process_sp)
513 m_ptr_size = process_sp->GetAddressByteSize();
514 uint64_t data_location = valobj_sp->GetValueAsUnsigned(0) + m_ptr_size;
515 if (m_ptr_size == 4) {
516 m_data_32 = new D32();
517 process_sp->ReadMemory(data_location, m_data_32, sizeof(D32),
518 error);
519 } else {
520 m_data_64 = new D64();
521 process_sp->ReadMemory(data_location, m_data_64, sizeof(D64),
522 error);
523 }
524
525 return error.Success() ? lldb::ChildCacheState::eReuse
527}
528
531 auto optional_idx = ExtractIndexFromString(name.AsCString());
532 if (!optional_idx) {
533 return llvm::createStringError("Type has no child named '%s'",
534 name.AsCString());
535 }
536 uint32_t idx = *optional_idx;
538 return llvm::createStringError("Type has no child named '%s'",
539 name.AsCString());
540 return idx;
541}
542
543template <typename D32, typename D64>
546 delete m_data_32;
547 m_data_32 = nullptr;
548 delete m_data_64;
549 m_data_64 = nullptr;
550}
551
552template <typename D32, typename D64>
554lldb_private::formatters::
555 GenericNSArrayMSyntheticFrontEnd<D32, D64>::
556 GenericNSArrayMSyntheticFrontEnd::GetDataAddress() {
557 if (!m_data_32 && !m_data_64)
559 return m_data_32 ? m_data_32->_data : m_data_64->_data;
560}
561
562template <typename D32, typename D64>
563uint64_t
564lldb_private::formatters::
565 GenericNSArrayMSyntheticFrontEnd<D32, D64>::
566 GenericNSArrayMSyntheticFrontEnd::GetUsedCount() {
567 if (!m_data_32 && !m_data_64)
568 return 0;
569 return m_data_32 ? m_data_32->_used : m_data_64->_used;
570}
571
572template <typename D32, typename D64>
573uint64_t
574lldb_private::formatters::
575 GenericNSArrayMSyntheticFrontEnd<D32, D64>::
576 GenericNSArrayMSyntheticFrontEnd::GetOffset() {
577 if (!m_data_32 && !m_data_64)
578 return 0;
579 return m_data_32 ? m_data_32->_offset : m_data_64->_offset;
580}
581
582template <typename D32, typename D64>
583uint64_t
584lldb_private::formatters::
585 GenericNSArrayMSyntheticFrontEnd<D32, D64>::
586 GenericNSArrayMSyntheticFrontEnd::GetSize() {
587 if (!m_data_32 && !m_data_64)
588 return 0;
589 return m_data_32 ? m_data_32->_size : m_data_64->_size;
590}
591
592template <typename D32, typename D64, bool Inline>
596 m_data_32(nullptr), m_data_64(nullptr) {
597 if (valobj_sp) {
598 CompilerType type = valobj_sp->GetCompilerType();
599 if (type) {
601 *valobj_sp->GetExecutionContextRef().GetTargetSP());
602 if (scratch_ts_sp)
603 m_id_type = scratch_ts_sp->GetType(
604 scratch_ts_sp->getASTContext().ObjCBuiltinIdTy);
605 }
606 }
607}
608
609template <typename D32, typename D64, bool Inline>
612 delete m_data_32;
613 m_data_32 = nullptr;
614 delete m_data_64;
615 m_data_64 = nullptr;
616}
617
618template <typename D32, typename D64, bool Inline>
619llvm::Expected<size_t>
621 D32, D64, Inline>::GetIndexOfChildWithName(ConstString name) {
622 auto optional_idx = ExtractIndexFromString(name.AsCString());
623 if (!optional_idx) {
624 return llvm::createStringError("Type has no child named '%s'",
625 name.AsCString());
626 }
627 uint32_t idx = *optional_idx;
629 return llvm::createStringError("Type has no child named '%s'",
630 name.AsCString());
631 return idx;
632}
633
634template <typename D32, typename D64, bool Inline>
635llvm::Expected<uint32_t>
637 D32, D64, Inline>::CalculateNumChildren() {
638 return m_data_32 ? m_data_32->used : m_data_64->used;
639}
640
641template <typename D32, typename D64, bool Inline>
644 Inline>::Update() {
645 ValueObjectSP valobj_sp = m_backend.GetSP();
646 m_ptr_size = 0;
647 delete m_data_32;
648 m_data_32 = nullptr;
649 delete m_data_64;
650 m_data_64 = nullptr;
651 if (!valobj_sp)
653 m_exe_ctx_ref = valobj_sp->GetExecutionContextRef();
655 error.Clear();
656 lldb::ProcessSP process_sp(valobj_sp->GetProcessSP());
657 if (!process_sp)
659 m_ptr_size = process_sp->GetAddressByteSize();
660 uint64_t data_location = valobj_sp->GetValueAsUnsigned(0) + m_ptr_size;
661 if (m_ptr_size == 4) {
662 m_data_32 = new D32();
663 process_sp->ReadMemory(data_location, m_data_32, sizeof(D32),
664 error);
665 } else {
666 m_data_64 = new D64();
667 process_sp->ReadMemory(data_location, m_data_64, sizeof(D64),
668 error);
669 }
670
671 return error.Success() ? lldb::ChildCacheState::eReuse
673}
674
675template <typename D32, typename D64, bool Inline>
678 GetChildAtIndex(uint32_t idx) {
680 return lldb::ValueObjectSP();
681 lldb::addr_t object_at_idx;
682 if (Inline) {
683 object_at_idx = m_backend.GetSP()->GetValueAsUnsigned(0) + m_ptr_size;
684 object_at_idx += m_ptr_size == 4 ? sizeof(D32) : sizeof(D64); // skip the data header
685 object_at_idx -= m_ptr_size; // we treat the last entry in the data header as the first pointer
686 } else {
687 object_at_idx = m_data_32 ? m_data_32->list : m_data_64->list;
688 }
689 object_at_idx += (idx * m_ptr_size);
690
691 ProcessSP process_sp = m_exe_ctx_ref.GetProcessSP();
692 if (!process_sp)
693 return lldb::ValueObjectSP();
695 if (error.Fail())
696 return lldb::ValueObjectSP();
697 StreamString idx_name;
698 idx_name.Printf("[%" PRIu64 "]", (uint64_t)idx);
699 return CreateValueObjectFromAddress(idx_name.GetString(), object_at_idx,
701}
702
706
707llvm::Expected<size_t>
712
713llvm::Expected<uint32_t>
717
722
726
732
736
737llvm::Expected<size_t>
739 ConstString name) {
740 static const ConstString g_zero("[0]");
741
742 if (name == g_zero)
743 return 0;
744
745 return UINT32_MAX;
746}
747
748llvm::Expected<uint32_t>
752
757
760 uint32_t idx) {
761 static const ConstString g_zero("[0]");
762
763 if (idx == 0) {
764 TypeSystemClangSP scratch_ts_sp =
766 if (scratch_ts_sp) {
767 CompilerType id_type(scratch_ts_sp->GetBasicType(lldb::eBasicTypeObjCID));
768 return m_backend.GetSyntheticChildAtOffset(
769 m_backend.GetProcessSP()->GetAddressByteSize(), id_type, true,
770 g_zero);
771 }
772 }
773 return lldb::ValueObjectSP();
774}
775
778 CXXSyntheticChildren *synth, lldb::ValueObjectSP valobj_sp) {
779 if (!valobj_sp)
780 return nullptr;
781
782 lldb::ProcessSP process_sp(valobj_sp->GetProcessSP());
783 if (!process_sp)
784 return nullptr;
785 AppleObjCRuntime *runtime = llvm::dyn_cast_or_null<AppleObjCRuntime>(
786 ObjCLanguageRuntime::Get(*process_sp));
787 if (!runtime)
788 return nullptr;
789
790 CompilerType valobj_type(valobj_sp->GetCompilerType());
791 Flags flags(valobj_type.GetTypeInfo());
792
793 if (flags.IsClear(eTypeIsPointer)) {
795 valobj_sp = valobj_sp->AddressOf(error);
796 if (error.Fail() || !valobj_sp)
797 return nullptr;
798 }
799
801 runtime->GetClassDescriptor(*valobj_sp));
802
803 if (!descriptor || !descriptor->IsValid())
804 return nullptr;
805
806 ConstString class_name(descriptor->GetClassName());
807
808 static const ConstString g_NSArrayI("__NSArrayI");
809 static const ConstString g_NSConstantArray("NSConstantArray");
810 static const ConstString g_NSArrayI_Transfer("__NSArrayI_Transfer");
811 static const ConstString g_NSFrozenArrayM("__NSFrozenArrayM");
812 static const ConstString g_NSArrayM("__NSArrayM");
813 static const ConstString g_NSArray0("__NSArray0");
814 static const ConstString g_NSArray1("__NSSingleObjectArrayI");
815 static const ConstString g_NSArrayMLegacy("__NSArrayM_Legacy");
816 static const ConstString g_NSArrayMImmutable("__NSArrayM_Immutable");
817 static const ConstString g_NSCallStackArray("_NSCallStackArray");
818
819 if (class_name.IsEmpty())
820 return nullptr;
821
822 if (class_name == g_NSArrayI) {
823 if (runtime->GetFoundationVersion() >= 1436)
824 return (new Foundation1436::NSArrayISyntheticFrontEnd(valobj_sp));
825 if (runtime->GetFoundationVersion() >= 1430)
826 return (new Foundation1430::NSArrayISyntheticFrontEnd(valobj_sp));
827 return (new Foundation1300::NSArrayISyntheticFrontEnd(valobj_sp));
828 } else if (class_name == g_NSArrayI_Transfer) {
830 } else if (class_name == g_NSConstantArray) {
832 } else if (class_name == g_NSFrozenArrayM) {
834 } else if (class_name == g_NSArray0) {
835 return (new NSArray0SyntheticFrontEnd(valobj_sp));
836 } else if (class_name == g_NSArray1) {
837 return (new NSArray1SyntheticFrontEnd(valobj_sp));
838 } else if (class_name == g_NSArrayM) {
839 if (runtime->GetFoundationVersion() >= 1437)
840 return (new Foundation1437::NSArrayMSyntheticFrontEnd(valobj_sp));
841 if (runtime->GetFoundationVersion() >= 1428)
842 return (new Foundation1428::NSArrayMSyntheticFrontEnd(valobj_sp));
843 if (runtime->GetFoundationVersion() >= 1100)
844 return (new Foundation1010::NSArrayMSyntheticFrontEnd(valobj_sp));
845 } else if (class_name == g_NSCallStackArray) {
847 } else {
849 auto iter = map.find(class_name), end = map.end();
850 if (iter != end)
851 return iter->second(synth, valobj_sp);
852 }
853
854 return nullptr;
855}
static llvm::raw_ostream & error(Stream &strm)
static std::optional< size_t > CalculateNumChildren(CompilerType container_elem_type, uint64_t num_elements, CompilerType element_type)
Calculates the number of elements stored in a container (with element type 'container_elem_type') as ...
Generic representation of a type in a programming language.
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.
bool IsEmpty() const
Test for empty string.
Execution context objects refer to objects in the execution of the program that is being debugged.
A class to manage flags.
Definition Flags.h:22
bool IsClear(ValueType bit) const
Test a single flag bit to see if it is clear (zero).
Definition Flags.h:111
static Language * FindPlugin(lldb::LanguageType language)
Definition Language.cpp:84
std::shared_ptr< ClassDescriptor > ClassDescriptorSP
static ObjCLanguageRuntime * Get(Process &process)
virtual ClassDescriptorSP GetClassDescriptor(ValueObject &in_value)
A plug-in interface definition class for debugging a process.
Definition Process.h:357
virtual size_t ReadMemory(lldb::addr_t vm_addr, void *buf, size_t size, Status &error)
Read of memory from a process.
Definition Process.cpp:1930
uint32_t GetAddressByteSize() const
Definition Process.cpp:3620
static lldb::TypeSystemClangSP GetForTarget(Target &target, std::optional< IsolatedASTKind > ast_kind=DefaultAST, bool create_on_demand=true)
Returns the scratch TypeSystemClang for the given target.
An error handling class.
Definition Status.h:118
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
uint32_t CalculateNumChildrenIgnoringErrors(uint32_t max=UINT32_MAX)
SyntheticChildrenFrontEnd(ValueObject &backend)
lldb::ValueObjectSP CreateValueObjectFromAddress(llvm::StringRef name, uint64_t address, const ExecutionContext &exe_ctx, CompilerType type, bool do_deref=true)
lldb::LanguageType GetLanguage() const
lldb::ProcessSP GetProcessSP() const
virtual uint64_t GetValueAsUnsigned(uint64_t fail_value, bool *success=nullptr)
llvm::Expected< size_t > GetIndexOfChildWithName(ConstString name) override
Definition NSArray.cpp:621
GenericNSArrayISyntheticFrontEnd(lldb::ValueObjectSP valobj_sp)
Definition NSArray.cpp:594
lldb::ValueObjectSP GetChildAtIndex(uint32_t idx) override
Definition NSArray.cpp:678
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 NSArray.cpp:644
llvm::Expected< uint32_t > CalculateNumChildren() override
Definition NSArray.cpp:637
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 NSArray.cpp:498
GenericNSArrayMSyntheticFrontEnd(lldb::ValueObjectSP valobj_sp)
Definition NSArray.cpp:470
llvm::Expected< size_t > GetIndexOfChildWithName(ConstString name) override
Definition NSArray.cpp:708
lldb::ValueObjectSP GetChildAtIndex(uint32_t idx) override
Definition NSArray.cpp:728
NSArray0SyntheticFrontEnd(lldb::ValueObjectSP valobj_sp)
Definition NSArray.cpp:703
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 NSArray.cpp:719
llvm::Expected< uint32_t > CalculateNumChildren() override
Definition NSArray.cpp:714
llvm::Expected< uint32_t > CalculateNumChildren() override
Definition NSArray.cpp:749
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 NSArray.cpp:754
NSArray1SyntheticFrontEnd(lldb::ValueObjectSP valobj_sp)
Definition NSArray.cpp:733
llvm::Expected< size_t > GetIndexOfChildWithName(ConstString name) override
Definition NSArray.cpp:738
lldb::ValueObjectSP GetChildAtIndex(uint32_t idx) override
Definition NSArray.cpp:759
llvm::Expected< size_t > GetIndexOfChildWithName(ConstString name) override
Definition NSArray.cpp:530
llvm::Expected< uint32_t > CalculateNumChildren() override
Definition NSArray.cpp:475
NSArrayMSyntheticFrontEndBase(lldb::ValueObjectSP valobj_sp)
Definition NSArray.cpp:453
lldb::ValueObjectSP GetChildAtIndex(uint32_t idx) override
Definition NSArray.cpp:480
lldb::ChildCacheState Update() override=0
This function is assumed to always succeed and if it fails, the front-end should know to deal with it...
static std::map< ConstString, CXXFunctionSummaryFormat::Callback > & GetAdditionalSummaries()
Definition NSArray.cpp:35
static std::map< ConstString, CXXSyntheticChildren::CreateFrontEndCallback > & GetAdditionalSynthetics()
Definition NSArray.cpp:41
#define LLDB_INVALID_ADDRESS
#define UINT32_MAX
GenericNSArrayMSyntheticFrontEnd< DataDescriptor_32, DataDescriptor_64 > NSCallStackArraySyntheticFrontEnd
Definition NSArray.cpp:204
GenericNSArrayISyntheticFrontEnd< ConstantArray32, ConstantArray64, false > NSConstantArraySyntheticFrontEnd
Definition NSArray.cpp:291
GenericNSArrayMSyntheticFrontEnd< DataDescriptor_32, DataDescriptor_64 > NSArrayMSyntheticFrontEnd
Definition NSArray.cpp:119
GenericNSArrayISyntheticFrontEnd< IDD32, IDD64, true > NSArrayISyntheticFrontEnd
Definition NSArray.cpp:243
GenericNSArrayMSyntheticFrontEnd< DataDescriptor_32, DataDescriptor_64 > NSArrayMSyntheticFrontEnd
Definition NSArray.cpp:140
Foundation1428::NSArrayMSyntheticFrontEnd NSArrayISyntheticFrontEnd
Definition NSArray.cpp:248
Foundation1437::NSArrayMSyntheticFrontEnd NSFrozenArrayMSyntheticFrontEnd
Definition NSArray.cpp:269
GenericNSArrayISyntheticFrontEnd< IDD32, IDD64, true > NSArrayISyntheticFrontEnd
Definition NSArray.cpp:266
GenericNSArrayISyntheticFrontEnd< IDD32, IDD64, false > NSArrayI_TransferSyntheticFrontEnd
Definition NSArray.cpp:263
uint64_t __NSFrozenArrayMSize(lldb_private::Process &process, lldb::addr_t valobj_addr, Status &error)
Definition NSArray.cpp:273
GenericNSArrayMSyntheticFrontEnd< DataDescriptor< uint32_t >, DataDescriptor< uint64_t > > NSArrayMSyntheticFrontEnd
Definition NSArray.cpp:156
uint64_t __NSArrayMSize(lldb_private::Process &process, lldb::addr_t valobj_addr, Status &error)
Definition NSArray.cpp:176
uint64_t __NSArrayMSize_Impl(lldb_private::Process &process, lldb::addr_t valobj_addr, Status &error)
Definition NSArray.cpp:162
std::optional< size_t > ExtractIndexFromString(const char *item_name)
SyntheticChildrenFrontEnd * NSArraySyntheticFrontEndCreator(CXXSyntheticChildren *, lldb::ValueObjectSP)
Definition NSArray.cpp:777
bool NSArraySummaryProvider(ValueObject &valobj, Stream &stream, const TypeSummaryOptions &options)
Definition NSArray.cpp:329
A class that represents a running process on the host machine.
ChildCacheState
Specifies if children need to be re-computed after a call to SyntheticChildrenFrontEnd::Update.
@ eRefetch
Children need to be recomputed dynamically.
@ eReuse
Children did not change and don't need to be recomputed; re-use what we computed the last time we cal...
std::shared_ptr< lldb_private::ValueObject > ValueObjectSP
std::shared_ptr< lldb_private::Process > ProcessSP
std::shared_ptr< lldb_private::TypeSystemClang > TypeSystemClangSP
uint64_t addr_t
Definition lldb-types.h:80