<rdar://problem/11086338> Implementing support for synthetic children generated by running C++ code instead of Python scripts ; Adding a bunch of value-generating APIs to our private code layer ; Providing synthetic children for NSArray

llvm-svn: 163818
This commit is contained in:
Enrico Granata 2012-09-13 18:27:09 +00:00
parent d0080c45f9
commit b2698cdf59
15 changed files with 898 additions and 78 deletions

View File

@ -13,44 +13,161 @@
#include <stdint.h>
#include "lldb/lldb-forward.h"
#include "lldb/Core/ConstString.h"
#include "lldb/Core/FormatClasses.h"
#include "clang/AST/ASTContext.h"
namespace lldb_private {
namespace formatters
{
bool
CodeRunning_Fetcher (ValueObject &valobj,
ExtractValueFromObjCExpression (ValueObject &valobj,
const char* target_type,
const char* selector,
uint64_t &value);
lldb::ValueObjectSP
CallSelectorOnObject (ValueObject &valobj,
const char* return_type,
const char* selector,
uint64_t index);
lldb::ValueObjectSP
CallSelectorOnObject (ValueObject &valobj,
const char* return_type,
const char* selector,
const char* key);
template<bool name_entries>
bool
NSDictionary_SummaryProvider (ValueObject& valobj, Stream& stream);
NSDictionarySummaryProvider (ValueObject& valobj, Stream& stream);
bool
NSArray_SummaryProvider (ValueObject& valobj, Stream& stream);
NSArraySummaryProvider (ValueObject& valobj, Stream& stream);
template<bool needs_at>
bool
NSData_SummaryProvider (ValueObject& valobj, Stream& stream);
NSDataSummaryProvider (ValueObject& valobj, Stream& stream);
bool
NSNumber_SummaryProvider (ValueObject& valobj, Stream& stream);
NSNumberSummaryProvider (ValueObject& valobj, Stream& stream);
bool
NSString_SummaryProvider (ValueObject& valobj, Stream& stream);
NSStringSummaryProvider (ValueObject& valobj, Stream& stream);
extern template bool
NSDictionary_SummaryProvider<true> (ValueObject&, Stream&) ;
NSDictionarySummaryProvider<true> (ValueObject&, Stream&) ;
extern template bool
NSDictionary_SummaryProvider<false> (ValueObject&, Stream&) ;
NSDictionarySummaryProvider<false> (ValueObject&, Stream&) ;
extern template bool
NSData_SummaryProvider<true> (ValueObject&, Stream&) ;
NSDataSummaryProvider<true> (ValueObject&, Stream&) ;
extern template bool
NSData_SummaryProvider<false> (ValueObject&, Stream&) ;
NSDataSummaryProvider<false> (ValueObject&, Stream&) ;
class NSArrayMSyntheticFrontEnd : public SyntheticChildrenFrontEnd
{
private:
struct DataDescriptor_32
{
uint32_t _used;
uint32_t _priv1 : 2 ;
uint32_t _size : 30;
uint32_t _priv2 : 2;
uint32_t offset : 30;
uint32_t _priv3;
uint32_t _data;
};
struct DataDescriptor_64
{
uint64_t _used;
uint64_t _priv1 : 2 ;
uint64_t _size : 62;
uint64_t _priv2 : 2;
uint64_t offset : 62;
uint32_t _priv3;
uint64_t _data;
};
public:
NSArrayMSyntheticFrontEnd (lldb::ValueObjectSP valobj_sp);
virtual uint32_t
CalculateNumChildren ();
virtual lldb::ValueObjectSP
GetChildAtIndex (uint32_t idx);
virtual bool
Update();
virtual uint32_t
GetIndexOfChildWithName (const ConstString &name);
virtual
~NSArrayMSyntheticFrontEnd ();
private:
ExecutionContextRef m_exe_ctx_ref;
uint8_t m_ptr_size;
DataDescriptor_32 *m_data_32;
DataDescriptor_64 *m_data_64;
ClangASTType m_id_type;
std::vector<lldb::ValueObjectSP> m_children;
};
class NSArrayISyntheticFrontEnd : public SyntheticChildrenFrontEnd
{
public:
NSArrayISyntheticFrontEnd (lldb::ValueObjectSP valobj_sp);
virtual uint32_t
CalculateNumChildren ();
virtual lldb::ValueObjectSP
GetChildAtIndex (uint32_t idx);
virtual bool
Update();
virtual uint32_t
GetIndexOfChildWithName (const ConstString &name);
virtual
~NSArrayISyntheticFrontEnd ();
private:
ExecutionContextRef m_exe_ctx_ref;
uint8_t m_ptr_size;
uint64_t m_items;
lldb::addr_t m_data_ptr;
ClangASTType m_id_type;
std::vector<lldb::ValueObjectSP> m_children;
};
class NSArrayCodeRunningSyntheticFrontEnd : public SyntheticChildrenFrontEnd
{
public:
NSArrayCodeRunningSyntheticFrontEnd (lldb::ValueObjectSP valobj_sp);
virtual uint32_t
CalculateNumChildren ();
virtual lldb::ValueObjectSP
GetChildAtIndex (uint32_t idx);
virtual bool
Update();
virtual uint32_t
GetIndexOfChildWithName (const ConstString &name);
virtual
~NSArrayCodeRunningSyntheticFrontEnd ();
};
SyntheticChildrenFrontEnd* NSArraySyntheticFrontEndCreator (CXXSyntheticChildren*, lldb::ValueObjectSP);
}
}

View File

@ -241,7 +241,7 @@ public:
CalculateNumChildren() = 0;
virtual lldb::ValueObjectSP
GetChildAtIndex (uint32_t idx, bool can_create) = 0;
GetChildAtIndex (uint32_t idx) = 0;
virtual uint32_t
GetIndexOfChildWithName (const ConstString &name) = 0;
@ -556,11 +556,11 @@ public:
}
virtual lldb::ValueObjectSP
GetChildAtIndex (uint32_t idx, bool can_create)
GetChildAtIndex (uint32_t idx)
{
if (idx >= filter->GetCount())
return lldb::ValueObjectSP();
return m_backend.GetSyntheticExpressionPathChild(filter->GetExpressionPathAtIndex(idx), can_create);
return m_backend.GetSyntheticExpressionPathChild(filter->GetExpressionPathAtIndex(idx), true);
}
virtual bool
@ -602,6 +602,42 @@ private:
DISALLOW_COPY_AND_ASSIGN(TypeFilterImpl);
};
class CXXSyntheticChildren : public SyntheticChildren
{
public:
typedef SyntheticChildrenFrontEnd* (*CreateFrontEndCallback) (CXXSyntheticChildren*, lldb::ValueObjectSP);
protected:
CreateFrontEndCallback m_create_callback;
std::string m_description;
public:
CXXSyntheticChildren(const SyntheticChildren::Flags& flags,
const char* description,
CreateFrontEndCallback callback) :
SyntheticChildren(flags),
m_create_callback(callback),
m_description(description ? description : "")
{
}
bool
IsScripted()
{
return false;
}
std::string
GetDescription();
virtual SyntheticChildrenFrontEnd::AutoPointer
GetFrontEnd(ValueObject &backend)
{
return SyntheticChildrenFrontEnd::AutoPointer(m_create_callback(this, backend.GetSP()));
}
private:
DISALLOW_COPY_AND_ASSIGN(CXXSyntheticChildren);
};
#ifndef LLDB_DISABLE_PYTHON
class TypeSyntheticImpl : public SyntheticChildren
@ -680,7 +716,7 @@ public:
}
virtual lldb::ValueObjectSP
GetChildAtIndex (uint32_t idx, bool can_create);
GetChildAtIndex (uint32_t idx);
virtual bool
Update()
@ -888,11 +924,11 @@ public:
}
virtual lldb::ValueObjectSP
GetChildAtIndex (uint32_t idx, bool can_create)
GetChildAtIndex (uint32_t idx)
{
if (idx >= filter->GetCount())
return lldb::ValueObjectSP();
return m_backend.GetSyntheticArrayMember(filter->GetRealIndexForIndex(idx), can_create);
return m_backend.GetSyntheticArrayMember(filter->GetRealIndexForIndex(idx), true);
}
virtual bool

View File

@ -25,6 +25,9 @@
#include "lldb/Core/Log.h"
#include "lldb/Core/RegularExpression.h"
#include "lldb/Core/ValueObject.h"
#include "lldb/Symbol/ClangASTContext.h"
#include "lldb/Target/ObjCLanguageRuntime.h"
#include "lldb/Target/Process.h"
#include "lldb/Target/StackFrame.h"
@ -578,8 +581,7 @@ protected:
return true;
}
}
if (typePtr->isPointerType())
else if (typePtr->isPointerType())
{
if (log)
log->Printf("stripping pointer");
@ -591,7 +593,13 @@ protected:
}
}
if (typePtr->isObjCObjectPointerType())
bool canBeObjCDynamic = ClangASTContext::IsPossibleDynamicType (valobj.GetClangAST(),
type.getAsOpaquePtr(),
NULL,
false, // no C++
true); // yes ObjC
if (canBeObjCDynamic)
{
if (use_dynamic != lldb::eNoDynamicValues)
{

View File

@ -910,6 +910,23 @@ public:
ValueObject *valobj,
const DumpValueObjectOptions& options);
static lldb::ValueObjectSP
CreateValueObjectFromExpression (const char* name,
const char* expression,
const ExecutionContext& exe_ctx);
static lldb::ValueObjectSP
CreateValueObjectFromAddress (const char* name,
uint64_t address,
const ExecutionContext& exe_ctx,
ClangASTType type);
static lldb::ValueObjectSP
CreateValueObjectFromData (const char* name,
DataExtractor& data,
const ExecutionContext& exe_ctx,
ClangASTType type);
static void
LogValueObject (Log *log,
ValueObject *valobj);

View File

@ -85,6 +85,7 @@ class Condition;
class Connection;
class ConnectionFileDescriptor;
class ConstString;
class CXXSyntheticChildren;
class DWARFCallFrameInfo;
class DWARFExpression;
class DataBuffer;

View File

@ -13,8 +13,12 @@
#define CLANG_NEEDS_THESE_ONE_DAY
#include "clang/Basic/ConvertUTF.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/Target/ObjCLanguageRuntime.h"
#include "lldb/Target/Target.h"
@ -23,7 +27,7 @@ using namespace lldb_private;
using namespace lldb_private::formatters;
bool
lldb_private::formatters::CodeRunning_Fetcher (ValueObject &valobj,
lldb_private::formatters::ExtractValueFromObjCExpression (ValueObject &valobj,
const char* target_type,
const char* selector,
uint64_t &value)
@ -59,9 +63,81 @@ lldb_private::formatters::CodeRunning_Fetcher (ValueObject &valobj,
return true;
}
lldb::ValueObjectSP
lldb_private::formatters::CallSelectorOnObject (ValueObject &valobj,
const char* return_type,
const char* selector,
uint64_t index)
{
lldb::ValueObjectSP valobj_sp;
if (!return_type || !*return_type)
return valobj_sp;
if (!selector || !*selector)
return valobj_sp;
StreamString expr_path_stream;
valobj.GetExpressionPath(expr_path_stream, false);
StreamString expr;
expr.Printf("(%s)[%s %s:%lld]",return_type,expr_path_stream.GetData(),selector,index);
ExecutionContext exe_ctx (valobj.GetExecutionContextRef());
lldb::ValueObjectSP result_sp;
Target* target = exe_ctx.GetTargetPtr();
StackFrame* stack_frame = exe_ctx.GetFramePtr();
if (!target || !stack_frame)
return valobj_sp;
Target::EvaluateExpressionOptions options;
options.SetCoerceToId(false)
.SetUnwindOnError(true)
.SetKeepInMemory(true)
.SetUseDynamic(lldb::eDynamicCanRunTarget);
target->EvaluateExpression(expr.GetData(),
stack_frame,
valobj_sp,
options);
return valobj_sp;
}
lldb::ValueObjectSP
lldb_private::formatters::CallSelectorOnObject (ValueObject &valobj,
const char* return_type,
const char* selector,
const char* key)
{
lldb::ValueObjectSP valobj_sp;
if (!return_type || !*return_type)
return valobj_sp;
if (!selector || !*selector)
return valobj_sp;
if (!key || !*key)
return valobj_sp;
StreamString expr_path_stream;
valobj.GetExpressionPath(expr_path_stream, false);
StreamString expr;
expr.Printf("(%s)[%s %s:%s]",return_type,expr_path_stream.GetData(),selector,key);
ExecutionContext exe_ctx (valobj.GetExecutionContextRef());
lldb::ValueObjectSP result_sp;
Target* target = exe_ctx.GetTargetPtr();
StackFrame* stack_frame = exe_ctx.GetFramePtr();
if (!target || !stack_frame)
return valobj_sp;
Target::EvaluateExpressionOptions options;
options.SetCoerceToId(false)
.SetUnwindOnError(true)
.SetKeepInMemory(true)
.SetUseDynamic(lldb::eDynamicCanRunTarget);
target->EvaluateExpression(expr.GetData(),
stack_frame,
valobj_sp,
options);
return valobj_sp;
}
template<bool name_entries>
bool
lldb_private::formatters::NSDictionary_SummaryProvider (ValueObject& valobj, Stream& stream)
lldb_private::formatters::NSDictionarySummaryProvider (ValueObject& valobj, Stream& stream)
{
ProcessSP process_sp = valobj.GetProcessSP();
if (!process_sp)
@ -115,7 +191,7 @@ lldb_private::formatters::NSDictionary_SummaryProvider (ValueObject& valobj, Str
}
else
{
if (!CodeRunning_Fetcher(valobj, "int", "count", value))
if (!ExtractValueFromObjCExpression(valobj, "int", "count", value))
return false;
}
@ -128,7 +204,7 @@ lldb_private::formatters::NSDictionary_SummaryProvider (ValueObject& valobj, Str
}
bool
lldb_private::formatters::NSArray_SummaryProvider (ValueObject& valobj, Stream& stream)
lldb_private::formatters::NSArraySummaryProvider (ValueObject& valobj, Stream& stream)
{
ProcessSP process_sp = valobj.GetProcessSP();
if (!process_sp)
@ -177,7 +253,7 @@ lldb_private::formatters::NSArray_SummaryProvider (ValueObject& valobj, Stream&
}
else
{
if (!CodeRunning_Fetcher(valobj, "int", "count", value))
if (!ExtractValueFromObjCExpression(valobj, "int", "count", value))
return false;
}
@ -189,7 +265,7 @@ lldb_private::formatters::NSArray_SummaryProvider (ValueObject& valobj, Stream&
template<bool needs_at>
bool
lldb_private::formatters::NSData_SummaryProvider (ValueObject& valobj, Stream& stream)
lldb_private::formatters::NSDataSummaryProvider (ValueObject& valobj, Stream& stream)
{
ProcessSP process_sp = valobj.GetProcessSP();
if (!process_sp)
@ -226,7 +302,7 @@ lldb_private::formatters::NSData_SummaryProvider (ValueObject& valobj, Stream& s
}
else
{
if (!CodeRunning_Fetcher(valobj, "int", "length", value))
if (!ExtractValueFromObjCExpression(valobj, "int", "length", value))
return false;
}
@ -240,7 +316,7 @@ lldb_private::formatters::NSData_SummaryProvider (ValueObject& valobj, Stream& s
}
bool
lldb_private::formatters::NSNumber_SummaryProvider (ValueObject& valobj, Stream& stream)
lldb_private::formatters::NSNumberSummaryProvider (ValueObject& valobj, Stream& stream)
{
ProcessSP process_sp = valobj.GetProcessSP();
if (!process_sp)
@ -356,7 +432,7 @@ lldb_private::formatters::NSNumber_SummaryProvider (ValueObject& valobj, Stream&
}
else
{
// similar to CodeRunning_Fetcher but uses summary instead of value
// similar to ExtractValueFromObjCExpression but uses summary instead of value
StreamString expr_path_stream;
valobj.GetExpressionPath(expr_path_stream, false);
StreamString expr;
@ -386,7 +462,7 @@ lldb_private::formatters::NSNumber_SummaryProvider (ValueObject& valobj, Stream&
}
bool
lldb_private::formatters::NSString_SummaryProvider (ValueObject& valobj, Stream& stream)
lldb_private::formatters::NSStringSummaryProvider (ValueObject& valobj, Stream& stream)
{
ProcessSP process_sp = valobj.GetProcessSP();
if (!process_sp)
@ -673,14 +749,296 @@ lldb_private::formatters::NSString_SummaryProvider (ValueObject& valobj, Stream&
}
template bool
lldb_private::formatters::NSDictionary_SummaryProvider<true> (ValueObject&, Stream&) ;
lldb_private::formatters::NSArrayMSyntheticFrontEnd::NSArrayMSyntheticFrontEnd (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)
return;
if (valobj_sp->IsDynamic())
valobj_sp = valobj_sp->GetStaticValue();
if (!valobj_sp)
return;
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;
}
error.Clear();
lldb::ProcessSP process_sp(valobj_sp->GetProcessSP());
if (!process_sp)
return;
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;
m_id_type = ClangASTType(valobj_sp->GetClangAST(),valobj_sp->GetClangAST()->ObjCBuiltinIdTy.getAsOpaquePtr());
}
uint32_t
lldb_private::formatters::NSArrayMSyntheticFrontEnd::CalculateNumChildren ()
{
if (m_data_32)
return m_data_32->_used;
if (m_data_64)
return m_data_64->_used;
return 0;
}
lldb::ValueObjectSP
lldb_private::formatters::NSArrayMSyntheticFrontEnd::GetChildAtIndex (uint32_t idx)
{
if (!m_data_32 && !m_data_64)
return lldb::ValueObjectSP();
if (idx >= CalculateNumChildren())
return lldb::ValueObjectSP();
lldb::addr_t object_at_idx = (m_data_32 ? m_data_32->_data : m_data_64->_data);
object_at_idx += (idx * m_ptr_size);
StreamString idx_name;
idx_name.Printf("[%d]",idx);
lldb::ValueObjectSP retval_sp = ValueObject::CreateValueObjectFromAddress(idx_name.GetData(),
object_at_idx,
m_exe_ctx_ref,
m_id_type);
m_children.push_back(retval_sp);
return retval_sp;
}
bool
lldb_private::formatters::NSArrayMSyntheticFrontEnd::Update()
{
m_children.clear();
return false;
}
static uint32_t
ExtractIndexFromString (const char* item_name)
{
if (!item_name || !*item_name)
return UINT32_MAX;
if (*item_name != '[')
return UINT32_MAX;
item_name++;
uint32_t idx = 0;
while(*item_name)
{
char x = *item_name;
if (x == ']')
break;
if (x < '0' || x > '9')
return UINT32_MAX;
idx = 10*idx + (x-'0');
item_name++;
}
return idx;
}
uint32_t
lldb_private::formatters::NSArrayMSyntheticFrontEnd::GetIndexOfChildWithName (const ConstString &name)
{
if (!m_data_32 && !m_data_64)
return UINT32_MAX;
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::NSArrayMSyntheticFrontEnd::~NSArrayMSyntheticFrontEnd ()
{
delete m_data_32;
m_data_32 = NULL;
delete m_data_64;
m_data_64 = NULL;
}
lldb_private::formatters::NSArrayISyntheticFrontEnd::NSArrayISyntheticFrontEnd (lldb::ValueObjectSP valobj_sp) :
SyntheticChildrenFrontEnd(*valobj_sp.get()),
m_exe_ctx_ref(),
m_ptr_size(8),
m_items(0),
m_data_ptr(0)
{
if (!valobj_sp)
return;
if (valobj_sp->IsDynamic())
valobj_sp = valobj_sp->GetStaticValue();
if (!valobj_sp)
return;
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;
}
error.Clear();
lldb::ProcessSP process_sp(valobj_sp->GetProcessSP());
if (!process_sp)
return;
m_ptr_size = process_sp->GetAddressByteSize();
uint64_t data_location = valobj_sp->GetAddressOf() + m_ptr_size;
m_items = process_sp->ReadPointerFromMemory(data_location, error);
if (error.Fail())
return;
m_data_ptr = data_location+m_ptr_size;
m_id_type = ClangASTType(valobj_sp->GetClangAST(),valobj_sp->GetClangAST()->ObjCBuiltinIdTy.getAsOpaquePtr());
}
lldb_private::formatters::NSArrayISyntheticFrontEnd::~NSArrayISyntheticFrontEnd ()
{
}
uint32_t
lldb_private::formatters::NSArrayISyntheticFrontEnd::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;
}
uint32_t
lldb_private::formatters::NSArrayISyntheticFrontEnd::CalculateNumChildren ()
{
return m_items;
}
bool
lldb_private::formatters::NSArrayISyntheticFrontEnd::Update()
{
m_children.clear();
return false;
}
lldb::ValueObjectSP
lldb_private::formatters::NSArrayISyntheticFrontEnd::GetChildAtIndex (uint32_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();
Error error;
object_at_idx = process_sp->ReadPointerFromMemory(object_at_idx, error);
if (error.Fail())
return lldb::ValueObjectSP();
StreamString expr;
expr.Printf("(id)%llu",object_at_idx);
StreamString idx_name;
idx_name.Printf("[%d]",idx);
lldb::ValueObjectSP retval_sp = ValueObject::CreateValueObjectFromExpression(idx_name.GetData(), expr.GetData(), m_exe_ctx_ref);
m_children.push_back(retval_sp);
return retval_sp;
}
SyntheticChildrenFrontEnd* lldb_private::formatters::NSArraySyntheticFrontEndCreator (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 (!strcmp(class_name,"__NSArrayI"))
{
return (new NSArrayISyntheticFrontEnd(valobj_sp));
}
else if (!strcmp(class_name,"__NSArrayM"))
{
return (new NSArrayMSyntheticFrontEnd(valobj_sp));
}
else
{
return (new NSArrayCodeRunningSyntheticFrontEnd(valobj_sp));
}
}
lldb_private::formatters::NSArrayCodeRunningSyntheticFrontEnd::NSArrayCodeRunningSyntheticFrontEnd (lldb::ValueObjectSP valobj_sp) :
SyntheticChildrenFrontEnd(*valobj_sp.get())
{}
uint32_t
lldb_private::formatters::NSArrayCodeRunningSyntheticFrontEnd::CalculateNumChildren ()
{
return 0;
uint64_t count = 0;
if (ExtractValueFromObjCExpression(m_backend, "int", "count", count))
return count;
return 0;
}
lldb::ValueObjectSP
lldb_private::formatters::NSArrayCodeRunningSyntheticFrontEnd::GetChildAtIndex (uint32_t idx)
{
StreamString idx_name;
idx_name.Printf("[%d]",idx);
lldb::ValueObjectSP valobj_sp = CallSelectorOnObject(m_backend,"id","objectAtIndex:",idx);
if (valobj_sp)
valobj_sp->SetName(ConstString(idx_name.GetData()));
return valobj_sp;
}
bool
lldb_private::formatters::NSArrayCodeRunningSyntheticFrontEnd::Update()
{
return false;
}
uint32_t
lldb_private::formatters::NSArrayCodeRunningSyntheticFrontEnd::GetIndexOfChildWithName (const ConstString &name)
{
return 0;
}
lldb_private::formatters::NSArrayCodeRunningSyntheticFrontEnd::~NSArrayCodeRunningSyntheticFrontEnd ()
{}
template bool
lldb_private::formatters::NSDictionary_SummaryProvider<false> (ValueObject&, Stream&) ;
lldb_private::formatters::NSDictionarySummaryProvider<true> (ValueObject&, Stream&) ;
template bool
lldb_private::formatters::NSData_SummaryProvider<true> (ValueObject&, Stream&) ;
lldb_private::formatters::NSDictionarySummaryProvider<false> (ValueObject&, Stream&) ;
template bool
lldb_private::formatters::NSData_SummaryProvider<false> (ValueObject&, Stream&) ;
lldb_private::formatters::NSDataSummaryProvider<true> (ValueObject&, Stream&) ;
template bool
lldb_private::formatters::NSDataSummaryProvider<false> (ValueObject&, Stream&) ;

View File

@ -276,6 +276,20 @@ TypeFilterImpl::GetDescription()
return sstr.GetString();
}
std::string
CXXSyntheticChildren::GetDescription()
{
StreamString sstr;
sstr.Printf("%s%s%s Generator at %p - %s\n",
Cascades() ? "" : " (not cascading)",
SkipsPointers() ? " (skip pointers)" : "",
SkipsReferences() ? " (skip references)" : "",
m_create_callback,
m_description.c_str());
return sstr.GetString();
}
std::string
SyntheticArrayView::GetDescription()
{
@ -329,7 +343,7 @@ TypeSyntheticImpl::FrontEnd::~FrontEnd()
}
lldb::ValueObjectSP
TypeSyntheticImpl::FrontEnd::GetChildAtIndex (uint32_t idx, bool can_create)
TypeSyntheticImpl::FrontEnd::GetChildAtIndex (uint32_t idx)
{
if (!m_wrapper_sp || !m_interpreter)
return lldb::ValueObjectSP();

View File

@ -907,6 +907,16 @@ AddCXXSummary (TypeCategoryImpl::SharedPointer category_sp,
summary_sp);
}
static void AddCXXSynthetic (TypeCategoryImpl::SharedPointer category_sp,
CXXSyntheticChildren::CreateFrontEndCallback generator,
const char* description,
ConstString type_name,
TypeSyntheticImpl::Flags flags)
{
lldb::SyntheticChildrenSP synth_sp(new CXXSyntheticChildren(flags,description,generator));
category_sp->GetSyntheticNavigator()->Add(type_name,synth_sp);
}
void
FormatManager::LoadObjCFormatters()
{
@ -1038,13 +1048,23 @@ FormatManager::LoadObjCFormatters()
.SetShowMembersOneLiner(false)
.SetHideItemNames(false);
AddCXXSummary(appkit_category_sp, lldb_private::formatters::NSArray_SummaryProvider, "NSArray summary provider", ConstString("NSArray"), appkit_flags);
AddCXXSummary(appkit_category_sp, lldb_private::formatters::NSArray_SummaryProvider, "NSArray summary provider", ConstString("NSMutableArray"), appkit_flags);
AddCXXSummary(appkit_category_sp, lldb_private::formatters::NSArray_SummaryProvider, "NSArray summary provider", ConstString("__NSArrayI"), appkit_flags);
AddCXXSummary(appkit_category_sp, lldb_private::formatters::NSArray_SummaryProvider, "NSArray summary provider", ConstString("__NSArrayM"), appkit_flags);
AddCXXSummary(appkit_category_sp, lldb_private::formatters::NSArray_SummaryProvider, "NSArray summary provider", ConstString("__NSCFArray"), appkit_flags);
AddCXXSummary(appkit_category_sp, lldb_private::formatters::NSArray_SummaryProvider, "NSArray summary provider", ConstString("CFArrayRef"), appkit_flags);
AddCXXSummary(appkit_category_sp, lldb_private::formatters::NSArray_SummaryProvider, "NSArray summary provider", ConstString("CFMutableArrayRef"), appkit_flags);
appkit_flags.SetDontShowChildren(false);
AddCXXSummary(appkit_category_sp, lldb_private::formatters::NSArraySummaryProvider, "NSArray summary provider", ConstString("NSArray"), appkit_flags);
AddCXXSummary(appkit_category_sp, lldb_private::formatters::NSArraySummaryProvider, "NSArray summary provider", ConstString("NSMutableArray"), appkit_flags);
AddCXXSummary(appkit_category_sp, lldb_private::formatters::NSArraySummaryProvider, "NSArray summary provider", ConstString("__NSArrayI"), appkit_flags);
AddCXXSummary(appkit_category_sp, lldb_private::formatters::NSArraySummaryProvider, "NSArray summary provider", ConstString("__NSArrayM"), appkit_flags);
AddCXXSummary(appkit_category_sp, lldb_private::formatters::NSArraySummaryProvider, "NSArray summary provider", ConstString("__NSCFArray"), appkit_flags);
AddCXXSummary(appkit_category_sp, lldb_private::formatters::NSArraySummaryProvider, "NSArray summary provider", ConstString("CFArrayRef"), appkit_flags);
AddCXXSummary(appkit_category_sp, lldb_private::formatters::NSArraySummaryProvider, "NSArray summary provider", ConstString("CFMutableArrayRef"), appkit_flags);
appkit_flags.SetDontShowChildren(true);
AddCXXSynthetic(appkit_category_sp, lldb_private::formatters::NSArraySyntheticFrontEndCreator, "NSArray synthetic children", ConstString("__NSArrayM"), TypeSyntheticImpl::Flags());
AddCXXSynthetic(appkit_category_sp, lldb_private::formatters::NSArraySyntheticFrontEndCreator, "NSArray synthetic children", ConstString("__NSArrayI"), TypeSyntheticImpl::Flags());
AddCXXSynthetic(appkit_category_sp, lldb_private::formatters::NSArraySyntheticFrontEndCreator, "NSArray synthetic children", ConstString("NSArray"), TypeSyntheticImpl::Flags());
AddCXXSynthetic(appkit_category_sp, lldb_private::formatters::NSArraySyntheticFrontEndCreator, "NSArray synthetic children", ConstString("NSMutableArray"), TypeSyntheticImpl::Flags());
AddCXXSynthetic(appkit_category_sp, lldb_private::formatters::NSArraySyntheticFrontEndCreator, "NSArray synthetic children", ConstString("__NSCFArray"), TypeSyntheticImpl::Flags());
#ifndef LLDB_DISABLE_PYTHON
AddScriptSummary(appkit_category_sp, "lldb.formatters.objc.CFBag.CFBag_SummaryProvider", ConstString("CFBagRef"), appkit_flags);
@ -1056,21 +1076,21 @@ FormatManager::LoadObjCFormatters()
AddScriptSummary(appkit_category_sp, "lldb.formatters.objc.CFBinaryHeap.CFBinaryHeap_SummaryProvider", ConstString("__CFBinaryHeap"), appkit_flags);
#endif // LLDB_DISABLE_PYTHON
AddCXXSummary(appkit_category_sp, lldb_private::formatters::NSDictionary_SummaryProvider<false>, "NSDictionary summary provider", ConstString("NSDictionary"), appkit_flags);
AddCXXSummary(appkit_category_sp, lldb_private::formatters::NSDictionary_SummaryProvider<false>, "NSDictionary summary provider", ConstString("__NSCFDictionary"), appkit_flags);
AddCXXSummary(appkit_category_sp, lldb_private::formatters::NSDictionary_SummaryProvider<false>, "NSDictionary summary provider", ConstString("__NSDictionaryI"), appkit_flags);
AddCXXSummary(appkit_category_sp, lldb_private::formatters::NSDictionary_SummaryProvider<false>, "NSDictionary summary provider", ConstString("__NSDictionaryM"), appkit_flags);
AddCXXSummary(appkit_category_sp, lldb_private::formatters::NSDictionary_SummaryProvider<true>, "NSDictionary summary provider", ConstString("CFDictionaryRef"), appkit_flags);
AddCXXSummary(appkit_category_sp, lldb_private::formatters::NSDictionary_SummaryProvider<true>, "NSDictionary summary provider", ConstString("CFMutableDictionaryRef"), appkit_flags);
AddCXXSummary(appkit_category_sp, lldb_private::formatters::NSDictionarySummaryProvider<false>, "NSDictionary summary provider", ConstString("NSDictionary"), appkit_flags);
AddCXXSummary(appkit_category_sp, lldb_private::formatters::NSDictionarySummaryProvider<false>, "NSDictionary summary provider", ConstString("__NSCFDictionary"), appkit_flags);
AddCXXSummary(appkit_category_sp, lldb_private::formatters::NSDictionarySummaryProvider<false>, "NSDictionary summary provider", ConstString("__NSDictionaryI"), appkit_flags);
AddCXXSummary(appkit_category_sp, lldb_private::formatters::NSDictionarySummaryProvider<false>, "NSDictionary summary provider", ConstString("__NSDictionaryM"), appkit_flags);
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::NSString_SummaryProvider, "NSString summary provider", ConstString("NSString"), appkit_flags);
AddCXXSummary(appkit_category_sp, lldb_private::formatters::NSString_SummaryProvider, "NSString summary provider", ConstString("CFStringRef"), appkit_flags);
AddCXXSummary(appkit_category_sp, lldb_private::formatters::NSString_SummaryProvider, "NSString summary provider", ConstString("CFMutableStringRef"), appkit_flags);
AddCXXSummary(appkit_category_sp, lldb_private::formatters::NSString_SummaryProvider, "NSString summary provider", ConstString("__NSCFConstantString"), appkit_flags);
AddCXXSummary(appkit_category_sp, lldb_private::formatters::NSString_SummaryProvider, "NSString summary provider", ConstString("__NSCFString"), appkit_flags);
AddCXXSummary(appkit_category_sp, lldb_private::formatters::NSString_SummaryProvider, "NSString summary provider", ConstString("NSCFConstantString"), appkit_flags);
AddCXXSummary(appkit_category_sp, lldb_private::formatters::NSString_SummaryProvider, "NSString summary provider", ConstString("NSCFString"), appkit_flags);
AddCXXSummary(appkit_category_sp, lldb_private::formatters::NSString_SummaryProvider, "NSString summary provider", ConstString("NSPathStore2"), appkit_flags);
AddCXXSummary(appkit_category_sp, lldb_private::formatters::NSStringSummaryProvider, "NSString summary provider", ConstString("NSString"), appkit_flags);
AddCXXSummary(appkit_category_sp, lldb_private::formatters::NSStringSummaryProvider, "NSString summary provider", ConstString("CFStringRef"), appkit_flags);
AddCXXSummary(appkit_category_sp, lldb_private::formatters::NSStringSummaryProvider, "NSString summary provider", ConstString("CFMutableStringRef"), appkit_flags);
AddCXXSummary(appkit_category_sp, lldb_private::formatters::NSStringSummaryProvider, "NSString summary provider", ConstString("__NSCFConstantString"), appkit_flags);
AddCXXSummary(appkit_category_sp, lldb_private::formatters::NSStringSummaryProvider, "NSString summary provider", ConstString("__NSCFString"), appkit_flags);
AddCXXSummary(appkit_category_sp, lldb_private::formatters::NSStringSummaryProvider, "NSString summary provider", ConstString("NSCFConstantString"), appkit_flags);
AddCXXSummary(appkit_category_sp, lldb_private::formatters::NSStringSummaryProvider, "NSString summary provider", ConstString("NSCFString"), appkit_flags);
AddCXXSummary(appkit_category_sp, lldb_private::formatters::NSStringSummaryProvider, "NSString summary provider", ConstString("NSPathStore2"), appkit_flags);
#ifndef LLDB_DISABLE_PYTHON
AddScriptSummary(appkit_category_sp, "lldb.formatters.objc.CFString.CFAttributedString_SummaryProvider", ConstString("NSAttributedString"), appkit_flags);
@ -1078,12 +1098,12 @@ FormatManager::LoadObjCFormatters()
AddScriptSummary(appkit_category_sp, "lldb.formatters.objc.NSBundle.NSBundle_SummaryProvider", ConstString("NSBundle"), appkit_flags);
#endif // LLDB_DISABLE_PYTHON
AddCXXSummary(appkit_category_sp, lldb_private::formatters::NSData_SummaryProvider<false>, "NSData summary provider", ConstString("NSData"), appkit_flags);
AddCXXSummary(appkit_category_sp, lldb_private::formatters::NSData_SummaryProvider<false>, "NSData summary provider", ConstString("NSConcreteData"), appkit_flags);
AddCXXSummary(appkit_category_sp, lldb_private::formatters::NSData_SummaryProvider<false>, "NSData summary provider", ConstString("NSConcreteMutableData"), appkit_flags);
AddCXXSummary(appkit_category_sp, lldb_private::formatters::NSData_SummaryProvider<false>, "NSData summary provider", ConstString("__NSCFData"), appkit_flags);
AddCXXSummary(appkit_category_sp, lldb_private::formatters::NSData_SummaryProvider<true>, "NSData summary provider", ConstString("CFDataRef"), appkit_flags);
AddCXXSummary(appkit_category_sp, lldb_private::formatters::NSData_SummaryProvider<true>, "NSData summary provider", ConstString("CFMutableDataRef"), appkit_flags);
AddCXXSummary(appkit_category_sp, lldb_private::formatters::NSDataSummaryProvider<false>, "NSData summary provider", ConstString("NSData"), appkit_flags);
AddCXXSummary(appkit_category_sp, lldb_private::formatters::NSDataSummaryProvider<false>, "NSData summary provider", ConstString("NSConcreteData"), appkit_flags);
AddCXXSummary(appkit_category_sp, lldb_private::formatters::NSDataSummaryProvider<false>, "NSData summary provider", ConstString("NSConcreteMutableData"), appkit_flags);
AddCXXSummary(appkit_category_sp, lldb_private::formatters::NSDataSummaryProvider<false>, "NSData summary provider", ConstString("__NSCFData"), appkit_flags);
AddCXXSummary(appkit_category_sp, lldb_private::formatters::NSDataSummaryProvider<true>, "NSData summary provider", ConstString("CFDataRef"), appkit_flags);
AddCXXSummary(appkit_category_sp, lldb_private::formatters::NSDataSummaryProvider<true>, "NSData summary provider", ConstString("CFMutableDataRef"), appkit_flags);
#ifndef LLDB_DISABLE_PYTHON
AddScriptSummary(appkit_category_sp, "lldb.formatters.objc.NSException.NSException_SummaryProvider", ConstString("NSException"), appkit_flags);
@ -1094,11 +1114,11 @@ FormatManager::LoadObjCFormatters()
AddScriptSummary(appkit_category_sp, "lldb.formatters.objc.NSNotification.NSNotification_SummaryProvider", ConstString("NSConcreteNotification"), appkit_flags);
#endif // LLDB_DISABLE_PYTHON
AddCXXSummary(appkit_category_sp, lldb_private::formatters::NSNumber_SummaryProvider, "NSNumber summary provider", ConstString("NSNumber"), appkit_flags);
AddCXXSummary(appkit_category_sp, lldb_private::formatters::NSNumber_SummaryProvider, "NSNumber summary provider", ConstString("__NSCFBoolean"), appkit_flags);
AddCXXSummary(appkit_category_sp, lldb_private::formatters::NSNumber_SummaryProvider, "NSNumber summary provider", ConstString("__NSCFNumber"), appkit_flags);
AddCXXSummary(appkit_category_sp, lldb_private::formatters::NSNumber_SummaryProvider, "NSNumber summary provider", ConstString("NSCFBoolean"), appkit_flags);
AddCXXSummary(appkit_category_sp, lldb_private::formatters::NSNumber_SummaryProvider, "NSNumber summary provider", ConstString("NSCFNumber"), appkit_flags);
AddCXXSummary(appkit_category_sp, lldb_private::formatters::NSNumberSummaryProvider, "NSNumber summary provider", ConstString("NSNumber"), appkit_flags);
AddCXXSummary(appkit_category_sp, lldb_private::formatters::NSNumberSummaryProvider, "NSNumber summary provider", ConstString("__NSCFBoolean"), appkit_flags);
AddCXXSummary(appkit_category_sp, lldb_private::formatters::NSNumberSummaryProvider, "NSNumber summary provider", ConstString("__NSCFNumber"), appkit_flags);
AddCXXSummary(appkit_category_sp, lldb_private::formatters::NSNumberSummaryProvider, "NSNumber summary provider", ConstString("NSCFBoolean"), appkit_flags);
AddCXXSummary(appkit_category_sp, lldb_private::formatters::NSNumberSummaryProvider, "NSNumber summary provider", ConstString("NSCFNumber"), appkit_flags);
#ifndef LLDB_DISABLE_PYTHON
AddScriptSummary(appkit_category_sp, "lldb.formatters.objc.NSSet.NSSet_SummaryProvider", ConstString("NSSet"), appkit_flags);

View File

@ -3990,3 +3990,67 @@ ValueObject::GetSymbolContextScope()
}
return NULL;
}
lldb::ValueObjectSP
ValueObject::CreateValueObjectFromExpression (const char* name,
const char* expression,
const ExecutionContext& exe_ctx)
{
lldb::ValueObjectSP retval_sp;
lldb::TargetSP target_sp(exe_ctx.GetTargetSP());
if (!target_sp)
return retval_sp;
if (!expression || !*expression)
return retval_sp;
target_sp->EvaluateExpression (expression,
exe_ctx.GetFrameSP().get(),
retval_sp);
if (retval_sp && name && *name)
retval_sp->SetName(ConstString(name));
return retval_sp;
}
lldb::ValueObjectSP
ValueObject::CreateValueObjectFromAddress (const char* name,
uint64_t address,
const ExecutionContext& exe_ctx,
ClangASTType type)
{
ClangASTType pointer_type(type.GetASTContext(),type.GetPointerType());
lldb::DataBufferSP buffer(new lldb_private::DataBufferHeap(&address,sizeof(lldb::addr_t)));
lldb::ValueObjectSP ptr_result_valobj_sp(ValueObjectConstResult::Create (exe_ctx.GetBestExecutionContextScope(),
pointer_type.GetASTContext(),
pointer_type.GetOpaqueQualType(),
ConstString(name),
buffer,
lldb::endian::InlHostByteOrder(),
exe_ctx.GetAddressByteSize()));
if (ptr_result_valobj_sp)
{
ptr_result_valobj_sp->GetValue().SetValueType(Value::eValueTypeLoadAddress);
Error err;
ptr_result_valobj_sp = ptr_result_valobj_sp->Dereference(err);
if (ptr_result_valobj_sp && name && *name)
ptr_result_valobj_sp->SetName(ConstString(name));
}
return ptr_result_valobj_sp;
}
lldb::ValueObjectSP
ValueObject::CreateValueObjectFromData (const char* name,
DataExtractor& data,
const ExecutionContext& exe_ctx,
ClangASTType type)
{
lldb::ValueObjectSP new_value_sp;
new_value_sp = ValueObjectConstResult::Create (exe_ctx.GetBestExecutionContextScope(),
type.GetASTContext() ,
type.GetOpaqueQualType(),
ConstString(name),
data,
LLDB_INVALID_ADDRESS);
new_value_sp->SetAddressTypeOfChildren(eAddressTypeLoad);
if (new_value_sp && name && *name)
new_value_sp->SetName(ConstString(name));
return new_value_sp;
}

View File

@ -121,7 +121,7 @@ ValueObjectSynthetic::GetChildAtIndex (uint32_t idx, bool can_create)
{
if (can_create && m_synth_filter_ap.get() != NULL)
{
lldb::ValueObjectSP synth_guy = m_synth_filter_ap->GetChildAtIndex (idx, can_create);
lldb::ValueObjectSP synth_guy = m_synth_filter_ap->GetChildAtIndex (idx);
if (!synth_guy)
return synth_guy;
m_children_byindex[idx]= synth_guy.get();

View File

@ -646,7 +646,33 @@ AppleObjCRuntimeV2::GetISA(ValueObject& valobj)
// tagged pointer
if (IsTaggedPointer(isa_pointer))
{
ClassDescriptorV2Tagged descriptor(valobj);
// probably an invalid tagged pointer - say it's wrong
if (!descriptor.IsValid())
return 0;
static const ConstString g_objc_tagged_isa_nsatom_name ("NSAtom");
static const ConstString g_objc_tagged_isa_nsnumber_name ("NSNumber");
static const ConstString g_objc_tagged_isa_nsdatets_name ("NSDateTS");
static const ConstString g_objc_tagged_isa_nsmanagedobject_name ("NSManagedObject");
static const ConstString g_objc_tagged_isa_nsdate_name ("NSDate");
ConstString class_name_const_string = descriptor.GetClassName();
if (class_name_const_string == g_objc_tagged_isa_nsatom_name)
return g_objc_Tagged_ISA_NSAtom;
if (class_name_const_string == g_objc_tagged_isa_nsnumber_name)
return g_objc_Tagged_ISA_NSNumber;
if (class_name_const_string == g_objc_tagged_isa_nsdatets_name)
return g_objc_Tagged_ISA_NSDateTS;
if (class_name_const_string == g_objc_tagged_isa_nsmanagedobject_name)
return g_objc_Tagged_ISA_NSManagedObject;
if (class_name_const_string == g_objc_tagged_isa_nsdate_name)
return g_objc_Tagged_ISA_NSDate;
return g_objc_Tagged_ISA;
}
ExecutionContext exe_ctx (valobj.GetExecutionContextRef());
@ -679,6 +705,31 @@ AppleObjCRuntimeV2::GetActualTypeName(ObjCLanguageRuntime::ObjCISA isa)
static const ConstString g_objc_tagged_isa_name ("_lldb_Tagged_ObjC_ISA");
return g_objc_tagged_isa_name;
}
if (isa == g_objc_Tagged_ISA_NSAtom)
{
static const ConstString g_objc_tagged_isa_nsatom_name ("NSAtom");
return g_objc_tagged_isa_nsatom_name;
}
if (isa == g_objc_Tagged_ISA_NSNumber)
{
static const ConstString g_objc_tagged_isa_nsnumber_name ("NSNumber");
return g_objc_tagged_isa_nsnumber_name;
}
if (isa == g_objc_Tagged_ISA_NSDateTS)
{
static const ConstString g_objc_tagged_isa_nsdatets_name ("NSDateTS");
return g_objc_tagged_isa_nsdatets_name;
}
if (isa == g_objc_Tagged_ISA_NSManagedObject)
{
static const ConstString g_objc_tagged_isa_nsmanagedobject_name ("NSManagedObject");
return g_objc_tagged_isa_nsmanagedobject_name;
}
if (isa == g_objc_Tagged_ISA_NSDate)
{
static const ConstString g_objc_tagged_isa_nsdate_name ("NSDate");
return g_objc_tagged_isa_nsdate_name;
}
ISAToDescriptorIterator found = m_isa_to_descriptor_cache.find(isa);
ISAToDescriptorIterator end = m_isa_to_descriptor_cache.end();

View File

@ -238,11 +238,19 @@ public:
return (isa != 0);
}
// this is not a valid ISA in the sense that no valid
// class pointer can live at address 1. we use it to refer to
// tagged types, where the ISA must be dynamically determined
// none of these are valid ISAs - we use them to infer the type
// of tagged pointers - if we have something meaningful to say
// we report an actual type - otherwise, we just say tagged
// there is no connection between the values here and the tagged pointers map
static const ObjCLanguageRuntime::ObjCISA g_objc_Tagged_ISA = 1;
static const ObjCLanguageRuntime::ObjCISA g_objc_Tagged_ISA_NSAtom = 2;
static const ObjCLanguageRuntime::ObjCISA g_objc_Tagged_ISA_NSNumber = 3;
static const ObjCLanguageRuntime::ObjCISA g_objc_Tagged_ISA_NSDateTS = 4;
static const ObjCLanguageRuntime::ObjCISA g_objc_Tagged_ISA_NSManagedObject = 5;
static const ObjCLanguageRuntime::ObjCISA g_objc_Tagged_ISA_NSDate = 6;
virtual ObjCLanguageRuntime::ObjCISA
GetISA(ValueObject& valobj);

View File

@ -0,0 +1,9 @@
LEVEL = ../../../make
OBJC_SOURCES := main.m
CFLAGS_EXTRAS += -w
include $(LEVEL)/Makefile.rules
LDFLAGS += -framework Foundation

View File

@ -0,0 +1,82 @@
"""
Test lldb data formatter subsystem.
"""
import os, time
import unittest2
import lldb
from lldbtest import *
import datetime
class DataFormatterRdar11086338TestCase(TestBase):
mydir = os.path.join("functionalities", "data-formatter", "rdar-11086338")
@unittest2.skipUnless(sys.platform.startswith("darwin"), "requires Darwin")
@dsym_test
def test_rdar11086338_with_dsym_and_run_command(self):
"""Test that NSArray reports its synthetic children properly."""
self.buildDsym()
self.rdar11086338_tester()
@unittest2.skipUnless(sys.platform.startswith("darwin"), "requires Darwin")
@dwarf_test
def test_rdar11086338_with_dwarf_and_run_command(self):
"""Test that NSArray reports its synthetic children properly."""
self.buildDwarf()
self.rdar11086338_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 rdar11086338_tester(self):
"""Test that NSArray reports its synthetic children properly."""
self.runCmd("file a.out", CURRENT_EXECUTABLE_SET)
self.expect("breakpoint set -f main.m -l %d" % self.line,
BREAKPOINT_CREATED,
startstr = "Breakpoint created: 1: file ='main.m', line = %d, locations = 1" %
self.line)
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 arr',
substrs = ['@"6 objects"'])
self.expect('frame variable other_arr',
substrs = ['@"4 objects"'])
self.expect('frame variable arr --ptr-depth 1',
substrs = ['@"6 objects"','[0] = 0x','[1] = 0x','[2] = 0x','[3] = 0x','[4] = 0x','[5] = 0x'])
self.expect('frame variable other_arr --ptr-depth 1',
substrs = ['@"4 objects"','[0] = 0x','[1] = 0x','[2] = 0x','[3] = 0x'])
self.expect('frame variable arr --ptr-depth 1 -d no-run-target',
substrs = ['@"6 objects"','@"hello"','@"world"','@"this"','@"is"','@"me"','@"http://www.apple.com'])
self.expect('frame variable other_arr --ptr-depth 1 -d no-run-target',
substrs = ['@"4 objects"','(int)5','@"a string"','@"6 objects"'])
self.expect('frame variable other_arr --ptr-depth 2 -d no-run-target',
substrs = ['@"4 objects"','@"6 objects" {','@"hello"','@"world"','@"this"','@"is"','@"me"','@"http://www.apple.com'])
if __name__ == '__main__':
import atexit
lldb.SBDebugger.Initialize()
atexit.register(lambda: lldb.SBDebugger.Terminate())
unittest2.main()

View File

@ -0,0 +1,35 @@
//===-- 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];
NSMutableArray* arr = [[NSMutableArray alloc] init];
[arr addObject:@"hello"];
[arr addObject:@"world"];
[arr addObject:@"this"];
[arr addObject:@"is"];
[arr addObject:@"me"];
[arr addObject:[NSURL URLWithString:@"http://www.apple.com/"]];
NSDate *aDate = [NSDate distantFuture];
NSValue *aValue = [NSNumber numberWithInt:5];
NSString *aString = @"a string";
NSArray *other_arr = [NSArray arrayWithObjects:aDate, aValue, aString, arr, nil];
[pool drain];// Set break point at this line.
return 0;
}