diff options
Diffstat (limited to 'lldb/source/Plugins/Language/ObjC/NSIndexPath.cpp')
-rw-r--r-- | lldb/source/Plugins/Language/ObjC/NSIndexPath.cpp | 620 |
1 files changed, 274 insertions, 346 deletions
diff --git a/lldb/source/Plugins/Language/ObjC/NSIndexPath.cpp b/lldb/source/Plugins/Language/ObjC/NSIndexPath.cpp index 0bebaca256b..d169334f537 100644 --- a/lldb/source/Plugins/Language/ObjC/NSIndexPath.cpp +++ b/lldb/source/Plugins/Language/ObjC/NSIndexPath.cpp @@ -26,371 +26,299 @@ using namespace lldb; using namespace lldb_private; using namespace lldb_private::formatters; -static constexpr size_t -PACKED_INDEX_SHIFT_64(size_t i) -{ - return (60 - (13 * (4-i))); +static constexpr size_t PACKED_INDEX_SHIFT_64(size_t i) { + return (60 - (13 * (4 - i))); } -static constexpr size_t -PACKED_INDEX_SHIFT_32(size_t i) -{ - return (32 - (13 * (2-i))); +static constexpr size_t PACKED_INDEX_SHIFT_32(size_t i) { + return (32 - (13 * (2 - i))); } -class NSIndexPathSyntheticFrontEnd : public SyntheticChildrenFrontEnd -{ +class NSIndexPathSyntheticFrontEnd : public SyntheticChildrenFrontEnd { public: - NSIndexPathSyntheticFrontEnd (lldb::ValueObjectSP valobj_sp) : - SyntheticChildrenFrontEnd (*valobj_sp.get()), - m_descriptor_sp(nullptr), - m_impl(), - m_ptr_size(0), - m_uint_star_type() - { - m_ptr_size = m_backend.GetTargetSP()->GetArchitecture().GetAddressByteSize(); - } + NSIndexPathSyntheticFrontEnd(lldb::ValueObjectSP valobj_sp) + : SyntheticChildrenFrontEnd(*valobj_sp.get()), m_descriptor_sp(nullptr), + m_impl(), m_ptr_size(0), m_uint_star_type() { + m_ptr_size = + m_backend.GetTargetSP()->GetArchitecture().GetAddressByteSize(); + } - ~NSIndexPathSyntheticFrontEnd() override = default; + ~NSIndexPathSyntheticFrontEnd() override = default; - size_t - CalculateNumChildren() override - { - return m_impl.GetNumIndexes(); - } - - lldb::ValueObjectSP - GetChildAtIndex(size_t idx) override - { - return m_impl.GetIndexAtIndex(idx, m_uint_star_type); - } - - bool - Update() override - { - m_impl.Clear(); - - TypeSystem* type_system = m_backend.GetCompilerType().GetTypeSystem(); - if (!type_system) - return false; - - ClangASTContext *ast = m_backend.GetExecutionContextRef().GetTargetSP()->GetScratchClangASTContext(); - if (!ast) - return false; - - m_uint_star_type = ast->GetPointerSizedIntType(false); - - static ConstString g__indexes("_indexes"); - static ConstString g__length("_length"); - - ProcessSP process_sp = m_backend.GetProcessSP(); - if (!process_sp) - return false; - - ObjCLanguageRuntime* runtime = (ObjCLanguageRuntime*)process_sp->GetLanguageRuntime(lldb::eLanguageTypeObjC); - - if (!runtime) - return false; - - ObjCLanguageRuntime::ClassDescriptorSP descriptor(runtime->GetClassDescriptor(m_backend)); - - if (!descriptor.get() || !descriptor->IsValid()) - return false; - - uint64_t info_bits(0),value_bits(0),payload(0); - - if (descriptor->GetTaggedPointerInfo(&info_bits, &value_bits, &payload)) - { - m_impl.m_inlined.SetIndexes(payload, *process_sp); - m_impl.m_mode = Mode::Inlined; + size_t CalculateNumChildren() override { return m_impl.GetNumIndexes(); } + + lldb::ValueObjectSP GetChildAtIndex(size_t idx) override { + return m_impl.GetIndexAtIndex(idx, m_uint_star_type); + } + + bool Update() override { + m_impl.Clear(); + + TypeSystem *type_system = m_backend.GetCompilerType().GetTypeSystem(); + if (!type_system) + return false; + + ClangASTContext *ast = m_backend.GetExecutionContextRef() + .GetTargetSP() + ->GetScratchClangASTContext(); + if (!ast) + return false; + + m_uint_star_type = ast->GetPointerSizedIntType(false); + + static ConstString g__indexes("_indexes"); + static ConstString g__length("_length"); + + ProcessSP process_sp = m_backend.GetProcessSP(); + if (!process_sp) + return false; + + ObjCLanguageRuntime *runtime = + (ObjCLanguageRuntime *)process_sp->GetLanguageRuntime( + lldb::eLanguageTypeObjC); + + if (!runtime) + return false; + + ObjCLanguageRuntime::ClassDescriptorSP descriptor( + runtime->GetClassDescriptor(m_backend)); + + if (!descriptor.get() || !descriptor->IsValid()) + return false; + + uint64_t info_bits(0), value_bits(0), payload(0); + + if (descriptor->GetTaggedPointerInfo(&info_bits, &value_bits, &payload)) { + m_impl.m_inlined.SetIndexes(payload, *process_sp); + m_impl.m_mode = Mode::Inlined; + } else { + ObjCLanguageRuntime::ClassDescriptor::iVarDescriptor _indexes_id; + ObjCLanguageRuntime::ClassDescriptor::iVarDescriptor _length_id; + + bool has_indexes(false), has_length(false); + + for (size_t x = 0; x < descriptor->GetNumIVars(); x++) { + const auto &ivar = descriptor->GetIVarAtIndex(x); + if (ivar.m_name == g__indexes) { + _indexes_id = ivar; + has_indexes = true; + } else if (ivar.m_name == g__length) { + _length_id = ivar; + has_length = true; } - else - { - ObjCLanguageRuntime::ClassDescriptor::iVarDescriptor _indexes_id; - ObjCLanguageRuntime::ClassDescriptor::iVarDescriptor _length_id; - - bool has_indexes(false),has_length(false); - - for (size_t x = 0; - x < descriptor->GetNumIVars(); - x++) - { - const auto& ivar = descriptor->GetIVarAtIndex(x); - if (ivar.m_name == g__indexes) - { - _indexes_id = ivar; - has_indexes = true; - } - else if (ivar.m_name == g__length) - { - _length_id = ivar; - has_length = true; - } - - if (has_length && has_indexes) - break; - } - - if (has_length && has_indexes) - { - m_impl.m_outsourced.m_indexes = m_backend.GetSyntheticChildAtOffset(_indexes_id.m_offset, - m_uint_star_type.GetPointerType(), - true).get(); - ValueObjectSP length_sp(m_backend.GetSyntheticChildAtOffset(_length_id.m_offset, - m_uint_star_type, - true)); - if (length_sp) - { - m_impl.m_outsourced.m_count = length_sp->GetValueAsUnsigned(0); - if (m_impl.m_outsourced.m_indexes) - m_impl.m_mode = Mode::Outsourced; - } - } + + if (has_length && has_indexes) + break; + } + + if (has_length && has_indexes) { + m_impl.m_outsourced.m_indexes = + m_backend + .GetSyntheticChildAtOffset(_indexes_id.m_offset, + m_uint_star_type.GetPointerType(), + true) + .get(); + ValueObjectSP length_sp(m_backend.GetSyntheticChildAtOffset( + _length_id.m_offset, m_uint_star_type, true)); + if (length_sp) { + m_impl.m_outsourced.m_count = length_sp->GetValueAsUnsigned(0); + if (m_impl.m_outsourced.m_indexes) + m_impl.m_mode = Mode::Outsourced; } - return false; - } - - bool - MightHaveChildren() override - { - if (m_impl.m_mode == Mode::Invalid) - return false; - return true; + } } - - size_t - GetIndexOfChildWithName(const ConstString &name) override - { - const char* item_name = name.GetCString(); - uint32_t idx = ExtractIndexFromString(item_name); - if (idx < UINT32_MAX && idx >= CalculateNumChildren()) - return UINT32_MAX; - return idx; + return false; + } + + bool MightHaveChildren() override { + if (m_impl.m_mode == Mode::Invalid) + return false; + return true; + } + + size_t GetIndexOfChildWithName(const ConstString &name) override { + const char *item_name = name.GetCString(); + uint32_t idx = ExtractIndexFromString(item_name); + if (idx < UINT32_MAX && idx >= CalculateNumChildren()) + return UINT32_MAX; + return idx; + } + + lldb::ValueObjectSP GetSyntheticValue() override { return nullptr; } + +protected: + ObjCLanguageRuntime::ClassDescriptorSP m_descriptor_sp; + + enum class Mode { Inlined, Outsourced, Invalid }; + + struct Impl { + size_t GetNumIndexes() { + switch (m_mode) { + case Mode::Inlined: + return m_inlined.GetNumIndexes(); + case Mode::Outsourced: + return m_outsourced.m_count; + default: + return 0; + } } - - lldb::ValueObjectSP - GetSyntheticValue() override - { + + lldb::ValueObjectSP GetIndexAtIndex(size_t idx, + const CompilerType &desired_type) { + if (idx >= GetNumIndexes()) return nullptr; + switch (m_mode) { + default: + return nullptr; + case Mode::Inlined: + return m_inlined.GetIndexAtIndex(idx, desired_type); + case Mode::Outsourced: + return m_outsourced.GetIndexAtIndex(idx); + } } -protected: - ObjCLanguageRuntime::ClassDescriptorSP m_descriptor_sp; - - enum class Mode { - Inlined, - Outsourced, - Invalid - }; - - struct Impl - { - size_t - GetNumIndexes () - { - switch (m_mode) - { - case Mode::Inlined: - return m_inlined.GetNumIndexes(); - case Mode::Outsourced: - return m_outsourced.m_count; - default: - return 0; - } - } - - lldb::ValueObjectSP - GetIndexAtIndex (size_t idx, const CompilerType& desired_type) - { - if (idx >= GetNumIndexes()) - return nullptr; - switch (m_mode) - { - default: return nullptr; - case Mode::Inlined: - return m_inlined.GetIndexAtIndex (idx, desired_type); - case Mode::Outsourced: - return m_outsourced.GetIndexAtIndex (idx); - } + struct InlinedIndexes { + public: + void SetIndexes(uint64_t value, Process &p) { + m_indexes = value; + _lengthForInlinePayload(p.GetAddressByteSize()); + m_process = &p; + } + + size_t GetNumIndexes() { return m_count; } + + lldb::ValueObjectSP GetIndexAtIndex(size_t idx, + const CompilerType &desired_type) { + if (!m_process) + return nullptr; + + std::pair<uint64_t, bool> value(_indexAtPositionForInlinePayload(idx)); + if (!value.second) + return nullptr; + + Value v; + if (m_ptr_size == 8) { + Scalar scalar((unsigned long long)value.first); + v = Value(scalar); + } else { + Scalar scalar((unsigned int)value.first); + v = Value(scalar); } - - struct InlinedIndexes - { - public: - void SetIndexes(uint64_t value, Process& p) - { - m_indexes = value; - _lengthForInlinePayload(p.GetAddressByteSize()); - m_process = &p; - } - - size_t - GetNumIndexes () - { - return m_count; - } - - lldb::ValueObjectSP - GetIndexAtIndex (size_t idx, const CompilerType& desired_type) - { - if (!m_process) - return nullptr; - - std::pair<uint64_t, bool> value(_indexAtPositionForInlinePayload(idx)); - if (!value.second) - return nullptr; - - Value v; - if (m_ptr_size == 8) - { - Scalar scalar( (unsigned long long)value.first ); - v = Value(scalar); - } - else - { - Scalar scalar( (unsigned int)value.first ); - v = Value(scalar); - } - - v.SetCompilerType(desired_type); - - StreamString idx_name; - idx_name.Printf("[%" PRIu64 "]", (uint64_t)idx); - - return ValueObjectConstResult::Create(m_process, v, ConstString(idx_name.GetData())); - } - - void - Clear () - { - m_indexes = 0; - m_count = 0; - m_ptr_size = 0; - m_process = nullptr; - } - - InlinedIndexes () : - m_indexes(0), - m_count(0), - m_ptr_size(0), - m_process(nullptr) - { - } - - private: - uint64_t m_indexes; - size_t m_count; - uint32_t m_ptr_size; - Process *m_process; - - // cfr. Foundation for the details of this code - size_t _lengthForInlinePayload(uint32_t ptr_size) { - m_ptr_size = ptr_size; - if (m_ptr_size == 8) - m_count = ((m_indexes >> 3) & 0x7); - else - m_count = ((m_indexes >> 3) & 0x3); - return m_count; - } - - std::pair<uint64_t, bool> - _indexAtPositionForInlinePayload(size_t pos) - { - static const uint64_t PACKED_INDEX_MASK = ((1 << 13) - 1); - if (m_ptr_size == 8) - { - switch (pos) - { - case 3: - case 2: - case 1: - case 0: - return {(m_indexes >> PACKED_INDEX_SHIFT_64(pos)) & PACKED_INDEX_MASK,true}; - default: - return {0,false}; - } - } - else - { - switch (pos) - { - case 0: - case 1: - return {(m_indexes >> PACKED_INDEX_SHIFT_32(pos)) & PACKED_INDEX_MASK,true}; - default: - return {0,false}; - } - } - return {0,false}; - } - - }; - - struct OutsourcedIndexes - { - lldb::ValueObjectSP - GetIndexAtIndex (size_t idx) - { - if (m_indexes) - { - ValueObjectSP index_sp(m_indexes->GetSyntheticArrayMember(idx, true)); - return index_sp; - } - return nullptr; - } - - void - Clear () - { - m_indexes = nullptr; - m_count = 0; - } - - OutsourcedIndexes () : - m_indexes(nullptr), - m_count(0) - { - } - - ValueObject *m_indexes; - size_t m_count; - }; - - union - { - struct InlinedIndexes m_inlined; - struct OutsourcedIndexes m_outsourced; - }; - - void - Clear () - { - m_mode = Mode::Invalid; - m_inlined.Clear(); - m_outsourced.Clear(); + + v.SetCompilerType(desired_type); + + StreamString idx_name; + idx_name.Printf("[%" PRIu64 "]", (uint64_t)idx); + + return ValueObjectConstResult::Create(m_process, v, + ConstString(idx_name.GetData())); + } + + void Clear() { + m_indexes = 0; + m_count = 0; + m_ptr_size = 0; + m_process = nullptr; + } + + InlinedIndexes() + : m_indexes(0), m_count(0), m_ptr_size(0), m_process(nullptr) {} + + private: + uint64_t m_indexes; + size_t m_count; + uint32_t m_ptr_size; + Process *m_process; + + // cfr. Foundation for the details of this code + size_t _lengthForInlinePayload(uint32_t ptr_size) { + m_ptr_size = ptr_size; + if (m_ptr_size == 8) + m_count = ((m_indexes >> 3) & 0x7); + else + m_count = ((m_indexes >> 3) & 0x3); + return m_count; + } + + std::pair<uint64_t, bool> _indexAtPositionForInlinePayload(size_t pos) { + static const uint64_t PACKED_INDEX_MASK = ((1 << 13) - 1); + if (m_ptr_size == 8) { + switch (pos) { + case 3: + case 2: + case 1: + case 0: + return {(m_indexes >> PACKED_INDEX_SHIFT_64(pos)) & + PACKED_INDEX_MASK, + true}; + default: + return {0, false}; + } + } else { + switch (pos) { + case 0: + case 1: + return {(m_indexes >> PACKED_INDEX_SHIFT_32(pos)) & + PACKED_INDEX_MASK, + true}; + default: + return {0, false}; + } } - - Impl() : - m_mode(Mode::Invalid) - { + return {0, false}; + } + }; + + struct OutsourcedIndexes { + lldb::ValueObjectSP GetIndexAtIndex(size_t idx) { + if (m_indexes) { + ValueObjectSP index_sp(m_indexes->GetSyntheticArrayMember(idx, true)); + return index_sp; } - - Mode m_mode; - } m_impl; - - uint32_t m_ptr_size; - CompilerType m_uint_star_type; + return nullptr; + } + + void Clear() { + m_indexes = nullptr; + m_count = 0; + } + + OutsourcedIndexes() : m_indexes(nullptr), m_count(0) {} + + ValueObject *m_indexes; + size_t m_count; + }; + + union { + struct InlinedIndexes m_inlined; + struct OutsourcedIndexes m_outsourced; + }; + + void Clear() { + m_mode = Mode::Invalid; + m_inlined.Clear(); + m_outsourced.Clear(); + } + + Impl() : m_mode(Mode::Invalid) {} + + Mode m_mode; + } m_impl; + + uint32_t m_ptr_size; + CompilerType m_uint_star_type; }; namespace lldb_private { - namespace formatters { - - SyntheticChildrenFrontEnd* NSIndexPathSyntheticFrontEndCreator (CXXSyntheticChildren*, lldb::ValueObjectSP valobj_sp) - { - if (valobj_sp) - return new NSIndexPathSyntheticFrontEnd(valobj_sp); - return nullptr; - } +namespace formatters { + +SyntheticChildrenFrontEnd * +NSIndexPathSyntheticFrontEndCreator(CXXSyntheticChildren *, + lldb::ValueObjectSP valobj_sp) { + if (valobj_sp) + return new NSIndexPathSyntheticFrontEnd(valobj_sp); + return nullptr; +} - } // namespace formatters +} // namespace formatters } // namespace lldb_private |