diff options
Diffstat (limited to 'lldb/source/DataFormatters/CXXFormatterFunctions.cpp')
-rw-r--r-- | lldb/source/DataFormatters/CXXFormatterFunctions.cpp | 112 |
1 files changed, 112 insertions, 0 deletions
diff --git a/lldb/source/DataFormatters/CXXFormatterFunctions.cpp b/lldb/source/DataFormatters/CXXFormatterFunctions.cpp index 0ac0f73df6d..6f7e84ab9f8 100644 --- a/lldb/source/DataFormatters/CXXFormatterFunctions.cpp +++ b/lldb/source/DataFormatters/CXXFormatterFunctions.cpp @@ -615,6 +615,118 @@ lldb_private::formatters::NSDataSummaryProvider (ValueObject& valobj, Stream& st } bool +lldb_private::formatters::NSBundleSummaryProvider (ValueObject& valobj, Stream& stream) +{ + ProcessSP process_sp = valobj.GetProcessSP(); + if (!process_sp) + return false; + + ObjCLanguageRuntime* runtime = (ObjCLanguageRuntime*)process_sp->GetLanguageRuntime(lldb::eLanguageTypeObjC); + + if (!runtime) + return false; + + ObjCLanguageRuntime::ClassDescriptorSP descriptor(runtime->GetClassDescriptor(valobj)); + + if (!descriptor.get() || !descriptor->IsValid()) + return false; + + uint32_t ptr_size = process_sp->GetAddressByteSize(); + + lldb::addr_t valobj_addr = valobj.GetValueAsUnsigned(0); + + if (!valobj_addr) + return false; + + const char* class_name = descriptor->GetClassName().GetCString(); + + if (!class_name || !*class_name) + return false; + + if (!strcmp(class_name,"NSBundle")) + { + uint64_t offset = 5 * ptr_size; + ClangASTType type(valobj.GetClangAST(),valobj.GetClangType()); + ValueObjectSP text(valobj.GetSyntheticChildAtOffset(offset, type, true)); + StreamString summary_stream; + bool was_nsstring_ok = NSStringSummaryProvider(*text.get(), summary_stream); + if (was_nsstring_ok && summary_stream.GetSize() > 0) + { + stream.Printf("%s",summary_stream.GetData()); + return true; + } + } + // this is either an unknown subclass or an NSBundle that comes from [NSBundle mainBundle] + // which is encoded differently and needs to be handled by running code + return ExtractSummaryFromObjCExpression(valobj, "NSString*", "bundlePath", stream); +} + +bool +lldb_private::formatters::CFBagSummaryProvider (ValueObject& valobj, Stream& stream) +{ + ProcessSP process_sp = valobj.GetProcessSP(); + if (!process_sp) + return false; + + ObjCLanguageRuntime* runtime = (ObjCLanguageRuntime*)process_sp->GetLanguageRuntime(lldb::eLanguageTypeObjC); + + if (!runtime) + return false; + + ObjCLanguageRuntime::ClassDescriptorSP descriptor(runtime->GetClassDescriptor(valobj)); + + if (!descriptor.get() || !descriptor->IsValid()) + return false; + + uint32_t ptr_size = process_sp->GetAddressByteSize(); + + lldb::addr_t valobj_addr = valobj.GetValueAsUnsigned(0); + + if (!valobj_addr) + return false; + + uint32_t count = 0; + + bool is_type_ok = false; // check to see if this is a CFBag we know about + if (descriptor->IsCFType()) + { + ConstString type_name(valobj.GetTypeName()); + if (type_name == ConstString("__CFBag") || type_name == ConstString("const struct __CFBag")) + { + if (valobj.IsPointerType()) + is_type_ok = true; + } + } + + if (is_type_ok == false) + { +// num_children_vo = self.valobj.CreateValueFromExpression("count","(int)CFBagGetCount(" + stream.GetData() + " )") + StackFrameSP frame_sp(valobj.GetFrameSP()); + if (!frame_sp) + return false; + ValueObjectSP count_sp; + StreamString expr; + expr.Printf("(int)CFBagGetCount((void*)0x%" PRIx64 ")",valobj.GetPointerValue()); + if (process_sp->GetTarget().EvaluateExpression(expr.GetData(), frame_sp.get(), count_sp) != eExecutionCompleted) + return false; + if (!count_sp) + return false; + count = count_sp->GetValueAsUnsigned(0); + } + else + { + uint32_t offset = 2*ptr_size+4 + valobj_addr; + Error error; + count = process_sp->ReadUnsignedIntegerFromMemory(offset, 4, 0, error); + if (error.Fail()) + return false; + } + stream.Printf("@\"%u value%s\"", + count,(count == 1 ? "" : "s")); + return true; +} + +bool lldb_private::formatters::NSNumberSummaryProvider (ValueObject& valobj, Stream& stream) { ProcessSP process_sp = valobj.GetProcessSP(); |