9 #include "clang/AST/ASTContext.h"
10 #include "clang/Basic/TargetInfo.h"
33 namespace formatters {
34 std::map<ConstString, CXXFunctionSummaryFormat::Callback> &
35 NSArray_Additionals::GetAdditionalSummaries() {
36 static std::map<ConstString, CXXFunctionSummaryFormat::Callback> g_map;
40 std::map<ConstString, CXXSyntheticChildren::CreateFrontEndCallback> &
41 NSArray_Additionals::GetAdditionalSynthetics() {
42 static std::map<ConstString, CXXSyntheticChildren::CreateFrontEndCallback>
55 lldb::ValueObjectSP GetChildAtIndex(
size_t idx)
override;
57 bool Update()
override = 0;
59 bool MightHaveChildren()
override;
61 size_t GetIndexOfChildWithName(
ConstString name)
override;
66 virtual uint64_t GetUsedCount() = 0;
68 virtual uint64_t GetOffset() = 0;
70 virtual uint64_t GetSize() = 0;
73 uint8_t m_ptr_size = 8;
77 template <
typename D32,
typename D64>
84 bool Update()
override;
89 uint64_t GetUsedCount()
override;
91 uint64_t GetOffset()
override;
93 uint64_t GetSize()
override;
100 namespace Foundation1010 {
102 struct DataDescriptor_32 {
111 struct DataDescriptor_64 {
125 namespace Foundation1428 {
127 struct DataDescriptor_32 {
134 struct DataDescriptor_64 {
146 namespace Foundation1437 {
147 template <
typename PtrType>
162 template <
typename DD>
168 DD descriptor = DD();
169 process.
ReadMemory(start_of_descriptor, &descriptor,
170 sizeof(descriptor),
error);
174 return descriptor._used;
181 return __NSArrayMSize_Impl<DataDescriptor<uint32_t>>(process, valobj_addr,
184 return __NSArrayMSize_Impl<DataDescriptor<uint64_t>>(process, valobj_addr,
191 namespace CallStackArray {
210 template <
typename D32,
typename D64,
bool Inline>
219 lldb::ValueObjectSP GetChildAtIndex(
size_t idx)
override;
221 bool Update()
override;
223 bool MightHaveChildren()
override;
225 size_t GetIndexOfChildWithName(
ConstString name)
override;
229 uint8_t m_ptr_size = 8;
236 namespace Foundation1300 {
251 namespace Foundation1430 {
256 namespace Foundation1436 {
283 namespace ConstantArray {
307 lldb::ValueObjectSP GetChildAtIndex(
size_t idx)
override;
309 bool Update()
override;
311 bool MightHaveChildren()
override;
313 size_t GetIndexOfChildWithName(
ConstString name)
override;
324 lldb::ValueObjectSP GetChildAtIndex(
size_t idx)
override;
326 bool Update()
override;
328 bool MightHaveChildren()
override;
330 size_t GetIndexOfChildWithName(
ConstString name)
override;
351 if (!descriptor || !descriptor->IsValid())
354 uint32_t ptr_size = process_sp->GetAddressByteSize();
363 ConstString class_name(descriptor->GetClassName());
367 static const ConstString g_NSArrayI_Transfer(
"__NSArrayI_Transfer");
368 static const ConstString g_NSFrozenArrayM(
"__NSFrozenArrayM");
370 static const ConstString g_NSArray1(
"__NSSingleObjectArrayI");
371 static const ConstString g_NSArrayCF(
"__NSCFArray");
372 static const ConstString g_NSArrayMLegacy(
"__NSArrayM_Legacy");
373 static const ConstString g_NSArrayMImmutable(
"__NSArrayM_Immutable");
374 static const ConstString g_NSCallStackArray(
"_NSCallStackArray");
375 static const ConstString g_NSConstantArray(
"NSConstantArray");
380 if (class_name == g_NSArrayI) {
382 value = process_sp->ReadUnsignedIntegerFromMemory(valobj_addr + ptr_size,
386 }
else if (class_name == g_NSConstantArray) {
388 value = process_sp->ReadUnsignedIntegerFromMemory(valobj_addr + ptr_size, 8,
392 }
else if (class_name == g_NSArrayM) {
394 llvm::dyn_cast_or_null<AppleObjCRuntime>(runtime);
399 value = process_sp->ReadUnsignedIntegerFromMemory(valobj_addr + ptr_size,
404 }
else if (class_name == g_NSArrayI_Transfer) {
406 value = process_sp->ReadUnsignedIntegerFromMemory(valobj_addr + ptr_size,
410 }
else if (class_name == g_NSFrozenArrayM) {
415 }
else if (class_name == g_NSArrayMLegacy) {
417 value = process_sp->ReadUnsignedIntegerFromMemory(valobj_addr + ptr_size,
421 }
else if (class_name == g_NSArrayMImmutable) {
423 value = process_sp->ReadUnsignedIntegerFromMemory(valobj_addr + ptr_size,
427 }
else if (class_name == g_NSArray0) {
429 }
else if (class_name == g_NSArray1) {
431 }
else if (class_name == g_NSArrayCF || class_name == g_NSCallStackArray) {
435 value = process_sp->ReadUnsignedIntegerFromMemory(
436 valobj_addr + 2 * ptr_size, ptr_size, 0,
error);
440 auto &map(NSArray_Additionals::GetAdditionalSummaries());
441 auto iter = map.find(class_name), end = map.end();
443 return iter->second(valobj, stream, options);
450 if (!language->GetFormatterPrefixSuffix(valobj, g_TypeHint, prefix,
457 stream.
Printf(
"%s%" PRIu64
" %s%s%s", prefix.c_str(), value,
"element",
458 value == 1 ?
"" :
"s", suffix.c_str());
467 *valobj_sp->GetExecutionContextRef().GetTargetSP());
468 if (clang_ast_context)
471 clang_ast_context->getASTContext().ObjCBuiltinIdTy.getAsOpaquePtr());
472 if (valobj_sp->GetProcessSP())
473 m_ptr_size = valobj_sp->GetProcessSP()->GetAddressByteSize();
477 template <
typename D32,
typename D64>
482 m_data_64(nullptr) {}
486 return GetUsedCount();
493 return lldb::ValueObjectSP();
495 size_t pyhs_idx = idx;
496 pyhs_idx += GetOffset();
497 if (GetSize() <= pyhs_idx)
498 pyhs_idx -= GetSize();
499 object_at_idx += (pyhs_idx * m_ptr_size);
501 idx_name.
Printf(
"[%" PRIu64
"]", (uint64_t)idx);
502 return CreateValueObjectFromAddress(idx_name.
GetString(), object_at_idx,
503 m_exe_ctx_ref, m_id_type);
506 template <
typename D32,
typename D64>
510 ValueObjectSP valobj_sp = m_backend.GetSP();
518 m_exe_ctx_ref = valobj_sp->GetExecutionContextRef();
521 lldb::ProcessSP process_sp(valobj_sp->GetProcessSP());
524 m_ptr_size = process_sp->GetAddressByteSize();
525 uint64_t data_location = valobj_sp->GetValueAsUnsigned(0) + m_ptr_size;
526 if (m_ptr_size == 4) {
527 m_data_32 =
new D32();
528 process_sp->ReadMemory(data_location, m_data_32,
sizeof(D32),
531 m_data_64 =
new D64();
532 process_sp->ReadMemory(data_location, m_data_64,
sizeof(D64),
555 template <
typename D32,
typename D64>
556 lldb_private::formatters::
557 GenericNSArrayMSyntheticFrontEnd<D32, D64>::
558 ~GenericNSArrayMSyntheticFrontEnd<D32, D64>() {
565 template <
typename D32,
typename D64>
567 lldb_private::formatters::
568 GenericNSArrayMSyntheticFrontEnd<D32, D64>::
569 GenericNSArrayMSyntheticFrontEnd::GetDataAddress() {
570 if (!m_data_32 && !m_data_64)
572 return m_data_32 ? m_data_32->_data : m_data_64->_data;
575 template <
typename D32,
typename D64>
577 lldb_private::formatters::
578 GenericNSArrayMSyntheticFrontEnd<D32, D64>::
579 GenericNSArrayMSyntheticFrontEnd::GetUsedCount() {
580 if (!m_data_32 && !m_data_64)
582 return m_data_32 ? m_data_32->_used : m_data_64->_used;
585 template <
typename D32,
typename D64>
587 lldb_private::formatters::
588 GenericNSArrayMSyntheticFrontEnd<D32, D64>::
589 GenericNSArrayMSyntheticFrontEnd::GetOffset() {
590 if (!m_data_32 && !m_data_64)
592 return m_data_32 ? m_data_32->_offset : m_data_64->_offset;
595 template <
typename D32,
typename D64>
597 lldb_private::formatters::
598 GenericNSArrayMSyntheticFrontEnd<D32, D64>::
599 GenericNSArrayMSyntheticFrontEnd::GetSize() {
600 if (!m_data_32 && !m_data_64)
602 return m_data_32 ? m_data_32->_size : m_data_64->_size;
605 template <
typename D32,
typename D64,
bool Inline>
609 m_data_32(nullptr), m_data_64(nullptr) {
614 *valobj_sp->GetExecutionContextRef().GetTargetSP());
615 if (clang_ast_context)
617 clang_ast_context->getASTContext().ObjCBuiltinIdTy);
622 template <
typename D32,
typename D64,
bool Inline>
631 template <
typename D32,
typename D64,
bool Inline>
642 template <
typename D32,
typename D64,
bool Inline>
646 return m_data_32 ? m_data_32->used : m_data_64->used;
649 template <
typename D32,
typename D64,
bool Inline>
653 ValueObjectSP valobj_sp = m_backend.GetSP();
661 m_exe_ctx_ref = valobj_sp->GetExecutionContextRef();
664 lldb::ProcessSP process_sp(valobj_sp->GetProcessSP());
667 m_ptr_size = process_sp->GetAddressByteSize();
668 uint64_t data_location = valobj_sp->GetValueAsUnsigned(0) + m_ptr_size;
669 if (m_ptr_size == 4) {
670 m_data_32 =
new D32();
671 process_sp->ReadMemory(data_location, m_data_32,
sizeof(D32),
674 m_data_64 =
new D64();
675 process_sp->ReadMemory(data_location, m_data_64,
sizeof(D64),
683 template <
typename D32,
typename D64,
bool Inline>
690 template <
typename D32,
typename D64,
bool Inline>
695 return lldb::ValueObjectSP();
698 object_at_idx = m_backend.GetSP()->GetValueAsUnsigned(0) + m_ptr_size;
699 object_at_idx += m_ptr_size == 4 ?
sizeof(D32) :
sizeof(D64);
700 object_at_idx -= m_ptr_size;
702 object_at_idx = m_data_32 ? m_data_32->list : m_data_64->list;
704 object_at_idx += (idx * m_ptr_size);
706 ProcessSP process_sp = m_exe_ctx_ref.GetProcessSP();
708 return lldb::ValueObjectSP();
711 return lldb::ValueObjectSP();
713 idx_name.
Printf(
"[%" PRIu64
"]", (uint64_t)idx);
714 return CreateValueObjectFromAddress(idx_name.
GetString(), object_at_idx,
715 m_exe_ctx_ref, m_id_type);
719 lldb::ValueObjectSP valobj_sp)
744 return lldb::ValueObjectSP();
748 lldb::ValueObjectSP valobj_sp)
781 auto *clang_ast_context =
783 if (clang_ast_context) {
786 return m_backend.GetSyntheticChildAtOffset(
787 m_backend.GetProcessSP()->GetAddressByteSize(), id_type,
true,
791 return lldb::ValueObjectSP();
800 lldb::ProcessSP process_sp(valobj_sp->GetProcessSP());
811 if (flags.
IsClear(eTypeIsPointer)) {
813 valobj_sp = valobj_sp->AddressOf(
error);
814 if (
error.Fail() || !valobj_sp)
821 if (!descriptor || !descriptor->IsValid())
824 ConstString class_name(descriptor->GetClassName());
827 static const ConstString g_NSConstantArray(
"NSConstantArray");
828 static const ConstString g_NSArrayI_Transfer(
"__NSArrayI_Transfer");
829 static const ConstString g_NSFrozenArrayM(
"__NSFrozenArrayM");
832 static const ConstString g_NSArray1(
"__NSSingleObjectArrayI");
833 static const ConstString g_NSArrayMLegacy(
"__NSArrayM_Legacy");
834 static const ConstString g_NSArrayMImmutable(
"__NSArrayM_Immutable");
835 static const ConstString g_NSCallStackArray(
"_NSCallStackArray");
840 if (class_name == g_NSArrayI) {
846 }
else if (class_name == g_NSArrayI_Transfer) {
848 }
else if (class_name == g_NSConstantArray) {
850 }
else if (class_name == g_NSFrozenArrayM) {
852 }
else if (class_name == g_NSArray0) {
854 }
else if (class_name == g_NSArray1) {
856 }
else if (class_name == g_NSArrayM) {
863 }
else if (class_name == g_NSCallStackArray) {
867 auto iter = map.find(class_name), end = map.end();
869 return iter->second(synth, valobj_sp);