diff --git a/lldb/examples/summaries/cocoa/CFBag.py b/lldb/examples/summaries/cocoa/CFBag.py index 7c7493e2a778..37d14a432d52 100644 --- a/lldb/examples/summaries/cocoa/CFBag.py +++ b/lldb/examples/summaries/cocoa/CFBag.py @@ -5,7 +5,8 @@ part of The LLVM Compiler Infrastructure This file is distributed under the University of Illinois Open Source License. See LICENSE.TXT for details. """ -# summary provider for CFBag +# example summary provider for CFBag +# the real summary is now C++ code built into LLDB import lldb import ctypes import lldb.runtime.objc.objc_runtime diff --git a/lldb/examples/summaries/cocoa/CFBinaryHeap.py b/lldb/examples/summaries/cocoa/CFBinaryHeap.py index 1b7183d1417a..2348a8971815 100644 --- a/lldb/examples/summaries/cocoa/CFBinaryHeap.py +++ b/lldb/examples/summaries/cocoa/CFBinaryHeap.py @@ -5,7 +5,8 @@ part of The LLVM Compiler Infrastructure This file is distributed under the University of Illinois Open Source License. See LICENSE.TXT for details. """ -# summary provider for CFBinaryHeap +# example summary provider for CFBinaryHeap +# the real summary is now C++ code built into LLDB import lldb import ctypes import lldb.runtime.objc.objc_runtime diff --git a/lldb/examples/summaries/cocoa/NSBundle.py b/lldb/examples/summaries/cocoa/NSBundle.py index 342ccfac7d93..1f6a7dd39d89 100644 --- a/lldb/examples/summaries/cocoa/NSBundle.py +++ b/lldb/examples/summaries/cocoa/NSBundle.py @@ -5,7 +5,8 @@ part of The LLVM Compiler Infrastructure This file is distributed under the University of Illinois Open Source License. See LICENSE.TXT for details. """ -# summary provider for NSBundle +# example summary provider for NSBundle +# the real summary is now C++ code built into LLDB import lldb import ctypes import lldb.runtime.objc.objc_runtime diff --git a/lldb/examples/summaries/cocoa/NSMachPort.py b/lldb/examples/summaries/cocoa/NSMachPort.py index ecb4b7590ca5..554d2ca7785a 100644 --- a/lldb/examples/summaries/cocoa/NSMachPort.py +++ b/lldb/examples/summaries/cocoa/NSMachPort.py @@ -5,7 +5,8 @@ part of The LLVM Compiler Infrastructure This file is distributed under the University of Illinois Open Source License. See LICENSE.TXT for details. """ -# summary provider for NSData +# example summary provider for NSMachPort +# the real summary is now C++ code built into LLDB import lldb import ctypes import lldb.runtime.objc.objc_runtime diff --git a/lldb/examples/summaries/cocoa/NSNotification.py b/lldb/examples/summaries/cocoa/NSNotification.py index 8d49caa93d36..33c20065346f 100644 --- a/lldb/examples/summaries/cocoa/NSNotification.py +++ b/lldb/examples/summaries/cocoa/NSNotification.py @@ -5,7 +5,8 @@ part of The LLVM Compiler Infrastructure This file is distributed under the University of Illinois Open Source License. See LICENSE.TXT for details. """ -# summary provider for class NSNotification +# example summary provider for NSNotification +# the real summary is now C++ code built into LLDB import lldb.runtime.objc.objc_runtime import lldb.formatters.metrics import CFString diff --git a/lldb/include/lldb/DataFormatters/CXXFormatterFunctions.h b/lldb/include/lldb/DataFormatters/CXXFormatterFunctions.h index f06467e84254..8ba709efa389 100644 --- a/lldb/include/lldb/DataFormatters/CXXFormatterFunctions.h +++ b/lldb/include/lldb/DataFormatters/CXXFormatterFunctions.h @@ -94,9 +94,18 @@ namespace lldb_private { bool NSNumberSummaryProvider (ValueObject& valobj, Stream& stream); + bool + NSNotificationSummaryProvider (ValueObject& valobj, Stream& stream); + + bool + NSMachPortSummaryProvider (ValueObject& valobj, Stream& stream); + bool CFBagSummaryProvider (ValueObject& valobj, Stream& stream); + bool + CFBinaryHeapSummaryProvider (ValueObject& valobj, Stream& stream); + bool NSBundleSummaryProvider (ValueObject& valobj, Stream& stream); diff --git a/lldb/source/DataFormatters/CXXFormatterFunctions.cpp b/lldb/source/DataFormatters/CXXFormatterFunctions.cpp index 11075665dfe4..89e156d8869f 100644 --- a/lldb/source/DataFormatters/CXXFormatterFunctions.cpp +++ b/lldb/source/DataFormatters/CXXFormatterFunctions.cpp @@ -687,6 +687,102 @@ lldb_private::formatters::NSBundleSummaryProvider (ValueObject& valobj, Stream& return ExtractSummaryFromObjCExpression(valobj, "NSString*", "bundlePath", stream); } +bool +lldb_private::formatters::NSNotificationSummaryProvider (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,"NSConcreteNotification")) + { + uint64_t offset = 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*", "name", stream); +} + +bool +lldb_private::formatters::NSMachPortSummaryProvider (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; + + uint64_t port_number = 0; + + do + { + if (!strcmp(class_name,"NSMachPort")) + { + uint64_t offset = (ptr_size == 4 ? 12 : 20); + Error error; + port_number = process_sp->ReadUnsignedIntegerFromMemory(offset+valobj_addr, 4, 0, error); + if (error.Success()) + break; + } + if (!ExtractValueFromObjCExpression(valobj, "int", "machPort", port_number)) + return false; + } while (false); + + stream.Printf("mach port: %u",(uint32_t)(port_number & 0x00000000FFFFFFFF)); + return true; +} + bool lldb_private::formatters::CFBagSummaryProvider (ValueObject& valobj, Stream& stream) { @@ -726,7 +822,6 @@ lldb_private::formatters::CFBagSummaryProvider (ValueObject& valobj, Stream& str 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; @@ -752,6 +847,70 @@ lldb_private::formatters::CFBagSummaryProvider (ValueObject& valobj, Stream& str return true; } +bool +lldb_private::formatters::CFBinaryHeapSummaryProvider (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 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()); + 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; + Error error; + count = process_sp->ReadUnsignedIntegerFromMemory(offset, 4, 0, error); + if (error.Fail()) + return false; + } + stream.Printf("@\"%u item%s\"", + count,(count == 1 ? "" : "s")); + return true; +} + bool lldb_private::formatters::NSNumberSummaryProvider (ValueObject& valobj, Stream& stream) { diff --git a/lldb/source/DataFormatters/FormatManager.cpp b/lldb/source/DataFormatters/FormatManager.cpp index b13c468e4e6a..afc88d4160cb 100644 --- a/lldb/source/DataFormatters/FormatManager.cpp +++ b/lldb/source/DataFormatters/FormatManager.cpp @@ -926,8 +926,8 @@ FormatManager::LoadObjCFormatters() AddCXXSummary(appkit_category_sp,lldb_private::formatters::CFBagSummaryProvider, "CFBag summary provider", ConstString("const struct __CFBag"), appkit_flags); AddCXXSummary(appkit_category_sp,lldb_private::formatters::CFBagSummaryProvider, "CFBag summary provider", ConstString("CFMutableBagRef"), appkit_flags); - AddScriptSummary(appkit_category_sp, "lldb.formatters.objc.CFBinaryHeap.CFBinaryHeap_SummaryProvider", ConstString("CFBinaryHeapRef"), appkit_flags); - AddScriptSummary(appkit_category_sp, "lldb.formatters.objc.CFBinaryHeap.CFBinaryHeap_SummaryProvider", ConstString("__CFBinaryHeap"), appkit_flags); + AddCXXSummary(appkit_category_sp,lldb_private::formatters::CFBinaryHeapSummaryProvider, "CFBinaryHeap summary provider", ConstString("CFBinaryHeapRef"), appkit_flags); + AddCXXSummary(appkit_category_sp,lldb_private::formatters::CFBinaryHeapSummaryProvider, "CFBinaryHeap summary provider", ConstString("__CFBinaryHeap"), 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); @@ -952,10 +952,10 @@ FormatManager::LoadObjCFormatters() AddCXXSummary(appkit_category_sp, lldb_private::formatters::NSDataSummaryProvider, "NSData summary provider", ConstString("CFDataRef"), appkit_flags); AddCXXSummary(appkit_category_sp, lldb_private::formatters::NSDataSummaryProvider, "NSData summary provider", ConstString("CFMutableDataRef"), appkit_flags); - AddScriptSummary(appkit_category_sp, "lldb.formatters.objc.NSMachPort.NSMachPort_SummaryProvider", ConstString("NSMachPort"), appkit_flags); - - AddScriptSummary(appkit_category_sp, "lldb.formatters.objc.NSNotification.NSNotification_SummaryProvider", ConstString("NSNotification"), appkit_flags); - AddScriptSummary(appkit_category_sp, "lldb.formatters.objc.NSNotification.NSNotification_SummaryProvider", ConstString("NSConcreteNotification"), appkit_flags); + AddCXXSummary(appkit_category_sp, lldb_private::formatters::NSMachPortSummaryProvider, "NSMachPort summary provider", ConstString("NSMachPort"), appkit_flags); + + AddCXXSummary(appkit_category_sp, lldb_private::formatters::NSNotificationSummaryProvider, "NSNotification summary provider", ConstString("NSNotification"), appkit_flags); + AddCXXSummary(appkit_category_sp, lldb_private::formatters::NSNotificationSummaryProvider, "NSNotification summary provider", ConstString("NSConcreteNotification"), appkit_flags); AddStringSummary(appkit_category_sp, "domain: ${var._domain} - code: ${var._code}", ConstString("NSError"), appkit_flags); AddStringSummary(appkit_category_sp,"name:${var.name%S} reason:${var.reason%S}",ConstString("NSException"),appkit_flags);