Since interaction with the python interpreter is moving towards being more isolated, we won't be able to include this header from normal files anymore, all includes of it should be localized to the python library which will live under source/bindings/API/Python after a future patch. None of the files that were including this header actually depended on it anyway, so it was just a dead include in every single instance. llvm-svn: 238581
718 lines
21 KiB
C++
718 lines
21 KiB
C++
//===-- NSSet.cpp ------------------------------------------------*- C++ -*-===//
|
|
//
|
|
// The LLVM Compiler Infrastructure
|
|
//
|
|
// This file is distributed under the University of Illinois Open Source
|
|
// License. See LICENSE.TXT for details.
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
#include "lldb/DataFormatters/CXXFormatterFunctions.h"
|
|
|
|
#include "lldb/Core/DataBufferHeap.h"
|
|
#include "lldb/Core/Error.h"
|
|
#include "lldb/Core/Stream.h"
|
|
#include "lldb/Core/ValueObject.h"
|
|
#include "lldb/Core/ValueObjectConstResult.h"
|
|
#include "lldb/Host/Endian.h"
|
|
#include "lldb/Symbol/ClangASTContext.h"
|
|
#include "lldb/Target/ObjCLanguageRuntime.h"
|
|
#include "lldb/Target/Target.h"
|
|
|
|
using namespace lldb;
|
|
using namespace lldb_private;
|
|
using namespace lldb_private::formatters;
|
|
|
|
namespace lldb_private {
|
|
namespace formatters {
|
|
class NSSetISyntheticFrontEnd : public SyntheticChildrenFrontEnd
|
|
{
|
|
private:
|
|
struct DataDescriptor_32
|
|
{
|
|
uint32_t _used : 26;
|
|
uint32_t _szidx : 6;
|
|
};
|
|
struct DataDescriptor_64
|
|
{
|
|
uint64_t _used : 58;
|
|
uint32_t _szidx : 6;
|
|
};
|
|
|
|
struct SetItemDescriptor
|
|
{
|
|
lldb::addr_t item_ptr;
|
|
lldb::ValueObjectSP valobj_sp;
|
|
};
|
|
|
|
public:
|
|
NSSetISyntheticFrontEnd (lldb::ValueObjectSP valobj_sp);
|
|
|
|
virtual size_t
|
|
CalculateNumChildren ();
|
|
|
|
virtual lldb::ValueObjectSP
|
|
GetChildAtIndex (size_t idx);
|
|
|
|
virtual bool
|
|
Update();
|
|
|
|
virtual bool
|
|
MightHaveChildren ();
|
|
|
|
virtual size_t
|
|
GetIndexOfChildWithName (const ConstString &name);
|
|
|
|
virtual
|
|
~NSSetISyntheticFrontEnd ();
|
|
private:
|
|
ExecutionContextRef m_exe_ctx_ref;
|
|
uint8_t m_ptr_size;
|
|
DataDescriptor_32 *m_data_32;
|
|
DataDescriptor_64 *m_data_64;
|
|
lldb::addr_t m_data_ptr;
|
|
std::vector<SetItemDescriptor> m_children;
|
|
};
|
|
|
|
class NSOrderedSetSyntheticFrontEnd : public SyntheticChildrenFrontEnd
|
|
{
|
|
private:
|
|
|
|
public:
|
|
NSOrderedSetSyntheticFrontEnd (lldb::ValueObjectSP valobj_sp);
|
|
|
|
virtual size_t
|
|
CalculateNumChildren ();
|
|
|
|
virtual lldb::ValueObjectSP
|
|
GetChildAtIndex (size_t idx);
|
|
|
|
virtual bool
|
|
Update();
|
|
|
|
virtual bool
|
|
MightHaveChildren ();
|
|
|
|
virtual size_t
|
|
GetIndexOfChildWithName (const ConstString &name);
|
|
|
|
virtual
|
|
~NSOrderedSetSyntheticFrontEnd ();
|
|
private:
|
|
uint32_t m_count;
|
|
std::map<uint32_t,lldb::ValueObjectSP> m_children;
|
|
};
|
|
|
|
class NSSetMSyntheticFrontEnd : public SyntheticChildrenFrontEnd
|
|
{
|
|
private:
|
|
struct DataDescriptor_32
|
|
{
|
|
uint32_t _used : 26;
|
|
uint32_t _size;
|
|
uint32_t _mutations;
|
|
uint32_t _objs_addr;
|
|
};
|
|
struct DataDescriptor_64
|
|
{
|
|
uint64_t _used : 58;
|
|
uint64_t _size;
|
|
uint64_t _mutations;
|
|
uint64_t _objs_addr;
|
|
};
|
|
struct SetItemDescriptor
|
|
{
|
|
lldb::addr_t item_ptr;
|
|
lldb::ValueObjectSP valobj_sp;
|
|
};
|
|
public:
|
|
NSSetMSyntheticFrontEnd (lldb::ValueObjectSP valobj_sp);
|
|
|
|
virtual size_t
|
|
CalculateNumChildren ();
|
|
|
|
virtual lldb::ValueObjectSP
|
|
GetChildAtIndex (size_t idx);
|
|
|
|
virtual bool
|
|
Update();
|
|
|
|
virtual bool
|
|
MightHaveChildren ();
|
|
|
|
virtual size_t
|
|
GetIndexOfChildWithName (const ConstString &name);
|
|
|
|
virtual
|
|
~NSSetMSyntheticFrontEnd ();
|
|
private:
|
|
ExecutionContextRef m_exe_ctx_ref;
|
|
uint8_t m_ptr_size;
|
|
DataDescriptor_32 *m_data_32;
|
|
DataDescriptor_64 *m_data_64;
|
|
std::vector<SetItemDescriptor> m_children;
|
|
};
|
|
|
|
class NSSetCodeRunningSyntheticFrontEnd : public SyntheticChildrenFrontEnd
|
|
{
|
|
public:
|
|
NSSetCodeRunningSyntheticFrontEnd (lldb::ValueObjectSP valobj_sp);
|
|
|
|
virtual size_t
|
|
CalculateNumChildren ();
|
|
|
|
virtual lldb::ValueObjectSP
|
|
GetChildAtIndex (size_t idx);
|
|
|
|
virtual bool
|
|
Update();
|
|
|
|
virtual bool
|
|
MightHaveChildren ();
|
|
|
|
virtual size_t
|
|
GetIndexOfChildWithName (const ConstString &name);
|
|
|
|
virtual
|
|
~NSSetCodeRunningSyntheticFrontEnd ();
|
|
};
|
|
}
|
|
}
|
|
|
|
template<bool cf_style>
|
|
bool
|
|
lldb_private::formatters::NSSetSummaryProvider (ValueObject& valobj, Stream& stream, const TypeSummaryOptions& options)
|
|
{
|
|
ProcessSP process_sp = valobj.GetProcessSP();
|
|
if (!process_sp)
|
|
return false;
|
|
|
|
ObjCLanguageRuntime* runtime = (ObjCLanguageRuntime*)process_sp->GetLanguageRuntime(lldb::eLanguageTypeObjC);
|
|
|
|
if (!runtime)
|
|
return false;
|
|
|
|
ObjCLanguageRuntime::ClassDescriptorSP descriptor(runtime->GetClassDescriptor(valobj));
|
|
|
|
if (!descriptor.get() || !descriptor->IsValid())
|
|
return false;
|
|
|
|
uint32_t ptr_size = process_sp->GetAddressByteSize();
|
|
bool is_64bit = (ptr_size == 8);
|
|
|
|
lldb::addr_t valobj_addr = valobj.GetValueAsUnsigned(0);
|
|
|
|
if (!valobj_addr)
|
|
return false;
|
|
|
|
uint64_t value = 0;
|
|
|
|
const char* class_name = descriptor->GetClassName().GetCString();
|
|
|
|
if (!class_name || !*class_name)
|
|
return false;
|
|
|
|
if (!strcmp(class_name,"__NSSetI"))
|
|
{
|
|
Error error;
|
|
value = process_sp->ReadUnsignedIntegerFromMemory(valobj_addr + ptr_size, ptr_size, 0, error);
|
|
if (error.Fail())
|
|
return false;
|
|
value &= (is_64bit ? ~0xFC00000000000000UL : ~0xFC000000U);
|
|
}
|
|
else if (!strcmp(class_name,"__NSSetM"))
|
|
{
|
|
Error error;
|
|
value = process_sp->ReadUnsignedIntegerFromMemory(valobj_addr + ptr_size, ptr_size, 0, error);
|
|
if (error.Fail())
|
|
return false;
|
|
value &= (is_64bit ? ~0xFC00000000000000UL : ~0xFC000000U);
|
|
}
|
|
/*else if (!strcmp(class_name,"__NSCFSet"))
|
|
{
|
|
Error error;
|
|
value = process_sp->ReadUnsignedIntegerFromMemory(valobj_addr + (is_64bit ? 20 : 12), 4, 0, error);
|
|
if (error.Fail())
|
|
return false;
|
|
if (is_64bit)
|
|
value &= ~0x1fff000000000000UL;
|
|
}
|
|
else if (!strcmp(class_name,"NSCountedSet"))
|
|
{
|
|
Error error;
|
|
value = process_sp->ReadUnsignedIntegerFromMemory(valobj_addr + ptr_size, ptr_size, 0, error);
|
|
if (error.Fail())
|
|
return false;
|
|
value = process_sp->ReadUnsignedIntegerFromMemory(value + (is_64bit ? 20 : 12), 4, 0, error);
|
|
if (error.Fail())
|
|
return false;
|
|
if (is_64bit)
|
|
value &= ~0x1fff000000000000UL;
|
|
}*/
|
|
else
|
|
{
|
|
if (!ExtractValueFromObjCExpression(valobj, "int", "count", value))
|
|
return false;
|
|
}
|
|
|
|
stream.Printf("%s%" PRIu64 " %s%s",
|
|
(cf_style ? "@\"" : ""),
|
|
value,
|
|
(cf_style ? (value == 1 ? "value" : "values") : (value == 1 ? "object" : "objects")),
|
|
(cf_style ? "\"" : ""));
|
|
return true;
|
|
}
|
|
|
|
SyntheticChildrenFrontEnd* lldb_private::formatters::NSSetSyntheticFrontEndCreator (CXXSyntheticChildren*, lldb::ValueObjectSP valobj_sp)
|
|
{
|
|
lldb::ProcessSP process_sp (valobj_sp->GetProcessSP());
|
|
if (!process_sp)
|
|
return NULL;
|
|
ObjCLanguageRuntime *runtime = (ObjCLanguageRuntime*)process_sp->GetLanguageRuntime(lldb::eLanguageTypeObjC);
|
|
if (!runtime)
|
|
return NULL;
|
|
|
|
if (!valobj_sp->IsPointerType())
|
|
{
|
|
Error error;
|
|
valobj_sp = valobj_sp->AddressOf(error);
|
|
if (error.Fail() || !valobj_sp)
|
|
return NULL;
|
|
}
|
|
|
|
ObjCLanguageRuntime::ClassDescriptorSP descriptor(runtime->GetClassDescriptor(*valobj_sp.get()));
|
|
|
|
if (!descriptor.get() || !descriptor->IsValid())
|
|
return NULL;
|
|
|
|
const char* class_name = descriptor->GetClassName().GetCString();
|
|
|
|
if (!class_name || !*class_name)
|
|
return NULL;
|
|
|
|
if (!strcmp(class_name,"__NSSetI"))
|
|
{
|
|
return (new NSSetISyntheticFrontEnd(valobj_sp));
|
|
}
|
|
else if (!strcmp(class_name,"__NSSetM"))
|
|
{
|
|
return (new NSSetMSyntheticFrontEnd(valobj_sp));
|
|
}
|
|
else if ((!strcmp(class_name,"__NSOrderedSetI")) || (!strcmp(class_name,"__NSOrderedSetM")))
|
|
{
|
|
return new NSOrderedSetSyntheticFrontEnd(valobj_sp); // this runs code
|
|
}
|
|
else
|
|
{
|
|
return /*(new NSSetCodeRunningSyntheticFrontEnd(valobj_sp))*/ NULL;
|
|
}
|
|
}
|
|
|
|
lldb_private::formatters::NSSetISyntheticFrontEnd::NSSetISyntheticFrontEnd (lldb::ValueObjectSP valobj_sp) :
|
|
SyntheticChildrenFrontEnd(*valobj_sp.get()),
|
|
m_exe_ctx_ref(),
|
|
m_ptr_size(8),
|
|
m_data_32(NULL),
|
|
m_data_64(NULL)
|
|
{
|
|
if (valobj_sp)
|
|
Update();
|
|
}
|
|
|
|
lldb_private::formatters::NSSetISyntheticFrontEnd::~NSSetISyntheticFrontEnd ()
|
|
{
|
|
delete m_data_32;
|
|
m_data_32 = NULL;
|
|
delete m_data_64;
|
|
m_data_64 = NULL;
|
|
}
|
|
|
|
size_t
|
|
lldb_private::formatters::NSSetISyntheticFrontEnd::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::NSSetISyntheticFrontEnd::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::NSSetISyntheticFrontEnd::Update()
|
|
{
|
|
m_children.clear();
|
|
delete m_data_32;
|
|
m_data_32 = NULL;
|
|
delete m_data_64;
|
|
m_data_64 = NULL;
|
|
m_ptr_size = 0;
|
|
ValueObjectSP valobj_sp = m_backend.GetSP();
|
|
if (!valobj_sp)
|
|
return false;
|
|
if (!valobj_sp)
|
|
return false;
|
|
m_exe_ctx_ref = valobj_sp->GetExecutionContextRef();
|
|
Error error;
|
|
if (valobj_sp->IsPointerType())
|
|
{
|
|
valobj_sp = valobj_sp->Dereference(error);
|
|
if (error.Fail() || !valobj_sp)
|
|
return false;
|
|
}
|
|
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->GetAddressOf() + 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;
|
|
m_data_ptr = data_location + m_ptr_size;
|
|
return false;
|
|
}
|
|
|
|
bool
|
|
lldb_private::formatters::NSSetISyntheticFrontEnd::MightHaveChildren ()
|
|
{
|
|
return true;
|
|
}
|
|
|
|
lldb::ValueObjectSP
|
|
lldb_private::formatters::NSSetISyntheticFrontEnd::GetChildAtIndex (size_t idx)
|
|
{
|
|
uint32_t num_children = CalculateNumChildren();
|
|
|
|
if (idx >= num_children)
|
|
return lldb::ValueObjectSP();
|
|
|
|
ProcessSP process_sp = m_exe_ctx_ref.GetProcessSP();
|
|
if (!process_sp)
|
|
return lldb::ValueObjectSP();
|
|
|
|
if (m_children.empty())
|
|
{
|
|
// do the scan phase
|
|
lldb::addr_t obj_at_idx = 0;
|
|
|
|
uint32_t tries = 0;
|
|
uint32_t test_idx = 0;
|
|
|
|
while(tries < num_children)
|
|
{
|
|
obj_at_idx = m_data_ptr + (test_idx * m_ptr_size);
|
|
if (!process_sp)
|
|
return lldb::ValueObjectSP();
|
|
Error error;
|
|
obj_at_idx = process_sp->ReadPointerFromMemory(obj_at_idx, error);
|
|
if (error.Fail())
|
|
return lldb::ValueObjectSP();
|
|
|
|
test_idx++;
|
|
|
|
if (!obj_at_idx)
|
|
continue;
|
|
tries++;
|
|
|
|
SetItemDescriptor descriptor = {obj_at_idx,lldb::ValueObjectSP()};
|
|
|
|
m_children.push_back(descriptor);
|
|
}
|
|
}
|
|
|
|
if (idx >= m_children.size()) // should never happen
|
|
return lldb::ValueObjectSP();
|
|
|
|
SetItemDescriptor &set_item = m_children[idx];
|
|
if (!set_item.valobj_sp)
|
|
{
|
|
auto ptr_size = process_sp->GetAddressByteSize();
|
|
DataBufferHeap buffer(ptr_size,0);
|
|
switch (ptr_size)
|
|
{
|
|
case 0: // architecture has no clue?? - fail
|
|
return lldb::ValueObjectSP();
|
|
case 4:
|
|
*((uint32_t*)buffer.GetBytes()) = (uint32_t)set_item.item_ptr;
|
|
break;
|
|
case 8:
|
|
*((uint64_t*)buffer.GetBytes()) = (uint64_t)set_item.item_ptr;
|
|
break;
|
|
default:
|
|
assert(false && "pointer size is not 4 nor 8 - get out of here ASAP");
|
|
}
|
|
StreamString idx_name;
|
|
idx_name.Printf("[%" PRIu64 "]", (uint64_t)idx);
|
|
|
|
DataExtractor data(buffer.GetBytes(),
|
|
buffer.GetByteSize(),
|
|
process_sp->GetByteOrder(),
|
|
process_sp->GetAddressByteSize());
|
|
|
|
set_item.valobj_sp =
|
|
CreateValueObjectFromData(idx_name.GetData(),
|
|
data,
|
|
m_exe_ctx_ref,
|
|
m_backend.GetClangType().GetBasicTypeFromAST(lldb::eBasicTypeObjCID));
|
|
}
|
|
return set_item.valobj_sp;
|
|
}
|
|
|
|
lldb_private::formatters::NSSetMSyntheticFrontEnd::NSSetMSyntheticFrontEnd (lldb::ValueObjectSP valobj_sp) :
|
|
SyntheticChildrenFrontEnd(*valobj_sp.get()),
|
|
m_exe_ctx_ref(),
|
|
m_ptr_size(8),
|
|
m_data_32(NULL),
|
|
m_data_64(NULL)
|
|
{
|
|
if (valobj_sp)
|
|
Update ();
|
|
}
|
|
|
|
lldb_private::formatters::NSSetMSyntheticFrontEnd::~NSSetMSyntheticFrontEnd ()
|
|
{
|
|
delete m_data_32;
|
|
m_data_32 = NULL;
|
|
delete m_data_64;
|
|
m_data_64 = NULL;
|
|
}
|
|
|
|
size_t
|
|
lldb_private::formatters::NSSetMSyntheticFrontEnd::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::NSSetMSyntheticFrontEnd::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::NSSetMSyntheticFrontEnd::Update()
|
|
{
|
|
m_children.clear();
|
|
ValueObjectSP valobj_sp = m_backend.GetSP();
|
|
m_ptr_size = 0;
|
|
delete m_data_32;
|
|
m_data_32 = NULL;
|
|
delete m_data_64;
|
|
m_data_64 = NULL;
|
|
if (!valobj_sp)
|
|
return false;
|
|
if (!valobj_sp)
|
|
return false;
|
|
m_exe_ctx_ref = valobj_sp->GetExecutionContextRef();
|
|
Error error;
|
|
if (valobj_sp->IsPointerType())
|
|
{
|
|
valobj_sp = valobj_sp->Dereference(error);
|
|
if (error.Fail() || !valobj_sp)
|
|
return false;
|
|
}
|
|
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->GetAddressOf() + 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::NSSetMSyntheticFrontEnd::MightHaveChildren ()
|
|
{
|
|
return true;
|
|
}
|
|
|
|
lldb::ValueObjectSP
|
|
lldb_private::formatters::NSSetMSyntheticFrontEnd::GetChildAtIndex (size_t idx)
|
|
{
|
|
lldb::addr_t m_objs_addr = (m_data_32 ? m_data_32->_objs_addr : m_data_64->_objs_addr);
|
|
|
|
uint32_t num_children = CalculateNumChildren();
|
|
|
|
if (idx >= num_children)
|
|
return lldb::ValueObjectSP();
|
|
|
|
ProcessSP process_sp = m_exe_ctx_ref.GetProcessSP();
|
|
if (!process_sp)
|
|
return lldb::ValueObjectSP();
|
|
|
|
if (m_children.empty())
|
|
{
|
|
// do the scan phase
|
|
lldb::addr_t obj_at_idx = 0;
|
|
|
|
uint32_t tries = 0;
|
|
uint32_t test_idx = 0;
|
|
|
|
while(tries < num_children)
|
|
{
|
|
obj_at_idx = m_objs_addr + (test_idx * m_ptr_size);
|
|
if (!process_sp)
|
|
return lldb::ValueObjectSP();
|
|
Error error;
|
|
obj_at_idx = process_sp->ReadPointerFromMemory(obj_at_idx, error);
|
|
if (error.Fail())
|
|
return lldb::ValueObjectSP();
|
|
|
|
test_idx++;
|
|
|
|
if (!obj_at_idx)
|
|
continue;
|
|
tries++;
|
|
|
|
SetItemDescriptor descriptor = {obj_at_idx,lldb::ValueObjectSP()};
|
|
|
|
m_children.push_back(descriptor);
|
|
}
|
|
}
|
|
|
|
if (idx >= m_children.size()) // should never happen
|
|
return lldb::ValueObjectSP();
|
|
|
|
SetItemDescriptor &set_item = m_children[idx];
|
|
if (!set_item.valobj_sp)
|
|
{
|
|
auto ptr_size = process_sp->GetAddressByteSize();
|
|
DataBufferHeap buffer(ptr_size,0);
|
|
switch (ptr_size)
|
|
{
|
|
case 0: // architecture has no clue?? - fail
|
|
return lldb::ValueObjectSP();
|
|
case 4:
|
|
*((uint32_t*)buffer.GetBytes()) = (uint32_t)set_item.item_ptr;
|
|
break;
|
|
case 8:
|
|
*((uint64_t*)buffer.GetBytes()) = (uint64_t)set_item.item_ptr;
|
|
break;
|
|
default:
|
|
assert(false && "pointer size is not 4 nor 8 - get out of here ASAP");
|
|
}
|
|
StreamString idx_name;
|
|
idx_name.Printf("[%" PRIu64 "]", (uint64_t)idx);
|
|
|
|
DataExtractor data(buffer.GetBytes(),
|
|
buffer.GetByteSize(),
|
|
process_sp->GetByteOrder(),
|
|
process_sp->GetAddressByteSize());
|
|
|
|
set_item.valobj_sp =
|
|
CreateValueObjectFromData(idx_name.GetData(),
|
|
data,
|
|
m_exe_ctx_ref,
|
|
m_backend.GetClangType().GetBasicTypeFromAST(lldb::eBasicTypeObjCID));
|
|
}
|
|
return set_item.valobj_sp;
|
|
}
|
|
|
|
lldb_private::formatters::NSOrderedSetSyntheticFrontEnd::NSOrderedSetSyntheticFrontEnd (lldb::ValueObjectSP valobj_sp) :
|
|
SyntheticChildrenFrontEnd(*valobj_sp.get()),
|
|
m_count(UINT32_MAX),
|
|
m_children()
|
|
{}
|
|
|
|
size_t
|
|
lldb_private::formatters::NSOrderedSetSyntheticFrontEnd::CalculateNumChildren ()
|
|
{
|
|
if (m_count != UINT32_MAX)
|
|
return m_count;
|
|
uint64_t count_temp;
|
|
if (ExtractValueFromObjCExpression(m_backend,"unsigned int","count",count_temp))
|
|
return (m_count = count_temp);
|
|
return (m_count = 0);
|
|
}
|
|
|
|
lldb::ValueObjectSP
|
|
lldb_private::formatters::NSOrderedSetSyntheticFrontEnd::GetChildAtIndex (size_t idx)
|
|
{
|
|
auto iter = m_children.find(idx);
|
|
if (iter == m_children.end())
|
|
{
|
|
lldb::ValueObjectSP retval_sp;
|
|
if (idx <= m_count)
|
|
{
|
|
retval_sp = CallSelectorOnObject(m_backend, "id", "objectAtIndex", idx);
|
|
if (retval_sp)
|
|
{
|
|
StreamString idx_name;
|
|
idx_name.Printf("[%" PRIu64 "]", (uint64_t)idx);
|
|
retval_sp->SetName(ConstString(idx_name.GetData()));
|
|
}
|
|
m_children[idx] = retval_sp;
|
|
}
|
|
return retval_sp;
|
|
}
|
|
else
|
|
return iter->second;
|
|
}
|
|
|
|
bool
|
|
lldb_private::formatters::NSOrderedSetSyntheticFrontEnd::Update()
|
|
{
|
|
return false;
|
|
}
|
|
|
|
bool
|
|
lldb_private::formatters::NSOrderedSetSyntheticFrontEnd::MightHaveChildren ()
|
|
{
|
|
return true;
|
|
}
|
|
|
|
size_t
|
|
lldb_private::formatters::NSOrderedSetSyntheticFrontEnd::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;
|
|
}
|
|
|
|
lldb_private::formatters::NSOrderedSetSyntheticFrontEnd::~NSOrderedSetSyntheticFrontEnd ()
|
|
{
|
|
}
|
|
|
|
template bool
|
|
lldb_private::formatters::NSSetSummaryProvider<true> (ValueObject& valobj, Stream& stream, const TypeSummaryOptions& options);
|
|
|
|
template bool
|
|
lldb_private::formatters::NSSetSummaryProvider<false> (ValueObject& valobj, Stream& stream, const TypeSummaryOptions& options);
|