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) { 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::CFBinaryHeapSummaryProvider (ValueObject& valobj, Stream& stream, const TypeSummaryOptions& options) { static ConstString g_TypeHint("CFBinaryHeap"); 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 CFBinaryHeap we know about if (descriptor->IsCFType()) { ConstString type_name(valobj.GetTypeName()); if (type_name == ConstString("__CFBinaryHeap") || type_name == ConstString("const struct __CFBinaryHeap")) { if (valobj.IsPointerType()) is_type_ok = true; } } if (is_type_ok == false) { StackFrameSP frame_sp(valobj.GetFrameSP()); if (!frame_sp) return false; ValueObjectSP count_sp; StreamString expr; expr.Printf("(int)CFBinaryHeapGetCount((void*)0x%" PRIx64 ")",valobj.GetPointerValue()); EvaluateExpressionOptions options; options.SetResultIsInternal(true); if (process_sp->GetTarget().EvaluateExpression(expr.GetData(), frame_sp.get(), count_sp, options) != eExpressionCompleted) return false; if (!count_sp) return false; count = count_sp->GetValueAsUnsigned(0); } else { uint32_t offset = 2*ptr_size; Error error; count = process_sp->ReadUnsignedIntegerFromMemory(offset, 4, 0, error); if (error.Fail()) return false; } std::string prefix,suffix; if (Language* language = Language::FindPlugin(options.GetLanguage())) { if (!language->GetFormatterPrefixSuffix(valobj, g_TypeHint, prefix, suffix)) { prefix.clear(); suffix.clear(); } } stream.Printf("%s\"%u item%s\"%s", prefix.c_str(), count,(count == 1 ? "" : "s"), suffix.c_str()); return true; }