forked from OSchip/llvm-project
<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:
parent
d0080c45f9
commit
b2698cdf59
|
@ -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);
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -85,6 +85,7 @@ class Condition;
|
|||
class Connection;
|
||||
class ConnectionFileDescriptor;
|
||||
class ConstString;
|
||||
class CXXSyntheticChildren;
|
||||
class DWARFCallFrameInfo;
|
||||
class DWARFExpression;
|
||||
class DataBuffer;
|
||||
|
|
|
@ -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&) ;
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -0,0 +1,9 @@
|
|||
LEVEL = ../../../make
|
||||
|
||||
OBJC_SOURCES := main.m
|
||||
|
||||
CFLAGS_EXTRAS += -w
|
||||
|
||||
include $(LEVEL)/Makefile.rules
|
||||
|
||||
LDFLAGS += -framework Foundation
|
|
@ -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()
|
|
@ -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;
|
||||
}
|
||||
|
Loading…
Reference in New Issue