From 8d5c83f6ef5fce44b6375aa208c2768f3634e7ee Mon Sep 17 00:00:00 2001 From: Enrico Granata Date: Fri, 2 Mar 2012 00:55:53 +0000 Subject: [PATCH] (a) adding formatters for: NSTimeZone and CFTimeZonRef SEL and related types CFGregorianDate llvm-svn: 151866 --- lldb/examples/summaries/cocoa/NSDate.py | 45 ++++++++++++++++++- lldb/examples/summaries/cocoa/Selector.py | 7 +++ .../scripts/Python/finish-swig-Python-LLDB.sh | 14 ++++++ lldb/source/Core/FormatManager.cpp | 37 +++++++++++---- .../Interpreter/ScriptInterpreterPython.cpp | 2 +- .../TestDataFormatterObjC.py | 20 ++++++++- .../data-formatter/data-formatter-objc/main.m | 21 +++++++++ 7 files changed, 134 insertions(+), 12 deletions(-) create mode 100644 lldb/examples/summaries/cocoa/Selector.py diff --git a/lldb/examples/summaries/cocoa/NSDate.py b/lldb/examples/summaries/cocoa/NSDate.py index df493cbc0704..0e7038b488d5 100644 --- a/lldb/examples/summaries/cocoa/NSDate.py +++ b/lldb/examples/summaries/cocoa/NSDate.py @@ -6,6 +6,7 @@ import metrics import struct import time import datetime +import CFString statistics = metrics.Metrics() statistics.add_metric('invalid_isa') @@ -132,6 +133,32 @@ class NSCalendarDate_SummaryProvider: value_double = struct.unpack('d', struct.pack('Q', value.GetValueAsUnsigned(0)))[0] return time.ctime(osx_to_python_time(value_double)) +class NSTimeZoneClass_SummaryProvider: + def adjust_for_architecture(self): + self.is_64_bit = (self.valobj.GetTarget().GetProcess().GetAddressByteSize() == 8) + self.is_little = (self.valobj.GetTarget().GetProcess().GetByteOrder() == lldb.eByteOrderLittle) + self.pointer_size = self.valobj.GetTarget().GetProcess().GetAddressByteSize() + + def __init__(self, valobj): + self.valobj = valobj; + self.update() + + def update(self): + self.adjust_for_architecture(); + self.id_type = self.valobj.GetType().GetBasicType(lldb.eBasicTypeObjCID) + self.voidptr_type = self.valobj.GetType().GetBasicType(lldb.eBasicTypeVoid).GetPointerType() + + def offset(self): + if self.is_64_bit: + return 8 + else: + return 4 + + def timezone(self): + tz_string = self.valobj.CreateChildAtOffset("tz_name", + self.offset(), + self.voidptr_type) + return CFString.CFString_SummaryProvider(tz_string,None) class NSUnknownDate_SummaryProvider: def adjust_for_architecture(self): @@ -184,8 +211,10 @@ def GetSummary_Impl(valobj): elif name_string == 'NSCalendarDate': wrapper = NSCalendarDate_SummaryProvider(valobj) statistics.metric_hit('code_notrun',valobj) + elif name_string == '__NSTimeZone': + wrapper = NSTimeZoneClass_SummaryProvider(valobj) + statistics.metric_hit('code_notrun',valobj) else: - print name_string # comment this out in release mode wrapper = NSUnknownDate_SummaryProvider(valobj) statistics.metric_hit('unknown_class',str(valobj) + " seen as " + name_string) return wrapper; @@ -203,6 +232,19 @@ def NSDate_SummaryProvider (valobj,dict): return str(summary) return '' +def NSTimeZone_SummaryProvider (valobj,dict): + provider = GetSummary_Impl(valobj); + if provider != None: + try: + summary = provider.timezone(); + except: + summary = None + if summary == None: + summary = 'no valid timezone here' + return str(summary) + return '' + + def CFAbsoluteTime_SummaryProvider (valobj,dict): try: value_double = struct.unpack('d', struct.pack('Q', valobj.GetValueAsUnsigned(0)))[0] @@ -214,4 +256,5 @@ def CFAbsoluteTime_SummaryProvider (valobj,dict): def __lldb_init_module(debugger,dict): debugger.HandleCommand("type summary add -F NSDate.NSDate_SummaryProvider NSDate") debugger.HandleCommand("type summary add -F NSDate.CFAbsoluteTime_SummaryProvider CFAbsoluteTime") + debugger.HandleCommand("type summary add -F NSDate.NSTimeZone_SummaryProvider NSTimeZone CFTimeZoneRef") diff --git a/lldb/examples/summaries/cocoa/Selector.py b/lldb/examples/summaries/cocoa/Selector.py new file mode 100644 index 000000000000..38576ab8c3d7 --- /dev/null +++ b/lldb/examples/summaries/cocoa/Selector.py @@ -0,0 +1,7 @@ +import lldb + +def SEL_Summary(valobj,dict): + return valobj.Cast(valobj.GetType().GetBasicType(lldb.eBasicTypeChar).GetPointerType()).GetSummary() + +def SELPointer_Summary(valobj,dict): + return valobj.CreateValueFromAddress('text',valobj.GetValueAsUnsigned(0),valobj.GetType().GetBasicType(lldb.eBasicTypeChar)).AddressOf().GetSummary() diff --git a/lldb/scripts/Python/finish-swig-Python-LLDB.sh b/lldb/scripts/Python/finish-swig-Python-LLDB.sh index 66dfd9978ced..4fd1d376912f 100755 --- a/lldb/scripts/Python/finish-swig-Python-LLDB.sh +++ b/lldb/scripts/Python/finish-swig-Python-LLDB.sh @@ -410,6 +410,20 @@ else fi fi +if [ -f "${SRC_ROOT}/examples/summaries/cocoa/Selector.py" ] +then + if [ $Debug == 1 ] + then + echo "Copying Selector.py to ${framework_python_dir}" + fi + cp "${SRC_ROOT}/examples/summaries/cocoa/Selector.py" "${framework_python_dir}" +else + if [ $Debug == 1 ] + then + echo "Unable to find ${SRC_ROOT}/examples/summaries/cocoa/Selector.py" + fi +fi + if [ -f "${SRC_ROOT}/examples/summaries/cocoa/cache.py" ] then if [ $Debug == 1 ] diff --git a/lldb/source/Core/FormatManager.cpp b/lldb/source/Core/FormatManager.cpp index 4e12903cdcb0..66cd6a5b6300 100644 --- a/lldb/source/Core/FormatManager.cpp +++ b/lldb/source/Core/FormatManager.cpp @@ -607,13 +607,16 @@ FormatManager::FormatManager() : void FormatManager::LoadSTLFormatters() { - lldb::TypeSummaryImplSP std_string_summary_sp(new StringSummaryFormat(TypeSummaryImpl::Flags().SetCascades(true) - .SetSkipPointers(false) - .SetSkipReferences(false) - .SetDontShowChildren(true) - .SetDontShowValue(true) - .SetShowMembersOneLiner(false) - .SetHideItemNames(false), + TypeSummaryImpl::Flags stl_summary_flags; + stl_summary_flags.SetCascades(true) + .SetSkipPointers(false) + .SetSkipReferences(false) + .SetDontShowChildren(true) + .SetDontShowValue(true) + .SetShowMembersOneLiner(false) + .SetHideItemNames(false); + + lldb::TypeSummaryImplSP std_string_summary_sp(new StringSummaryFormat(stl_summary_flags, "${var._M_dataplus._M_p}")); TypeCategoryImpl::SharedPointer gnu_category_sp = GetCategory(m_gnu_cpp_category_name); @@ -642,6 +645,10 @@ FormatManager::LoadSTLFormatters() gnu_category_sp->GetRegexSyntheticNavigator()->Add(RegularExpressionSP(new RegularExpression("^(std::)?list<.+>$")), SyntheticChildrenSP(new TypeSyntheticImpl(stl_synth_flags, "gnu_libstdcpp.StdListSynthProvider"))); + + gnu_category_sp->GetRegexSummaryNavigator()->Add(RegularExpressionSP(new RegularExpression("^(std::)?vector<.+>$")), + TypeSummaryImplSP(new StringSummaryFormat(stl_summary_flags, + "size=${svar%#}"))); #endif } @@ -726,7 +733,14 @@ FormatManager::LoadObjCFormatters() objc_category_sp->GetSummaryNavigator()->Add(ConstString("BOOL"), ObjC_BOOL_summary); - + // we need to skip pointers here since we are special casing a SEL* when retrieving its value + objc_flags.SetSkipPointers(true); + AddScriptSummary(objc_category_sp, "Selector.SEL_Summary", ConstString("SEL"), objc_flags); + AddScriptSummary(objc_category_sp, "Selector.SEL_Summary", ConstString("struct objc_selector"), objc_flags); + AddScriptSummary(objc_category_sp, "Selector.SEL_Summary", ConstString("objc_selector"), objc_flags); + AddScriptSummary(objc_category_sp, "Selector.SELPointer_Summary", ConstString("objc_selector *"), objc_flags); + objc_flags.SetSkipPointers(false); + TypeCategoryImpl::SharedPointer corefoundation_category_sp = GetCategory(m_corefoundation_category_name); AddSummary(corefoundation_category_sp, @@ -855,7 +869,10 @@ FormatManager::LoadObjCFormatters() AddScriptSummary(appkit_category_sp, "NSURL.NSURL_SummaryProvider", ConstString("CFURLRef"), appkit_flags); AddScriptSummary(appkit_category_sp, "NSDate.NSDate_SummaryProvider", ConstString("NSDate"), appkit_flags); - + + AddScriptSummary(appkit_category_sp, "NSDate.NSTimeZone_SummaryProvider", ConstString("NSTimeZone"), appkit_flags); + AddScriptSummary(appkit_category_sp, "NSDate.NSTimeZone_SummaryProvider", ConstString("CFTimeZoneRef"), appkit_flags); + // CFAbsoluteTime is actually a double rather than a pointer to an object // we do not care about the numeric value, since it is probably meaningless to users appkit_flags.SetDontShowValue(true); @@ -865,6 +882,8 @@ FormatManager::LoadObjCFormatters() AddScriptSummary(appkit_category_sp, "NSIndexSet.NSIndexSet_SummaryProvider", ConstString("NSIndexSet"), appkit_flags); AddScriptSummary(appkit_category_sp, "NSIndexSet.NSIndexSet_SummaryProvider", ConstString("NSMutableIndexSet"), appkit_flags); + AddSummary(appkit_category_sp, "@\"${var.month%d}/${var.day%d}/${var.year%d} ${var.hour%d}:${var.minute%d}:${var.second}\"", ConstString("CFGregorianDate"), appkit_flags); + TypeCategoryImpl::SharedPointer vectors_category_sp = GetCategory(m_vectortypes_category_name); TypeSummaryImpl::Flags vector_flags; diff --git a/lldb/source/Interpreter/ScriptInterpreterPython.cpp b/lldb/source/Interpreter/ScriptInterpreterPython.cpp index 9d0d96983fdb..475378f3fb0e 100644 --- a/lldb/source/Interpreter/ScriptInterpreterPython.cpp +++ b/lldb/source/Interpreter/ScriptInterpreterPython.cpp @@ -282,7 +282,7 @@ ScriptInterpreterPython::ScriptInterpreterPython (CommandInterpreter &interprete // WARNING: temporary code that loads Cocoa formatters - this should be done on a per-platform basis rather than loading the whole set // and letting the individual formatter classes exploit APIs to check whether they can/cannot do their task run_string.Clear(); - run_string.Printf ("run_one_line (%s, 'import CFString, CFArray, CFDictionary, NSData, NSMachPort, NSSet, NSNotification, NSException, CFBag, CFBinaryHeap, NSURL, NSBundle, NSNumber, NSDate, NSIndexSet')", m_dictionary_name.c_str()); + run_string.Printf ("run_one_line (%s, 'import CFString, CFArray, CFDictionary, NSData, NSMachPort, NSSet, NSNotification, NSException, CFBag, CFBinaryHeap, NSURL, NSBundle, NSNumber, NSDate, NSIndexSet, Selector')", m_dictionary_name.c_str()); PyRun_SimpleString (run_string.GetData()); int new_count = Debugger::TestDebuggerRefCount(); diff --git a/lldb/test/functionalities/data-formatter/data-formatter-objc/TestDataFormatterObjC.py b/lldb/test/functionalities/data-formatter/data-formatter-objc/TestDataFormatterObjC.py index 26bba6214f6b..fdff521eefdc 100644 --- a/lldb/test/functionalities/data-formatter/data-formatter-objc/TestDataFormatterObjC.py +++ b/lldb/test/functionalities/data-formatter/data-formatter-objc/TestDataFormatterObjC.py @@ -297,6 +297,18 @@ class ObjCDataFormatterTestCase(TestBase): self.expect('frame variable iset1 iset2 imset', substrs = ['4 objects','512 objects','10 objects']) + self.expect('frame variable cupertino home europe', + substrs = ['@"America/Los_Angeles"', + '@"Europe/Rome"', + '@"Europe/Paris"']) + + + self.expect('frame variable cupertino_ns home_ns europe_ns', + substrs = ['@"America/Los_Angeles"', + '@"Europe/Rome"', + '@"Europe/Paris"']) + + def expr_objc_data_formatter_commands(self): """Test common cases of expression parser <--> formatters interaction.""" self.runCmd("file a.out", CURRENT_EXECUTABLE_SET) @@ -403,7 +415,9 @@ class ObjCDataFormatterTestCase(TestBase): '(Point *) point_ptr = (v=7, h=12)', '(HIPoint) hi_point = (x=7, y=12)', '(HIRect) hi_rect = origin=(x=3, y=5) size=(width=4, height=6)', - '@"TheGuyWhoHasNoName" @"cuz it\'s funny"']) + '@"TheGuyWhoHasNoName" @"cuz it\'s funny"', + '1985', + 'foo_selector_impl']) self.runCmd('log timers dump') @@ -456,6 +470,10 @@ class ObjCDataFormatterTestCase(TestBase): # check that NSMutableDictionary's formatter is not confused when dealing with a KVO'd dictionary self.expect('frame variable newMutableDictionary', substrs = ['(NSDictionary *) newMutableDictionary = ',' 21 key/value pairs']) + self.runCmd("breakpoint set -r setAtoms") + self.runCmd("continue") + self.expect("frame variable _cmd",substrs = ['setAtoms:']) + if __name__ == '__main__': import atexit lldb.SBDebugger.Initialize() diff --git a/lldb/test/functionalities/data-formatter/data-formatter-objc/main.m b/lldb/test/functionalities/data-formatter/data-formatter-objc/main.m index 12d4650ae572..b43cb21889d7 100644 --- a/lldb/test/functionalities/data-formatter/data-formatter-objc/main.m +++ b/lldb/test/functionalities/data-formatter/data-formatter-objc/main.m @@ -552,7 +552,26 @@ int main (int argc, const char * argv[]) [imset addIndex:62]; [imset addIndex:63]; + CFTimeZoneRef cupertino = CFTimeZoneCreateWithName ( + NULL, + CFSTR("PST"), + YES); + CFTimeZoneRef home = CFTimeZoneCreateWithName ( + NULL, + CFSTR("Europe/Rome"), + YES); + CFTimeZoneRef europe = CFTimeZoneCreateWithName ( + NULL, + CFSTR("CET"), + YES); + + NSTimeZone *cupertino_ns = [NSTimeZone timeZoneWithAbbreviation:@"PST"]; + NSTimeZone *home_ns = [NSTimeZone timeZoneWithName:@"Europe/Rome"]; + NSTimeZone *europe_ns = [NSTimeZone timeZoneWithAbbreviation:@"CET"]; + + CFGregorianUnits cf_greg_units = {1,3,5,12,5,7}; + CFGregorianDate cf_greg_date = CFAbsoluteTimeGetGregorianDate(CFDateGetAbsoluteTime(date1), NULL); CFRange cf_range = {4,4}; NSPoint ns_point = {4,4}; NSRange ns_range = {4,4}; @@ -577,6 +596,8 @@ int main (int argc, const char * argv[]) HIPoint hi_point = {7,12}; HIRect hi_rect = {{3,5},{4,6}}; + + SEL foo_selector = @selector(foo_selector_impl); Molecule *molecule = [Molecule new];