blob: 6035ca7b13017df3977e17980fed9ee8e153c71c [file] [log] [blame]
Enrico Granata3f1052b2012-03-13 21:52:00 +00001"""
2LLDB AppKit formatters
3
4part of The LLVM Compiler Infrastructure
5This file is distributed under the University of Illinois Open Source
6License. See LICENSE.TXT for details.
7"""
Enrico Granata385ad4e2012-03-03 00:45:57 +00008# summary provider for CF(Mutable)BitVector
9import lldb
10import ctypes
11import objc_runtime
12import metrics
13
14# first define some utility functions
15def byte_index(abs_pos):
16 return abs_pos/8
17
18def bit_index(abs_pos):
19 return abs_pos & 7
20
21def get_bit(byte,index):
22 if index < 0 or index > 7:
23 return None
24 return (byte >> (7-index)) & 1
25
26def grab_array_item_data(pointer,index):
27 return pointer.GetPointeeData(index,1)
28
29statistics = metrics.Metrics()
30statistics.add_metric('invalid_isa')
31statistics.add_metric('invalid_pointer')
32statistics.add_metric('unknown_class')
33statistics.add_metric('code_notrun')
34
35# despite the similary to synthetic children providers, these classes are not
36# trying to provide anything but a summary for a CF*BitVector, so they need not
37# obey the interface specification for synthetic children providers
38class CFBitVectorKnown_SummaryProvider:
39 def adjust_for_architecture(self):
Enrico Granatacfdafa32012-03-05 19:56:33 +000040 self.uiint_size = self.sys_params.types_cache.NSUInteger.GetByteSize()
41 pass
Enrico Granata385ad4e2012-03-03 00:45:57 +000042
43 def __init__(self, valobj, params):
44 self.valobj = valobj;
45 self.sys_params = params
Enrico Granatacfdafa32012-03-05 19:56:33 +000046 if not(self.sys_params.types_cache.NSUInteger):
47 if self.sys_params.is_64_bit:
48 self.sys_params.types_cache.NSUInteger = self.valobj.GetType().GetBasicType(lldb.eBasicTypeUnsignedLong)
49 else:
50 self.sys_params.types_cache.NSUInteger = self.valobj.GetType().GetBasicType(lldb.eBasicTypeUnsignedInt)
51 if not(self.sys_params.types_cache.charptr):
52 self.sys_params.types_cache.charptr = self.valobj.GetType().GetBasicType(lldb.eBasicTypeChar).GetPointerType()
Enrico Granata385ad4e2012-03-03 00:45:57 +000053 self.update();
54
55 def update(self):
56 self.adjust_for_architecture();
Enrico Granata385ad4e2012-03-03 00:45:57 +000057
58 # we skip the CFRuntimeBase
59 # then the next CFIndex is the count
60 # then we skip another CFIndex and then we get at a byte array
61 # that wraps the individual bits
62
63 def contents(self):
Enrico Granatacfdafa32012-03-05 19:56:33 +000064 count_vo = self.valobj.CreateChildAtOffset("count",self.sys_params.cfruntime_size,
65 self.sys_params.types_cache.NSUInteger)
Enrico Granata385ad4e2012-03-03 00:45:57 +000066 count = count_vo.GetValueAsUnsigned(0)
67 if count == 0:
68 return '(empty)'
69
70 array_vo = self.valobj.CreateChildAtOffset("data",
Enrico Granatacfdafa32012-03-05 19:56:33 +000071 self.sys_params.cfruntime_size+2*self.uiint_size,
72 self.sys_params.types_cache.charptr)
Enrico Granata385ad4e2012-03-03 00:45:57 +000073
74 data_list = []
75 cur_byte_pos = None
76 for i in range(0,count):
77 if cur_byte_pos == None:
78 cur_byte_pos = byte_index(i)
79 cur_byte = grab_array_item_data(array_vo,cur_byte_pos)
80 cur_byte_val = cur_byte.uint8[0]
81 else:
82 byte_pos = byte_index(i)
83 # do not fetch the pointee data every single time through
84 if byte_pos != cur_byte_pos:
85 cur_byte_pos = byte_pos
86 cur_byte = grab_array_item_data(array_vo,cur_byte_pos)
87 cur_byte_val = cur_byte.uint8[0]
88 bit = get_bit(cur_byte_val,bit_index(i))
89 if (i % 4) == 0:
90 data_list.append(' ')
91 if bit == 1:
92 data_list.append('1')
93 else:
94 data_list.append('0')
95 return ''.join(data_list)
96
97
98class CFBitVectorUnknown_SummaryProvider:
99 def adjust_for_architecture(self):
Enrico Granatacfdafa32012-03-05 19:56:33 +0000100 pass
Enrico Granata385ad4e2012-03-03 00:45:57 +0000101
Enrico Granatacfdafa32012-03-05 19:56:33 +0000102 def __init__(self, valobj, params):
Enrico Granata385ad4e2012-03-03 00:45:57 +0000103 self.valobj = valobj;
Enrico Granatacfdafa32012-03-05 19:56:33 +0000104 self.sys_params = params
105 self.update();
Enrico Granata385ad4e2012-03-03 00:45:57 +0000106
107 def update(self):
108 self.adjust_for_architecture();
Enrico Granata385ad4e2012-03-03 00:45:57 +0000109
110 def contents(self):
Enrico Granata3f1052b2012-03-13 21:52:00 +0000111 return '<unable to summarize this CFBitVector>'
Enrico Granata385ad4e2012-03-03 00:45:57 +0000112
113
114def GetSummary_Impl(valobj):
115 global statistics
Enrico Granata3f1052b2012-03-13 21:52:00 +0000116 class_data,wrapper = objc_runtime.Utilities.prepare_class_detection(valobj,statistics)
117 if wrapper:
118 return wrapper
Enrico Granata385ad4e2012-03-03 00:45:57 +0000119
120 name_string = class_data.class_name()
Enrico Granata3f1052b2012-03-13 21:52:00 +0000121 actual_name = name_string
122 if class_data.is_cftype():
Enrico Granata385ad4e2012-03-03 00:45:57 +0000123 # CFBitVectorRef does not expose an actual NSWrapper type, so we have to check that this is
124 # an NSCFType and then check we are a pointer-to CFBitVectorRef
125 valobj_type = valobj.GetType()
126 if valobj_type.IsValid() and valobj_type.IsPointerType():
Enrico Granata3f1052b2012-03-13 21:52:00 +0000127 valobj_type = valobj_type.GetPointeeType()
128 if valobj_type.IsValid():
129 actual_name = valobj_type.GetName()
130 if actual_name == '__CFBitVector' or actual_name == '__CFMutableBitVector':
131 wrapper = CFBitVectorKnown_SummaryProvider(valobj, class_data.sys_params)
132 statistics.metric_hit('code_notrun',valobj)
133 else:
134 wrapper = CFBitVectorUnknown_SummaryProvider(valobj, class_data.sys_params)
135 print actual_name
Enrico Granata385ad4e2012-03-03 00:45:57 +0000136 else:
Enrico Granatacfdafa32012-03-05 19:56:33 +0000137 wrapper = CFBitVectorUnknown_SummaryProvider(valobj, class_data.sys_params)
Enrico Granata385ad4e2012-03-03 00:45:57 +0000138 print name_string
139 statistics.metric_hit('unknown_class',str(valobj) + " seen as " + name_string)
140 return wrapper;
141
142def CFBitVector_SummaryProvider (valobj,dict):
143 provider = GetSummary_Impl(valobj);
144 if provider != None:
Enrico Granata3f1052b2012-03-13 21:52:00 +0000145 if isinstance(provider,objc_runtime.SpecialSituation_Description):
146 return provider.message()
147 try:
148 summary = provider.contents();
149 except:
150 summary = None
151 if summary == None or summary == '':
152 summary = '<variable is not CFBitVector>'
153 return summary
154 return 'Summary Unavailable'
Enrico Granata385ad4e2012-03-03 00:45:57 +0000155
156def __lldb_init_module(debugger,dict):
157 debugger.HandleCommand("type summary add -F CFBitVector.CFBitVector_SummaryProvider CFBitVectorRef CFMutableBitVectorRef")