forked from OSchip/llvm-project
<rdar://problem/12529957>
Synthetic children provider for NSSet llvm-svn: 175468
This commit is contained in:
parent
3a8002f61d
commit
9f02e0912d
|
@ -371,6 +371,131 @@ namespace lldb_private {
|
|||
|
||||
SyntheticChildrenFrontEnd* NSDictionarySyntheticFrontEndCreator (CXXSyntheticChildren*, lldb::ValueObjectSP);
|
||||
|
||||
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 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 ();
|
||||
};
|
||||
|
||||
SyntheticChildrenFrontEnd* NSSetSyntheticFrontEndCreator (CXXSyntheticChildren*, lldb::ValueObjectSP);
|
||||
|
||||
class LibcxxVectorBoolSyntheticFrontEnd : public SyntheticChildrenFrontEnd
|
||||
{
|
||||
public:
|
||||
|
|
|
@ -868,6 +868,15 @@ FormatManager::LoadObjCFormatters()
|
|||
AddCXXSummary(appkit_category_sp, lldb_private::formatters::NSDictionarySummaryProvider<true>, "NSDictionary summary provider", ConstString("CFDictionaryRef"), appkit_flags);
|
||||
AddCXXSummary(appkit_category_sp, lldb_private::formatters::NSDictionarySummaryProvider<true>, "NSDictionary summary provider", ConstString("CFMutableDictionaryRef"), appkit_flags);
|
||||
|
||||
AddCXXSummary(appkit_category_sp, lldb_private::formatters::NSSetSummaryProvider<false>, "NSSet summary", ConstString("NSSet"), appkit_flags);
|
||||
AddCXXSummary(appkit_category_sp, lldb_private::formatters::NSSetSummaryProvider<true>, "CFSetRef summary", ConstString("CFSetRef"), appkit_flags);
|
||||
AddCXXSummary(appkit_category_sp, lldb_private::formatters::NSSetSummaryProvider<true>, "CFMutableSetRef summary", ConstString("CFMutableSetRef"), appkit_flags);
|
||||
AddCXXSummary(appkit_category_sp, lldb_private::formatters::NSSetSummaryProvider<false>, "__NSCFSet summary", ConstString("__NSCFSet"), appkit_flags);
|
||||
AddCXXSummary(appkit_category_sp, lldb_private::formatters::NSSetSummaryProvider<false>, "__NSSetI summary", ConstString("__NSSetI"), appkit_flags);
|
||||
AddCXXSummary(appkit_category_sp, lldb_private::formatters::NSSetSummaryProvider<false>, "__NSSetM summary", ConstString("__NSSetM"), appkit_flags);
|
||||
AddCXXSummary(appkit_category_sp, lldb_private::formatters::NSSetSummaryProvider<false>, "NSCountedSet summary", ConstString("NSCountedSet"), appkit_flags);
|
||||
AddCXXSummary(appkit_category_sp, lldb_private::formatters::NSSetSummaryProvider<false>, "NSSet summary", ConstString("NSMutableSet"), appkit_flags);
|
||||
|
||||
// AddSummary(appkit_category_sp, "${var.key%@} -> ${var.value%@}", ConstString("$_lldb_typegen_nspair"), appkit_flags);
|
||||
|
||||
appkit_flags.SetDontShowChildren(true);
|
||||
|
@ -885,6 +894,11 @@ FormatManager::LoadObjCFormatters()
|
|||
AddCXXSynthetic(appkit_category_sp, lldb_private::formatters::NSDictionarySyntheticFrontEndCreator, "NSDictionary synthetic children", ConstString("CFDictionaryRef"), ScriptedSyntheticChildren::Flags());
|
||||
AddCXXSynthetic(appkit_category_sp, lldb_private::formatters::NSDictionarySyntheticFrontEndCreator, "NSDictionary synthetic children", ConstString("CFMutableDictionaryRef"), ScriptedSyntheticChildren::Flags());
|
||||
|
||||
AddCXXSynthetic(appkit_category_sp, lldb_private::formatters::NSSetSyntheticFrontEndCreator, "NSSet synthetic children", ConstString("NSSet"), ScriptedSyntheticChildren::Flags());
|
||||
AddCXXSynthetic(appkit_category_sp, lldb_private::formatters::NSSetSyntheticFrontEndCreator, "NSSet synthetic children", ConstString("__NSSetI"), ScriptedSyntheticChildren::Flags());
|
||||
AddCXXSynthetic(appkit_category_sp, lldb_private::formatters::NSSetSyntheticFrontEndCreator, "NSSet synthetic children", ConstString("__NSSetM"), ScriptedSyntheticChildren::Flags());
|
||||
AddCXXSynthetic(appkit_category_sp, lldb_private::formatters::NSSetSyntheticFrontEndCreator, "NSSet synthetic children", ConstString("NSMutableSet"), ScriptedSyntheticChildren::Flags());
|
||||
|
||||
AddScriptSummary(appkit_category_sp, "lldb.formatters.objc.CFBag.CFBag_SummaryProvider", ConstString("CFBagRef"), appkit_flags);
|
||||
AddScriptSummary(appkit_category_sp, "lldb.formatters.objc.CFBag.CFBag_SummaryProvider", ConstString("__CFBag"), appkit_flags);
|
||||
AddScriptSummary(appkit_category_sp, "lldb.formatters.objc.CFBag.CFBag_SummaryProvider", ConstString("const struct __CFBag"), appkit_flags);
|
||||
|
@ -934,14 +948,6 @@ FormatManager::LoadObjCFormatters()
|
|||
AddCXXSummary(appkit_category_sp, lldb_private::formatters::RuntimeSpecificDescriptionSummaryProvider, "NSHost summary provider", ConstString("NSHost"), appkit_flags);
|
||||
AddCXXSummary(appkit_category_sp, lldb_private::formatters::RuntimeSpecificDescriptionSummaryProvider, "NSTask summary provider", ConstString("NSTask"), appkit_flags);
|
||||
AddCXXSummary(appkit_category_sp, lldb_private::formatters::RuntimeSpecificDescriptionSummaryProvider, "NSValue summary provider", ConstString("NSValue"), appkit_flags);
|
||||
|
||||
AddCXXSummary(appkit_category_sp, lldb_private::formatters::NSSetSummaryProvider<false>, "NSSet summary", ConstString("NSSet"), appkit_flags);
|
||||
AddCXXSummary(appkit_category_sp, lldb_private::formatters::NSSetSummaryProvider<true>, "CFSetRef summary", ConstString("CFSetRef"), appkit_flags);
|
||||
AddCXXSummary(appkit_category_sp, lldb_private::formatters::NSSetSummaryProvider<true>, "CFMutableSetRef summary", ConstString("CFMutableSetRef"), appkit_flags);
|
||||
AddCXXSummary(appkit_category_sp, lldb_private::formatters::NSSetSummaryProvider<false>, "__NSCFSet summary", ConstString("__NSCFSet"), appkit_flags);
|
||||
AddCXXSummary(appkit_category_sp, lldb_private::formatters::NSSetSummaryProvider<false>, "__NSSetI summary", ConstString("__NSSetI"), appkit_flags);
|
||||
AddCXXSummary(appkit_category_sp, lldb_private::formatters::NSSetSummaryProvider<false>, "__NSSetM summary", ConstString("__NSSetM"), appkit_flags);
|
||||
AddCXXSummary(appkit_category_sp, lldb_private::formatters::NSSetSummaryProvider<false>, "NSCountedSet summary", ConstString("NSCountedSet"), appkit_flags);
|
||||
|
||||
AddCXXSummary(appkit_category_sp, lldb_private::formatters::NSURLSummaryProvider, "NSURL summary provider", ConstString("NSURL"), appkit_flags);
|
||||
AddCXXSummary(appkit_category_sp, lldb_private::formatters::NSURLSummaryProvider, "NSURL summary provider", ConstString("CFURLRef"), appkit_flags);
|
||||
|
|
|
@ -111,6 +111,336 @@ lldb_private::formatters::NSSetSummaryProvider (ValueObject& valobj, Stream& str
|
|||
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
|
||||
{
|
||||
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->IsDynamic())
|
||||
valobj_sp = valobj_sp->GetStaticValue();
|
||||
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();
|
||||
|
||||
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);
|
||||
ProcessSP process_sp = m_exe_ctx_ref.GetProcessSP();
|
||||
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)
|
||||
{
|
||||
// make the new ValueObject
|
||||
StreamString expr;
|
||||
expr.Printf("(id)%" PRIu64,set_item.item_ptr);
|
||||
StreamString idx_name;
|
||||
idx_name.Printf("[%zu]",idx);
|
||||
set_item.valobj_sp = ValueObject::CreateValueObjectFromExpression(idx_name.GetData(), expr.GetData(), m_exe_ctx_ref);
|
||||
}
|
||||
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->IsDynamic())
|
||||
valobj_sp = valobj_sp->GetStaticValue();
|
||||
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();
|
||||
|
||||
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);
|
||||
ProcessSP process_sp = m_exe_ctx_ref.GetProcessSP();
|
||||
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)
|
||||
{
|
||||
// make the new ValueObject
|
||||
StreamString expr;
|
||||
expr.Printf("(id)%" PRIu64,set_item.item_ptr);
|
||||
StreamString idx_name;
|
||||
idx_name.Printf("[%zu]",idx);
|
||||
set_item.valobj_sp = ValueObject::CreateValueObjectFromExpression(idx_name.GetData(), expr.GetData(), m_exe_ctx_ref);
|
||||
}
|
||||
return set_item.valobj_sp;
|
||||
}
|
||||
|
||||
template bool
|
||||
lldb_private::formatters::NSSetSummaryProvider<true> (ValueObject& valobj, Stream& stream);
|
||||
|
||||
|
|
|
@ -0,0 +1,9 @@
|
|||
LEVEL = ../../../make
|
||||
|
||||
OBJC_SOURCES := main.m
|
||||
|
||||
CFLAGS_EXTRAS += -w
|
||||
|
||||
include $(LEVEL)/Makefile.rules
|
||||
|
||||
LDFLAGS += -framework Foundation
|
|
@ -0,0 +1,89 @@
|
|||
"""
|
||||
Test lldb data formatter subsystem.
|
||||
"""
|
||||
|
||||
import os, time
|
||||
import unittest2
|
||||
import lldb
|
||||
from lldbtest import *
|
||||
import datetime
|
||||
import lldbutil
|
||||
|
||||
class DataFormatterRdar12529957TestCase(TestBase):
|
||||
|
||||
mydir = os.path.join("functionalities", "data-formatter", "rdar-12529957")
|
||||
|
||||
@unittest2.skipUnless(sys.platform.startswith("darwin"), "requires Darwin")
|
||||
@dsym_test
|
||||
def test_rdar12529957_with_dsym_and_run_command(self):
|
||||
"""Test that NSSet reports its synthetic children properly."""
|
||||
self.buildDsym()
|
||||
self.rdar12529957_tester()
|
||||
|
||||
@unittest2.skipUnless(sys.platform.startswith("darwin"), "requires Darwin")
|
||||
@dwarf_test
|
||||
def test_rdar12529957_with_dwarf_and_run_command(self):
|
||||
"""Test that NSSet reports its synthetic children properly."""
|
||||
self.buildDwarf()
|
||||
self.rdar12529957_tester()
|
||||
|
||||
def setUp(self):
|
||||
# Call super's setUp().
|
||||
TestBase.setUp(self)
|
||||
# Find the line number to break at.
|
||||
self.line = line_number('main.m', '// Set break point at this line.')
|
||||
|
||||
def rdar12529957_tester(self):
|
||||
"""Test that NSSet reports its synthetic children properly."""
|
||||
self.runCmd("file a.out", CURRENT_EXECUTABLE_SET)
|
||||
|
||||
lldbutil.run_break_set_by_file_and_line (self, "main.m", self.line, num_expected_locations=1, loc_exact=True)
|
||||
|
||||
self.runCmd("run", RUN_SUCCEEDED)
|
||||
|
||||
# The stop reason of the thread should be breakpoint.
|
||||
self.expect("thread list", STOPPED_DUE_TO_BREAKPOINT,
|
||||
substrs = ['stopped',
|
||||
'stop reason = breakpoint'])
|
||||
|
||||
# This is the function to remove the custom formats in order to have a
|
||||
# clean slate for the next test case.
|
||||
def cleanup():
|
||||
self.runCmd('type format clear', check=False)
|
||||
self.runCmd('type summary clear', check=False)
|
||||
self.runCmd('type synth clear', check=False)
|
||||
|
||||
# Execute the cleanup function during test case tear down.
|
||||
self.addTearDownHook(cleanup)
|
||||
|
||||
# Now check that we are displaying Cocoa classes correctly
|
||||
self.expect('frame variable set',
|
||||
substrs = ['4 objects'])
|
||||
self.expect('frame variable mutable',
|
||||
substrs = ['9 objects'])
|
||||
self.expect('frame variable set --ptr-depth 1 -d run -T',
|
||||
substrs = ['4 objects','[0]','[1]','[2]','[3]','hello','world','(int)1','(int)2'])
|
||||
self.expect('frame variable mutable --ptr-depth 1 -d run -T',
|
||||
substrs = ['9 objects','(int)5','@"3 objects"','@"www.apple.com"','(int)3','@"world"','(int)4'])
|
||||
|
||||
self.runCmd("next")
|
||||
self.expect('frame variable mutable',
|
||||
substrs = ['0 objects'])
|
||||
|
||||
self.runCmd("next")
|
||||
self.expect('frame variable mutable',
|
||||
substrs = ['4 objects'])
|
||||
self.expect('frame variable mutable --ptr-depth 1 -d run -T',
|
||||
substrs = ['4 objects','[0]','[1]','[2]','[3]','hello','world','(int)1','(int)2'])
|
||||
|
||||
self.runCmd("next")
|
||||
self.expect('frame variable mutable',
|
||||
substrs = ['4 objects'])
|
||||
self.expect('frame variable mutable --ptr-depth 1 -d run -T',
|
||||
substrs = ['4 objects','[0]','[1]','[2]','[3]','hello','world','(int)1','(int)2'])
|
||||
|
||||
if __name__ == '__main__':
|
||||
import atexit
|
||||
lldb.SBDebugger.Initialize()
|
||||
atexit.register(lambda: lldb.SBDebugger.Terminate())
|
||||
unittest2.main()
|
|
@ -0,0 +1,34 @@
|
|||
//===-- main.m ------------------------------------------------*- ObjC -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
int main (int argc, const char * argv[])
|
||||
{
|
||||
|
||||
NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
|
||||
|
||||
NSSet* set = [NSSet setWithArray:@[@1,@"hello",@2,@"world"]];
|
||||
NSMutableSet* mutable = [NSMutableSet setWithCapacity:5];
|
||||
[mutable addObject:@1];
|
||||
[mutable addObject:@2];
|
||||
[mutable addObject:@3];
|
||||
[mutable addObject:@4];
|
||||
[mutable addObject:@5];
|
||||
[mutable addObject:[NSURL URLWithString:@"www.apple.com"]];
|
||||
[mutable addObject:@[@1,@2,@3]];
|
||||
[mutable unionSet:set];
|
||||
[mutable removeAllObjects]; // Set break point at this line.
|
||||
[mutable unionSet:set];
|
||||
[mutable addObject:@1];
|
||||
|
||||
[pool drain];
|
||||
return 0;
|
||||
}
|
||||
|
Loading…
Reference in New Issue