summaryrefslogtreecommitdiff
path: root/source/Plugins/Language
diff options
context:
space:
mode:
Diffstat (limited to 'source/Plugins/Language')
-rw-r--r--source/Plugins/Language/CPlusPlus/CMakeLists.txt3
-rw-r--r--source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.cpp39
-rw-r--r--source/Plugins/Language/CPlusPlus/CPlusPlusNameParser.cpp2
-rw-r--r--source/Plugins/Language/CPlusPlus/LibCxx.cpp3
-rw-r--r--source/Plugins/Language/CPlusPlus/LibCxx.h14
-rw-r--r--source/Plugins/Language/CPlusPlus/LibCxxBitset.cpp107
-rw-r--r--source/Plugins/Language/CPlusPlus/LibCxxInitializerList.cpp5
-rw-r--r--source/Plugins/Language/CPlusPlus/LibCxxList.cpp268
-rw-r--r--source/Plugins/Language/CPlusPlus/LibCxxMap.cpp9
-rw-r--r--source/Plugins/Language/CPlusPlus/LibCxxQueue.cpp61
-rw-r--r--source/Plugins/Language/CPlusPlus/LibCxxTuple.cpp83
-rw-r--r--source/Plugins/Language/CPlusPlus/LibCxxUnorderedMap.cpp5
-rw-r--r--source/Plugins/Language/CPlusPlus/LibCxxVector.cpp3
-rw-r--r--source/Plugins/Language/CPlusPlus/LibStdcpp.cpp7
-rw-r--r--source/Plugins/Language/ObjC/CMakeLists.txt12
-rw-r--r--source/Plugins/Language/ObjC/NSArray.cpp624
-rw-r--r--source/Plugins/Language/ObjC/NSDictionary.cpp319
-rw-r--r--source/Plugins/Language/ObjC/NSSet.cpp84
18 files changed, 1064 insertions, 584 deletions
diff --git a/source/Plugins/Language/CPlusPlus/CMakeLists.txt b/source/Plugins/Language/CPlusPlus/CMakeLists.txt
index 8f769c499987f..180440a244a4a 100644
--- a/source/Plugins/Language/CPlusPlus/CMakeLists.txt
+++ b/source/Plugins/Language/CPlusPlus/CMakeLists.txt
@@ -5,9 +5,12 @@ add_lldb_library(lldbPluginCPlusPlusLanguage PLUGIN
CxxStringTypes.cpp
LibCxx.cpp
LibCxxAtomic.cpp
+ LibCxxBitset.cpp
LibCxxInitializerList.cpp
LibCxxList.cpp
LibCxxMap.cpp
+ LibCxxQueue.cpp
+ LibCxxTuple.cpp
LibCxxUnorderedMap.cpp
LibCxxVector.cpp
LibStdcpp.cpp
diff --git a/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.cpp b/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.cpp
index 1ae9418e4d9c0..51ed88065c84d 100644
--- a/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.cpp
+++ b/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.cpp
@@ -422,12 +422,24 @@ static void LoadLibCxxFormatters(lldb::TypeCategoryImplSP cpp_category_sp) {
AddCXXSynthetic(
cpp_category_sp,
+ lldb_private::formatters::LibcxxBitsetSyntheticFrontEndCreator,
+ "libc++ std::bitset synthetic children",
+ ConstString("^std::__(ndk)?1::bitset<.+>(( )?&)?$"), stl_synth_flags,
+ true);
+ AddCXXSynthetic(
+ cpp_category_sp,
lldb_private::formatters::LibcxxStdVectorSyntheticFrontEndCreator,
"libc++ std::vector synthetic children",
ConstString("^std::__(ndk)?1::vector<.+>(( )?&)?$"), stl_synth_flags,
true);
AddCXXSynthetic(
cpp_category_sp,
+ lldb_private::formatters::LibcxxStdForwardListSyntheticFrontEndCreator,
+ "libc++ std::forward_list synthetic children",
+ ConstString("^std::__(ndk)?1::forward_list<.+>(( )?&)?$"),
+ stl_synth_flags, true);
+ AddCXXSynthetic(
+ cpp_category_sp,
lldb_private::formatters::LibcxxStdListSyntheticFrontEndCreator,
"libc++ std::list synthetic children",
ConstString("^std::__(ndk)?1::list<.+>(( )?&)?$"), stl_synth_flags, true);
@@ -467,6 +479,14 @@ static void LoadLibCxxFormatters(lldb::TypeCategoryImplSP cpp_category_sp) {
"libc++ std::initializer_list synthetic children",
ConstString("^std::initializer_list<.+>(( )?&)?$"), stl_synth_flags,
true);
+ AddCXXSynthetic(cpp_category_sp, LibcxxQueueFrontEndCreator,
+ "libc++ std::queue synthetic children",
+ ConstString("^std::__(ndk)?1::queue<.+>(( )?&)?$"),
+ stl_synth_flags, true);
+ AddCXXSynthetic(cpp_category_sp, LibcxxTupleFrontEndCreator,
+ "libc++ std::tuple synthetic children",
+ ConstString("^std::__(ndk)?1::tuple<.*>(( )?&)?$"), stl_synth_flags,
+ true);
AddCXXSynthetic(
cpp_category_sp,
lldb_private::formatters::LibcxxAtomicSyntheticFrontEndCreator,
@@ -497,12 +517,22 @@ static void LoadLibCxxFormatters(lldb::TypeCategoryImplSP cpp_category_sp) {
stl_summary_flags.SetSkipPointers(false);
AddCXXSummary(cpp_category_sp,
lldb_private::formatters::LibcxxContainerSummaryProvider,
+ "libc++ std::bitset summary provider",
+ ConstString("^std::__(ndk)?1::bitset<.+>(( )?&)?$"),
+ stl_summary_flags, true);
+ AddCXXSummary(cpp_category_sp,
+ lldb_private::formatters::LibcxxContainerSummaryProvider,
"libc++ std::vector summary provider",
ConstString("^std::__(ndk)?1::vector<.+>(( )?&)?$"),
stl_summary_flags, true);
AddCXXSummary(cpp_category_sp,
lldb_private::formatters::LibcxxContainerSummaryProvider,
"libc++ std::list summary provider",
+ ConstString("^std::__(ndk)?1::forward_list<.+>(( )?&)?$"),
+ stl_summary_flags, true);
+ AddCXXSummary(cpp_category_sp,
+ lldb_private::formatters::LibcxxContainerSummaryProvider,
+ "libc++ std::list summary provider",
ConstString("^std::__(ndk)?1::list<.+>(( )?&)?$"),
stl_summary_flags, true);
AddCXXSummary(cpp_category_sp,
@@ -517,6 +547,11 @@ static void LoadLibCxxFormatters(lldb::TypeCategoryImplSP cpp_category_sp) {
stl_summary_flags, true);
AddCXXSummary(cpp_category_sp,
lldb_private::formatters::LibcxxContainerSummaryProvider,
+ "libc++ std::queue summary provider",
+ ConstString("^std::__(ndk)?1::queue<.+>(( )?&)?$"),
+ stl_summary_flags, true);
+ AddCXXSummary(cpp_category_sp,
+ lldb_private::formatters::LibcxxContainerSummaryProvider,
"libc++ std::set summary provider",
ConstString("^std::__(ndk)?1::set<.+>(( )?&)?$"),
stl_summary_flags, true);
@@ -535,6 +570,10 @@ static void LoadLibCxxFormatters(lldb::TypeCategoryImplSP cpp_category_sp) {
"libc++ std::unordered containers summary provider",
ConstString("^(std::__(ndk)?1::)unordered_(multi)?(map|set)<.+> >$"),
stl_summary_flags, true);
+ AddCXXSummary(cpp_category_sp, LibcxxContainerSummaryProvider,
+ "libc++ std::tuple summary provider",
+ ConstString("^std::__(ndk)?1::tuple<.*>(( )?&)?$"), stl_summary_flags,
+ true);
AddCXXSummary(
cpp_category_sp, lldb_private::formatters::LibCxxAtomicSummaryProvider,
"libc++ std::atomic summary provider",
diff --git a/source/Plugins/Language/CPlusPlus/CPlusPlusNameParser.cpp b/source/Plugins/Language/CPlusPlus/CPlusPlusNameParser.cpp
index 88bdd68ff3011..aebea6ae3569b 100644
--- a/source/Plugins/Language/CPlusPlus/CPlusPlusNameParser.cpp
+++ b/source/Plugins/Language/CPlusPlus/CPlusPlusNameParser.cpp
@@ -628,7 +628,7 @@ static const clang::LangOptions &GetLangOptions() {
g_options.CPlusPlus = true;
g_options.CPlusPlus11 = true;
g_options.CPlusPlus14 = true;
- g_options.CPlusPlus1z = true;
+ g_options.CPlusPlus17 = true;
});
return g_options;
}
diff --git a/source/Plugins/Language/CPlusPlus/LibCxx.cpp b/source/Plugins/Language/CPlusPlus/LibCxx.cpp
index 11245e1310b77..f6d1f18cb596b 100644
--- a/source/Plugins/Language/CPlusPlus/LibCxx.cpp
+++ b/source/Plugins/Language/CPlusPlus/LibCxx.cpp
@@ -153,12 +153,11 @@ bool lldb_private::formatters::LibCxxMapIteratorSyntheticFrontEnd::Update() {
.get();
if (m_pair_ptr) {
auto __i_(valobj_sp->GetChildMemberWithName(g___i_, true));
- lldb::TemplateArgumentKind kind;
if (!__i_) {
m_pair_ptr = nullptr;
return false;
}
- CompilerType pair_type(__i_->GetCompilerType().GetTemplateArgument(0, kind));
+ CompilerType pair_type(__i_->GetCompilerType().GetTypeTemplateArgument(0));
std::string name; uint64_t bit_offset_ptr; uint32_t bitfield_bit_size_ptr; bool is_bitfield_ptr;
pair_type = pair_type.GetFieldAtIndex(0, name, &bit_offset_ptr, &bitfield_bit_size_ptr, &is_bitfield_ptr);
if (!pair_type) {
diff --git a/source/Plugins/Language/CPlusPlus/LibCxx.h b/source/Plugins/Language/CPlusPlus/LibCxx.h
index 7610212b4245a..3f6e0d6e14d7f 100644
--- a/source/Plugins/Language/CPlusPlus/LibCxx.h
+++ b/source/Plugins/Language/CPlusPlus/LibCxx.h
@@ -93,6 +93,10 @@ private:
};
SyntheticChildrenFrontEnd *
+LibcxxBitsetSyntheticFrontEndCreator(CXXSyntheticChildren *,
+ lldb::ValueObjectSP);
+
+SyntheticChildrenFrontEnd *
LibcxxSharedPtrSyntheticFrontEndCreator(CXXSyntheticChildren *,
lldb::ValueObjectSP);
@@ -105,6 +109,10 @@ LibcxxStdListSyntheticFrontEndCreator(CXXSyntheticChildren *,
lldb::ValueObjectSP);
SyntheticChildrenFrontEnd *
+LibcxxStdForwardListSyntheticFrontEndCreator(CXXSyntheticChildren *,
+ lldb::ValueObjectSP);
+
+SyntheticChildrenFrontEnd *
LibcxxStdMapSyntheticFrontEndCreator(CXXSyntheticChildren *,
lldb::ValueObjectSP);
@@ -119,6 +127,12 @@ LibcxxInitializerListSyntheticFrontEndCreator(CXXSyntheticChildren *,
SyntheticChildrenFrontEnd *LibcxxFunctionFrontEndCreator(CXXSyntheticChildren *,
lldb::ValueObjectSP);
+SyntheticChildrenFrontEnd *LibcxxQueueFrontEndCreator(CXXSyntheticChildren *,
+ lldb::ValueObjectSP);
+
+SyntheticChildrenFrontEnd *LibcxxTupleFrontEndCreator(CXXSyntheticChildren *,
+ lldb::ValueObjectSP);
+
} // namespace formatters
} // namespace lldb_private
diff --git a/source/Plugins/Language/CPlusPlus/LibCxxBitset.cpp b/source/Plugins/Language/CPlusPlus/LibCxxBitset.cpp
new file mode 100644
index 0000000000000..0cdb0b26cf3bd
--- /dev/null
+++ b/source/Plugins/Language/CPlusPlus/LibCxxBitset.cpp
@@ -0,0 +1,107 @@
+//===-- LibCxxBitset.cpp ----------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "LibCxx.h"
+#include "lldb/DataFormatters/FormattersHelpers.h"
+#include "lldb/Symbol/ClangASTContext.h"
+#include "lldb/Target/Target.h"
+
+using namespace lldb;
+using namespace lldb_private;
+
+namespace {
+
+class BitsetFrontEnd : public SyntheticChildrenFrontEnd {
+public:
+ BitsetFrontEnd(ValueObject &valobj);
+
+ size_t GetIndexOfChildWithName(const ConstString &name) override {
+ return formatters::ExtractIndexFromString(name.GetCString());
+ }
+
+ bool MightHaveChildren() override { return true; }
+ bool Update() override;
+ size_t CalculateNumChildren() override { return m_elements.size(); }
+ ValueObjectSP GetChildAtIndex(size_t idx) override;
+
+private:
+ std::vector<ValueObjectSP> m_elements;
+ ValueObjectSP m_first;
+ CompilerType m_bool_type;
+ ByteOrder m_byte_order = eByteOrderInvalid;
+ uint8_t m_byte_size = 0;
+};
+} // namespace
+
+BitsetFrontEnd::BitsetFrontEnd(ValueObject &valobj)
+ : SyntheticChildrenFrontEnd(valobj) {
+ m_bool_type = valobj.GetCompilerType().GetBasicTypeFromAST(eBasicTypeBool);
+ if (auto target_sp = m_backend.GetTargetSP()) {
+ m_byte_order = target_sp->GetArchitecture().GetByteOrder();
+ m_byte_size = target_sp->GetArchitecture().GetAddressByteSize();
+ Update();
+ }
+}
+
+bool BitsetFrontEnd::Update() {
+ m_elements.clear();
+ m_first.reset();
+
+ TargetSP target_sp = m_backend.GetTargetSP();
+ if (!target_sp)
+ return false;
+ size_t capping_size = target_sp->GetMaximumNumberOfChildrenToDisplay();
+
+ size_t size = 0;
+ if (auto arg = m_backend.GetCompilerType().GetIntegralTemplateArgument(0))
+ size = arg->value.getLimitedValue(capping_size);
+
+ m_elements.assign(size, ValueObjectSP());
+
+ m_first = m_backend.GetChildMemberWithName(ConstString("__first_"), true);
+ return false;
+}
+
+ValueObjectSP BitsetFrontEnd::GetChildAtIndex(size_t idx) {
+ if (idx >= m_elements.size() || !m_first)
+ return ValueObjectSP();
+
+ if (m_elements[idx])
+ return m_elements[idx];
+
+ ExecutionContext ctx = m_backend.GetExecutionContextRef().Lock(false);
+ CompilerType type;
+ ValueObjectSP chunk;
+ // For small bitsets __first_ is not an array, but a plain size_t.
+ if (m_first->GetCompilerType().IsArrayType(&type, nullptr, nullptr))
+ chunk = m_first->GetChildAtIndex(
+ idx / type.GetBitSize(ctx.GetBestExecutionContextScope()), true);
+ else {
+ type = m_first->GetCompilerType();
+ chunk = m_first;
+ }
+ if (!type || !chunk)
+ return ValueObjectSP();
+
+ size_t chunk_idx = idx % type.GetBitSize(ctx.GetBestExecutionContextScope());
+ uint8_t value = !!(chunk->GetValueAsUnsigned(0) & (uint64_t(1) << chunk_idx));
+ DataExtractor data(&value, sizeof(value), m_byte_order, m_byte_size);
+
+ m_elements[idx] = CreateValueObjectFromData(llvm::formatv("[{0}]", idx).str(),
+ data, ctx, m_bool_type);
+
+ return m_elements[idx];
+}
+
+SyntheticChildrenFrontEnd *formatters::LibcxxBitsetSyntheticFrontEndCreator(
+ CXXSyntheticChildren *, lldb::ValueObjectSP valobj_sp) {
+ if (valobj_sp)
+ return new BitsetFrontEnd(*valobj_sp);
+ return nullptr;
+}
diff --git a/source/Plugins/Language/CPlusPlus/LibCxxInitializerList.cpp b/source/Plugins/Language/CPlusPlus/LibCxxInitializerList.cpp
index 4e839532afb79..5823f6f3e0382 100644
--- a/source/Plugins/Language/CPlusPlus/LibCxxInitializerList.cpp
+++ b/source/Plugins/Language/CPlusPlus/LibCxxInitializerList.cpp
@@ -94,9 +94,8 @@ bool lldb_private::formatters::LibcxxInitializerListSyntheticFrontEnd::
m_start = nullptr;
m_num_elements = 0;
- lldb::TemplateArgumentKind kind;
- m_element_type = m_backend.GetCompilerType().GetTemplateArgument(0, kind);
- if (kind != lldb::eTemplateArgumentKindType || !m_element_type.IsValid())
+ m_element_type = m_backend.GetCompilerType().GetTypeTemplateArgument(0);
+ if (!m_element_type.IsValid())
return false;
m_element_size = m_element_type.GetByteSize(nullptr);
diff --git a/source/Plugins/Language/CPlusPlus/LibCxxList.cpp b/source/Plugins/Language/CPlusPlus/LibCxxList.cpp
index 56d8edaba72ac..6407ae129ad7d 100644
--- a/source/Plugins/Language/CPlusPlus/LibCxxList.cpp
+++ b/source/Plugins/Language/CPlusPlus/LibCxxList.cpp
@@ -114,58 +114,90 @@ private:
ListEntry m_entry;
};
-} // end anonymous namespace
-
-namespace lldb_private {
-namespace formatters {
-class LibcxxStdListSyntheticFrontEnd : public SyntheticChildrenFrontEnd {
+class AbstractListFrontEnd : public SyntheticChildrenFrontEnd {
public:
- LibcxxStdListSyntheticFrontEnd(lldb::ValueObjectSP valobj_sp);
+ size_t GetIndexOfChildWithName(const ConstString &name) override {
+ return ExtractIndexFromString(name.GetCString());
+ }
+ bool MightHaveChildren() override { return true; }
+ bool Update() override;
- ~LibcxxStdListSyntheticFrontEnd() override = default;
+protected:
+ AbstractListFrontEnd(ValueObject &valobj)
+ : SyntheticChildrenFrontEnd(valobj) {}
- size_t CalculateNumChildren() override;
+ size_t m_count;
+ ValueObject *m_head;
- lldb::ValueObjectSP GetChildAtIndex(size_t idx) override;
+ static constexpr bool g_use_loop_detect = true;
+ size_t m_loop_detected; // The number of elements that have had loop detection
+ // run over them.
+ ListEntry m_slow_runner; // Used for loop detection
+ ListEntry m_fast_runner; // Used for loop detection
+
+ size_t m_list_capping_size;
+ CompilerType m_element_type;
+ std::map<size_t, ListIterator> m_iterators;
+
+ bool HasLoop(size_t count);
+ ValueObjectSP GetItem(size_t idx);
+};
+class ForwardListFrontEnd : public AbstractListFrontEnd {
+public:
+ ForwardListFrontEnd(ValueObject &valobj);
+
+ size_t CalculateNumChildren() override;
+ ValueObjectSP GetChildAtIndex(size_t idx) override;
bool Update() override;
+};
- bool MightHaveChildren() override;
+class ListFrontEnd : public AbstractListFrontEnd {
+public:
+ ListFrontEnd(lldb::ValueObjectSP valobj_sp);
- size_t GetIndexOfChildWithName(const ConstString &name) override;
+ ~ListFrontEnd() override = default;
-private:
- bool HasLoop(size_t count);
+ size_t CalculateNumChildren() override;
- size_t m_list_capping_size;
- static const bool g_use_loop_detect = true;
+ lldb::ValueObjectSP GetChildAtIndex(size_t idx) override;
- size_t m_loop_detected; // The number of elements that have had loop detection
- // run over them.
- ListEntry m_slow_runner; // Used for loop detection
- ListEntry m_fast_runner; // Used for loop detection
+ bool Update() override;
+private:
lldb::addr_t m_node_address;
- ValueObject *m_head;
ValueObject *m_tail;
- CompilerType m_element_type;
- size_t m_count;
- std::map<size_t, ListIterator> m_iterators;
};
-} // namespace formatters
-} // namespace lldb_private
-
-lldb_private::formatters::LibcxxStdListSyntheticFrontEnd::
- LibcxxStdListSyntheticFrontEnd(lldb::ValueObjectSP valobj_sp)
- : SyntheticChildrenFrontEnd(*valobj_sp), m_list_capping_size(0),
- m_loop_detected(0), m_node_address(), m_head(nullptr), m_tail(nullptr),
- m_element_type(), m_count(UINT32_MAX), m_iterators() {
- if (valobj_sp)
- Update();
+
+} // end anonymous namespace
+
+bool AbstractListFrontEnd::Update() {
+ m_loop_detected = 0;
+ m_count = UINT32_MAX;
+ m_head = nullptr;
+ m_list_capping_size = 0;
+ m_slow_runner.SetEntry(nullptr);
+ m_fast_runner.SetEntry(nullptr);
+ m_iterators.clear();
+
+ if (m_backend.GetTargetSP())
+ m_list_capping_size =
+ m_backend.GetTargetSP()->GetMaximumNumberOfChildrenToDisplay();
+ if (m_list_capping_size == 0)
+ m_list_capping_size = 255;
+
+ CompilerType list_type = m_backend.GetCompilerType();
+ if (list_type.IsReferenceType())
+ list_type = list_type.GetNonReferenceType();
+
+ if (list_type.GetNumTemplateArguments() == 0)
+ return false;
+ m_element_type = list_type.GetTypeTemplateArgument(0);
+
+ return false;
}
-bool lldb_private::formatters::LibcxxStdListSyntheticFrontEnd::HasLoop(
- size_t count) {
+bool AbstractListFrontEnd::HasLoop(size_t count) {
if (!g_use_loop_detect)
return false;
// don't bother checking for a loop if we won't actually need to jump nodes
@@ -201,8 +233,105 @@ bool lldb_private::formatters::LibcxxStdListSyntheticFrontEnd::HasLoop(
return m_slow_runner == m_fast_runner;
}
-size_t lldb_private::formatters::LibcxxStdListSyntheticFrontEnd::
- CalculateNumChildren() {
+ValueObjectSP AbstractListFrontEnd::GetItem(size_t idx) {
+ size_t advance = idx;
+ ListIterator current(m_head);
+ if (idx > 0) {
+ auto cached_iterator = m_iterators.find(idx - 1);
+ if (cached_iterator != m_iterators.end()) {
+ current = cached_iterator->second;
+ advance = 1;
+ }
+ }
+ ValueObjectSP value_sp = current.advance(advance);
+ m_iterators[idx] = current;
+ return value_sp;
+}
+
+ForwardListFrontEnd::ForwardListFrontEnd(ValueObject &valobj)
+ : AbstractListFrontEnd(valobj) {
+ Update();
+}
+
+size_t ForwardListFrontEnd::CalculateNumChildren() {
+ if (m_count != UINT32_MAX)
+ return m_count;
+
+ ListEntry current(m_head);
+ m_count = 0;
+ while (current && m_count < m_list_capping_size) {
+ ++m_count;
+ current = current.next();
+ }
+ return m_count;
+}
+
+ValueObjectSP ForwardListFrontEnd::GetChildAtIndex(size_t idx) {
+ if (idx >= CalculateNumChildren())
+ return nullptr;
+
+ if (!m_head)
+ return nullptr;
+
+ if (HasLoop(idx + 1))
+ return nullptr;
+
+ ValueObjectSP current_sp = GetItem(idx);
+ if (!current_sp)
+ return nullptr;
+
+ current_sp = current_sp->GetChildAtIndex(1, true); // get the __value_ child
+ if (!current_sp)
+ return nullptr;
+
+ // we need to copy current_sp into a new object otherwise we will end up with
+ // all items named __value_
+ DataExtractor data;
+ Status error;
+ current_sp->GetData(data, error);
+ if (error.Fail())
+ return nullptr;
+
+ return CreateValueObjectFromData(llvm::formatv("[{0}]", idx).str(), data,
+ m_backend.GetExecutionContextRef(),
+ m_element_type);
+}
+
+static ValueObjectSP GetValueOfCompressedPair(ValueObject &pair) {
+ ValueObjectSP value = pair.GetChildMemberWithName(ConstString("__value_"), true);
+ if (! value) {
+ // pre-r300140 member name
+ value = pair.GetChildMemberWithName(ConstString("__first_"), true);
+ }
+ return value;
+}
+
+bool ForwardListFrontEnd::Update() {
+ AbstractListFrontEnd::Update();
+
+ Status err;
+ ValueObjectSP backend_addr(m_backend.AddressOf(err));
+ if (err.Fail() || !backend_addr)
+ return false;
+
+ ValueObjectSP impl_sp(
+ m_backend.GetChildMemberWithName(ConstString("__before_begin_"), true));
+ if (!impl_sp)
+ return false;
+ impl_sp = GetValueOfCompressedPair(*impl_sp);
+ if (!impl_sp)
+ return false;
+ m_head = impl_sp->GetChildMemberWithName(ConstString("__next_"), true).get();
+ return false;
+}
+
+ListFrontEnd::ListFrontEnd(lldb::ValueObjectSP valobj_sp)
+ : AbstractListFrontEnd(*valobj_sp), m_node_address(), m_tail(nullptr) {
+ if (valobj_sp)
+ Update();
+}
+
+size_t ListFrontEnd::CalculateNumChildren() {
if (m_count != UINT32_MAX)
return m_count;
if (!m_head || !m_tail || m_node_address == 0)
@@ -210,10 +339,9 @@ size_t lldb_private::formatters::LibcxxStdListSyntheticFrontEnd::
ValueObjectSP size_alloc(
m_backend.GetChildMemberWithName(ConstString("__size_alloc_"), true));
if (size_alloc) {
- ValueObjectSP first(
- size_alloc->GetChildMemberWithName(ConstString("__first_"), true));
- if (first) {
- m_count = first->GetValueAsUnsigned(UINT32_MAX);
+ ValueObjectSP value = GetValueOfCompressedPair(*size_alloc);
+ if (value) {
+ m_count = value->GetValueAsUnsigned(UINT32_MAX);
}
}
if (m_count != UINT32_MAX) {
@@ -239,9 +367,7 @@ size_t lldb_private::formatters::LibcxxStdListSyntheticFrontEnd::
}
}
-lldb::ValueObjectSP
-lldb_private::formatters::LibcxxStdListSyntheticFrontEnd::GetChildAtIndex(
- size_t idx) {
+lldb::ValueObjectSP ListFrontEnd::GetChildAtIndex(size_t idx) {
static ConstString g_value("__value_");
static ConstString g_next("__next_");
@@ -254,23 +380,10 @@ lldb_private::formatters::LibcxxStdListSyntheticFrontEnd::GetChildAtIndex(
if (HasLoop(idx + 1))
return lldb::ValueObjectSP();
- size_t actual_advance = idx;
-
- ListIterator current(m_head);
- if (idx > 0) {
- auto cached_iterator = m_iterators.find(idx - 1);
- if (cached_iterator != m_iterators.end()) {
- current = cached_iterator->second;
- actual_advance = 1;
- }
- }
-
- ValueObjectSP current_sp(current.advance(actual_advance));
+ ValueObjectSP current_sp = GetItem(idx);
if (!current_sp)
return lldb::ValueObjectSP();
- m_iterators[idx] = current;
-
current_sp = current_sp->GetChildAtIndex(1, true); // get the __value_ child
if (!current_sp)
return lldb::ValueObjectSP();
@@ -303,23 +416,13 @@ lldb_private::formatters::LibcxxStdListSyntheticFrontEnd::GetChildAtIndex(
m_element_type);
}
-bool lldb_private::formatters::LibcxxStdListSyntheticFrontEnd::Update() {
- m_iterators.clear();
- m_head = m_tail = nullptr;
+bool ListFrontEnd::Update() {
+ AbstractListFrontEnd::Update();
+ m_tail = nullptr;
m_node_address = 0;
- m_count = UINT32_MAX;
- m_loop_detected = 0;
- m_slow_runner.SetEntry(nullptr);
- m_fast_runner.SetEntry(nullptr);
Status err;
ValueObjectSP backend_addr(m_backend.AddressOf(err));
- m_list_capping_size = 0;
- if (m_backend.GetTargetSP())
- m_list_capping_size =
- m_backend.GetTargetSP()->GetMaximumNumberOfChildrenToDisplay();
- if (m_list_capping_size == 0)
- m_list_capping_size = 255;
if (err.Fail() || !backend_addr)
return false;
m_node_address = backend_addr->GetValueAsUnsigned(0);
@@ -329,31 +432,18 @@ bool lldb_private::formatters::LibcxxStdListSyntheticFrontEnd::Update() {
m_backend.GetChildMemberWithName(ConstString("__end_"), true));
if (!impl_sp)
return false;
- CompilerType list_type = m_backend.GetCompilerType();
- if (list_type.IsReferenceType())
- list_type = list_type.GetNonReferenceType();
-
- if (list_type.GetNumTemplateArguments() == 0)
- return false;
- lldb::TemplateArgumentKind kind;
- m_element_type = list_type.GetTemplateArgument(0, kind);
m_head = impl_sp->GetChildMemberWithName(ConstString("__next_"), true).get();
m_tail = impl_sp->GetChildMemberWithName(ConstString("__prev_"), true).get();
return false;
}
-bool lldb_private::formatters::LibcxxStdListSyntheticFrontEnd::
- MightHaveChildren() {
- return true;
-}
-
-size_t lldb_private::formatters::LibcxxStdListSyntheticFrontEnd::
- GetIndexOfChildWithName(const ConstString &name) {
- return ExtractIndexFromString(name.GetCString());
+SyntheticChildrenFrontEnd *formatters::LibcxxStdListSyntheticFrontEndCreator(
+ CXXSyntheticChildren *, lldb::ValueObjectSP valobj_sp) {
+ return (valobj_sp ? new ListFrontEnd(valobj_sp) : nullptr);
}
SyntheticChildrenFrontEnd *
-lldb_private::formatters::LibcxxStdListSyntheticFrontEndCreator(
+formatters::LibcxxStdForwardListSyntheticFrontEndCreator(
CXXSyntheticChildren *, lldb::ValueObjectSP valobj_sp) {
- return (valobj_sp ? new LibcxxStdListSyntheticFrontEnd(valobj_sp) : nullptr);
+ return valobj_sp ? new ForwardListFrontEnd(*valobj_sp) : nullptr;
}
diff --git a/source/Plugins/Language/CPlusPlus/LibCxxMap.cpp b/source/Plugins/Language/CPlusPlus/LibCxxMap.cpp
index b7215dbcbb485..be96a6d95bcd5 100644
--- a/source/Plugins/Language/CPlusPlus/LibCxxMap.cpp
+++ b/source/Plugins/Language/CPlusPlus/LibCxxMap.cpp
@@ -268,13 +268,12 @@ bool lldb_private::formatters::LibcxxStdMapSyntheticFrontEnd::GetDataType() {
m_element_type = deref->GetCompilerType();
return true;
}
- lldb::TemplateArgumentKind kind;
deref = m_backend.GetChildAtNamePath({g_tree_, g_pair3});
if (!deref)
return false;
- m_element_type =
- deref->GetCompilerType().GetTemplateArgument(1, kind).GetTemplateArgument(
- 1, kind);
+ m_element_type = deref->GetCompilerType()
+ .GetTypeTemplateArgument(1)
+ .GetTypeTemplateArgument(1);
if (m_element_type) {
std::string name;
uint64_t bit_offset_ptr;
@@ -285,7 +284,7 @@ bool lldb_private::formatters::LibcxxStdMapSyntheticFrontEnd::GetDataType() {
m_element_type = m_element_type.GetTypedefedType();
return m_element_type.IsValid();
} else {
- m_element_type = m_backend.GetCompilerType().GetTemplateArgument(0, kind);
+ m_element_type = m_backend.GetCompilerType().GetTypeTemplateArgument(0);
return m_element_type.IsValid();
}
}
diff --git a/source/Plugins/Language/CPlusPlus/LibCxxQueue.cpp b/source/Plugins/Language/CPlusPlus/LibCxxQueue.cpp
new file mode 100644
index 0000000000000..c4e0b66d4272e
--- /dev/null
+++ b/source/Plugins/Language/CPlusPlus/LibCxxQueue.cpp
@@ -0,0 +1,61 @@
+//===-- LibCxxQueue.cpp -----------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "LibCxx.h"
+#include "lldb/DataFormatters/FormattersHelpers.h"
+
+using namespace lldb;
+using namespace lldb_private;
+
+namespace {
+
+class QueueFrontEnd : public SyntheticChildrenFrontEnd {
+public:
+ QueueFrontEnd(ValueObject &valobj) : SyntheticChildrenFrontEnd(valobj) {
+ Update();
+ }
+
+ size_t GetIndexOfChildWithName(const ConstString &name) override {
+ return m_container_sp ? m_container_sp->GetIndexOfChildWithName(name)
+ : UINT32_MAX;
+ }
+
+ bool MightHaveChildren() override { return true; }
+ bool Update() override;
+
+ size_t CalculateNumChildren() override {
+ return m_container_sp ? m_container_sp->GetNumChildren() : 0;
+ }
+
+ ValueObjectSP GetChildAtIndex(size_t idx) override {
+ return m_container_sp ? m_container_sp->GetChildAtIndex(idx, true)
+ : nullptr;
+ }
+
+private:
+ ValueObjectSP m_container_sp;
+};
+} // namespace
+
+bool QueueFrontEnd::Update() {
+ m_container_sp.reset();
+ ValueObjectSP c_sp = m_backend.GetChildMemberWithName(ConstString("c"), true);
+ if (!c_sp)
+ return false;
+ m_container_sp = c_sp->GetSyntheticValue();
+ return false;
+}
+
+SyntheticChildrenFrontEnd *
+formatters::LibcxxQueueFrontEndCreator(CXXSyntheticChildren *,
+ lldb::ValueObjectSP valobj_sp) {
+ if (valobj_sp)
+ return new QueueFrontEnd(*valobj_sp);
+ return nullptr;
+}
diff --git a/source/Plugins/Language/CPlusPlus/LibCxxTuple.cpp b/source/Plugins/Language/CPlusPlus/LibCxxTuple.cpp
new file mode 100644
index 0000000000000..9b412a12f532f
--- /dev/null
+++ b/source/Plugins/Language/CPlusPlus/LibCxxTuple.cpp
@@ -0,0 +1,83 @@
+//===-- LibCxxTuple.cpp -----------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "LibCxx.h"
+#include "lldb/DataFormatters/FormattersHelpers.h"
+
+using namespace lldb;
+using namespace lldb_private;
+
+namespace {
+
+class TupleFrontEnd: public SyntheticChildrenFrontEnd {
+public:
+ TupleFrontEnd(ValueObject &valobj) : SyntheticChildrenFrontEnd(valobj) {
+ Update();
+ }
+
+ size_t GetIndexOfChildWithName(const ConstString &name) override {
+ return formatters::ExtractIndexFromString(name.GetCString());
+ }
+
+ bool MightHaveChildren() override { return true; }
+ bool Update() override;
+ size_t CalculateNumChildren() override { return m_elements.size(); }
+ ValueObjectSP GetChildAtIndex(size_t idx) override;
+
+private:
+ std::vector<ValueObjectSP> m_elements;
+ ValueObjectSP m_base_sp;
+};
+}
+
+bool TupleFrontEnd::Update() {
+ m_elements.clear();
+ m_base_sp = m_backend.GetChildMemberWithName(ConstString("__base_"), true);
+ if (! m_base_sp) {
+ // Pre r304382 name of the base element.
+ m_base_sp = m_backend.GetChildMemberWithName(ConstString("base_"), true);
+ }
+ if (! m_base_sp)
+ return false;
+ m_elements.assign(m_base_sp->GetCompilerType().GetNumDirectBaseClasses(),
+ ValueObjectSP());
+ return false;
+}
+
+ValueObjectSP TupleFrontEnd::GetChildAtIndex(size_t idx) {
+ if (idx >= m_elements.size())
+ return ValueObjectSP();
+ if (!m_base_sp)
+ return ValueObjectSP();
+ if (m_elements[idx])
+ return m_elements[idx];
+
+ CompilerType holder_type =
+ m_base_sp->GetCompilerType().GetDirectBaseClassAtIndex(idx, nullptr);
+ if (!holder_type)
+ return ValueObjectSP();
+ ValueObjectSP holder_sp = m_base_sp->GetChildAtIndex(idx, true);
+ if (!holder_sp)
+ return ValueObjectSP();
+
+ ValueObjectSP elem_sp = holder_sp->GetChildAtIndex(0, true);
+ if (elem_sp)
+ m_elements[idx] =
+ elem_sp->Clone(ConstString(llvm::formatv("[{0}]", idx).str()));
+
+ return m_elements[idx];
+}
+
+SyntheticChildrenFrontEnd *
+formatters::LibcxxTupleFrontEndCreator(CXXSyntheticChildren *,
+ lldb::ValueObjectSP valobj_sp) {
+ if (valobj_sp)
+ return new TupleFrontEnd(*valobj_sp);
+ return nullptr;
+}
diff --git a/source/Plugins/Language/CPlusPlus/LibCxxUnorderedMap.cpp b/source/Plugins/Language/CPlusPlus/LibCxxUnorderedMap.cpp
index 190b5f64381ea..0f1c2537d651e 100644
--- a/source/Plugins/Language/CPlusPlus/LibCxxUnorderedMap.cpp
+++ b/source/Plugins/Language/CPlusPlus/LibCxxUnorderedMap.cpp
@@ -121,11 +121,10 @@ lldb::ValueObjectSP lldb_private::formatters::
if (!first_sp)
return nullptr;
m_element_type = first_sp->GetCompilerType();
- lldb::TemplateArgumentKind kind;
- m_element_type = m_element_type.GetTemplateArgument(0, kind);
+ m_element_type = m_element_type.GetTypeTemplateArgument(0);
m_element_type = m_element_type.GetPointeeType();
m_node_type = m_element_type;
- m_element_type = m_element_type.GetTemplateArgument(0, kind);
+ m_element_type = m_element_type.GetTypeTemplateArgument(0);
std::string name;
m_element_type =
m_element_type.GetFieldAtIndex(0, name, nullptr, nullptr, nullptr);
diff --git a/source/Plugins/Language/CPlusPlus/LibCxxVector.cpp b/source/Plugins/Language/CPlusPlus/LibCxxVector.cpp
index 6f601c9f6ccbf..711130639cd2f 100644
--- a/source/Plugins/Language/CPlusPlus/LibCxxVector.cpp
+++ b/source/Plugins/Language/CPlusPlus/LibCxxVector.cpp
@@ -290,8 +290,7 @@ lldb_private::formatters::LibcxxStdVectorSyntheticFrontEndCreator(
CompilerType type = valobj_sp->GetCompilerType();
if (!type.IsValid() || type.GetNumTemplateArguments() == 0)
return nullptr;
- TemplateArgumentKind kind;
- CompilerType arg_type = type.GetTemplateArgument(0, kind);
+ CompilerType arg_type = type.GetTypeTemplateArgument(0);
if (arg_type.GetTypeName() == ConstString("bool"))
return new LibcxxVectorBoolSyntheticFrontEnd(valobj_sp);
return new LibcxxStdVectorSyntheticFrontEnd(valobj_sp);
diff --git a/source/Plugins/Language/CPlusPlus/LibStdcpp.cpp b/source/Plugins/Language/CPlusPlus/LibStdcpp.cpp
index e3018a1884be1..3e2b7159f8944 100644
--- a/source/Plugins/Language/CPlusPlus/LibStdcpp.cpp
+++ b/source/Plugins/Language/CPlusPlus/LibStdcpp.cpp
@@ -117,11 +117,8 @@ bool LibstdcppMapIteratorSyntheticFrontEnd::Update() {
CompilerType my_type(valobj_sp->GetCompilerType());
if (my_type.GetNumTemplateArguments() >= 1) {
- TemplateArgumentKind kind;
- CompilerType pair_type = my_type.GetTemplateArgument(0, kind);
- if (kind != eTemplateArgumentKindType &&
- kind != eTemplateArgumentKindTemplate &&
- kind != eTemplateArgumentKindTemplateExpansion)
+ CompilerType pair_type = my_type.GetTypeTemplateArgument(0);
+ if (!pair_type)
return false;
m_pair_type = pair_type;
} else
diff --git a/source/Plugins/Language/ObjC/CMakeLists.txt b/source/Plugins/Language/ObjC/CMakeLists.txt
index 7cc93c7b05580..95ace3a3633ab 100644
--- a/source/Plugins/Language/ObjC/CMakeLists.txt
+++ b/source/Plugins/Language/ObjC/CMakeLists.txt
@@ -1,3 +1,13 @@
+set(EXTRA_CXXFLAGS "")
+
+if (CXX_SUPPORTS_NO_GNU_ANONYMOUS_STRUCT)
+ set(EXTRA_CXXFLAGS ${EXTRA_CXXFLAGS} -Wno-gnu-anonymous-struct)
+endif ()
+
+if (CXX_SUPPORTS_NO_NESTED_ANON_TYPES)
+ set(EXTRA_CXXFLAGS ${EXTRA_CXXFLAGS} -Wno-nested-anon-types)
+endif ()
+
add_lldb_library(lldbPluginObjCLanguage PLUGIN
ObjCLanguage.cpp
CF.cpp
@@ -21,4 +31,6 @@ add_lldb_library(lldbPluginObjCLanguage PLUGIN
lldbTarget
lldbUtility
lldbPluginAppleObjCRuntime
+
+ EXTRA_CXXFLAGS ${EXTRA_CXXFLAGS}
)
diff --git a/source/Plugins/Language/ObjC/NSArray.cpp b/source/Plugins/Language/ObjC/NSArray.cpp
index 27cb9558c482d..f6d1592019511 100644
--- a/source/Plugins/Language/ObjC/NSArray.cpp
+++ b/source/Plugins/Language/ObjC/NSArray.cpp
@@ -48,11 +48,11 @@ NSArray_Additionals::GetAdditionalSynthetics() {
return g_map;
}
-class NSArrayMSyntheticFrontEnd : public SyntheticChildrenFrontEnd {
+class NSArrayMSyntheticFrontEndBase : public SyntheticChildrenFrontEnd {
public:
- NSArrayMSyntheticFrontEnd(lldb::ValueObjectSP valobj_sp);
+ NSArrayMSyntheticFrontEndBase(lldb::ValueObjectSP valobj_sp);
- ~NSArrayMSyntheticFrontEnd() override = default;
+ ~NSArrayMSyntheticFrontEndBase() override = default;
size_t CalculateNumChildren() override;
@@ -78,11 +78,12 @@ protected:
CompilerType m_id_type;
};
-class NSArrayMSyntheticFrontEnd_109 : public NSArrayMSyntheticFrontEnd {
+template <typename D32, typename D64>
+class GenericNSArrayMSyntheticFrontEnd : public NSArrayMSyntheticFrontEndBase {
public:
- NSArrayMSyntheticFrontEnd_109(lldb::ValueObjectSP valobj_sp);
+ GenericNSArrayMSyntheticFrontEnd(lldb::ValueObjectSP valobj_sp);
- ~NSArrayMSyntheticFrontEnd_109() override;
+ ~GenericNSArrayMSyntheticFrontEnd() override;
bool Update() override;
@@ -96,6 +97,11 @@ protected:
uint64_t GetSize() override;
private:
+ D32 *m_data_32;
+ D64 *m_data_64;
+};
+
+namespace Foundation109 {
struct DataDescriptor_32 {
uint32_t _used;
uint32_t _priv1 : 2;
@@ -105,7 +111,7 @@ private:
uint32_t _priv3;
uint32_t _data;
};
-
+
struct DataDescriptor_64 {
uint64_t _used;
uint64_t _priv1 : 2;
@@ -115,29 +121,12 @@ private:
uint32_t _priv3;
uint64_t _data;
};
-
- DataDescriptor_32 *m_data_32;
- DataDescriptor_64 *m_data_64;
-};
-
-class NSArrayMSyntheticFrontEnd_1010 : public NSArrayMSyntheticFrontEnd {
-public:
- NSArrayMSyntheticFrontEnd_1010(lldb::ValueObjectSP valobj_sp);
-
- ~NSArrayMSyntheticFrontEnd_1010() override;
-
- bool Update() override;
-
-protected:
- lldb::addr_t GetDataAddress() override;
-
- uint64_t GetUsedCount() override;
-
- uint64_t GetOffset() override;
-
- uint64_t GetSize() override;
-
-private:
+
+ using NSArrayMSyntheticFrontEnd =
+ GenericNSArrayMSyntheticFrontEnd<DataDescriptor_32, DataDescriptor_64>;
+}
+
+namespace Foundation1010 {
struct DataDescriptor_32 {
uint32_t _used;
uint32_t _offset;
@@ -146,7 +135,7 @@ private:
uint32_t _priv2;
uint32_t _data;
};
-
+
struct DataDescriptor_64 {
uint64_t _used;
uint64_t _offset;
@@ -155,76 +144,86 @@ private:
uint32_t _priv2;
uint64_t _data;
};
-
- DataDescriptor_32 *m_data_32;
- DataDescriptor_64 *m_data_64;
-};
-
-class NSArrayMSyntheticFrontEnd_1400 : public NSArrayMSyntheticFrontEnd {
-public:
- NSArrayMSyntheticFrontEnd_1400(lldb::ValueObjectSP valobj_sp);
-
- ~NSArrayMSyntheticFrontEnd_1400() override;
-
- bool Update() override;
-
-protected:
- lldb::addr_t GetDataAddress() override;
-
- uint64_t GetUsedCount() override;
-
- uint64_t GetOffset() override;
-
- uint64_t GetSize() override;
-
-private:
+
+ using NSArrayMSyntheticFrontEnd =
+ GenericNSArrayMSyntheticFrontEnd<DataDescriptor_32, DataDescriptor_64>;
+}
+
+namespace Foundation1428 {
struct DataDescriptor_32 {
- uint32_t used;
- uint32_t offset;
- uint32_t size;
- uint32_t list;
+ uint32_t _used;
+ uint32_t _offset;
+ uint32_t _size;
+ uint32_t _data;
};
-
+
struct DataDescriptor_64 {
- uint64_t used;
- uint64_t offset;
- uint64_t size;
- uint64_t list;
+ uint64_t _used;
+ uint64_t _offset;
+ uint64_t _size;
+ uint64_t _data;
};
+
+ using NSArrayMSyntheticFrontEnd =
+ GenericNSArrayMSyntheticFrontEnd<DataDescriptor_32, DataDescriptor_64>;
+}
+
+namespace Foundation1437 {
+ template <typename PtrType>
+ struct DataDescriptor {
+ PtrType _cow;
+ // __deque
+ PtrType _data;
+ uint32_t _offset;
+ uint32_t _size;
+ union {
+ PtrType _mutations;
+ struct {
+ uint32_t _muts;
+ uint32_t _used;
+ };
+ };
+ };
+
+ using NSArrayMSyntheticFrontEnd =
+ GenericNSArrayMSyntheticFrontEnd<
+ DataDescriptor<uint32_t>, DataDescriptor<uint64_t>>;
+
+ template <typename DD>
+ uint64_t
+ __NSArrayMSize_Impl(lldb_private::Process &process,
+ lldb::addr_t valobj_addr, Status &error) {
+ const lldb::addr_t start_of_descriptor =
+ valobj_addr + process.GetAddressByteSize();
+ DD descriptor = DD();
+ process.ReadMemory(start_of_descriptor, &descriptor,
+ sizeof(descriptor), error);
+ if (error.Fail()) {
+ return 0;
+ }
+ return descriptor._used;
+ }
+
+ uint64_t
+ __NSArrayMSize(lldb_private::Process &process, lldb::addr_t valobj_addr,
+ Status &error) {
+ if (process.GetAddressByteSize() == 4) {
+ return __NSArrayMSize_Impl<DataDescriptor<uint32_t>>(process, valobj_addr,
+ error);
+ } else {
+ return __NSArrayMSize_Impl<DataDescriptor<uint64_t>>(process, valobj_addr,
+ error);
+ }
+ }
- DataDescriptor_32 *m_data_32;
- DataDescriptor_64 *m_data_64;
-};
-
-class NSArrayISyntheticFrontEnd_1300 : public SyntheticChildrenFrontEnd {
-public:
- NSArrayISyntheticFrontEnd_1300(lldb::ValueObjectSP valobj_sp);
-
- ~NSArrayISyntheticFrontEnd_1300() override = default;
-
- size_t CalculateNumChildren() override;
-
- lldb::ValueObjectSP GetChildAtIndex(size_t idx) override;
-
- bool Update() override;
-
- bool MightHaveChildren() override;
-
- size_t GetIndexOfChildWithName(const ConstString &name) override;
-
-private:
- ExecutionContextRef m_exe_ctx_ref;
- uint8_t m_ptr_size;
- uint64_t m_items;
- lldb::addr_t m_data_ptr;
- CompilerType m_id_type;
-};
+}
-class NSArrayISyntheticFrontEnd_1400 : public SyntheticChildrenFrontEnd {
+template <typename D32, typename D64, bool Inline>
+class GenericNSArrayISyntheticFrontEnd : public SyntheticChildrenFrontEnd {
public:
- NSArrayISyntheticFrontEnd_1400(lldb::ValueObjectSP valobj_sp);
+ GenericNSArrayISyntheticFrontEnd(lldb::ValueObjectSP valobj_sp);
- ~NSArrayISyntheticFrontEnd_1400() override;
+ ~GenericNSArrayISyntheticFrontEnd() override;
size_t CalculateNumChildren() override;
@@ -239,25 +238,58 @@ public:
private:
ExecutionContextRef m_exe_ctx_ref;
uint8_t m_ptr_size;
-
- struct DataDescriptor_32 {
- uint32_t used;
- uint32_t offset;
- uint32_t size;
- uint32_t list;
- };
-
- struct DataDescriptor_64 {
- uint64_t used;
- uint64_t offset;
- uint64_t size;
- uint64_t list;
- };
-
- DataDescriptor_32 *m_data_32;
- DataDescriptor_64 *m_data_64;
+
+ D32 *m_data_32;
+ D64 *m_data_64;
CompilerType m_id_type;
};
+
+namespace Foundation1300 {
+ struct IDD32 {
+ uint32_t used;
+ uint32_t list;
+ };
+
+ struct IDD64 {
+ uint64_t used;
+ uint64_t list;
+ };
+
+ using NSArrayISyntheticFrontEnd =
+ GenericNSArrayISyntheticFrontEnd<IDD32, IDD64, true>;
+}
+
+namespace Foundation1430 {
+ using NSArrayISyntheticFrontEnd =
+ Foundation1428::NSArrayMSyntheticFrontEnd;
+}
+
+namespace Foundation1436 {
+ struct IDD32 {
+ uint32_t used;
+ uint32_t list; // in Inline cases, this is the first element
+ };
+
+ struct IDD64 {
+ uint64_t used;
+ uint64_t list; // in Inline cases, this is the first element
+ };
+
+ using NSArrayI_TransferSyntheticFrontEnd =
+ GenericNSArrayISyntheticFrontEnd<IDD32, IDD64, false>;
+
+ using NSArrayISyntheticFrontEnd =
+ GenericNSArrayISyntheticFrontEnd<IDD32, IDD64, true>;
+
+ using NSFrozenArrayMSyntheticFrontEnd =
+ Foundation1437::NSArrayMSyntheticFrontEnd;
+
+ uint64_t
+ __NSFrozenArrayMSize(lldb_private::Process &process, lldb::addr_t valobj_addr,
+ Status &error) {
+ return Foundation1437::__NSArrayMSize(process, valobj_addr, error);
+ }
+}
class NSArray0SyntheticFrontEnd : public SyntheticChildrenFrontEnd {
public:
@@ -329,6 +361,8 @@ bool lldb_private::formatters::NSArraySummaryProvider(
static const ConstString g_NSArrayI("__NSArrayI");
static const ConstString g_NSArrayM("__NSArrayM");
+ static const ConstString g_NSArrayI_Transfer("__NSArrayI_Transfer");
+ static const ConstString g_NSFrozenArrayM("__NSFrozenArrayM");
static const ConstString g_NSArray0("__NSArray0");
static const ConstString g_NSArray1("__NSSingleObjectArrayI");
static const ConstString g_NSArrayCF("__NSCFArray");
@@ -345,11 +379,28 @@ bool lldb_private::formatters::NSArraySummaryProvider(
if (error.Fail())
return false;
} else if (class_name == g_NSArrayM) {
+ AppleObjCRuntime *apple_runtime =
+ llvm::dyn_cast_or_null<AppleObjCRuntime>(runtime);
+ Status error;
+ if (apple_runtime && apple_runtime->GetFoundationVersion() >= 1437) {
+ value = Foundation1437::__NSArrayMSize(*process_sp, valobj_addr, error);
+ } else {
+ value = process_sp->ReadUnsignedIntegerFromMemory(valobj_addr + ptr_size,
+ ptr_size, 0, error);
+ }
+ if (error.Fail())
+ return false;
+ } else if (class_name == g_NSArrayI_Transfer) {
Status error;
value = process_sp->ReadUnsignedIntegerFromMemory(valobj_addr + ptr_size,
ptr_size, 0, error);
if (error.Fail())
return false;
+ } else if (class_name == g_NSFrozenArrayM) {
+ Status error;
+ value = Foundation1436::__NSFrozenArrayMSize(*process_sp, valobj_addr, error);
+ if (error.Fail())
+ return false;
} else if (class_name == g_NSArrayMLegacy) {
Status error;
value = process_sp->ReadUnsignedIntegerFromMemory(valobj_addr + ptr_size,
@@ -395,7 +446,7 @@ bool lldb_private::formatters::NSArraySummaryProvider(
return true;
}
-lldb_private::formatters::NSArrayMSyntheticFrontEnd::NSArrayMSyntheticFrontEnd(
+lldb_private::formatters::NSArrayMSyntheticFrontEndBase::NSArrayMSyntheticFrontEndBase(
lldb::ValueObjectSP valobj_sp)
: SyntheticChildrenFrontEnd(*valobj_sp), m_exe_ctx_ref(), m_ptr_size(8),
m_id_type() {
@@ -411,28 +462,20 @@ lldb_private::formatters::NSArrayMSyntheticFrontEnd::NSArrayMSyntheticFrontEnd(
}
}
-lldb_private::formatters::NSArrayMSyntheticFrontEnd_109::
- NSArrayMSyntheticFrontEnd_109(lldb::ValueObjectSP valobj_sp)
- : NSArrayMSyntheticFrontEnd(valobj_sp), m_data_32(nullptr),
- m_data_64(nullptr) {}
-
-lldb_private::formatters::NSArrayMSyntheticFrontEnd_1010::
- NSArrayMSyntheticFrontEnd_1010(lldb::ValueObjectSP valobj_sp)
- : NSArrayMSyntheticFrontEnd(valobj_sp), m_data_32(nullptr),
- m_data_64(nullptr) {}
-
-lldb_private::formatters::NSArrayMSyntheticFrontEnd_1400::
- NSArrayMSyntheticFrontEnd_1400(lldb::ValueObjectSP valobj_sp)
- : NSArrayMSyntheticFrontEnd(valobj_sp), m_data_32(nullptr),
+template <typename D32, typename D64>
+lldb_private::formatters::
+ GenericNSArrayMSyntheticFrontEnd<D32, D64>::
+ GenericNSArrayMSyntheticFrontEnd(lldb::ValueObjectSP valobj_sp)
+ : NSArrayMSyntheticFrontEndBase(valobj_sp), m_data_32(nullptr),
m_data_64(nullptr) {}
size_t
-lldb_private::formatters::NSArrayMSyntheticFrontEnd::CalculateNumChildren() {
+lldb_private::formatters::NSArrayMSyntheticFrontEndBase::CalculateNumChildren() {
return GetUsedCount();
}
lldb::ValueObjectSP
-lldb_private::formatters::NSArrayMSyntheticFrontEnd::GetChildAtIndex(
+lldb_private::formatters::NSArrayMSyntheticFrontEndBase::GetChildAtIndex(
size_t idx) {
if (idx >= CalculateNumChildren())
return lldb::ValueObjectSP();
@@ -448,69 +491,10 @@ lldb_private::formatters::NSArrayMSyntheticFrontEnd::GetChildAtIndex(
m_exe_ctx_ref, m_id_type);
}
-bool lldb_private::formatters::NSArrayMSyntheticFrontEnd_109::Update() {
- ValueObjectSP valobj_sp = m_backend.GetSP();
- m_ptr_size = 0;
- delete m_data_32;
- m_data_32 = nullptr;
- delete m_data_64;
- m_data_64 = nullptr;
- if (!valobj_sp)
- return false;
- m_exe_ctx_ref = valobj_sp->GetExecutionContextRef();
- Status error;
- error.Clear();
- lldb::ProcessSP process_sp(valobj_sp->GetProcessSP());
- if (!process_sp)
- return false;
- m_ptr_size = process_sp->GetAddressByteSize();
- uint64_t data_location = valobj_sp->GetValueAsUnsigned(0) + m_ptr_size;
- if (m_ptr_size == 4) {
- m_data_32 = new DataDescriptor_32();
- process_sp->ReadMemory(data_location, m_data_32, sizeof(DataDescriptor_32),
- error);
- } else {
- m_data_64 = new DataDescriptor_64();
- process_sp->ReadMemory(data_location, m_data_64, sizeof(DataDescriptor_64),
- error);
- }
- if (error.Fail())
- return false;
- return false;
-}
-
-bool lldb_private::formatters::NSArrayMSyntheticFrontEnd_1010::Update() {
- ValueObjectSP valobj_sp = m_backend.GetSP();
- m_ptr_size = 0;
- delete m_data_32;
- m_data_32 = nullptr;
- delete m_data_64;
- m_data_64 = nullptr;
- if (!valobj_sp)
- return false;
- m_exe_ctx_ref = valobj_sp->GetExecutionContextRef();
- Status error;
- error.Clear();
- lldb::ProcessSP process_sp(valobj_sp->GetProcessSP());
- if (!process_sp)
- return false;
- m_ptr_size = process_sp->GetAddressByteSize();
- uint64_t data_location = valobj_sp->GetValueAsUnsigned(0) + m_ptr_size;
- if (m_ptr_size == 4) {
- m_data_32 = new DataDescriptor_32();
- process_sp->ReadMemory(data_location, m_data_32, sizeof(DataDescriptor_32),
- error);
- } else {
- m_data_64 = new DataDescriptor_64();
- process_sp->ReadMemory(data_location, m_data_64, sizeof(DataDescriptor_64),
- error);
- }
- if (error.Fail())
- return false;
- return false;
-}
-
-bool lldb_private::formatters::NSArrayMSyntheticFrontEnd_1400::Update() {
+template <typename D32, typename D64>
+bool
+lldb_private::formatters::
+ GenericNSArrayMSyntheticFrontEnd<D32, D64>::Update() {
ValueObjectSP valobj_sp = m_backend.GetSP();
m_ptr_size = 0;
delete m_data_32;
@@ -528,12 +512,12 @@ bool lldb_private::formatters::NSArrayMSyntheticFrontEnd_1400::Update() {
m_ptr_size = process_sp->GetAddressByteSize();
uint64_t data_location = valobj_sp->GetValueAsUnsigned(0) + m_ptr_size;
if (m_ptr_size == 4) {
- m_data_32 = new DataDescriptor_32();
- process_sp->ReadMemory(data_location, m_data_32, sizeof(DataDescriptor_32),
+ m_data_32 = new D32();
+ process_sp->ReadMemory(data_location, m_data_32, sizeof(D32),
error);
} else {
- m_data_64 = new DataDescriptor_64();
- process_sp->ReadMemory(data_location, m_data_64, sizeof(DataDescriptor_64),
+ m_data_64 = new D64();
+ process_sp->ReadMemory(data_location, m_data_64, sizeof(D64),
error);
}
if (error.Fail())
@@ -541,12 +525,13 @@ bool lldb_private::formatters::NSArrayMSyntheticFrontEnd_1400::Update() {
return false;
}
-bool lldb_private::formatters::NSArrayMSyntheticFrontEnd::MightHaveChildren() {
+bool
+lldb_private::formatters::NSArrayMSyntheticFrontEndBase::MightHaveChildren() {
return true;
}
size_t
-lldb_private::formatters::NSArrayMSyntheticFrontEnd::GetIndexOfChildWithName(
+lldb_private::formatters::NSArrayMSyntheticFrontEndBase::GetIndexOfChildWithName(
const ConstString &name) {
const char *item_name = name.GetCString();
uint32_t idx = ExtractIndexFromString(item_name);
@@ -555,187 +540,59 @@ lldb_private::formatters::NSArrayMSyntheticFrontEnd::GetIndexOfChildWithName(
return idx;
}
-lldb_private::formatters::NSArrayMSyntheticFrontEnd_109::
- ~NSArrayMSyntheticFrontEnd_109() {
+template <typename D32, typename D64>
+lldb_private::formatters::
+ GenericNSArrayMSyntheticFrontEnd<D32, D64>::
+ ~GenericNSArrayMSyntheticFrontEnd() {
delete m_data_32;
m_data_32 = nullptr;
delete m_data_64;
m_data_64 = nullptr;
}
+template <typename D32, typename D64>
lldb::addr_t
-lldb_private::formatters::NSArrayMSyntheticFrontEnd_109::GetDataAddress() {
+lldb_private::formatters::
+ GenericNSArrayMSyntheticFrontEnd<D32, D64>::
+ GenericNSArrayMSyntheticFrontEnd::GetDataAddress() {
if (!m_data_32 && !m_data_64)
return LLDB_INVALID_ADDRESS;
return m_data_32 ? m_data_32->_data : m_data_64->_data;
}
+template <typename D32, typename D64>
uint64_t
-lldb_private::formatters::NSArrayMSyntheticFrontEnd_109::GetUsedCount() {
+lldb_private::formatters::
+ GenericNSArrayMSyntheticFrontEnd<D32, D64>::
+ GenericNSArrayMSyntheticFrontEnd::GetUsedCount() {
if (!m_data_32 && !m_data_64)
return 0;
return m_data_32 ? m_data_32->_used : m_data_64->_used;
}
-uint64_t lldb_private::formatters::NSArrayMSyntheticFrontEnd_109::GetOffset() {
- if (!m_data_32 && !m_data_64)
- return 0;
- return m_data_32 ? m_data_32->_offset : m_data_64->_offset;
-}
-
-uint64_t lldb_private::formatters::NSArrayMSyntheticFrontEnd_109::GetSize() {
- if (!m_data_32 && !m_data_64)
- return 0;
- return m_data_32 ? m_data_32->_size : m_data_64->_size;
-}
-
-lldb_private::formatters::NSArrayMSyntheticFrontEnd_1010::
- ~NSArrayMSyntheticFrontEnd_1010() {
- delete m_data_32;
- m_data_32 = nullptr;
- delete m_data_64;
- m_data_64 = nullptr;
-}
-
-lldb::addr_t
-lldb_private::formatters::NSArrayMSyntheticFrontEnd_1010::GetDataAddress() {
- if (!m_data_32 && !m_data_64)
- return LLDB_INVALID_ADDRESS;
- return m_data_32 ? m_data_32->_data : m_data_64->_data;
-}
-
+template <typename D32, typename D64>
uint64_t
-lldb_private::formatters::NSArrayMSyntheticFrontEnd_1010::GetUsedCount() {
- if (!m_data_32 && !m_data_64)
- return 0;
- return m_data_32 ? m_data_32->_used : m_data_64->_used;
-}
-
-uint64_t lldb_private::formatters::NSArrayMSyntheticFrontEnd_1010::GetOffset() {
+lldb_private::formatters::
+ GenericNSArrayMSyntheticFrontEnd<D32, D64>::
+ GenericNSArrayMSyntheticFrontEnd::GetOffset() {
if (!m_data_32 && !m_data_64)
return 0;
return m_data_32 ? m_data_32->_offset : m_data_64->_offset;
}
-uint64_t lldb_private::formatters::NSArrayMSyntheticFrontEnd_1010::GetSize() {
- if (!m_data_32 && !m_data_64)
- return 0;
- return m_data_32 ? m_data_32->_size : m_data_64->_size;
-}
-
-lldb_private::formatters::NSArrayMSyntheticFrontEnd_1400::
- ~NSArrayMSyntheticFrontEnd_1400() {
- delete m_data_32;
- m_data_32 = nullptr;
- delete m_data_64;
- m_data_64 = nullptr;
-}
-
-lldb::addr_t
-lldb_private::formatters::NSArrayMSyntheticFrontEnd_1400::GetDataAddress() {
- if (!m_data_32 && !m_data_64)
- return LLDB_INVALID_ADDRESS;
- return m_data_32 ? m_data_32->list : m_data_64->list;
-}
-
+template <typename D32, typename D64>
uint64_t
-lldb_private::formatters::NSArrayMSyntheticFrontEnd_1400::GetUsedCount() {
+lldb_private::formatters::
+ GenericNSArrayMSyntheticFrontEnd<D32, D64>::
+ GenericNSArrayMSyntheticFrontEnd::GetSize() {
if (!m_data_32 && !m_data_64)
return 0;
- return m_data_32 ? m_data_32->used : m_data_64->used;
-}
-
-uint64_t lldb_private::formatters::NSArrayMSyntheticFrontEnd_1400::GetOffset() {
- if (!m_data_32 && !m_data_64)
- return 0;
- return m_data_32 ? m_data_32->offset : m_data_64->offset;
-}
-
-uint64_t lldb_private::formatters::NSArrayMSyntheticFrontEnd_1400::GetSize() {
- if (!m_data_32 && !m_data_64)
- return 0;
- return m_data_32 ? m_data_32->size : m_data_64->size;
-}
-
-
-lldb_private::formatters::NSArrayISyntheticFrontEnd_1300::NSArrayISyntheticFrontEnd_1300(
- lldb::ValueObjectSP valobj_sp)
- : SyntheticChildrenFrontEnd(*valobj_sp), m_exe_ctx_ref(), m_ptr_size(8),
- m_items(0), m_data_ptr(0) {
- if (valobj_sp) {
- CompilerType type = valobj_sp->GetCompilerType();
- if (type) {
- ClangASTContext *ast = valobj_sp->GetExecutionContextRef()
- .GetTargetSP()
- ->GetScratchClangASTContext();
- if (ast)
- m_id_type = CompilerType(ast->getASTContext(),
- ast->getASTContext()->ObjCBuiltinIdTy);
- }
- }
-}
-
-size_t
-lldb_private::formatters::NSArrayISyntheticFrontEnd_1300::GetIndexOfChildWithName(
- const ConstString &name) {
- const char *item_name = name.GetCString();
- uint32_t idx = ExtractIndexFromString(item_name);
- if (idx < UINT32_MAX && idx >= CalculateNumChildren())
- return UINT32_MAX;
- return idx;
-}
-
-size_t
-lldb_private::formatters::NSArrayISyntheticFrontEnd_1300::CalculateNumChildren() {
- return m_items;
-}
-
-bool lldb_private::formatters::NSArrayISyntheticFrontEnd_1300::Update() {
- m_ptr_size = 0;
- m_items = 0;
- m_data_ptr = 0;
- ValueObjectSP valobj_sp = m_backend.GetSP();
- if (!valobj_sp)
- return false;
- m_exe_ctx_ref = valobj_sp->GetExecutionContextRef();
- Status error;
- error.Clear();
- lldb::ProcessSP process_sp(valobj_sp->GetProcessSP());
- if (!process_sp)
- return false;
- m_ptr_size = process_sp->GetAddressByteSize();
- uint64_t data_location = valobj_sp->GetValueAsUnsigned(0) + m_ptr_size;
- m_items = process_sp->ReadPointerFromMemory(data_location, error);
- if (error.Fail())
- return false;
- m_data_ptr = data_location + m_ptr_size;
- return false;
-}
-
-bool lldb_private::formatters::NSArrayISyntheticFrontEnd_1300::MightHaveChildren() {
- return true;
-}
-
-lldb::ValueObjectSP
-lldb_private::formatters::NSArrayISyntheticFrontEnd_1300::GetChildAtIndex(
- size_t idx) {
- if (idx >= CalculateNumChildren())
- return lldb::ValueObjectSP();
- lldb::addr_t object_at_idx = m_data_ptr;
- object_at_idx += (idx * m_ptr_size);
- ProcessSP process_sp = m_exe_ctx_ref.GetProcessSP();
- if (!process_sp)
- return lldb::ValueObjectSP();
- Status error;
- if (error.Fail())
- return lldb::ValueObjectSP();
- StreamString idx_name;
- idx_name.Printf("[%" PRIu64 "]", (uint64_t)idx);
- return CreateValueObjectFromAddress(idx_name.GetString(), object_at_idx,
- m_exe_ctx_ref, m_id_type);
+ return m_data_32 ? m_data_32->_size : m_data_64->_size;
}
-lldb_private::formatters::NSArrayISyntheticFrontEnd_1400::NSArrayISyntheticFrontEnd_1400(
+template <typename D32, typename D64, bool Inline>
+lldb_private::formatters::GenericNSArrayISyntheticFrontEnd<D32, D64, Inline>::
+ GenericNSArrayISyntheticFrontEnd(
lldb::ValueObjectSP valobj_sp)
: SyntheticChildrenFrontEnd(*valobj_sp), m_exe_ctx_ref(), m_ptr_size(8),
m_data_32(nullptr), m_data_64(nullptr) {
@@ -752,16 +609,19 @@ lldb_private::formatters::NSArrayISyntheticFrontEnd_1400::NSArrayISyntheticFront
}
}
-lldb_private::formatters::NSArrayISyntheticFrontEnd_1400::~NSArrayISyntheticFrontEnd_1400() {
+template <typename D32, typename D64, bool Inline>
+lldb_private::formatters::GenericNSArrayISyntheticFrontEnd<D32, D64, Inline>::
+ ~GenericNSArrayISyntheticFrontEnd() {
delete m_data_32;
m_data_32 = nullptr;
delete m_data_64;
m_data_64 = nullptr;
}
+template <typename D32, typename D64, bool Inline>
size_t
-lldb_private::formatters::NSArrayISyntheticFrontEnd_1400::GetIndexOfChildWithName(
- const ConstString &name) {
+lldb_private::formatters::GenericNSArrayISyntheticFrontEnd<D32, D64, Inline>::
+ GetIndexOfChildWithName(const ConstString &name) {
const char *item_name = name.GetCString();
uint32_t idx = ExtractIndexFromString(item_name);
if (idx < UINT32_MAX && idx >= CalculateNumChildren())
@@ -769,12 +629,17 @@ lldb_private::formatters::NSArrayISyntheticFrontEnd_1400::GetIndexOfChildWithNam
return idx;
}
+template <typename D32, typename D64, bool Inline>
size_t
-lldb_private::formatters::NSArrayISyntheticFrontEnd_1400::CalculateNumChildren() {
+lldb_private::formatters::GenericNSArrayISyntheticFrontEnd<D32, D64, Inline>::
+ CalculateNumChildren() {
return m_data_32 ? m_data_32->used : m_data_64->used;
}
-bool lldb_private::formatters::NSArrayISyntheticFrontEnd_1400::Update() {
+template <typename D32, typename D64, bool Inline>
+bool
+lldb_private::formatters::GenericNSArrayISyntheticFrontEnd<D32, D64, Inline>::
+ Update() {
ValueObjectSP valobj_sp = m_backend.GetSP();
m_ptr_size = 0;
delete m_data_32;
@@ -792,12 +657,12 @@ bool lldb_private::formatters::NSArrayISyntheticFrontEnd_1400::Update() {
m_ptr_size = process_sp->GetAddressByteSize();
uint64_t data_location = valobj_sp->GetValueAsUnsigned(0) + m_ptr_size;
if (m_ptr_size == 4) {
- m_data_32 = new DataDescriptor_32();
- process_sp->ReadMemory(data_location, m_data_32, sizeof(DataDescriptor_32),
+ m_data_32 = new D32();
+ process_sp->ReadMemory(data_location, m_data_32, sizeof(D32),
error);
} else {
- m_data_64 = new DataDescriptor_64();
- process_sp->ReadMemory(data_location, m_data_64, sizeof(DataDescriptor_64),
+ m_data_64 = new D64();
+ process_sp->ReadMemory(data_location, m_data_64, sizeof(D64),
error);
}
if (error.Fail())
@@ -805,17 +670,29 @@ bool lldb_private::formatters::NSArrayISyntheticFrontEnd_1400::Update() {
return false;
}
-bool lldb_private::formatters::NSArrayISyntheticFrontEnd_1400::MightHaveChildren() {
+template <typename D32, typename D64, bool Inline>
+bool
+lldb_private::formatters::GenericNSArrayISyntheticFrontEnd<D32, D64, Inline>::
+ MightHaveChildren() {
return true;
}
+template <typename D32, typename D64, bool Inline>
lldb::ValueObjectSP
-lldb_private::formatters::NSArrayISyntheticFrontEnd_1400::GetChildAtIndex(
- size_t idx) {
+lldb_private::formatters::GenericNSArrayISyntheticFrontEnd<D32, D64, Inline>::
+ GetChildAtIndex(size_t idx) {
if (idx >= CalculateNumChildren())
return lldb::ValueObjectSP();
- lldb::addr_t object_at_idx = m_data_32 ? m_data_32->list : m_data_64->list;
+ lldb::addr_t object_at_idx;
+ if (Inline) {
+ object_at_idx = m_backend.GetSP()->GetValueAsUnsigned(0) + m_ptr_size;
+ object_at_idx += m_ptr_size == 4 ? sizeof(D32) : sizeof(D64); // skip the data header
+ object_at_idx -= m_ptr_size; // we treat the last entry in the data header as the first pointer
+ } else {
+ object_at_idx = m_data_32 ? m_data_32->list : m_data_64->list;
+ }
object_at_idx += (idx * m_ptr_size);
+
ProcessSP process_sp = m_exe_ctx_ref.GetProcessSP();
if (!process_sp)
return lldb::ValueObjectSP();
@@ -933,6 +810,8 @@ lldb_private::formatters::NSArraySyntheticFrontEndCreator(
ConstString class_name(descriptor->GetClassName());
static const ConstString g_NSArrayI("__NSArrayI");
+ static const ConstString g_NSArrayI_Transfer("__NSArrayI_Transfer");
+ static const ConstString g_NSFrozenArrayM("__NSFrozenArrayM");
static const ConstString g_NSArrayM("__NSArrayM");
static const ConstString g_NSArray0("__NSArray0");
static const ConstString g_NSArray1("__NSSingleObjectArrayI");
@@ -943,21 +822,30 @@ lldb_private::formatters::NSArraySyntheticFrontEndCreator(
return nullptr;
if (class_name == g_NSArrayI) {
- if (runtime->GetFoundationVersion() >= 1400)
- return (new NSArrayISyntheticFrontEnd_1400(valobj_sp));
- else
- return (new NSArrayISyntheticFrontEnd_1300(valobj_sp));
+ if (runtime->GetFoundationVersion() >= 1436)
+ return (new Foundation1436::NSArrayISyntheticFrontEnd(valobj_sp));
+ if (runtime->GetFoundationVersion() >= 1430)
+ return (new Foundation1430::NSArrayISyntheticFrontEnd(valobj_sp));
+ else
+ return (new Foundation1300::NSArrayISyntheticFrontEnd(valobj_sp));
+ } else if (class_name == g_NSArrayI_Transfer) {
+ return (new Foundation1436::NSArrayI_TransferSyntheticFrontEnd(valobj_sp));
+ } else if (class_name == g_NSArray0) {
+ } else if (class_name == g_NSFrozenArrayM) {
+ return (new Foundation1436::NSFrozenArrayMSyntheticFrontEnd(valobj_sp));
} else if (class_name == g_NSArray0) {
return (new NSArray0SyntheticFrontEnd(valobj_sp));
} else if (class_name == g_NSArray1) {
return (new NSArray1SyntheticFrontEnd(valobj_sp));
} else if (class_name == g_NSArrayM) {
- if (runtime->GetFoundationVersion() >= 1400)
- return (new NSArrayMSyntheticFrontEnd_1400(valobj_sp));
+ if (runtime->GetFoundationVersion() >= 1437)
+ return (new Foundation1437::NSArrayMSyntheticFrontEnd(valobj_sp));
+ if (runtime->GetFoundationVersion() >= 1428)
+ return (new Foundation1428::NSArrayMSyntheticFrontEnd(valobj_sp));
if (runtime->GetFoundationVersion() >= 1100)
- return (new NSArrayMSyntheticFrontEnd_1010(valobj_sp));
+ return (new Foundation1010::NSArrayMSyntheticFrontEnd(valobj_sp));
else
- return (new NSArrayMSyntheticFrontEnd_109(valobj_sp));
+ return (new Foundation109::NSArrayMSyntheticFrontEnd(valobj_sp));
} else {
auto &map(NSArray_Additionals::GetAdditionalSynthetics());
auto iter = map.find(class_name), end = map.end();
diff --git a/source/Plugins/Language/ObjC/NSDictionary.cpp b/source/Plugins/Language/ObjC/NSDictionary.cpp
index 50febbe397583..c564aa1a85715 100644
--- a/source/Plugins/Language/ObjC/NSDictionary.cpp
+++ b/source/Plugins/Language/ObjC/NSDictionary.cpp
@@ -165,11 +165,12 @@ private:
ValueObjectSP m_pair;
};
-class NSDictionaryMSyntheticFrontEnd : public SyntheticChildrenFrontEnd {
+template <typename D32, typename D64>
+class GenericNSDictionaryMSyntheticFrontEnd : public SyntheticChildrenFrontEnd {
public:
- NSDictionaryMSyntheticFrontEnd(lldb::ValueObjectSP valobj_sp);
+ GenericNSDictionaryMSyntheticFrontEnd(lldb::ValueObjectSP valobj_sp);
- ~NSDictionaryMSyntheticFrontEnd() override;
+ ~GenericNSDictionaryMSyntheticFrontEnd() override;
size_t CalculateNumChildren() override;
@@ -182,20 +183,6 @@ public:
size_t GetIndexOfChildWithName(const ConstString &name) override;
private:
- struct DataDescriptor_32 {
- uint32_t used : 26;
- uint32_t kvo : 1;
- uint32_t size;
- uint32_t buffer;
- };
-
- struct DataDescriptor_64 {
- uint64_t used : 58;
- uint32_t kvo : 1;
- uint64_t size;
- uint64_t buffer;
- };
-
struct DictionaryItemDescriptor {
lldb::addr_t key_ptr;
lldb::addr_t val_ptr;
@@ -205,61 +192,169 @@ private:
ExecutionContextRef m_exe_ctx_ref;
uint8_t m_ptr_size;
lldb::ByteOrder m_order;
- DataDescriptor_32 *m_data_32;
- DataDescriptor_64 *m_data_64;
+ D32 *m_data_32;
+ D64 *m_data_64;
CompilerType m_pair_type;
std::vector<DictionaryItemDescriptor> m_children;
};
-
-class NSDictionaryMLegacySyntheticFrontEnd : public SyntheticChildrenFrontEnd {
-public:
- NSDictionaryMLegacySyntheticFrontEnd(lldb::ValueObjectSP valobj_sp);
-
- ~NSDictionaryMLegacySyntheticFrontEnd() override;
-
- size_t CalculateNumChildren() override;
-
- lldb::ValueObjectSP GetChildAtIndex(size_t idx) override;
-
- bool Update() override;
-
- bool MightHaveChildren() override;
-
- size_t GetIndexOfChildWithName(const ConstString &name) override;
-
-private:
+
+namespace Foundation1100 {
+ class NSDictionaryMSyntheticFrontEnd : public SyntheticChildrenFrontEnd {
+ public:
+ NSDictionaryMSyntheticFrontEnd(lldb::ValueObjectSP valobj_sp);
+
+ ~NSDictionaryMSyntheticFrontEnd() override;
+
+ size_t CalculateNumChildren() override;
+
+ lldb::ValueObjectSP GetChildAtIndex(size_t idx) override;
+
+ bool Update() override;
+
+ bool MightHaveChildren() override;
+
+ size_t GetIndexOfChildWithName(const ConstString &name) override;
+
+ private:
+ struct DataDescriptor_32 {
+ uint32_t _used : 26;
+ uint32_t _kvo : 1;
+ uint32_t _size;
+ uint32_t _mutations;
+ uint32_t _objs_addr;
+ uint32_t _keys_addr;
+ };
+
+ struct DataDescriptor_64 {
+ uint64_t _used : 58;
+ uint32_t _kvo : 1;
+ uint64_t _size;
+ uint64_t _mutations;
+ uint64_t _objs_addr;
+ uint64_t _keys_addr;
+ };
+
+ struct DictionaryItemDescriptor {
+ lldb::addr_t key_ptr;
+ lldb::addr_t val_ptr;
+ lldb::ValueObjectSP valobj_sp;
+ };
+
+ ExecutionContextRef m_exe_ctx_ref;
+ uint8_t m_ptr_size;
+ lldb::ByteOrder m_order;
+ DataDescriptor_32 *m_data_32;
+ DataDescriptor_64 *m_data_64;
+ CompilerType m_pair_type;
+ std::vector<DictionaryItemDescriptor> m_children;
+ };
+}
+
+namespace Foundation1428 {
struct DataDescriptor_32 {
uint32_t _used : 26;
uint32_t _kvo : 1;
uint32_t _size;
- uint32_t _mutations;
- uint32_t _objs_addr;
- uint32_t _keys_addr;
+ uint32_t _buffer;
+ uint64_t GetSize() { return _size; }
};
-
+
struct DataDescriptor_64 {
uint64_t _used : 58;
uint32_t _kvo : 1;
uint64_t _size;
- uint64_t _mutations;
- uint64_t _objs_addr;
- uint64_t _keys_addr;
+ uint64_t _buffer;
+ uint64_t GetSize() { return _size; }
};
-
- struct DictionaryItemDescriptor {
- lldb::addr_t key_ptr;
- lldb::addr_t val_ptr;
- lldb::ValueObjectSP valobj_sp;
+
+
+
+ using NSDictionaryMSyntheticFrontEnd =
+ GenericNSDictionaryMSyntheticFrontEnd<DataDescriptor_32, DataDescriptor_64>;
+}
+
+namespace Foundation1437 {
+ static const uint64_t NSDictionaryCapacities[] = {
+ 0, 3, 7, 13, 23, 41, 71, 127, 191, 251, 383, 631, 1087, 1723,
+ 2803, 4523, 7351, 11959, 19447, 31231, 50683, 81919, 132607,
+ 214519, 346607, 561109, 907759, 1468927, 2376191, 3845119,
+ 6221311, 10066421, 16287743, 26354171, 42641881, 68996069,
+ 111638519, 180634607, 292272623, 472907251
+ };
+
+ static const size_t NSDictionaryNumSizeBuckets = sizeof(NSDictionaryCapacities) / sizeof(uint64_t);
+
+ struct DataDescriptor_32 {
+ uint32_t _buffer;
+ union {
+ struct {
+ uint32_t _mutations;
+ };
+ struct {
+ uint32_t _muts;
+ uint32_t _used:25;
+ uint32_t _kvo:1;
+ uint32_t _szidx:6;
+ };
+ };
+
+ uint64_t GetSize() {
+ return (_szidx) >= NSDictionaryNumSizeBuckets ?
+ 0 : NSDictionaryCapacities[_szidx];
+ }
};
+
+ struct DataDescriptor_64 {
+ uint64_t _buffer;
+ union {
+ struct {
+ uint64_t _mutations;
+ };
+ struct {
+ uint32_t _muts;
+ uint32_t _used:25;
+ uint32_t _kvo:1;
+ uint32_t _szidx:6;
+ };
+ };
+
+ uint64_t GetSize() {
+ return (_szidx) >= NSDictionaryNumSizeBuckets ?
+ 0 : NSDictionaryCapacities[_szidx];
+ }
+ };
+
+ using NSDictionaryMSyntheticFrontEnd =
+ GenericNSDictionaryMSyntheticFrontEnd<DataDescriptor_32, DataDescriptor_64>;
+
+ template <typename DD>
+ uint64_t
+ __NSDictionaryMSize_Impl(lldb_private::Process &process,
+ lldb::addr_t valobj_addr, Status &error) {
+ const lldb::addr_t start_of_descriptor =
+ valobj_addr + process.GetAddressByteSize();
+ DD descriptor = DD();
+ process.ReadMemory(start_of_descriptor, &descriptor, sizeof(descriptor),
+ error);
+ if (error.Fail()) {
+ return 0;
+ }
+ return descriptor._used;
+ }
+
+ uint64_t
+ __NSDictionaryMSize(lldb_private::Process &process, lldb::addr_t valobj_addr,
+ Status &error) {
+ if (process.GetAddressByteSize() == 4) {
+ return __NSDictionaryMSize_Impl<DataDescriptor_32>(process, valobj_addr,
+ error);
+ } else {
+ return __NSDictionaryMSize_Impl<DataDescriptor_64>(process, valobj_addr,
+ error);
+ }
+ }
- ExecutionContextRef m_exe_ctx_ref;
- uint8_t m_ptr_size;
- lldb::ByteOrder m_order;
- DataDescriptor_32 *m_data_32;
- DataDescriptor_64 *m_data_64;
- CompilerType m_pair_type;
- std::vector<DictionaryItemDescriptor> m_children;
-};
+}
} // namespace formatters
} // namespace lldb_private
@@ -313,12 +408,19 @@ bool lldb_private::formatters::NSDictionarySummaryProvider(
return false;
value &= (is_64bit ? ~0xFC00000000000000UL : ~0xFC000000U);
} else if (class_name == g_DictionaryM || class_name == g_DictionaryMLegacy) {
+ AppleObjCRuntime *apple_runtime =
+ llvm::dyn_cast_or_null<AppleObjCRuntime>(runtime);
Status error;
- value = process_sp->ReadUnsignedIntegerFromMemory(valobj_addr + ptr_size,
- ptr_size, 0, error);
+ if (apple_runtime && apple_runtime->GetFoundationVersion() >= 1437) {
+ value = Foundation1437::__NSDictionaryMSize(*process_sp, valobj_addr,
+ error);
+ } else {
+ value = process_sp->ReadUnsignedIntegerFromMemory(valobj_addr + ptr_size,
+ ptr_size, 0, error);
+ value &= (is_64bit ? ~0xFC00000000000000UL : ~0xFC000000U);
+ }
if (error.Fail())
return false;
- value &= (is_64bit ? ~0xFC00000000000000UL : ~0xFC000000U);
} else if (class_name == g_Dictionary1) {
value = 1;
}
@@ -396,13 +498,15 @@ lldb_private::formatters::NSDictionarySyntheticFrontEndCreator(
if (class_name == g_DictionaryI) {
return (new NSDictionaryISyntheticFrontEnd(valobj_sp));
} else if (class_name == g_DictionaryM) {
- if (runtime->GetFoundationVersion() > 1400) {
- return (new NSDictionaryMSyntheticFrontEnd(valobj_sp));
+ if (runtime->GetFoundationVersion() >= 1437) {
+ return (new Foundation1437::NSDictionaryMSyntheticFrontEnd(valobj_sp));
+ } else if (runtime->GetFoundationVersion() >= 1428) {
+ return (new Foundation1428::NSDictionaryMSyntheticFrontEnd(valobj_sp));
} else {
- return (new NSDictionaryMLegacySyntheticFrontEnd(valobj_sp));
+ return (new Foundation1100::NSDictionaryMSyntheticFrontEnd(valobj_sp));
}
} else if (class_name == g_DictionaryMLegacy) {
- return (new NSDictionaryMLegacySyntheticFrontEnd(valobj_sp));
+ return (new Foundation1100::NSDictionaryMSyntheticFrontEnd(valobj_sp));
} else if (class_name == g_Dictionary1) {
return (new NSDictionary1SyntheticFrontEnd(valobj_sp));
} else {
@@ -641,22 +745,25 @@ lldb_private::formatters::NSDictionary1SyntheticFrontEnd::GetChildAtIndex(
return m_pair;
}
-lldb_private::formatters::NSDictionaryMSyntheticFrontEnd::
- NSDictionaryMSyntheticFrontEnd(lldb::ValueObjectSP valobj_sp)
+template <typename D32, typename D64>
+lldb_private::formatters::GenericNSDictionaryMSyntheticFrontEnd<D32,D64>::
+ GenericNSDictionaryMSyntheticFrontEnd(lldb::ValueObjectSP valobj_sp)
: SyntheticChildrenFrontEnd(*valobj_sp), m_exe_ctx_ref(), m_ptr_size(8),
m_order(lldb::eByteOrderInvalid), m_data_32(nullptr), m_data_64(nullptr),
m_pair_type() {}
-lldb_private::formatters::NSDictionaryMSyntheticFrontEnd::
- ~NSDictionaryMSyntheticFrontEnd() {
+template <typename D32, typename D64>
+lldb_private::formatters::GenericNSDictionaryMSyntheticFrontEnd<D32,D64>::
+ ~GenericNSDictionaryMSyntheticFrontEnd() {
delete m_data_32;
m_data_32 = nullptr;
delete m_data_64;
m_data_64 = nullptr;
}
-size_t lldb_private::formatters::NSDictionaryMSyntheticFrontEnd::
- GetIndexOfChildWithName(const ConstString &name) {
+template <typename D32, typename D64>
+size_t
+lldb_private::formatters::GenericNSDictionaryMSyntheticFrontEnd<D32,D64>:: GetIndexOfChildWithName(const ConstString &name) {
const char *item_name = name.GetCString();
uint32_t idx = ExtractIndexFromString(item_name);
if (idx < UINT32_MAX && idx >= CalculateNumChildren())
@@ -664,14 +771,18 @@ size_t lldb_private::formatters::NSDictionaryMSyntheticFrontEnd::
return idx;
}
-size_t lldb_private::formatters::NSDictionaryMSyntheticFrontEnd::
- CalculateNumChildren() {
+template <typename D32, typename D64>
+size_t
+lldb_private::formatters::GenericNSDictionaryMSyntheticFrontEnd<D32,D64>::CalculateNumChildren() {
if (!m_data_32 && !m_data_64)
return 0;
- return (m_data_32 ? m_data_32->used : m_data_64->used);
+ return (m_data_32 ? m_data_32->_used : m_data_64->_used);
}
-bool lldb_private::formatters::NSDictionaryMSyntheticFrontEnd::Update() {
+template <typename D32, typename D64>
+bool
+lldb_private::formatters::GenericNSDictionaryMSyntheticFrontEnd<D32,D64>::
+ Update() {
m_children.clear();
ValueObjectSP valobj_sp = m_backend.GetSP();
m_ptr_size = 0;
@@ -691,12 +802,12 @@ bool lldb_private::formatters::NSDictionaryMSyntheticFrontEnd::Update() {
m_order = process_sp->GetByteOrder();
uint64_t data_location = valobj_sp->GetValueAsUnsigned(0) + m_ptr_size;
if (m_ptr_size == 4) {
- m_data_32 = new DataDescriptor_32();
- process_sp->ReadMemory(data_location, m_data_32, sizeof(DataDescriptor_32),
+ m_data_32 = new D32();
+ process_sp->ReadMemory(data_location, m_data_32, sizeof(D32),
error);
} else {
- m_data_64 = new DataDescriptor_64();
- process_sp->ReadMemory(data_location, m_data_64, sizeof(DataDescriptor_64),
+ m_data_64 = new D64();
+ process_sp->ReadMemory(data_location, m_data_64, sizeof(D64),
error);
}
if (error.Fail())
@@ -704,24 +815,28 @@ bool lldb_private::formatters::NSDictionaryMSyntheticFrontEnd::Update() {
return false;
}
-bool lldb_private::formatters::NSDictionaryMSyntheticFrontEnd::
+template <typename D32, typename D64>
+bool
+lldb_private::formatters::GenericNSDictionaryMSyntheticFrontEnd<D32,D64>::
MightHaveChildren() {
return true;
}
+template <typename D32, typename D64>
lldb::ValueObjectSP
-lldb_private::formatters::NSDictionaryMSyntheticFrontEnd::GetChildAtIndex(
+lldb_private::formatters::GenericNSDictionaryMSyntheticFrontEnd<D32,D64>::
+ GetChildAtIndex(
size_t idx) {
lldb::addr_t m_keys_ptr;
lldb::addr_t m_values_ptr;
if (m_data_32) {
- uint32_t size = m_data_32->size;
- m_keys_ptr = m_data_32->buffer;
- m_values_ptr = m_data_32->buffer + (m_ptr_size * size);
+ uint32_t size = m_data_32->GetSize();
+ m_keys_ptr = m_data_32->_buffer;
+ m_values_ptr = m_data_32->_buffer + (m_ptr_size * size);
} else {
- uint32_t size = m_data_64->size;
- m_keys_ptr = m_data_64->buffer;
- m_values_ptr = m_data_64->buffer + (m_ptr_size * size);
+ uint32_t size = m_data_64->GetSize();
+ m_keys_ptr = m_data_64->_buffer;
+ m_values_ptr = m_data_64->_buffer + (m_ptr_size * size);
}
uint32_t num_children = CalculateNumChildren();
@@ -800,22 +915,24 @@ lldb_private::formatters::NSDictionaryMSyntheticFrontEnd::GetChildAtIndex(
}
-lldb_private::formatters::NSDictionaryMLegacySyntheticFrontEnd::
- NSDictionaryMLegacySyntheticFrontEnd(lldb::ValueObjectSP valobj_sp)
+lldb_private::formatters::Foundation1100::
+ NSDictionaryMSyntheticFrontEnd::
+ NSDictionaryMSyntheticFrontEnd(lldb::ValueObjectSP valobj_sp)
: SyntheticChildrenFrontEnd(*valobj_sp), m_exe_ctx_ref(), m_ptr_size(8),
m_order(lldb::eByteOrderInvalid), m_data_32(nullptr), m_data_64(nullptr),
m_pair_type() {}
-lldb_private::formatters::NSDictionaryMLegacySyntheticFrontEnd::
- ~NSDictionaryMLegacySyntheticFrontEnd() {
+lldb_private::formatters::Foundation1100::
+ NSDictionaryMSyntheticFrontEnd::~NSDictionaryMSyntheticFrontEnd() {
delete m_data_32;
m_data_32 = nullptr;
delete m_data_64;
m_data_64 = nullptr;
}
-size_t lldb_private::formatters::NSDictionaryMLegacySyntheticFrontEnd::
- GetIndexOfChildWithName(const ConstString &name) {
+size_t
+lldb_private::formatters::Foundation1100::
+ NSDictionaryMSyntheticFrontEnd::GetIndexOfChildWithName(const ConstString &name) {
const char *item_name = name.GetCString();
uint32_t idx = ExtractIndexFromString(item_name);
if (idx < UINT32_MAX && idx >= CalculateNumChildren())
@@ -823,14 +940,17 @@ size_t lldb_private::formatters::NSDictionaryMLegacySyntheticFrontEnd::
return idx;
}
-size_t lldb_private::formatters::NSDictionaryMLegacySyntheticFrontEnd::
- CalculateNumChildren() {
+size_t
+lldb_private::formatters::Foundation1100::
+ NSDictionaryMSyntheticFrontEnd::CalculateNumChildren() {
if (!m_data_32 && !m_data_64)
return 0;
return (m_data_32 ? m_data_32->_used : m_data_64->_used);
}
-bool lldb_private::formatters::NSDictionaryMLegacySyntheticFrontEnd::Update() {
+bool
+lldb_private::formatters::Foundation1100::
+ NSDictionaryMSyntheticFrontEnd::Update() {
m_children.clear();
ValueObjectSP valobj_sp = m_backend.GetSP();
m_ptr_size = 0;
@@ -863,14 +983,15 @@ bool lldb_private::formatters::NSDictionaryMLegacySyntheticFrontEnd::Update() {
return false;
}
-bool lldb_private::formatters::NSDictionaryMLegacySyntheticFrontEnd::
- MightHaveChildren() {
+bool
+lldb_private::formatters::Foundation1100::
+ NSDictionaryMSyntheticFrontEnd::MightHaveChildren() {
return true;
}
lldb::ValueObjectSP
-lldb_private::formatters::NSDictionaryMLegacySyntheticFrontEnd::GetChildAtIndex(
- size_t idx) {
+lldb_private::formatters::Foundation1100::
+ NSDictionaryMSyntheticFrontEnd::GetChildAtIndex(size_t idx) {
lldb::addr_t m_keys_ptr =
(m_data_32 ? m_data_32->_keys_addr : m_data_64->_keys_addr);
lldb::addr_t m_values_ptr =
diff --git a/source/Plugins/Language/ObjC/NSSet.cpp b/source/Plugins/Language/ObjC/NSSet.cpp
index 2f33987751699..fa2483ecc0947 100644
--- a/source/Plugins/Language/ObjC/NSSet.cpp
+++ b/source/Plugins/Language/ObjC/NSSet.cpp
@@ -135,7 +135,7 @@ namespace Foundation1300 {
GenericNSSetMSyntheticFrontEnd<DataDescriptor_32, DataDescriptor_64>;
}
-namespace Foundation1400 {
+namespace Foundation1428 {
struct DataDescriptor_32 {
uint32_t _used : 26;
uint32_t _size;
@@ -154,6 +154,64 @@ namespace Foundation1400 {
GenericNSSetMSyntheticFrontEnd<DataDescriptor_32, DataDescriptor_64>;
}
+namespace Foundation1437 {
+ struct DataDescriptor_32 {
+ uint32_t _cow;
+ // __table storage
+ uint32_t _objs_addr;
+ union {
+ uint32_t _mutations;
+ struct {
+ uint32_t _muts;
+ uint32_t _used : 26;
+ uint32_t _szidx : 6;
+ };
+ };
+ };
+
+ struct DataDescriptor_64 {
+ uint64_t _cow;
+ // __Table storage
+ uint64_t _objs_addr;
+ union {
+ uint64_t _mutations;
+ struct {
+ uint32_t _muts;
+ uint32_t _used : 26;
+ uint32_t _szidx : 6;
+ };
+ };
+ };
+
+ using NSSetMSyntheticFrontEnd =
+ GenericNSSetMSyntheticFrontEnd<DataDescriptor_32, DataDescriptor_64>;
+
+ template <typename DD>
+ uint64_t
+ __NSSetMSize_Impl(lldb_private::Process &process, lldb::addr_t valobj_addr,
+ Status &error) {
+ const lldb::addr_t start_of_descriptor =
+ valobj_addr + process.GetAddressByteSize();
+ DD descriptor = DD();
+ process.ReadMemory(start_of_descriptor, &descriptor, sizeof(descriptor),
+ error);
+ if (error.Fail()) {
+ return 0;
+ }
+ return descriptor._used;
+ }
+
+ uint64_t
+ __NSSetMSize(lldb_private::Process &process, lldb::addr_t valobj_addr,
+ Status &error) {
+ if (process.GetAddressByteSize() == 4) {
+ return __NSSetMSize_Impl<DataDescriptor_32>(process, valobj_addr, error);
+ } else {
+ return __NSSetMSize_Impl<DataDescriptor_64>(process, valobj_addr, error);
+ }
+ }
+}
+
class NSSetCodeRunningSyntheticFrontEnd : public SyntheticChildrenFrontEnd {
public:
NSSetCodeRunningSyntheticFrontEnd(lldb::ValueObjectSP valobj_sp);
@@ -219,12 +277,18 @@ bool lldb_private::formatters::NSSetSummaryProvider(
return false;
value &= (is_64bit ? ~0xFC00000000000000UL : ~0xFC000000U);
} else if (!strcmp(class_name, "__NSSetM")) {
+ AppleObjCRuntime *apple_runtime =
+ llvm::dyn_cast_or_null<AppleObjCRuntime>(runtime);
Status error;
- value = process_sp->ReadUnsignedIntegerFromMemory(valobj_addr + ptr_size,
- ptr_size, 0, error);
+ if (apple_runtime && apple_runtime->GetFoundationVersion() >= 1437) {
+ value = Foundation1437::__NSSetMSize(*process_sp, valobj_addr, error);
+ } else {
+ value = process_sp->ReadUnsignedIntegerFromMemory(valobj_addr + ptr_size,
+ ptr_size, 0, error);
+ value &= (is_64bit ? ~0xFC00000000000000UL : ~0xFC000000U);
+ }
if (error.Fail())
return false;
- value &= (is_64bit ? ~0xFC00000000000000UL : ~0xFC000000U);
}
/*else if (!strcmp(class_name,"__NSCFSet"))
{
@@ -312,10 +376,16 @@ lldb_private::formatters::NSSetSyntheticFrontEndCreator(
} else if (!strcmp(class_name, "__NSSetM")) {
AppleObjCRuntime *apple_runtime =
llvm::dyn_cast_or_null<AppleObjCRuntime>(runtime);
- if (apple_runtime && apple_runtime->GetFoundationVersion() >= 1400)
- return (new Foundation1400::NSSetMSyntheticFrontEnd(valobj_sp));
- else
+ if (apple_runtime) {
+ if (apple_runtime->GetFoundationVersion() >= 1437)
+ return (new Foundation1437::NSSetMSyntheticFrontEnd(valobj_sp));
+ else if (apple_runtime->GetFoundationVersion() >= 1428)
+ return (new Foundation1428::NSSetMSyntheticFrontEnd(valobj_sp));
+ else
+ return (new Foundation1300::NSSetMSyntheticFrontEnd(valobj_sp));
+ } else {
return (new Foundation1300::NSSetMSyntheticFrontEnd(valobj_sp));
+ }
} else {
auto &map(NSSet_Additionals::GetAdditionalSynthetics());
auto iter = map.find(class_name_cs), end = map.end();