1579a296e7566b7b6d24b51e383bca1fe1e62086fEnrico Granata""" 2579a296e7566b7b6d24b51e383bca1fe1e62086fEnrico GranataLLDB AppKit formatters 3579a296e7566b7b6d24b51e383bca1fe1e62086fEnrico Granata 4579a296e7566b7b6d24b51e383bca1fe1e62086fEnrico Granatapart of The LLVM Compiler Infrastructure 5579a296e7566b7b6d24b51e383bca1fe1e62086fEnrico GranataThis file is distributed under the University of Illinois Open Source 6579a296e7566b7b6d24b51e383bca1fe1e62086fEnrico GranataLicense. See LICENSE.TXT for details. 7579a296e7566b7b6d24b51e383bca1fe1e62086fEnrico Granata""" 83818e6ac2211921db522abedd43746c1de3e82b5Enrico Granata# example summary provider for NS(Mutable)IndexSet 93818e6ac2211921db522abedd43746c1de3e82b5Enrico Granata# the real summary is now C++ code built into LLDB 1083410e5e9e040ea5c6691f933aa9a6c4dcea4d8bEnrico Granataimport lldb 1183410e5e9e040ea5c6691f933aa9a6c4dcea4d8bEnrico Granataimport ctypes 120d235d5864e996d95f485df1a0df406126e1ccdeEnrico Granataimport lldb.runtime.objc.objc_runtime 130d235d5864e996d95f485df1a0df406126e1ccdeEnrico Granataimport lldb.formatters.metrics 140d235d5864e996d95f485df1a0df406126e1ccdeEnrico Granataimport lldb.formatters.Logger 1583410e5e9e040ea5c6691f933aa9a6c4dcea4d8bEnrico Granata 160d235d5864e996d95f485df1a0df406126e1ccdeEnrico Granatastatistics = lldb.formatters.metrics.Metrics() 1783410e5e9e040ea5c6691f933aa9a6c4dcea4d8bEnrico Granatastatistics.add_metric('invalid_isa') 1883410e5e9e040ea5c6691f933aa9a6c4dcea4d8bEnrico Granatastatistics.add_metric('invalid_pointer') 1983410e5e9e040ea5c6691f933aa9a6c4dcea4d8bEnrico Granatastatistics.add_metric('unknown_class') 2083410e5e9e040ea5c6691f933aa9a6c4dcea4d8bEnrico Granatastatistics.add_metric('code_notrun') 2183410e5e9e040ea5c6691f933aa9a6c4dcea4d8bEnrico Granata 2283410e5e9e040ea5c6691f933aa9a6c4dcea4d8bEnrico Granata# despite the similary to synthetic children providers, these classes are not 2383410e5e9e040ea5c6691f933aa9a6c4dcea4d8bEnrico Granata# trying to provide anything but the count of values for an NSIndexSet, so they need not 2483410e5e9e040ea5c6691f933aa9a6c4dcea4d8bEnrico Granata# obey the interface specification for synthetic children providers 2583410e5e9e040ea5c6691f933aa9a6c4dcea4d8bEnrico Granataclass NSIndexSetClass_SummaryProvider: 2683410e5e9e040ea5c6691f933aa9a6c4dcea4d8bEnrico Granata def adjust_for_architecture(self): 27f2a84671ff78bee1f82b60698f3ee9791585f8acEnrico Granata pass 2883410e5e9e040ea5c6691f933aa9a6c4dcea4d8bEnrico Granata 29f2a84671ff78bee1f82b60698f3ee9791585f8acEnrico Granata def __init__(self, valobj, params): 300d235d5864e996d95f485df1a0df406126e1ccdeEnrico Granata logger = lldb.formatters.Logger.Logger() 3183410e5e9e040ea5c6691f933aa9a6c4dcea4d8bEnrico Granata self.valobj = valobj; 32f2a84671ff78bee1f82b60698f3ee9791585f8acEnrico Granata self.sys_params = params 33f2a84671ff78bee1f82b60698f3ee9791585f8acEnrico Granata if not(self.sys_params.types_cache.NSUInteger): 34f2a84671ff78bee1f82b60698f3ee9791585f8acEnrico Granata if self.sys_params.is_64_bit: 35f2a84671ff78bee1f82b60698f3ee9791585f8acEnrico Granata self.sys_params.types_cache.NSUInteger = self.valobj.GetType().GetBasicType(lldb.eBasicTypeUnsignedLong) 362c56666dc5ab13b6299c0ef41439ded52bca5427Enrico Granata self.sys_params.types_cache.uint32 = self.valobj.GetType().GetBasicType(lldb.eBasicTypeUnsignedInt) 37f2a84671ff78bee1f82b60698f3ee9791585f8acEnrico Granata else: 38f2a84671ff78bee1f82b60698f3ee9791585f8acEnrico Granata self.sys_params.types_cache.NSUInteger = self.valobj.GetType().GetBasicType(lldb.eBasicTypeUnsignedInt) 392c56666dc5ab13b6299c0ef41439ded52bca5427Enrico Granata self.sys_params.types_cache.uint32 = self.valobj.GetType().GetBasicType(lldb.eBasicTypeUnsignedInt) 402c56666dc5ab13b6299c0ef41439ded52bca5427Enrico Granata if not(self.sys_params.types_cache.uint32): 412c56666dc5ab13b6299c0ef41439ded52bca5427Enrico Granata self.sys_params.types_cache.uint32 = self.valobj.GetType().GetBasicType(lldb.eBasicTypeUnsignedInt) 4283410e5e9e040ea5c6691f933aa9a6c4dcea4d8bEnrico Granata self.update(); 4383410e5e9e040ea5c6691f933aa9a6c4dcea4d8bEnrico Granata 4483410e5e9e040ea5c6691f933aa9a6c4dcea4d8bEnrico Granata def update(self): 450d235d5864e996d95f485df1a0df406126e1ccdeEnrico Granata logger = lldb.formatters.Logger.Logger() 4683410e5e9e040ea5c6691f933aa9a6c4dcea4d8bEnrico Granata self.adjust_for_architecture(); 4783410e5e9e040ea5c6691f933aa9a6c4dcea4d8bEnrico Granata 4883410e5e9e040ea5c6691f933aa9a6c4dcea4d8bEnrico Granata # NS(Mutable)IndexSet works in one of two modes: when having a compact block of data (e.g. a Range) 4983410e5e9e040ea5c6691f933aa9a6c4dcea4d8bEnrico Granata # the count is stored in the set itself, 3 pointers into it 5083410e5e9e040ea5c6691f933aa9a6c4dcea4d8bEnrico Granata # otherwise, it will store a pointer to an additional data structure (2 pointers into itself) and this 5183410e5e9e040ea5c6691f933aa9a6c4dcea4d8bEnrico Granata # additional structure will contain the count two pointers deep 522c56666dc5ab13b6299c0ef41439ded52bca5427Enrico Granata # a bunch of flags allow us to detect an empty set, vs. a one-range set, vs. a multi-range set 5383410e5e9e040ea5c6691f933aa9a6c4dcea4d8bEnrico Granata def count(self): 540d235d5864e996d95f485df1a0df406126e1ccdeEnrico Granata logger = lldb.formatters.Logger.Logger() 5583410e5e9e040ea5c6691f933aa9a6c4dcea4d8bEnrico Granata mode_chooser_vo = self.valobj.CreateChildAtOffset("mode_chooser", 562c56666dc5ab13b6299c0ef41439ded52bca5427Enrico Granata self.sys_params.pointer_size, 572c56666dc5ab13b6299c0ef41439ded52bca5427Enrico Granata self.sys_params.types_cache.uint32) 5883410e5e9e040ea5c6691f933aa9a6c4dcea4d8bEnrico Granata mode_chooser = mode_chooser_vo.GetValueAsUnsigned(0) 59f2a84671ff78bee1f82b60698f3ee9791585f8acEnrico Granata if self.sys_params.is_64_bit: 602c56666dc5ab13b6299c0ef41439ded52bca5427Enrico Granata mode_chooser = mode_chooser & 0x00000000FFFFFFFF 612c56666dc5ab13b6299c0ef41439ded52bca5427Enrico Granata # empty set 622c56666dc5ab13b6299c0ef41439ded52bca5427Enrico Granata if mode_chooser & 0x01 == 1: 632c56666dc5ab13b6299c0ef41439ded52bca5427Enrico Granata return 0 642c56666dc5ab13b6299c0ef41439ded52bca5427Enrico Granata # single range 652c56666dc5ab13b6299c0ef41439ded52bca5427Enrico Granata if mode_chooser & 0x02 == 2: 6683410e5e9e040ea5c6691f933aa9a6c4dcea4d8bEnrico Granata mode = 1 672c56666dc5ab13b6299c0ef41439ded52bca5427Enrico Granata # multi range 6883410e5e9e040ea5c6691f933aa9a6c4dcea4d8bEnrico Granata else: 6983410e5e9e040ea5c6691f933aa9a6c4dcea4d8bEnrico Granata mode = 2 7083410e5e9e040ea5c6691f933aa9a6c4dcea4d8bEnrico Granata if mode == 1: 7183410e5e9e040ea5c6691f933aa9a6c4dcea4d8bEnrico Granata count_vo = self.valobj.CreateChildAtOffset("count", 72f2a84671ff78bee1f82b60698f3ee9791585f8acEnrico Granata 3*self.sys_params.pointer_size, 73f2a84671ff78bee1f82b60698f3ee9791585f8acEnrico Granata self.sys_params.types_cache.NSUInteger) 7483410e5e9e040ea5c6691f933aa9a6c4dcea4d8bEnrico Granata else: 752c56666dc5ab13b6299c0ef41439ded52bca5427Enrico Granata count_ptr = self.valobj.CreateChildAtOffset("count_ptr", 762c56666dc5ab13b6299c0ef41439ded52bca5427Enrico Granata 2*self.sys_params.pointer_size, 772c56666dc5ab13b6299c0ef41439ded52bca5427Enrico Granata self.sys_params.types_cache.NSUInteger) 7883410e5e9e040ea5c6691f933aa9a6c4dcea4d8bEnrico Granata count_vo = self.valobj.CreateValueFromAddress("count", 792c56666dc5ab13b6299c0ef41439ded52bca5427Enrico Granata count_ptr.GetValueAsUnsigned()+2*self.sys_params.pointer_size, 80f2a84671ff78bee1f82b60698f3ee9791585f8acEnrico Granata self.sys_params.types_cache.NSUInteger) 8183410e5e9e040ea5c6691f933aa9a6c4dcea4d8bEnrico Granata return count_vo.GetValueAsUnsigned(0) 8283410e5e9e040ea5c6691f933aa9a6c4dcea4d8bEnrico Granata 8383410e5e9e040ea5c6691f933aa9a6c4dcea4d8bEnrico Granata 8483410e5e9e040ea5c6691f933aa9a6c4dcea4d8bEnrico Granataclass NSIndexSetUnknown_SummaryProvider: 8583410e5e9e040ea5c6691f933aa9a6c4dcea4d8bEnrico Granata def adjust_for_architecture(self): 86f2a84671ff78bee1f82b60698f3ee9791585f8acEnrico Granata pass 8783410e5e9e040ea5c6691f933aa9a6c4dcea4d8bEnrico Granata 88f2a84671ff78bee1f82b60698f3ee9791585f8acEnrico Granata def __init__(self, valobj, params): 890d235d5864e996d95f485df1a0df406126e1ccdeEnrico Granata logger = lldb.formatters.Logger.Logger() 9083410e5e9e040ea5c6691f933aa9a6c4dcea4d8bEnrico Granata self.valobj = valobj; 91f2a84671ff78bee1f82b60698f3ee9791585f8acEnrico Granata self.sys_params = params 92f2a84671ff78bee1f82b60698f3ee9791585f8acEnrico Granata self.update(); 9383410e5e9e040ea5c6691f933aa9a6c4dcea4d8bEnrico Granata 9483410e5e9e040ea5c6691f933aa9a6c4dcea4d8bEnrico Granata def update(self): 950d235d5864e996d95f485df1a0df406126e1ccdeEnrico Granata logger = lldb.formatters.Logger.Logger() 9683410e5e9e040ea5c6691f933aa9a6c4dcea4d8bEnrico Granata self.adjust_for_architecture(); 9783410e5e9e040ea5c6691f933aa9a6c4dcea4d8bEnrico Granata 9883410e5e9e040ea5c6691f933aa9a6c4dcea4d8bEnrico Granata def count(self): 990d235d5864e996d95f485df1a0df406126e1ccdeEnrico Granata logger = lldb.formatters.Logger.Logger() 10083410e5e9e040ea5c6691f933aa9a6c4dcea4d8bEnrico Granata stream = lldb.SBStream() 10183410e5e9e040ea5c6691f933aa9a6c4dcea4d8bEnrico Granata self.valobj.GetExpressionPath(stream) 10283410e5e9e040ea5c6691f933aa9a6c4dcea4d8bEnrico Granata expr = "(int)[" + stream.GetData() + " count]" 103579a296e7566b7b6d24b51e383bca1fe1e62086fEnrico Granata num_children_vo = self.valobj.CreateValueFromExpression("count",expr) 104579a296e7566b7b6d24b51e383bca1fe1e62086fEnrico Granata if num_children_vo.IsValid(): 105579a296e7566b7b6d24b51e383bca1fe1e62086fEnrico Granata return num_children_vo.GetValueAsUnsigned(0) 106579a296e7566b7b6d24b51e383bca1fe1e62086fEnrico Granata return '<variable is not NSIndexSet>' 10783410e5e9e040ea5c6691f933aa9a6c4dcea4d8bEnrico Granata 10883410e5e9e040ea5c6691f933aa9a6c4dcea4d8bEnrico Granata 10983410e5e9e040ea5c6691f933aa9a6c4dcea4d8bEnrico Granatadef GetSummary_Impl(valobj): 1100d235d5864e996d95f485df1a0df406126e1ccdeEnrico Granata logger = lldb.formatters.Logger.Logger() 11183410e5e9e040ea5c6691f933aa9a6c4dcea4d8bEnrico Granata global statistics 112a5c2ce05705f784fd4ada97823af6ff7006fea58Enrico Granata class_data,wrapper =lldb.runtime.objc.objc_runtime.Utilities.prepare_class_detection(valobj,statistics) 113579a296e7566b7b6d24b51e383bca1fe1e62086fEnrico Granata if wrapper: 114579a296e7566b7b6d24b51e383bca1fe1e62086fEnrico Granata return wrapper 11583410e5e9e040ea5c6691f933aa9a6c4dcea4d8bEnrico Granata 11683410e5e9e040ea5c6691f933aa9a6c4dcea4d8bEnrico Granata name_string = class_data.class_name() 1178f18240a09893310c43673901d863892ae7b0611Enrico Granata logger >> "class name is: " + str(name_string) 1188f18240a09893310c43673901d863892ae7b0611Enrico Granata 11983410e5e9e040ea5c6691f933aa9a6c4dcea4d8bEnrico Granata if name_string == 'NSIndexSet' or name_string == 'NSMutableIndexSet': 120f2a84671ff78bee1f82b60698f3ee9791585f8acEnrico Granata wrapper = NSIndexSetClass_SummaryProvider(valobj, class_data.sys_params) 12183410e5e9e040ea5c6691f933aa9a6c4dcea4d8bEnrico Granata statistics.metric_hit('code_notrun',valobj) 12283410e5e9e040ea5c6691f933aa9a6c4dcea4d8bEnrico Granata else: 123f2a84671ff78bee1f82b60698f3ee9791585f8acEnrico Granata wrapper = NSIndexSetUnknown_SummaryProvider(valobj, class_data.sys_params) 124805f79b15edd61887c26a3f0ea80457790ba5807Enrico Granata statistics.metric_hit('unknown_class',valobj.GetName() + " seen as " + name_string) 12583410e5e9e040ea5c6691f933aa9a6c4dcea4d8bEnrico Granata return wrapper; 12683410e5e9e040ea5c6691f933aa9a6c4dcea4d8bEnrico Granata 12783410e5e9e040ea5c6691f933aa9a6c4dcea4d8bEnrico Granata 12883410e5e9e040ea5c6691f933aa9a6c4dcea4d8bEnrico Granatadef NSIndexSet_SummaryProvider (valobj,dict): 1290d235d5864e996d95f485df1a0df406126e1ccdeEnrico Granata logger = lldb.formatters.Logger.Logger() 13083410e5e9e040ea5c6691f933aa9a6c4dcea4d8bEnrico Granata provider = GetSummary_Impl(valobj); 13183410e5e9e040ea5c6691f933aa9a6c4dcea4d8bEnrico Granata if provider != None: 132a5c2ce05705f784fd4ada97823af6ff7006fea58Enrico Granata if isinstance(provider,lldb.runtime.objc.objc_runtime.SpecialSituation_Description): 133579a296e7566b7b6d24b51e383bca1fe1e62086fEnrico Granata return provider.message() 13483410e5e9e040ea5c6691f933aa9a6c4dcea4d8bEnrico Granata try: 13583410e5e9e040ea5c6691f933aa9a6c4dcea4d8bEnrico Granata summary = provider.count(); 13683410e5e9e040ea5c6691f933aa9a6c4dcea4d8bEnrico Granata except: 13783410e5e9e040ea5c6691f933aa9a6c4dcea4d8bEnrico Granata summary = None 1388f18240a09893310c43673901d863892ae7b0611Enrico Granata logger >> "got summary " + str(summary) 13983410e5e9e040ea5c6691f933aa9a6c4dcea4d8bEnrico Granata if summary == None: 140579a296e7566b7b6d24b51e383bca1fe1e62086fEnrico Granata summary = '<variable is not NSIndexSet>' 141579a296e7566b7b6d24b51e383bca1fe1e62086fEnrico Granata if isinstance(summary, basestring): 142579a296e7566b7b6d24b51e383bca1fe1e62086fEnrico Granata return summary 14383410e5e9e040ea5c6691f933aa9a6c4dcea4d8bEnrico Granata else: 144defd0dc9331fbc7c8d0df60acf7fe63a64e393f4Enrico Granata summary = str(summary) + (' indexes' if summary != 1 else ' index') 14583410e5e9e040ea5c6691f933aa9a6c4dcea4d8bEnrico Granata return summary 146579a296e7566b7b6d24b51e383bca1fe1e62086fEnrico Granata return 'Summary Unavailable' 14783410e5e9e040ea5c6691f933aa9a6c4dcea4d8bEnrico Granata 14883410e5e9e040ea5c6691f933aa9a6c4dcea4d8bEnrico Granata 14983410e5e9e040ea5c6691f933aa9a6c4dcea4d8bEnrico Granatadef __lldb_init_module(debugger,dict): 15083410e5e9e040ea5c6691f933aa9a6c4dcea4d8bEnrico Granata debugger.HandleCommand("type summary add -F NSIndexSet.NSIndexSet_SummaryProvider NSIndexSet NSMutableIndexSet") 151