1170c395eSEnrico Granata //===-- NSArray.cpp ---------------------------------------------*- C++ -*-===// 2170c395eSEnrico Granata // 3170c395eSEnrico Granata // The LLVM Compiler Infrastructure 4170c395eSEnrico Granata // 5170c395eSEnrico Granata // This file is distributed under the University of Illinois Open Source 6170c395eSEnrico Granata // License. See LICENSE.TXT for details. 7170c395eSEnrico Granata // 8170c395eSEnrico Granata //===----------------------------------------------------------------------===// 9170c395eSEnrico Granata 108d15f33bSEugene Zelenko // C Includes 118d15f33bSEugene Zelenko // C++ Includes 128d15f33bSEugene Zelenko // Other libraries and framework includes 138d15f33bSEugene Zelenko #include "clang/AST/ASTContext.h" 148d15f33bSEugene Zelenko 158d15f33bSEugene Zelenko // Project includes 16170c395eSEnrico Granata #include "Cocoa.h" 17170c395eSEnrico Granata 18b9c1b51eSKate Stone #include "Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntime.h" 19170c395eSEnrico Granata #include "lldb/Core/ValueObject.h" 20170c395eSEnrico Granata #include "lldb/Core/ValueObjectConstResult.h" 21170c395eSEnrico Granata #include "lldb/DataFormatters/FormattersHelpers.h" 22151c032cSJim Ingham #include "lldb/Expression/FunctionCaller.h" 23170c395eSEnrico Granata #include "lldb/Symbol/ClangASTContext.h" 24675f49bbSEnrico Granata #include "lldb/Target/Language.h" 25170c395eSEnrico Granata #include "lldb/Target/ObjCLanguageRuntime.h" 26170c395eSEnrico Granata #include "lldb/Target/Target.h" 27666cc0b2SZachary Turner #include "lldb/Utility/DataBufferHeap.h" 2801c3243fSZachary Turner #include "lldb/Utility/Endian.h" 2997206d57SZachary Turner #include "lldb/Utility/Status.h" 30bf9a7730SZachary Turner #include "lldb/Utility/Stream.h" 31170c395eSEnrico Granata 32170c395eSEnrico Granata using namespace lldb; 33170c395eSEnrico Granata using namespace lldb_private; 34170c395eSEnrico Granata using namespace lldb_private::formatters; 35170c395eSEnrico Granata 36170c395eSEnrico Granata namespace lldb_private { 37170c395eSEnrico Granata namespace formatters { 38c28b3e88SEnrico Granata std::map<ConstString, CXXFunctionSummaryFormat::Callback> & 39b9c1b51eSKate Stone NSArray_Additionals::GetAdditionalSummaries() { 40c28b3e88SEnrico Granata static std::map<ConstString, CXXFunctionSummaryFormat::Callback> g_map; 41c28b3e88SEnrico Granata return g_map; 42c28b3e88SEnrico Granata } 43c28b3e88SEnrico Granata 44c28b3e88SEnrico Granata std::map<ConstString, CXXSyntheticChildren::CreateFrontEndCallback> & 45b9c1b51eSKate Stone NSArray_Additionals::GetAdditionalSynthetics() { 46b9c1b51eSKate Stone static std::map<ConstString, CXXSyntheticChildren::CreateFrontEndCallback> 47b9c1b51eSKate Stone g_map; 48c28b3e88SEnrico Granata return g_map; 49c28b3e88SEnrico Granata } 50c28b3e88SEnrico Granata 51bb93483cSJason Molenda class NSArrayMSyntheticFrontEndBase : public SyntheticChildrenFrontEnd { 52170c395eSEnrico Granata public: 53bb93483cSJason Molenda NSArrayMSyntheticFrontEndBase(lldb::ValueObjectSP valobj_sp); 54170c395eSEnrico Granata 55bb93483cSJason Molenda ~NSArrayMSyntheticFrontEndBase() override = default; 56170c395eSEnrico Granata 57b9c1b51eSKate Stone size_t CalculateNumChildren() override; 58170c395eSEnrico Granata 59b9c1b51eSKate Stone lldb::ValueObjectSP GetChildAtIndex(size_t idx) override; 60170c395eSEnrico Granata 61b9c1b51eSKate Stone bool Update() override = 0; 62170c395eSEnrico Granata 63b9c1b51eSKate Stone bool MightHaveChildren() override; 64170c395eSEnrico Granata 65b9c1b51eSKate Stone size_t GetIndexOfChildWithName(const ConstString &name) override; 66170c395eSEnrico Granata 67170c395eSEnrico Granata protected: 68b9c1b51eSKate Stone virtual lldb::addr_t GetDataAddress() = 0; 69170c395eSEnrico Granata 70b9c1b51eSKate Stone virtual uint64_t GetUsedCount() = 0; 71170c395eSEnrico Granata 72b9c1b51eSKate Stone virtual uint64_t GetOffset() = 0; 73170c395eSEnrico Granata 74b9c1b51eSKate Stone virtual uint64_t GetSize() = 0; 75170c395eSEnrico Granata 76170c395eSEnrico Granata ExecutionContextRef m_exe_ctx_ref; 77170c395eSEnrico Granata uint8_t m_ptr_size; 78170c395eSEnrico Granata CompilerType m_id_type; 79170c395eSEnrico Granata }; 80170c395eSEnrico Granata 81bb93483cSJason Molenda template <typename D32, typename D64> 82bb93483cSJason Molenda class GenericNSArrayMSyntheticFrontEnd : public NSArrayMSyntheticFrontEndBase { 838d15f33bSEugene Zelenko public: 84bb93483cSJason Molenda GenericNSArrayMSyntheticFrontEnd(lldb::ValueObjectSP valobj_sp); 858d15f33bSEugene Zelenko 86bb93483cSJason Molenda ~GenericNSArrayMSyntheticFrontEnd() override; 878d15f33bSEugene Zelenko 88b9c1b51eSKate Stone bool Update() override; 898d15f33bSEugene Zelenko 908d15f33bSEugene Zelenko protected: 91b9c1b51eSKate Stone lldb::addr_t GetDataAddress() override; 928d15f33bSEugene Zelenko 93b9c1b51eSKate Stone uint64_t GetUsedCount() override; 948d15f33bSEugene Zelenko 95b9c1b51eSKate Stone uint64_t GetOffset() override; 968d15f33bSEugene Zelenko 97b9c1b51eSKate Stone uint64_t GetSize() override; 988d15f33bSEugene Zelenko 99170c395eSEnrico Granata private: 100bb93483cSJason Molenda D32 *m_data_32; 101bb93483cSJason Molenda D64 *m_data_64; 102bb93483cSJason Molenda }; 103bb93483cSJason Molenda 104bb93483cSJason Molenda namespace Foundation109 { 105b9c1b51eSKate Stone struct DataDescriptor_32 { 106170c395eSEnrico Granata uint32_t _used; 107170c395eSEnrico Granata uint32_t _priv1 : 2; 108170c395eSEnrico Granata uint32_t _size : 30; 109170c395eSEnrico Granata uint32_t _priv2 : 2; 110170c395eSEnrico Granata uint32_t _offset : 30; 111170c395eSEnrico Granata uint32_t _priv3; 112170c395eSEnrico Granata uint32_t _data; 113170c395eSEnrico Granata }; 1148d15f33bSEugene Zelenko 115b9c1b51eSKate Stone struct DataDescriptor_64 { 116170c395eSEnrico Granata uint64_t _used; 117170c395eSEnrico Granata uint64_t _priv1 : 2; 118170c395eSEnrico Granata uint64_t _size : 62; 119170c395eSEnrico Granata uint64_t _priv2 : 2; 120170c395eSEnrico Granata uint64_t _offset : 62; 121170c395eSEnrico Granata uint32_t _priv3; 122170c395eSEnrico Granata uint64_t _data; 123170c395eSEnrico Granata }; 124170c395eSEnrico Granata 125bb93483cSJason Molenda using NSArrayMSyntheticFrontEnd = 126bb93483cSJason Molenda GenericNSArrayMSyntheticFrontEnd<DataDescriptor_32, DataDescriptor_64>; 127170c395eSEnrico Granata }; 128170c395eSEnrico Granata 129bb93483cSJason Molenda namespace Foundation1010 { 130b9c1b51eSKate Stone struct DataDescriptor_32 { 131170c395eSEnrico Granata uint32_t _used; 132170c395eSEnrico Granata uint32_t _offset; 133170c395eSEnrico Granata uint32_t _size : 28; 134170c395eSEnrico Granata uint64_t _priv1 : 4; 135170c395eSEnrico Granata uint32_t _priv2; 136170c395eSEnrico Granata uint32_t _data; 137170c395eSEnrico Granata }; 1388d15f33bSEugene Zelenko 139b9c1b51eSKate Stone struct DataDescriptor_64 { 140170c395eSEnrico Granata uint64_t _used; 141170c395eSEnrico Granata uint64_t _offset; 142170c395eSEnrico Granata uint64_t _size : 60; 143170c395eSEnrico Granata uint64_t _priv1 : 4; 144170c395eSEnrico Granata uint32_t _priv2; 145170c395eSEnrico Granata uint64_t _data; 146170c395eSEnrico Granata }; 147170c395eSEnrico Granata 148bb93483cSJason Molenda using NSArrayMSyntheticFrontEnd = 149bb93483cSJason Molenda GenericNSArrayMSyntheticFrontEnd<DataDescriptor_32, DataDescriptor_64>; 150170c395eSEnrico Granata }; 151170c395eSEnrico Granata 152bb93483cSJason Molenda namespace Foundation1428 { 153f40da172SSean Callanan struct DataDescriptor_32 { 154bb93483cSJason Molenda uint32_t _used; 155bb93483cSJason Molenda uint32_t _offset; 156bb93483cSJason Molenda uint32_t _size; 157bb93483cSJason Molenda uint32_t _data; 158f40da172SSean Callanan }; 159f40da172SSean Callanan 160f40da172SSean Callanan struct DataDescriptor_64 { 161bb93483cSJason Molenda uint64_t _used; 162bb93483cSJason Molenda uint64_t _offset; 163bb93483cSJason Molenda uint64_t _size; 164bb93483cSJason Molenda uint64_t _data; 165f40da172SSean Callanan }; 166f40da172SSean Callanan 167bb93483cSJason Molenda using NSArrayMSyntheticFrontEnd = 168bb93483cSJason Molenda GenericNSArrayMSyntheticFrontEnd<DataDescriptor_32, DataDescriptor_64>; 169f40da172SSean Callanan }; 170f40da172SSean Callanan 171bb93483cSJason Molenda namespace Foundation1437 { 172bb93483cSJason Molenda template <typename PtrType> 173bb93483cSJason Molenda struct DataDescriptor { 174bb93483cSJason Molenda PtrType _cow; 175bb93483cSJason Molenda // __deque 176bb93483cSJason Molenda PtrType _data; 177bb93483cSJason Molenda uint32_t _offset; 178bb93483cSJason Molenda uint32_t _size; 179bb93483cSJason Molenda union { 180bb93483cSJason Molenda PtrType _mutations; 181bb93483cSJason Molenda struct { 182bb93483cSJason Molenda uint32_t _muts; 183bb93483cSJason Molenda uint32_t _used; 184bb93483cSJason Molenda }; 185bb93483cSJason Molenda }; 186bb93483cSJason Molenda }; 187bb93483cSJason Molenda 188bb93483cSJason Molenda using NSArrayMSyntheticFrontEnd = 189bb93483cSJason Molenda GenericNSArrayMSyntheticFrontEnd< 190bb93483cSJason Molenda DataDescriptor<uint32_t>, DataDescriptor<uint64_t>>; 191bb93483cSJason Molenda 192bb93483cSJason Molenda template <typename DD> 193bb93483cSJason Molenda uint64_t 194bb93483cSJason Molenda __NSArrayMSize_Impl(lldb_private::Process &process, 195bb93483cSJason Molenda lldb::addr_t valobj_addr, Status &error) { 196bb93483cSJason Molenda const lldb::addr_t start_of_descriptor = 197bb93483cSJason Molenda valobj_addr + process.GetAddressByteSize(); 198bb93483cSJason Molenda DD descriptor = DD(); 199bb93483cSJason Molenda process.ReadMemory(start_of_descriptor, &descriptor, 200bb93483cSJason Molenda sizeof(descriptor), error); 201bb93483cSJason Molenda if (error.Fail()) { 202bb93483cSJason Molenda return 0; 203bb93483cSJason Molenda } 204bb93483cSJason Molenda return descriptor._used; 205bb93483cSJason Molenda } 206bb93483cSJason Molenda 207bb93483cSJason Molenda uint64_t 208bb93483cSJason Molenda __NSArrayMSize(lldb_private::Process &process, lldb::addr_t valobj_addr, 209bb93483cSJason Molenda Status &error) { 210bb93483cSJason Molenda if (process.GetAddressByteSize() == 4) { 211bb93483cSJason Molenda return __NSArrayMSize_Impl<DataDescriptor<uint32_t>>(process, valobj_addr, 212bb93483cSJason Molenda error); 213bb93483cSJason Molenda } else { 214bb93483cSJason Molenda return __NSArrayMSize_Impl<DataDescriptor<uint64_t>>(process, valobj_addr, 215bb93483cSJason Molenda error); 216bb93483cSJason Molenda } 217bb93483cSJason Molenda } 218bb93483cSJason Molenda 219*c8bee2ceSDavide Italiano } 220bb93483cSJason Molenda 221bb93483cSJason Molenda template <typename D32, typename D64, bool Inline> 222bb93483cSJason Molenda class GenericNSArrayISyntheticFrontEnd : public SyntheticChildrenFrontEnd { 223f40da172SSean Callanan public: 224bb93483cSJason Molenda GenericNSArrayISyntheticFrontEnd(lldb::ValueObjectSP valobj_sp); 225f40da172SSean Callanan 226bb93483cSJason Molenda ~GenericNSArrayISyntheticFrontEnd() override; 227f40da172SSean Callanan 228f40da172SSean Callanan size_t CalculateNumChildren() override; 229f40da172SSean Callanan 230f40da172SSean Callanan lldb::ValueObjectSP GetChildAtIndex(size_t idx) override; 231f40da172SSean Callanan 232f40da172SSean Callanan bool Update() override; 233f40da172SSean Callanan 234f40da172SSean Callanan bool MightHaveChildren() override; 235f40da172SSean Callanan 236f40da172SSean Callanan size_t GetIndexOfChildWithName(const ConstString &name) override; 237f40da172SSean Callanan 238f40da172SSean Callanan private: 239f40da172SSean Callanan ExecutionContextRef m_exe_ctx_ref; 240f40da172SSean Callanan uint8_t m_ptr_size; 241f40da172SSean Callanan 242bb93483cSJason Molenda D32 *m_data_32; 243bb93483cSJason Molenda D64 *m_data_64; 244bb93483cSJason Molenda CompilerType m_id_type; 245bb93483cSJason Molenda }; 246bb93483cSJason Molenda 247bb93483cSJason Molenda namespace Foundation1300 { 248bb93483cSJason Molenda struct IDD32 { 249f40da172SSean Callanan uint32_t used; 250f40da172SSean Callanan uint32_t list; 251f40da172SSean Callanan }; 252f40da172SSean Callanan 253bb93483cSJason Molenda struct IDD64 { 254f40da172SSean Callanan uint64_t used; 255f40da172SSean Callanan uint64_t list; 256f40da172SSean Callanan }; 257f40da172SSean Callanan 258bb93483cSJason Molenda using NSArrayISyntheticFrontEnd = 259bb93483cSJason Molenda GenericNSArrayISyntheticFrontEnd<IDD32, IDD64, true>; 260*c8bee2ceSDavide Italiano } 261bb93483cSJason Molenda 262bb93483cSJason Molenda namespace Foundation1430 { 263bb93483cSJason Molenda using NSArrayISyntheticFrontEnd = 264bb93483cSJason Molenda Foundation1428::NSArrayMSyntheticFrontEnd; 265*c8bee2ceSDavide Italiano } 266bb93483cSJason Molenda 267bb93483cSJason Molenda namespace Foundation1436 { 268bb93483cSJason Molenda struct IDD32 { 269bb93483cSJason Molenda uint32_t used; 270bb93483cSJason Molenda uint32_t list; // in Inline cases, this is the first element 271bb93483cSJason Molenda }; 272bb93483cSJason Molenda 273bb93483cSJason Molenda struct IDD64 { 274bb93483cSJason Molenda uint64_t used; 275bb93483cSJason Molenda uint64_t list; // in Inline cases, this is the first element 276bb93483cSJason Molenda }; 277bb93483cSJason Molenda 278bb93483cSJason Molenda using NSArrayI_TransferSyntheticFrontEnd = 279bb93483cSJason Molenda GenericNSArrayISyntheticFrontEnd<IDD32, IDD64, false>; 280bb93483cSJason Molenda 281bb93483cSJason Molenda using NSArrayISyntheticFrontEnd = 282bb93483cSJason Molenda GenericNSArrayISyntheticFrontEnd<IDD32, IDD64, true>; 283bb93483cSJason Molenda 284bb93483cSJason Molenda using NSFrozenArrayMSyntheticFrontEnd = 285bb93483cSJason Molenda Foundation1437::NSArrayMSyntheticFrontEnd; 286bb93483cSJason Molenda 287bb93483cSJason Molenda uint64_t 288bb93483cSJason Molenda __NSFrozenArrayMSize(lldb_private::Process &process, lldb::addr_t valobj_addr, 289bb93483cSJason Molenda Status &error) { 290bb93483cSJason Molenda return Foundation1437::__NSArrayMSize(process, valobj_addr, error); 291bb93483cSJason Molenda } 292*c8bee2ceSDavide Italiano } 293f40da172SSean Callanan 294b9c1b51eSKate Stone class NSArray0SyntheticFrontEnd : public SyntheticChildrenFrontEnd { 295bbf1da3cSEnrico Granata public: 296bbf1da3cSEnrico Granata NSArray0SyntheticFrontEnd(lldb::ValueObjectSP valobj_sp); 297bbf1da3cSEnrico Granata 2988d15f33bSEugene Zelenko ~NSArray0SyntheticFrontEnd() override = default; 299bbf1da3cSEnrico Granata 300b9c1b51eSKate Stone size_t CalculateNumChildren() override; 301bbf1da3cSEnrico Granata 302b9c1b51eSKate Stone lldb::ValueObjectSP GetChildAtIndex(size_t idx) override; 303bbf1da3cSEnrico Granata 304b9c1b51eSKate Stone bool Update() override; 305bbf1da3cSEnrico Granata 306b9c1b51eSKate Stone bool MightHaveChildren() override; 307bbf1da3cSEnrico Granata 308b9c1b51eSKate Stone size_t GetIndexOfChildWithName(const ConstString &name) override; 309bbf1da3cSEnrico Granata }; 310936499aeSEnrico Granata 311b9c1b51eSKate Stone class NSArray1SyntheticFrontEnd : public SyntheticChildrenFrontEnd { 312936499aeSEnrico Granata public: 313936499aeSEnrico Granata NSArray1SyntheticFrontEnd(lldb::ValueObjectSP valobj_sp); 314936499aeSEnrico Granata 315936499aeSEnrico Granata ~NSArray1SyntheticFrontEnd() override = default; 316936499aeSEnrico Granata 317b9c1b51eSKate Stone size_t CalculateNumChildren() override; 318936499aeSEnrico Granata 319b9c1b51eSKate Stone lldb::ValueObjectSP GetChildAtIndex(size_t idx) override; 320936499aeSEnrico Granata 321b9c1b51eSKate Stone bool Update() override; 322936499aeSEnrico Granata 323b9c1b51eSKate Stone bool MightHaveChildren() override; 324936499aeSEnrico Granata 325b9c1b51eSKate Stone size_t GetIndexOfChildWithName(const ConstString &name) override; 326936499aeSEnrico Granata }; 3278d15f33bSEugene Zelenko } // namespace formatters 3288d15f33bSEugene Zelenko } // namespace lldb_private 329170c395eSEnrico Granata 330b9c1b51eSKate Stone bool lldb_private::formatters::NSArraySummaryProvider( 331b9c1b51eSKate Stone ValueObject &valobj, Stream &stream, const TypeSummaryOptions &options) { 332675f49bbSEnrico Granata static ConstString g_TypeHint("NSArray"); 333675f49bbSEnrico Granata 334170c395eSEnrico Granata ProcessSP process_sp = valobj.GetProcessSP(); 335170c395eSEnrico Granata if (!process_sp) 336170c395eSEnrico Granata return false; 337170c395eSEnrico Granata 338b9c1b51eSKate Stone ObjCLanguageRuntime *runtime = 339b9c1b51eSKate Stone (ObjCLanguageRuntime *)process_sp->GetLanguageRuntime( 340b9c1b51eSKate Stone lldb::eLanguageTypeObjC); 341170c395eSEnrico Granata 342170c395eSEnrico Granata if (!runtime) 343170c395eSEnrico Granata return false; 344170c395eSEnrico Granata 345b9c1b51eSKate Stone ObjCLanguageRuntime::ClassDescriptorSP descriptor( 346b9c1b51eSKate Stone runtime->GetClassDescriptor(valobj)); 347170c395eSEnrico Granata 348bbd16815SEugene Zelenko if (!descriptor || !descriptor->IsValid()) 349170c395eSEnrico Granata return false; 350170c395eSEnrico Granata 351170c395eSEnrico Granata uint32_t ptr_size = process_sp->GetAddressByteSize(); 352170c395eSEnrico Granata 353170c395eSEnrico Granata lldb::addr_t valobj_addr = valobj.GetValueAsUnsigned(0); 354170c395eSEnrico Granata 355170c395eSEnrico Granata if (!valobj_addr) 356170c395eSEnrico Granata return false; 357170c395eSEnrico Granata 358170c395eSEnrico Granata uint64_t value = 0; 359170c395eSEnrico Granata 360936499aeSEnrico Granata ConstString class_name(descriptor->GetClassName()); 361170c395eSEnrico Granata 362936499aeSEnrico Granata static const ConstString g_NSArrayI("__NSArrayI"); 363936499aeSEnrico Granata static const ConstString g_NSArrayM("__NSArrayM"); 364bb93483cSJason Molenda static const ConstString g_NSArrayI_Transfer("__NSArrayI_Transfer"); 365bb93483cSJason Molenda static const ConstString g_NSFrozenArrayM("__NSFrozenArrayM"); 366936499aeSEnrico Granata static const ConstString g_NSArray0("__NSArray0"); 367936499aeSEnrico Granata static const ConstString g_NSArray1("__NSSingleObjectArrayI"); 368936499aeSEnrico Granata static const ConstString g_NSArrayCF("__NSCFArray"); 369f40da172SSean Callanan static const ConstString g_NSArrayMLegacy("__NSArrayM_Legacy"); 370f40da172SSean Callanan static const ConstString g_NSArrayMImmutable("__NSArrayM_Immutable"); 371936499aeSEnrico Granata 372936499aeSEnrico Granata if (class_name.IsEmpty()) 373170c395eSEnrico Granata return false; 374170c395eSEnrico Granata 375b9c1b51eSKate Stone if (class_name == g_NSArrayI) { 37697206d57SZachary Turner Status error; 377b9c1b51eSKate Stone value = process_sp->ReadUnsignedIntegerFromMemory(valobj_addr + ptr_size, 378b9c1b51eSKate Stone ptr_size, 0, error); 379170c395eSEnrico Granata if (error.Fail()) 380170c395eSEnrico Granata return false; 381b9c1b51eSKate Stone } else if (class_name == g_NSArrayM) { 382bb93483cSJason Molenda AppleObjCRuntime *apple_runtime = 383bb93483cSJason Molenda llvm::dyn_cast_or_null<AppleObjCRuntime>(runtime); 384bb93483cSJason Molenda Status error; 385bb93483cSJason Molenda if (apple_runtime && apple_runtime->GetFoundationVersion() >= 1437) { 386bb93483cSJason Molenda value = Foundation1437::__NSArrayMSize(*process_sp, valobj_addr, error); 387bb93483cSJason Molenda } else { 388bb93483cSJason Molenda value = process_sp->ReadUnsignedIntegerFromMemory(valobj_addr + ptr_size, 389bb93483cSJason Molenda ptr_size, 0, error); 390bb93483cSJason Molenda } 391bb93483cSJason Molenda if (error.Fail()) 392bb93483cSJason Molenda return false; 393bb93483cSJason Molenda } else if (class_name == g_NSArrayI_Transfer) { 39497206d57SZachary Turner Status error; 395b9c1b51eSKate Stone value = process_sp->ReadUnsignedIntegerFromMemory(valobj_addr + ptr_size, 396b9c1b51eSKate Stone ptr_size, 0, error); 397170c395eSEnrico Granata if (error.Fail()) 398170c395eSEnrico Granata return false; 399bb93483cSJason Molenda } else if (class_name == g_NSFrozenArrayM) { 400bb93483cSJason Molenda Status error; 401bb93483cSJason Molenda value = Foundation1436::__NSFrozenArrayMSize(*process_sp, valobj_addr, error); 402bb93483cSJason Molenda if (error.Fail()) 403bb93483cSJason Molenda return false; 404f40da172SSean Callanan } else if (class_name == g_NSArrayMLegacy) { 405f40da172SSean Callanan Status error; 406f40da172SSean Callanan value = process_sp->ReadUnsignedIntegerFromMemory(valobj_addr + ptr_size, 407f40da172SSean Callanan ptr_size, 0, error); 408f40da172SSean Callanan if (error.Fail()) 409f40da172SSean Callanan return false; 410f40da172SSean Callanan } else if (class_name == g_NSArrayMImmutable) { 411f40da172SSean Callanan Status error; 412f40da172SSean Callanan value = process_sp->ReadUnsignedIntegerFromMemory(valobj_addr + ptr_size, 413f40da172SSean Callanan ptr_size, 0, error); 414f40da172SSean Callanan if (error.Fail()) 415f40da172SSean Callanan return false; 416b9c1b51eSKate Stone } else if (class_name == g_NSArray0) { 417bbf1da3cSEnrico Granata value = 0; 418b9c1b51eSKate Stone } else if (class_name == g_NSArray1) { 419936499aeSEnrico Granata value = 1; 420b9c1b51eSKate Stone } else if (class_name == g_NSArrayCF) { 42197206d57SZachary Turner Status error; 422b9c1b51eSKate Stone value = process_sp->ReadUnsignedIntegerFromMemory( 423b9c1b51eSKate Stone valobj_addr + 2 * ptr_size, ptr_size, 0, error); 424170c395eSEnrico Granata if (error.Fail()) 425170c395eSEnrico Granata return false; 426b9c1b51eSKate Stone } else { 427c28b3e88SEnrico Granata auto &map(NSArray_Additionals::GetAdditionalSummaries()); 428c28b3e88SEnrico Granata auto iter = map.find(class_name), end = map.end(); 429c28b3e88SEnrico Granata if (iter != end) 430c28b3e88SEnrico Granata return iter->second(valobj, stream, options); 431c28b3e88SEnrico Granata else 432170c395eSEnrico Granata return false; 433c28b3e88SEnrico Granata } 434170c395eSEnrico Granata 435675f49bbSEnrico Granata std::string prefix, suffix; 436b9c1b51eSKate Stone if (Language *language = Language::FindPlugin(options.GetLanguage())) { 437b9c1b51eSKate Stone if (!language->GetFormatterPrefixSuffix(valobj, g_TypeHint, prefix, 438b9c1b51eSKate Stone suffix)) { 439675f49bbSEnrico Granata prefix.clear(); 440675f49bbSEnrico Granata suffix.clear(); 441675f49bbSEnrico Granata } 442675f49bbSEnrico Granata } 443675f49bbSEnrico Granata 444b9c1b51eSKate Stone stream.Printf("%s%" PRIu64 " %s%s%s", prefix.c_str(), value, "element", 445b9c1b51eSKate Stone value == 1 ? "" : "s", suffix.c_str()); 446170c395eSEnrico Granata return true; 447170c395eSEnrico Granata } 448170c395eSEnrico Granata 449bb93483cSJason Molenda lldb_private::formatters::NSArrayMSyntheticFrontEndBase::NSArrayMSyntheticFrontEndBase( 450b9c1b51eSKate Stone lldb::ValueObjectSP valobj_sp) 451b9c1b51eSKate Stone : SyntheticChildrenFrontEnd(*valobj_sp), m_exe_ctx_ref(), m_ptr_size(8), 452b9c1b51eSKate Stone m_id_type() { 453b9c1b51eSKate Stone if (valobj_sp) { 454b9c1b51eSKate Stone clang::ASTContext *ast = valobj_sp->GetExecutionContextRef() 455b9c1b51eSKate Stone .GetTargetSP() 456b9c1b51eSKate Stone ->GetScratchClangASTContext() 457b9c1b51eSKate Stone ->getASTContext(); 458170c395eSEnrico Granata if (ast) 459170c395eSEnrico Granata m_id_type = CompilerType(ast, ast->ObjCBuiltinIdTy); 460170c395eSEnrico Granata if (valobj_sp->GetProcessSP()) 461170c395eSEnrico Granata m_ptr_size = valobj_sp->GetProcessSP()->GetAddressByteSize(); 462170c395eSEnrico Granata } 463170c395eSEnrico Granata } 464170c395eSEnrico Granata 465bb93483cSJason Molenda template <typename D32, typename D64> 466bb93483cSJason Molenda lldb_private::formatters:: 467bb93483cSJason Molenda GenericNSArrayMSyntheticFrontEnd<D32, D64>:: 468bb93483cSJason Molenda GenericNSArrayMSyntheticFrontEnd(lldb::ValueObjectSP valobj_sp) 469bb93483cSJason Molenda : NSArrayMSyntheticFrontEndBase(valobj_sp), m_data_32(nullptr), 470f40da172SSean Callanan m_data_64(nullptr) {} 471f40da172SSean Callanan 472170c395eSEnrico Granata size_t 473bb93483cSJason Molenda lldb_private::formatters::NSArrayMSyntheticFrontEndBase::CalculateNumChildren() { 474170c395eSEnrico Granata return GetUsedCount(); 475170c395eSEnrico Granata } 476170c395eSEnrico Granata 477170c395eSEnrico Granata lldb::ValueObjectSP 478bb93483cSJason Molenda lldb_private::formatters::NSArrayMSyntheticFrontEndBase::GetChildAtIndex( 479b9c1b51eSKate Stone size_t idx) { 480170c395eSEnrico Granata if (idx >= CalculateNumChildren()) 481170c395eSEnrico Granata return lldb::ValueObjectSP(); 482170c395eSEnrico Granata lldb::addr_t object_at_idx = GetDataAddress(); 483170c395eSEnrico Granata size_t pyhs_idx = idx; 484170c395eSEnrico Granata pyhs_idx += GetOffset(); 485170c395eSEnrico Granata if (GetSize() <= pyhs_idx) 486170c395eSEnrico Granata pyhs_idx -= GetSize(); 487170c395eSEnrico Granata object_at_idx += (pyhs_idx * m_ptr_size); 488170c395eSEnrico Granata StreamString idx_name; 489170c395eSEnrico Granata idx_name.Printf("[%" PRIu64 "]", (uint64_t)idx); 490c156427dSZachary Turner return CreateValueObjectFromAddress(idx_name.GetString(), object_at_idx, 491b9c1b51eSKate Stone m_exe_ctx_ref, m_id_type); 492170c395eSEnrico Granata } 493170c395eSEnrico Granata 494bb93483cSJason Molenda template <typename D32, typename D64> 495bb93483cSJason Molenda bool 496bb93483cSJason Molenda lldb_private::formatters:: 497bb93483cSJason Molenda GenericNSArrayMSyntheticFrontEnd<D32, D64>::Update() { 498170c395eSEnrico Granata ValueObjectSP valobj_sp = m_backend.GetSP(); 499170c395eSEnrico Granata m_ptr_size = 0; 500170c395eSEnrico Granata delete m_data_32; 501bbd16815SEugene Zelenko m_data_32 = nullptr; 502170c395eSEnrico Granata delete m_data_64; 503bbd16815SEugene Zelenko m_data_64 = nullptr; 504170c395eSEnrico Granata if (!valobj_sp) 505170c395eSEnrico Granata return false; 506170c395eSEnrico Granata m_exe_ctx_ref = valobj_sp->GetExecutionContextRef(); 50797206d57SZachary Turner Status error; 508170c395eSEnrico Granata error.Clear(); 509170c395eSEnrico Granata lldb::ProcessSP process_sp(valobj_sp->GetProcessSP()); 510170c395eSEnrico Granata if (!process_sp) 511170c395eSEnrico Granata return false; 512170c395eSEnrico Granata m_ptr_size = process_sp->GetAddressByteSize(); 513170c395eSEnrico Granata uint64_t data_location = valobj_sp->GetValueAsUnsigned(0) + m_ptr_size; 514b9c1b51eSKate Stone if (m_ptr_size == 4) { 515bb93483cSJason Molenda m_data_32 = new D32(); 516bb93483cSJason Molenda process_sp->ReadMemory(data_location, m_data_32, sizeof(D32), 517b9c1b51eSKate Stone error); 518b9c1b51eSKate Stone } else { 519bb93483cSJason Molenda m_data_64 = new D64(); 520bb93483cSJason Molenda process_sp->ReadMemory(data_location, m_data_64, sizeof(D64), 521b9c1b51eSKate Stone error); 522170c395eSEnrico Granata } 523170c395eSEnrico Granata if (error.Fail()) 524170c395eSEnrico Granata return false; 525170c395eSEnrico Granata return false; 526170c395eSEnrico Granata } 527170c395eSEnrico Granata 528bb93483cSJason Molenda bool 529bb93483cSJason Molenda lldb_private::formatters::NSArrayMSyntheticFrontEndBase::MightHaveChildren() { 530170c395eSEnrico Granata return true; 531170c395eSEnrico Granata } 532170c395eSEnrico Granata 533170c395eSEnrico Granata size_t 534bb93483cSJason Molenda lldb_private::formatters::NSArrayMSyntheticFrontEndBase::GetIndexOfChildWithName( 535b9c1b51eSKate Stone const ConstString &name) { 536170c395eSEnrico Granata const char *item_name = name.GetCString(); 537170c395eSEnrico Granata uint32_t idx = ExtractIndexFromString(item_name); 538170c395eSEnrico Granata if (idx < UINT32_MAX && idx >= CalculateNumChildren()) 539170c395eSEnrico Granata return UINT32_MAX; 540170c395eSEnrico Granata return idx; 541170c395eSEnrico Granata } 542170c395eSEnrico Granata 543bb93483cSJason Molenda template <typename D32, typename D64> 544bb93483cSJason Molenda lldb_private::formatters:: 545bb93483cSJason Molenda GenericNSArrayMSyntheticFrontEnd<D32, D64>:: 546bb93483cSJason Molenda ~GenericNSArrayMSyntheticFrontEnd() { 5478d15f33bSEugene Zelenko delete m_data_32; 548bbd16815SEugene Zelenko m_data_32 = nullptr; 5498d15f33bSEugene Zelenko delete m_data_64; 550bbd16815SEugene Zelenko m_data_64 = nullptr; 5518d15f33bSEugene Zelenko } 5528d15f33bSEugene Zelenko 553bb93483cSJason Molenda template <typename D32, typename D64> 554170c395eSEnrico Granata lldb::addr_t 555bb93483cSJason Molenda lldb_private::formatters:: 556bb93483cSJason Molenda GenericNSArrayMSyntheticFrontEnd<D32, D64>:: 557bb93483cSJason Molenda GenericNSArrayMSyntheticFrontEnd::GetDataAddress() { 558170c395eSEnrico Granata if (!m_data_32 && !m_data_64) 559170c395eSEnrico Granata return LLDB_INVALID_ADDRESS; 560b9c1b51eSKate Stone return m_data_32 ? m_data_32->_data : m_data_64->_data; 561170c395eSEnrico Granata } 562170c395eSEnrico Granata 563bb93483cSJason Molenda template <typename D32, typename D64> 564170c395eSEnrico Granata uint64_t 565bb93483cSJason Molenda lldb_private::formatters:: 566bb93483cSJason Molenda GenericNSArrayMSyntheticFrontEnd<D32, D64>:: 567bb93483cSJason Molenda GenericNSArrayMSyntheticFrontEnd::GetUsedCount() { 568170c395eSEnrico Granata if (!m_data_32 && !m_data_64) 569170c395eSEnrico Granata return 0; 570b9c1b51eSKate Stone return m_data_32 ? m_data_32->_used : m_data_64->_used; 571170c395eSEnrico Granata } 572170c395eSEnrico Granata 573bb93483cSJason Molenda template <typename D32, typename D64> 574bb93483cSJason Molenda uint64_t 575bb93483cSJason Molenda lldb_private::formatters:: 576bb93483cSJason Molenda GenericNSArrayMSyntheticFrontEnd<D32, D64>:: 577bb93483cSJason Molenda GenericNSArrayMSyntheticFrontEnd::GetOffset() { 578170c395eSEnrico Granata if (!m_data_32 && !m_data_64) 579170c395eSEnrico Granata return 0; 580b9c1b51eSKate Stone return m_data_32 ? m_data_32->_offset : m_data_64->_offset; 581170c395eSEnrico Granata } 582170c395eSEnrico Granata 583bb93483cSJason Molenda template <typename D32, typename D64> 584bb93483cSJason Molenda uint64_t 585bb93483cSJason Molenda lldb_private::formatters:: 586bb93483cSJason Molenda GenericNSArrayMSyntheticFrontEnd<D32, D64>:: 587bb93483cSJason Molenda GenericNSArrayMSyntheticFrontEnd::GetSize() { 588170c395eSEnrico Granata if (!m_data_32 && !m_data_64) 589170c395eSEnrico Granata return 0; 590b9c1b51eSKate Stone return m_data_32 ? m_data_32->_size : m_data_64->_size; 591170c395eSEnrico Granata } 592170c395eSEnrico Granata 593bb93483cSJason Molenda template <typename D32, typename D64, bool Inline> 594bb93483cSJason Molenda lldb_private::formatters::GenericNSArrayISyntheticFrontEnd<D32, D64, Inline>:: 595bb93483cSJason Molenda GenericNSArrayISyntheticFrontEnd( 596f40da172SSean Callanan lldb::ValueObjectSP valobj_sp) 597f40da172SSean Callanan : SyntheticChildrenFrontEnd(*valobj_sp), m_exe_ctx_ref(), m_ptr_size(8), 598f40da172SSean Callanan m_data_32(nullptr), m_data_64(nullptr) { 599f40da172SSean Callanan if (valobj_sp) { 600f40da172SSean Callanan CompilerType type = valobj_sp->GetCompilerType(); 601f40da172SSean Callanan if (type) { 602f40da172SSean Callanan ClangASTContext *ast = valobj_sp->GetExecutionContextRef() 603f40da172SSean Callanan .GetTargetSP() 604f40da172SSean Callanan ->GetScratchClangASTContext(); 605f40da172SSean Callanan if (ast) 606f40da172SSean Callanan m_id_type = CompilerType(ast->getASTContext(), 607f40da172SSean Callanan ast->getASTContext()->ObjCBuiltinIdTy); 608f40da172SSean Callanan } 609f40da172SSean Callanan } 610f40da172SSean Callanan } 611f40da172SSean Callanan 612bb93483cSJason Molenda template <typename D32, typename D64, bool Inline> 613bb93483cSJason Molenda lldb_private::formatters::GenericNSArrayISyntheticFrontEnd<D32, D64, Inline>:: 614bb93483cSJason Molenda ~GenericNSArrayISyntheticFrontEnd() { 615f40da172SSean Callanan delete m_data_32; 616f40da172SSean Callanan m_data_32 = nullptr; 617f40da172SSean Callanan delete m_data_64; 618f40da172SSean Callanan m_data_64 = nullptr; 619f40da172SSean Callanan } 620f40da172SSean Callanan 621bb93483cSJason Molenda template <typename D32, typename D64, bool Inline> 622f40da172SSean Callanan size_t 623bb93483cSJason Molenda lldb_private::formatters::GenericNSArrayISyntheticFrontEnd<D32, D64, Inline>:: 624bb93483cSJason Molenda GetIndexOfChildWithName(const ConstString &name) { 625f40da172SSean Callanan const char *item_name = name.GetCString(); 626f40da172SSean Callanan uint32_t idx = ExtractIndexFromString(item_name); 627f40da172SSean Callanan if (idx < UINT32_MAX && idx >= CalculateNumChildren()) 628f40da172SSean Callanan return UINT32_MAX; 629f40da172SSean Callanan return idx; 630f40da172SSean Callanan } 631f40da172SSean Callanan 632bb93483cSJason Molenda template <typename D32, typename D64, bool Inline> 633f40da172SSean Callanan size_t 634bb93483cSJason Molenda lldb_private::formatters::GenericNSArrayISyntheticFrontEnd<D32, D64, Inline>:: 635bb93483cSJason Molenda CalculateNumChildren() { 636f40da172SSean Callanan return m_data_32 ? m_data_32->used : m_data_64->used; 637f40da172SSean Callanan } 638f40da172SSean Callanan 639bb93483cSJason Molenda template <typename D32, typename D64, bool Inline> 640bb93483cSJason Molenda bool 641bb93483cSJason Molenda lldb_private::formatters::GenericNSArrayISyntheticFrontEnd<D32, D64, Inline>:: 642bb93483cSJason Molenda Update() { 643f40da172SSean Callanan ValueObjectSP valobj_sp = m_backend.GetSP(); 644f40da172SSean Callanan m_ptr_size = 0; 645f40da172SSean Callanan delete m_data_32; 646f40da172SSean Callanan m_data_32 = nullptr; 647f40da172SSean Callanan delete m_data_64; 648f40da172SSean Callanan m_data_64 = nullptr; 649f40da172SSean Callanan if (!valobj_sp) 650f40da172SSean Callanan return false; 651f40da172SSean Callanan m_exe_ctx_ref = valobj_sp->GetExecutionContextRef(); 652f40da172SSean Callanan Status error; 653f40da172SSean Callanan error.Clear(); 654f40da172SSean Callanan lldb::ProcessSP process_sp(valobj_sp->GetProcessSP()); 655f40da172SSean Callanan if (!process_sp) 656f40da172SSean Callanan return false; 657f40da172SSean Callanan m_ptr_size = process_sp->GetAddressByteSize(); 658f40da172SSean Callanan uint64_t data_location = valobj_sp->GetValueAsUnsigned(0) + m_ptr_size; 659f40da172SSean Callanan if (m_ptr_size == 4) { 660bb93483cSJason Molenda m_data_32 = new D32(); 661bb93483cSJason Molenda process_sp->ReadMemory(data_location, m_data_32, sizeof(D32), 662f40da172SSean Callanan error); 663f40da172SSean Callanan } else { 664bb93483cSJason Molenda m_data_64 = new D64(); 665bb93483cSJason Molenda process_sp->ReadMemory(data_location, m_data_64, sizeof(D64), 666f40da172SSean Callanan error); 667f40da172SSean Callanan } 668f40da172SSean Callanan if (error.Fail()) 669f40da172SSean Callanan return false; 670f40da172SSean Callanan return false; 671f40da172SSean Callanan } 672f40da172SSean Callanan 673bb93483cSJason Molenda template <typename D32, typename D64, bool Inline> 674bb93483cSJason Molenda bool 675bb93483cSJason Molenda lldb_private::formatters::GenericNSArrayISyntheticFrontEnd<D32, D64, Inline>:: 676bb93483cSJason Molenda MightHaveChildren() { 677f40da172SSean Callanan return true; 678f40da172SSean Callanan } 679f40da172SSean Callanan 680bb93483cSJason Molenda template <typename D32, typename D64, bool Inline> 681f40da172SSean Callanan lldb::ValueObjectSP 682bb93483cSJason Molenda lldb_private::formatters::GenericNSArrayISyntheticFrontEnd<D32, D64, Inline>:: 683bb93483cSJason Molenda GetChildAtIndex(size_t idx) { 684f40da172SSean Callanan if (idx >= CalculateNumChildren()) 685f40da172SSean Callanan return lldb::ValueObjectSP(); 686bb93483cSJason Molenda lldb::addr_t object_at_idx; 687bb93483cSJason Molenda if (Inline) { 688bb93483cSJason Molenda object_at_idx = m_backend.GetSP()->GetValueAsUnsigned(0) + m_ptr_size; 689bb93483cSJason Molenda object_at_idx += m_ptr_size == 4 ? sizeof(D32) : sizeof(D64); // skip the data header 690bb93483cSJason Molenda object_at_idx -= m_ptr_size; // we treat the last entry in the data header as the first pointer 691bb93483cSJason Molenda } else { 692bb93483cSJason Molenda object_at_idx = m_data_32 ? m_data_32->list : m_data_64->list; 693bb93483cSJason Molenda } 694f40da172SSean Callanan object_at_idx += (idx * m_ptr_size); 695bb93483cSJason Molenda 696f40da172SSean Callanan ProcessSP process_sp = m_exe_ctx_ref.GetProcessSP(); 697f40da172SSean Callanan if (!process_sp) 698f40da172SSean Callanan return lldb::ValueObjectSP(); 699f40da172SSean Callanan Status error; 700f40da172SSean Callanan if (error.Fail()) 701f40da172SSean Callanan return lldb::ValueObjectSP(); 702f40da172SSean Callanan StreamString idx_name; 703f40da172SSean Callanan idx_name.Printf("[%" PRIu64 "]", (uint64_t)idx); 704f40da172SSean Callanan return CreateValueObjectFromAddress(idx_name.GetString(), object_at_idx, 705f40da172SSean Callanan m_exe_ctx_ref, m_id_type); 706f40da172SSean Callanan } 707f40da172SSean Callanan 708b9c1b51eSKate Stone lldb_private::formatters::NSArray0SyntheticFrontEnd::NSArray0SyntheticFrontEnd( 709b9c1b51eSKate Stone lldb::ValueObjectSP valobj_sp) 710b9c1b51eSKate Stone : SyntheticChildrenFrontEnd(*valobj_sp) {} 711bbf1da3cSEnrico Granata 712bbf1da3cSEnrico Granata size_t 713b9c1b51eSKate Stone lldb_private::formatters::NSArray0SyntheticFrontEnd::GetIndexOfChildWithName( 714b9c1b51eSKate Stone const ConstString &name) { 715bbf1da3cSEnrico Granata return UINT32_MAX; 716bbf1da3cSEnrico Granata } 717bbf1da3cSEnrico Granata 718bbf1da3cSEnrico Granata size_t 719b9c1b51eSKate Stone lldb_private::formatters::NSArray0SyntheticFrontEnd::CalculateNumChildren() { 720bbf1da3cSEnrico Granata return 0; 721bbf1da3cSEnrico Granata } 722bbf1da3cSEnrico Granata 723b9c1b51eSKate Stone bool lldb_private::formatters::NSArray0SyntheticFrontEnd::Update() { 724bbf1da3cSEnrico Granata return false; 725bbf1da3cSEnrico Granata } 726bbf1da3cSEnrico Granata 727b9c1b51eSKate Stone bool lldb_private::formatters::NSArray0SyntheticFrontEnd::MightHaveChildren() { 728bbf1da3cSEnrico Granata return false; 729bbf1da3cSEnrico Granata } 730bbf1da3cSEnrico Granata 731bbf1da3cSEnrico Granata lldb::ValueObjectSP 732b9c1b51eSKate Stone lldb_private::formatters::NSArray0SyntheticFrontEnd::GetChildAtIndex( 733b9c1b51eSKate Stone size_t idx) { 734bbf1da3cSEnrico Granata return lldb::ValueObjectSP(); 735bbf1da3cSEnrico Granata } 736bbf1da3cSEnrico Granata 737b9c1b51eSKate Stone lldb_private::formatters::NSArray1SyntheticFrontEnd::NSArray1SyntheticFrontEnd( 738b9c1b51eSKate Stone lldb::ValueObjectSP valobj_sp) 739b9c1b51eSKate Stone : SyntheticChildrenFrontEnd(*valobj_sp.get()) {} 740936499aeSEnrico Granata 741936499aeSEnrico Granata size_t 742b9c1b51eSKate Stone lldb_private::formatters::NSArray1SyntheticFrontEnd::GetIndexOfChildWithName( 743b9c1b51eSKate Stone const ConstString &name) { 744936499aeSEnrico Granata static const ConstString g_zero("[0]"); 745936499aeSEnrico Granata 746936499aeSEnrico Granata if (name == g_zero) 747936499aeSEnrico Granata return 0; 748936499aeSEnrico Granata 749936499aeSEnrico Granata return UINT32_MAX; 750936499aeSEnrico Granata } 751936499aeSEnrico Granata 752936499aeSEnrico Granata size_t 753b9c1b51eSKate Stone lldb_private::formatters::NSArray1SyntheticFrontEnd::CalculateNumChildren() { 754936499aeSEnrico Granata return 1; 755936499aeSEnrico Granata } 756936499aeSEnrico Granata 757b9c1b51eSKate Stone bool lldb_private::formatters::NSArray1SyntheticFrontEnd::Update() { 758936499aeSEnrico Granata return false; 759936499aeSEnrico Granata } 760936499aeSEnrico Granata 761b9c1b51eSKate Stone bool lldb_private::formatters::NSArray1SyntheticFrontEnd::MightHaveChildren() { 762936499aeSEnrico Granata return true; 763936499aeSEnrico Granata } 764936499aeSEnrico Granata 765936499aeSEnrico Granata lldb::ValueObjectSP 766b9c1b51eSKate Stone lldb_private::formatters::NSArray1SyntheticFrontEnd::GetChildAtIndex( 767b9c1b51eSKate Stone size_t idx) { 768936499aeSEnrico Granata static const ConstString g_zero("[0]"); 769936499aeSEnrico Granata 770b9c1b51eSKate Stone if (idx == 0) { 771b9c1b51eSKate Stone CompilerType id_type( 772b9c1b51eSKate Stone m_backend.GetTargetSP()->GetScratchClangASTContext()->GetBasicType( 773b9c1b51eSKate Stone lldb::eBasicTypeObjCID)); 774b9c1b51eSKate Stone return m_backend.GetSyntheticChildAtOffset( 775b9c1b51eSKate Stone m_backend.GetProcessSP()->GetAddressByteSize(), id_type, true, g_zero); 776936499aeSEnrico Granata } 777936499aeSEnrico Granata return lldb::ValueObjectSP(); 778936499aeSEnrico Granata } 779936499aeSEnrico Granata 780b9c1b51eSKate Stone SyntheticChildrenFrontEnd * 781b9c1b51eSKate Stone lldb_private::formatters::NSArraySyntheticFrontEndCreator( 782b9c1b51eSKate Stone CXXSyntheticChildren *synth, lldb::ValueObjectSP valobj_sp) { 783170c395eSEnrico Granata if (!valobj_sp) 784170c395eSEnrico Granata return nullptr; 785170c395eSEnrico Granata 786170c395eSEnrico Granata lldb::ProcessSP process_sp(valobj_sp->GetProcessSP()); 787170c395eSEnrico Granata if (!process_sp) 788bbd16815SEugene Zelenko return nullptr; 789b9c1b51eSKate Stone AppleObjCRuntime *runtime = llvm::dyn_cast_or_null<AppleObjCRuntime>( 790b9c1b51eSKate Stone process_sp->GetObjCLanguageRuntime()); 791170c395eSEnrico Granata if (!runtime) 792bbd16815SEugene Zelenko return nullptr; 793170c395eSEnrico Granata 794170c395eSEnrico Granata CompilerType valobj_type(valobj_sp->GetCompilerType()); 795170c395eSEnrico Granata Flags flags(valobj_type.GetTypeInfo()); 796170c395eSEnrico Granata 797b9c1b51eSKate Stone if (flags.IsClear(eTypeIsPointer)) { 79897206d57SZachary Turner Status error; 799170c395eSEnrico Granata valobj_sp = valobj_sp->AddressOf(error); 800170c395eSEnrico Granata if (error.Fail() || !valobj_sp) 801bbd16815SEugene Zelenko return nullptr; 802170c395eSEnrico Granata } 803170c395eSEnrico Granata 804b9c1b51eSKate Stone ObjCLanguageRuntime::ClassDescriptorSP descriptor( 805b9c1b51eSKate Stone runtime->GetClassDescriptor(*valobj_sp)); 806170c395eSEnrico Granata 807bbd16815SEugene Zelenko if (!descriptor || !descriptor->IsValid()) 808bbd16815SEugene Zelenko return nullptr; 809170c395eSEnrico Granata 810936499aeSEnrico Granata ConstString class_name(descriptor->GetClassName()); 811170c395eSEnrico Granata 812936499aeSEnrico Granata static const ConstString g_NSArrayI("__NSArrayI"); 813bb93483cSJason Molenda static const ConstString g_NSArrayI_Transfer("__NSArrayI_Transfer"); 814bb93483cSJason Molenda static const ConstString g_NSFrozenArrayM("__NSFrozenArrayM"); 815936499aeSEnrico Granata static const ConstString g_NSArrayM("__NSArrayM"); 816936499aeSEnrico Granata static const ConstString g_NSArray0("__NSArray0"); 817936499aeSEnrico Granata static const ConstString g_NSArray1("__NSSingleObjectArrayI"); 818f40da172SSean Callanan static const ConstString g_NSArrayMLegacy("__NSArrayM_Legacy"); 819f40da172SSean Callanan static const ConstString g_NSArrayMImmutable("__NSArrayM_Immutable"); 820936499aeSEnrico Granata 821936499aeSEnrico Granata if (class_name.IsEmpty()) 822bbd16815SEugene Zelenko return nullptr; 823170c395eSEnrico Granata 824b9c1b51eSKate Stone if (class_name == g_NSArrayI) { 825bb93483cSJason Molenda if (runtime->GetFoundationVersion() >= 1436) 826bb93483cSJason Molenda return (new Foundation1436::NSArrayISyntheticFrontEnd(valobj_sp)); 827bb93483cSJason Molenda if (runtime->GetFoundationVersion() >= 1430) 828bb93483cSJason Molenda return (new Foundation1430::NSArrayISyntheticFrontEnd(valobj_sp)); 829f40da172SSean Callanan else 830bb93483cSJason Molenda return (new Foundation1300::NSArrayISyntheticFrontEnd(valobj_sp)); 831bb93483cSJason Molenda } else if (class_name == g_NSArrayI_Transfer) { 832bb93483cSJason Molenda return (new Foundation1436::NSArrayI_TransferSyntheticFrontEnd(valobj_sp)); 833bb93483cSJason Molenda } else if (class_name == g_NSArray0) { 834bb93483cSJason Molenda } else if (class_name == g_NSFrozenArrayM) { 835bb93483cSJason Molenda return (new Foundation1436::NSFrozenArrayMSyntheticFrontEnd(valobj_sp)); 836b9c1b51eSKate Stone } else if (class_name == g_NSArray0) { 837bbf1da3cSEnrico Granata return (new NSArray0SyntheticFrontEnd(valobj_sp)); 838b9c1b51eSKate Stone } else if (class_name == g_NSArray1) { 839936499aeSEnrico Granata return (new NSArray1SyntheticFrontEnd(valobj_sp)); 840b9c1b51eSKate Stone } else if (class_name == g_NSArrayM) { 841bb93483cSJason Molenda if (runtime->GetFoundationVersion() >= 1437) 842bb93483cSJason Molenda return (new Foundation1437::NSArrayMSyntheticFrontEnd(valobj_sp)); 843bb93483cSJason Molenda if (runtime->GetFoundationVersion() >= 1428) 844bb93483cSJason Molenda return (new Foundation1428::NSArrayMSyntheticFrontEnd(valobj_sp)); 845170c395eSEnrico Granata if (runtime->GetFoundationVersion() >= 1100) 846bb93483cSJason Molenda return (new Foundation1010::NSArrayMSyntheticFrontEnd(valobj_sp)); 847170c395eSEnrico Granata else 848bb93483cSJason Molenda return (new Foundation109::NSArrayMSyntheticFrontEnd(valobj_sp)); 849b9c1b51eSKate Stone } else { 850c28b3e88SEnrico Granata auto &map(NSArray_Additionals::GetAdditionalSynthetics()); 851c28b3e88SEnrico Granata auto iter = map.find(class_name), end = map.end(); 852c28b3e88SEnrico Granata if (iter != end) 853c28b3e88SEnrico Granata return iter->second(synth, valobj_sp); 854c28b3e88SEnrico Granata } 855170c395eSEnrico Granata 8562543d290SEnrico Granata return nullptr; 857170c395eSEnrico Granata } 858