forked from OSchip/llvm-project
Add synthetic children support for NSIndexPath
llvm-svn: 219852
This commit is contained in:
parent
bbdd6c13de
commit
5510a5762c
|
@ -474,6 +474,8 @@ namespace lldb_private {
|
|||
|
||||
SyntheticChildrenFrontEnd* NSSetSyntheticFrontEndCreator (CXXSyntheticChildren*, lldb::ValueObjectSP);
|
||||
|
||||
SyntheticChildrenFrontEnd* NSIndexPathSyntheticFrontEndCreator (CXXSyntheticChildren*, lldb::ValueObjectSP);
|
||||
|
||||
class LibcxxVectorBoolSyntheticFrontEnd : public SyntheticChildrenFrontEnd
|
||||
{
|
||||
public:
|
||||
|
|
|
@ -648,6 +648,7 @@
|
|||
941BCC8114E48C4000BB969C /* SBTypeSummary.h in Headers */ = {isa = PBXBuildFile; fileRef = 9461568814E355F2003A195C /* SBTypeSummary.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
||||
941BCC8214E48C4000BB969C /* SBTypeSynthetic.h in Headers */ = {isa = PBXBuildFile; fileRef = 9461568914E355F2003A195C /* SBTypeSynthetic.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
||||
94380B8219940B0A00BFE4A8 /* StringLexer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 94380B8119940B0A00BFE4A8 /* StringLexer.cpp */; };
|
||||
9439FB1A19EF140C006FD6A4 /* NSIndexPath.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 9439FB1919EF140C006FD6A4 /* NSIndexPath.cpp */; };
|
||||
944372DC171F6B4300E57C32 /* RegisterContextDummy.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 944372DA171F6B4300E57C32 /* RegisterContextDummy.cpp */; };
|
||||
944372DD171F6B4300E57C32 /* RegisterContextDummy.h in Headers */ = {isa = PBXBuildFile; fileRef = 944372DB171F6B4300E57C32 /* RegisterContextDummy.h */; };
|
||||
9443B122140C18C40013457C /* SBData.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 9443B121140C18C10013457C /* SBData.cpp */; };
|
||||
|
@ -1985,6 +1986,7 @@
|
|||
94145430175D7FDE00284436 /* lldb-versioning.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "lldb-versioning.h"; path = "include/lldb/lldb-versioning.h"; sourceTree = "<group>"; };
|
||||
94380B8019940B0300BFE4A8 /* StringLexer.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = StringLexer.h; path = include/lldb/Utility/StringLexer.h; sourceTree = "<group>"; };
|
||||
94380B8119940B0A00BFE4A8 /* StringLexer.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = StringLexer.cpp; path = source/Utility/StringLexer.cpp; sourceTree = "<group>"; };
|
||||
9439FB1919EF140C006FD6A4 /* NSIndexPath.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = NSIndexPath.cpp; path = source/DataFormatters/NSIndexPath.cpp; sourceTree = "<group>"; };
|
||||
944372DA171F6B4300E57C32 /* RegisterContextDummy.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = RegisterContextDummy.cpp; path = Utility/RegisterContextDummy.cpp; sourceTree = "<group>"; };
|
||||
944372DB171F6B4300E57C32 /* RegisterContextDummy.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = RegisterContextDummy.h; path = Utility/RegisterContextDummy.h; sourceTree = "<group>"; };
|
||||
9443B120140C18A90013457C /* SBData.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = SBData.h; path = include/lldb/API/SBData.h; sourceTree = "<group>"; };
|
||||
|
@ -4327,6 +4329,7 @@
|
|||
94D0B10B16D5535900EA9C70 /* LibStdcpp.cpp */,
|
||||
94D6A0A716CEB55F00833B6E /* NSArray.cpp */,
|
||||
94D6A0A816CEB55F00833B6E /* NSDictionary.cpp */,
|
||||
9439FB1919EF140C006FD6A4 /* NSIndexPath.cpp */,
|
||||
94D6A0A916CEB55F00833B6E /* NSSet.cpp */,
|
||||
94CB256816B096F90059775D /* TypeCategory.h */,
|
||||
94CB256416B096F10059775D /* TypeCategory.cpp */,
|
||||
|
@ -5079,6 +5082,7 @@
|
|||
94D0B10D16D5535900EA9C70 /* LibStdcpp.cpp in Sources */,
|
||||
AF0E22F018A09FB20009B7D1 /* AppleGetItemInfoHandler.cpp in Sources */,
|
||||
2689004E13353E0400698AC0 /* Stream.cpp in Sources */,
|
||||
9439FB1A19EF140C006FD6A4 /* NSIndexPath.cpp in Sources */,
|
||||
2689004F13353E0400698AC0 /* StreamFile.cpp in Sources */,
|
||||
2689005013353E0400698AC0 /* StreamString.cpp in Sources */,
|
||||
2689005113353E0400698AC0 /* StringList.cpp in Sources */,
|
||||
|
|
|
@ -230,6 +230,7 @@ ValueObjectConstResult::ValueObjectConstResult (ExecutionContextScope *exe_scope
|
|||
{
|
||||
m_value = value;
|
||||
m_value.GetData(m_data);
|
||||
m_name = name;
|
||||
}
|
||||
|
||||
ValueObjectConstResult::~ValueObjectConstResult()
|
||||
|
|
|
@ -1394,6 +1394,8 @@ FormatManager::LoadObjCFormatters()
|
|||
AddCXXSynthetic(appkit_category_sp, lldb_private::formatters::NSSetSyntheticFrontEndCreator, "NSOrderedSet synthetic children", ConstString("NSOrderedSet"), ScriptedSyntheticChildren::Flags());
|
||||
AddCXXSynthetic(appkit_category_sp, lldb_private::formatters::NSSetSyntheticFrontEndCreator, "__NSOrderedSetI synthetic children", ConstString("__NSOrderedSetI"), ScriptedSyntheticChildren::Flags());
|
||||
AddCXXSynthetic(appkit_category_sp, lldb_private::formatters::NSSetSyntheticFrontEndCreator, "__NSOrderedSetM synthetic children", ConstString("__NSOrderedSetM"), ScriptedSyntheticChildren::Flags());
|
||||
|
||||
AddCXXSynthetic(appkit_category_sp, lldb_private::formatters::NSIndexPathSyntheticFrontEndCreator, "NSIndexPath synthetic children", ConstString("NSIndexPath"), ScriptedSyntheticChildren::Flags());
|
||||
|
||||
AddCXXSummary(corefoundation_category_sp,lldb_private::formatters::CFBagSummaryProvider, "CFBag summary provider", ConstString("CFBagRef"), appkit_flags);
|
||||
AddCXXSummary(corefoundation_category_sp,lldb_private::formatters::CFBagSummaryProvider, "CFBag summary provider", ConstString("__CFBag"), appkit_flags);
|
||||
|
|
|
@ -0,0 +1,306 @@
|
|||
//===-- NSIndexPath.cpp ------------------------------------------*- C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "lldb/DataFormatters/CXXFormatterFunctions.h"
|
||||
|
||||
#include "lldb/Core/ValueObject.h"
|
||||
#include "lldb/Core/ValueObjectConstResult.h"
|
||||
#include "lldb/DataFormatters/TypeSynthetic.h"
|
||||
#include "lldb/Target/ObjCLanguageRuntime.h"
|
||||
#include "lldb/Target/Process.h"
|
||||
#include "lldb/Symbol/ClangASTContext.h"
|
||||
|
||||
using namespace lldb;
|
||||
using namespace lldb_private;
|
||||
using namespace lldb_private::formatters;
|
||||
|
||||
class NSIndexPathSyntheticFrontEnd : public SyntheticChildrenFrontEnd
|
||||
{
|
||||
public:
|
||||
NSIndexPathSyntheticFrontEnd (lldb::ValueObjectSP valobj_sp) :
|
||||
SyntheticChildrenFrontEnd (*valobj_sp.get()),
|
||||
m_ptr_size(0),
|
||||
m_ast_ctx(nullptr),
|
||||
m_uint_star_type()
|
||||
{
|
||||
m_ptr_size = m_backend.GetTargetSP()->GetArchitecture().GetAddressByteSize();
|
||||
}
|
||||
|
||||
virtual size_t
|
||||
CalculateNumChildren ()
|
||||
{
|
||||
return m_impl.GetNumIndexes();
|
||||
}
|
||||
|
||||
virtual lldb::ValueObjectSP
|
||||
GetChildAtIndex (size_t idx)
|
||||
{
|
||||
return m_impl.GetIndexAtIndex(idx, m_uint_star_type);
|
||||
}
|
||||
|
||||
virtual bool
|
||||
Update()
|
||||
{
|
||||
m_impl.m_mode = Mode::Invalid;
|
||||
|
||||
m_ast_ctx = ClangASTContext::GetASTContext(m_backend.GetClangType().GetASTContext());
|
||||
if (!m_ast_ctx)
|
||||
return false;
|
||||
|
||||
m_uint_star_type = m_ast_ctx->GetPointerSizedIntType(false);
|
||||
|
||||
static ConstString g__indexes("_indexes");
|
||||
static ConstString g__length("_length");
|
||||
|
||||
ProcessSP process_sp = m_backend.GetProcessSP();
|
||||
if (!process_sp)
|
||||
return false;
|
||||
|
||||
ObjCLanguageRuntime* runtime = (ObjCLanguageRuntime*)process_sp->GetLanguageRuntime(lldb::eLanguageTypeObjC);
|
||||
|
||||
if (!runtime)
|
||||
return false;
|
||||
|
||||
ObjCLanguageRuntime::ClassDescriptorSP descriptor(runtime->GetClassDescriptor(m_backend));
|
||||
|
||||
if (!descriptor.get() || !descriptor->IsValid())
|
||||
return false;
|
||||
|
||||
uint64_t info_bits(0),value_bits(0),payload(0);
|
||||
|
||||
if (descriptor->GetTaggedPointerInfo(&info_bits, &value_bits, &payload))
|
||||
{
|
||||
m_impl.m_mode = Mode::Inlined;
|
||||
m_impl.m_inlined.SetIndexes(payload, *process_sp);
|
||||
}
|
||||
else
|
||||
{
|
||||
ObjCLanguageRuntime::ClassDescriptor::iVarDescriptor _indexes_id;
|
||||
ObjCLanguageRuntime::ClassDescriptor::iVarDescriptor _length_id;
|
||||
|
||||
bool has_indexes(false),has_length(false);
|
||||
|
||||
for (auto x = 0;
|
||||
x < descriptor->GetNumIVars();
|
||||
x++)
|
||||
{
|
||||
const auto& ivar = descriptor->GetIVarAtIndex(x);
|
||||
if (ivar.m_name == g__indexes)
|
||||
{
|
||||
_indexes_id = ivar;
|
||||
has_indexes = true;
|
||||
}
|
||||
else if (ivar.m_name == g__length)
|
||||
{
|
||||
_length_id = ivar;
|
||||
has_length = true;
|
||||
}
|
||||
|
||||
if (has_length && has_indexes)
|
||||
break;
|
||||
}
|
||||
|
||||
if (has_length && has_indexes)
|
||||
{
|
||||
m_impl.m_outsourced.m_indexes = m_backend.GetSyntheticChildAtOffset(_indexes_id.m_offset,
|
||||
m_uint_star_type.GetPointerType(),
|
||||
true).get();
|
||||
ValueObjectSP length_sp(m_backend.GetSyntheticChildAtOffset(_length_id.m_offset,
|
||||
m_uint_star_type,
|
||||
true));
|
||||
if (length_sp)
|
||||
{
|
||||
m_impl.m_outsourced.m_count = length_sp->GetValueAsUnsigned(0);
|
||||
if (m_impl.m_outsourced.m_indexes)
|
||||
m_impl.m_mode = Mode::Outsourced;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
virtual bool
|
||||
MightHaveChildren ()
|
||||
{
|
||||
if (m_impl.m_mode == Mode::Invalid)
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
virtual size_t
|
||||
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;
|
||||
}
|
||||
|
||||
virtual lldb::ValueObjectSP
|
||||
GetSyntheticValue () { return nullptr; }
|
||||
|
||||
virtual
|
||||
~NSIndexPathSyntheticFrontEnd () {}
|
||||
|
||||
protected:
|
||||
ObjCLanguageRuntime::ClassDescriptorSP m_descriptor_sp;
|
||||
|
||||
enum class Mode {
|
||||
Inlined,
|
||||
Outsourced,
|
||||
Invalid
|
||||
};
|
||||
|
||||
struct Impl {
|
||||
Mode m_mode;
|
||||
|
||||
size_t
|
||||
GetNumIndexes ()
|
||||
{
|
||||
switch (m_mode)
|
||||
{
|
||||
case Mode::Inlined:
|
||||
return m_inlined.GetNumIndexes();
|
||||
case Mode::Outsourced:
|
||||
return m_outsourced.m_count;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
lldb::ValueObjectSP
|
||||
GetIndexAtIndex (size_t idx, const ClangASTType& desired_type)
|
||||
{
|
||||
if (idx >= GetNumIndexes())
|
||||
return nullptr;
|
||||
switch (m_mode)
|
||||
{
|
||||
default: return nullptr;
|
||||
case Mode::Inlined:
|
||||
return m_inlined.GetIndexAtIndex (idx, desired_type);
|
||||
case Mode::Outsourced:
|
||||
return m_outsourced.GetIndexAtIndex (idx);
|
||||
}
|
||||
}
|
||||
|
||||
union {
|
||||
struct {
|
||||
public:
|
||||
void SetIndexes(uint64_t value, Process& p)
|
||||
{
|
||||
m_indexes = value;
|
||||
_lengthForInlinePayload(p.GetAddressByteSize());
|
||||
m_process = &p;
|
||||
}
|
||||
|
||||
size_t
|
||||
GetNumIndexes ()
|
||||
{
|
||||
return m_count;
|
||||
}
|
||||
|
||||
lldb::ValueObjectSP
|
||||
GetIndexAtIndex (size_t idx, const ClangASTType& desired_type)
|
||||
{
|
||||
std::pair<uint64_t, bool> value(_indexAtPositionForInlinePayload(idx));
|
||||
if (!value.second)
|
||||
return nullptr;
|
||||
Value v;
|
||||
if (m_ptr_size == 8)
|
||||
{
|
||||
Scalar scalar( (unsigned long long)value.first );
|
||||
v = Value(scalar);
|
||||
}
|
||||
else
|
||||
{
|
||||
Scalar scalar( (unsigned int)value.first );
|
||||
v = Value(scalar);
|
||||
}
|
||||
v.SetClangType(desired_type);
|
||||
StreamString idx_name;
|
||||
idx_name.Printf("[%" PRIu64 "]", (uint64_t)idx);
|
||||
return ValueObjectConstResult::Create(m_process, v, ConstString(idx_name.GetData()));
|
||||
}
|
||||
|
||||
private:
|
||||
uint64_t m_indexes;
|
||||
size_t m_count;
|
||||
uint32_t m_ptr_size;
|
||||
Process *m_process;
|
||||
|
||||
// cfr. Foundation for the details of this code
|
||||
size_t _lengthForInlinePayload(uint32_t ptr_size) {
|
||||
m_ptr_size = ptr_size;
|
||||
if (m_ptr_size == 8)
|
||||
m_count = ((m_indexes >> 3) & 0x7);
|
||||
else
|
||||
m_count = ((m_indexes >> 3) & 0x3);
|
||||
return m_count;
|
||||
}
|
||||
|
||||
std::pair<uint64_t, bool>
|
||||
_indexAtPositionForInlinePayload(size_t pos) {
|
||||
if (m_ptr_size == 8)
|
||||
{
|
||||
switch (pos) {
|
||||
case 5: return {((m_indexes >> 51) & 0x1ff),true};
|
||||
case 4: return {((m_indexes >> 42) & 0x1ff),true};
|
||||
case 3: return {((m_indexes >> 33) & 0x1ff),true};
|
||||
case 2: return {((m_indexes >> 24) & 0x1ff),true};
|
||||
case 1: return {((m_indexes >> 15) & 0x1ff),true};
|
||||
case 0: return {((m_indexes >> 6) & 0x1ff),true};
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
switch (pos) {
|
||||
case 2: return {((m_indexes >> 23) & 0x1ff),true};
|
||||
case 1: return {((m_indexes >> 14) & 0x1ff),true};
|
||||
case 0: return {((m_indexes >> 5) & 0x1ff),true};
|
||||
}
|
||||
}
|
||||
return {0,false};
|
||||
}
|
||||
|
||||
} m_inlined;
|
||||
struct {
|
||||
ValueObject *m_indexes;
|
||||
size_t m_count;
|
||||
|
||||
lldb::ValueObjectSP
|
||||
GetIndexAtIndex (size_t idx)
|
||||
{
|
||||
if (m_indexes)
|
||||
{
|
||||
ValueObjectSP index_sp(m_indexes->GetSyntheticArrayMemberFromPointer(idx, true));
|
||||
return index_sp;
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
} m_outsourced;
|
||||
};
|
||||
} m_impl;
|
||||
|
||||
uint32_t m_ptr_size;
|
||||
ClangASTContext* m_ast_ctx;
|
||||
ClangASTType m_uint_star_type;
|
||||
};
|
||||
|
||||
namespace lldb_private {
|
||||
namespace formatters {
|
||||
|
||||
SyntheticChildrenFrontEnd* NSIndexPathSyntheticFrontEndCreator (CXXSyntheticChildren*, lldb::ValueObjectSP valobj_sp)
|
||||
{
|
||||
if (valobj_sp)
|
||||
return new NSIndexPathSyntheticFrontEnd(valobj_sp);
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue