9#include "clang/AST/ASTContext.h"
10#include "clang/Basic/TargetInfo.h"
34std::map<ConstString, CXXFunctionSummaryFormat::Callback> &
36 static std::map<ConstString, CXXFunctionSummaryFormat::Callback> g_map;
40std::map<ConstString, CXXSyntheticChildren::CreateFrontEndCallback> &
42 static std::map<ConstString, CXXSyntheticChildren::CreateFrontEndCallback>
77template <
typename D32,
typename D64>
100namespace Foundation1010 {
102 struct DataDescriptor_32 {
111 struct DataDescriptor_64 {
125namespace Foundation1428 {
127 struct DataDescriptor_32 {
134 struct DataDescriptor_64 {
146namespace 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,
191namespace CallStackArray {
210template <
typename D32,
typename D64,
bool Inline>
236namespace Foundation1300 {
251namespace Foundation1430 {
256namespace Foundation1436 {
283namespace ConstantArray {
337 static constexpr llvm::StringLiteral g_TypeHint(
"NSArray");
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);
441 auto iter = map.find(class_name), end = map.end();
443 return iter->second(valobj, stream, options);
448 llvm::StringRef prefix, suffix;
450 std::tie(prefix, suffix) = language->GetFormatterPrefixSuffix(g_TypeHint);
453 stream.
Printf(
"%" PRIu64
" %s%s", value,
"element", value == 1 ?
"" :
"s");
463 *valobj_sp->GetExecutionContextRef().GetTargetSP());
466 scratch_ts_sp->weak_from_this(),
467 scratch_ts_sp->getASTContext().ObjCBuiltinIdTy.getAsOpaquePtr());
468 if (valobj_sp->GetProcessSP())
469 m_ptr_size = valobj_sp->GetProcessSP()->GetAddressByteSize();
473template <
typename D32,
typename D64>
478 m_data_64(nullptr) {}
482 return GetUsedCount();
489 return lldb::ValueObjectSP();
491 size_t pyhs_idx = idx;
492 pyhs_idx += GetOffset();
493 if (GetSize() <= pyhs_idx)
494 pyhs_idx -= GetSize();
495 object_at_idx += (pyhs_idx * m_ptr_size);
497 idx_name.
Printf(
"[%" PRIu64
"]", (uint64_t)idx);
498 return CreateValueObjectFromAddress(idx_name.
GetString(), object_at_idx,
499 m_exe_ctx_ref, m_id_type);
502template <
typename D32,
typename D64>
506 ValueObjectSP valobj_sp = m_backend.GetSP();
514 m_exe_ctx_ref = valobj_sp->GetExecutionContextRef();
517 lldb::ProcessSP process_sp(valobj_sp->GetProcessSP());
520 m_ptr_size = process_sp->GetAddressByteSize();
521 uint64_t data_location = valobj_sp->GetValueAsUnsigned(0) + m_ptr_size;
522 if (m_ptr_size == 4) {
523 m_data_32 =
new D32();
524 process_sp->ReadMemory(data_location, m_data_32,
sizeof(D32),
527 m_data_64 =
new D64();
528 process_sp->ReadMemory(data_location, m_data_64,
sizeof(D64),
532 return error.Success();
550template <
typename D32,
typename D64>
551lldb_private::formatters::
552 GenericNSArrayMSyntheticFrontEnd<D32, D64>::
553 ~GenericNSArrayMSyntheticFrontEnd<D32, D64>() {
560template <
typename D32,
typename D64>
562lldb_private::formatters::
563 GenericNSArrayMSyntheticFrontEnd<D32, D64>::
564 GenericNSArrayMSyntheticFrontEnd::GetDataAddress() {
565 if (!m_data_32 && !m_data_64)
567 return m_data_32 ? m_data_32->_data : m_data_64->_data;
570template <
typename D32,
typename D64>
572lldb_private::formatters::
573 GenericNSArrayMSyntheticFrontEnd<D32, D64>::
574 GenericNSArrayMSyntheticFrontEnd::GetUsedCount() {
575 if (!m_data_32 && !m_data_64)
577 return m_data_32 ? m_data_32->_used : m_data_64->_used;
580template <
typename D32,
typename D64>
582lldb_private::formatters::
583 GenericNSArrayMSyntheticFrontEnd<D32, D64>::
584 GenericNSArrayMSyntheticFrontEnd::GetOffset() {
585 if (!m_data_32 && !m_data_64)
587 return m_data_32 ? m_data_32->_offset : m_data_64->_offset;
590template <
typename D32,
typename D64>
592lldb_private::formatters::
593 GenericNSArrayMSyntheticFrontEnd<D32, D64>::
594 GenericNSArrayMSyntheticFrontEnd::GetSize() {
595 if (!m_data_32 && !m_data_64)
597 return m_data_32 ? m_data_32->_size : m_data_64->_size;
600template <
typename D32,
typename D64,
bool Inline>
604 m_data_32(nullptr), m_data_64(nullptr) {
609 *valobj_sp->GetExecutionContextRef().GetTargetSP());
612 scratch_ts_sp->getASTContext().ObjCBuiltinIdTy);
617template <
typename D32,
typename D64,
bool Inline>
626template <
typename D32,
typename D64,
bool Inline>
637template <
typename D32,
typename D64,
bool Inline>
641 return m_data_32 ? m_data_32->used : m_data_64->used;
644template <
typename D32,
typename D64,
bool Inline>
648 ValueObjectSP valobj_sp = m_backend.GetSP();
656 m_exe_ctx_ref = valobj_sp->GetExecutionContextRef();
659 lldb::ProcessSP process_sp(valobj_sp->GetProcessSP());
662 m_ptr_size = process_sp->GetAddressByteSize();
663 uint64_t data_location = valobj_sp->GetValueAsUnsigned(0) + m_ptr_size;
664 if (m_ptr_size == 4) {
665 m_data_32 =
new D32();
666 process_sp->ReadMemory(data_location, m_data_32,
sizeof(D32),
669 m_data_64 =
new D64();
670 process_sp->ReadMemory(data_location, m_data_64,
sizeof(D64),
674 return error.Success();
677template <
typename D32,
typename D64,
bool Inline>
684template <
typename D32,
typename D64,
bool Inline>
689 return lldb::ValueObjectSP();
692 object_at_idx = m_backend.GetSP()->GetValueAsUnsigned(0) + m_ptr_size;
693 object_at_idx += m_ptr_size == 4 ?
sizeof(D32) :
sizeof(D64);
694 object_at_idx -= m_ptr_size;
696 object_at_idx = m_data_32 ? m_data_32->list : m_data_64->list;
698 object_at_idx += (idx * m_ptr_size);
700 ProcessSP process_sp = m_exe_ctx_ref.GetProcessSP();
702 return lldb::ValueObjectSP();
705 return lldb::ValueObjectSP();
707 idx_name.
Printf(
"[%" PRIu64
"]", (uint64_t)idx);
708 return CreateValueObjectFromAddress(idx_name.
GetString(), object_at_idx,
709 m_exe_ctx_ref, m_id_type);
713 lldb::ValueObjectSP valobj_sp)
738 return lldb::ValueObjectSP();
742 lldb::ValueObjectSP valobj_sp)
775 TypeSystemClangSP scratch_ts_sp =
779 return m_backend.GetSyntheticChildAtOffset(
780 m_backend.GetProcessSP()->GetAddressByteSize(), id_type,
true,
784 return lldb::ValueObjectSP();
793 lldb::ProcessSP process_sp(valobj_sp->GetProcessSP());
804 if (flags.
IsClear(eTypeIsPointer)) {
806 valobj_sp = valobj_sp->AddressOf(
error);
807 if (
error.Fail() || !valobj_sp)
814 if (!descriptor || !descriptor->IsValid())
817 ConstString class_name(descriptor->GetClassName());
820 static const ConstString g_NSConstantArray(
"NSConstantArray");
821 static const ConstString g_NSArrayI_Transfer(
"__NSArrayI_Transfer");
822 static const ConstString g_NSFrozenArrayM(
"__NSFrozenArrayM");
825 static const ConstString g_NSArray1(
"__NSSingleObjectArrayI");
826 static const ConstString g_NSArrayMLegacy(
"__NSArrayM_Legacy");
827 static const ConstString g_NSArrayMImmutable(
"__NSArrayM_Immutable");
828 static const ConstString g_NSCallStackArray(
"_NSCallStackArray");
833 if (class_name == g_NSArrayI) {
839 }
else if (class_name == g_NSArrayI_Transfer) {
841 }
else if (class_name == g_NSConstantArray) {
843 }
else if (class_name == g_NSFrozenArrayM) {
845 }
else if (class_name == g_NSArray0) {
847 }
else if (class_name == g_NSArray1) {
849 }
else if (class_name == g_NSArrayM) {
856 }
else if (class_name == g_NSCallStackArray) {
860 auto iter = map.find(class_name), end = map.end();
862 return iter->second(synth, valobj_sp);
static llvm::raw_ostream & error(Stream &strm)
static size_t CalculateNumChildren(CompilerType container_type, CompilerType element_type, lldb_private::ExecutionContextScope *exe_scope=nullptr)
uint32_t GetFoundationVersion()
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.
bool IsEmpty() const
Test for empty string.
const char * GetCString() const
Get the string value as a C string.
Execution context objects refer to objects in the execution of the program that is being debugged.
bool IsClear(ValueType bit) const
Test a single flag bit to see if it is clear (zero).
static Language * FindPlugin(lldb::LanguageType language)
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.
virtual size_t ReadMemory(lldb::addr_t vm_addr, void *buf, size_t size, Status &error)
Read of memory from a process.
uint32_t GetAddressByteSize() const
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.
llvm::StringRef GetString() const
A stream class that can stream formatted output to a file.
size_t Printf(const char *format,...) __attribute__((format(printf
Output printf formatted output to the stream.
lldb::LanguageType GetLanguage() const
lldb::ProcessSP GetProcessSP() const
virtual uint64_t GetValueAsUnsigned(uint64_t fail_value, bool *success=nullptr)
#define LLDB_INVALID_ADDRESS
A class that represents a running process on the host machine.