Run DCE after a LoopFlatten test to reduce spurious output [nfc]
[llvm-project.git] / lldb / examples / summaries / cocoa / CFBitVector.py
blobdfb5fb1acf48765eeb6c558413b97a3885c04428
1 """
2 LLDB AppKit formatters
4 Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
5 See https://llvm.org/LICENSE.txt for license information.
6 SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7 """
9 # summary provider for CF(Mutable)BitVector
10 import lldb
11 import ctypes
12 import lldb.runtime.objc.objc_runtime
13 import lldb.formatters.metrics
14 import lldb.formatters.Logger
16 # first define some utility functions
19 def byte_index(abs_pos):
20 logger = lldb.formatters.Logger.Logger()
21 return abs_pos / 8
24 def bit_index(abs_pos):
25 logger = lldb.formatters.Logger.Logger()
26 return abs_pos & 7
29 def get_bit(byte, index):
30 logger = lldb.formatters.Logger.Logger()
31 if index < 0 or index > 7:
32 return None
33 return (byte >> (7 - index)) & 1
36 def grab_array_item_data(pointer, index):
37 logger = lldb.formatters.Logger.Logger()
38 return pointer.GetPointeeData(index, 1)
41 statistics = lldb.formatters.metrics.Metrics()
42 statistics.add_metric("invalid_isa")
43 statistics.add_metric("invalid_pointer")
44 statistics.add_metric("unknown_class")
45 statistics.add_metric("code_notrun")
47 # despite the similary to synthetic children providers, these classes are not
48 # trying to provide anything but a summary for a CF*BitVector, so they need not
49 # obey the interface specification for synthetic children providers
52 class CFBitVectorKnown_SummaryProvider:
53 def adjust_for_architecture(self):
54 logger = lldb.formatters.Logger.Logger()
55 self.uiint_size = self.sys_params.types_cache.NSUInteger.GetByteSize()
56 pass
58 def __init__(self, valobj, params):
59 logger = lldb.formatters.Logger.Logger()
60 self.valobj = valobj
61 self.sys_params = params
62 if not (self.sys_params.types_cache.NSUInteger):
63 if self.sys_params.is_64_bit:
64 self.sys_params.types_cache.NSUInteger = (
65 self.valobj.GetType().GetBasicType(lldb.eBasicTypeUnsignedLong)
67 else:
68 self.sys_params.types_cache.NSUInteger = (
69 self.valobj.GetType().GetBasicType(lldb.eBasicTypeUnsignedInt)
71 if not (self.sys_params.types_cache.charptr):
72 self.sys_params.types_cache.charptr = (
73 self.valobj.GetType().GetBasicType(lldb.eBasicTypeChar).GetPointerType()
75 self.update()
77 def update(self):
78 logger = lldb.formatters.Logger.Logger()
79 self.adjust_for_architecture()
81 # we skip the CFRuntimeBase
82 # then the next CFIndex is the count
83 # then we skip another CFIndex and then we get at a byte array
84 # that wraps the individual bits
86 def contents(self):
87 logger = lldb.formatters.Logger.Logger()
88 count_vo = self.valobj.CreateChildAtOffset(
89 "count",
90 self.sys_params.cfruntime_size,
91 self.sys_params.types_cache.NSUInteger,
93 count = count_vo.GetValueAsUnsigned(0)
94 if count == 0:
95 return "(empty)"
97 array_vo = self.valobj.CreateChildAtOffset(
98 "data",
99 self.sys_params.cfruntime_size + 2 * self.uiint_size,
100 self.sys_params.types_cache.charptr,
103 data_list = []
104 cur_byte_pos = None
105 for i in range(0, count):
106 if cur_byte_pos is None:
107 cur_byte_pos = byte_index(i)
108 cur_byte = grab_array_item_data(array_vo, cur_byte_pos)
109 cur_byte_val = cur_byte.uint8[0]
110 else:
111 byte_pos = byte_index(i)
112 # do not fetch the pointee data every single time through
113 if byte_pos != cur_byte_pos:
114 cur_byte_pos = byte_pos
115 cur_byte = grab_array_item_data(array_vo, cur_byte_pos)
116 cur_byte_val = cur_byte.uint8[0]
117 bit = get_bit(cur_byte_val, bit_index(i))
118 if (i % 4) == 0:
119 data_list.append(" ")
120 if bit == 1:
121 data_list.append("1")
122 else:
123 data_list.append("0")
124 return "".join(data_list)
127 class CFBitVectorUnknown_SummaryProvider:
128 def adjust_for_architecture(self):
129 pass
131 def __init__(self, valobj, params):
132 logger = lldb.formatters.Logger.Logger()
133 self.valobj = valobj
134 self.sys_params = params
135 self.update()
137 def update(self):
138 logger = lldb.formatters.Logger.Logger()
139 self.adjust_for_architecture()
141 def contents(self):
142 logger = lldb.formatters.Logger.Logger()
143 return "<unable to summarize this CFBitVector>"
146 def GetSummary_Impl(valobj):
147 logger = lldb.formatters.Logger.Logger()
148 global statistics
150 class_data,
151 wrapper,
152 ) = lldb.runtime.objc.objc_runtime.Utilities.prepare_class_detection(
153 valobj, statistics
155 if wrapper:
156 return wrapper
158 name_string = class_data.class_name()
159 actual_name = name_string
161 logger >> "name string got was " + str(name_string) + " but actual name is " + str(
162 actual_name
165 if class_data.is_cftype():
166 # CFBitVectorRef does not expose an actual NSWrapper type, so we have to check that this is
167 # an NSCFType and then check we are a pointer-to CFBitVectorRef
168 valobj_type = valobj.GetType()
169 if valobj_type.IsValid() and valobj_type.IsPointerType():
170 valobj_type = valobj_type.GetPointeeType()
171 if valobj_type.IsValid():
172 actual_name = valobj_type.GetName()
173 if actual_name == "__CFBitVector" or actual_name == "__CFMutableBitVector":
174 wrapper = CFBitVectorKnown_SummaryProvider(valobj, class_data.sys_params)
175 statistics.metric_hit("code_notrun", valobj)
176 else:
177 wrapper = CFBitVectorUnknown_SummaryProvider(valobj, class_data.sys_params)
178 print(actual_name)
179 else:
180 wrapper = CFBitVectorUnknown_SummaryProvider(valobj, class_data.sys_params)
181 print(name_string)
182 statistics.metric_hit(
183 "unknown_class", valobj.GetName() + " seen as " + name_string
185 return wrapper
188 def CFBitVector_SummaryProvider(valobj, dict):
189 logger = lldb.formatters.Logger.Logger()
190 provider = GetSummary_Impl(valobj)
191 if provider is not None:
192 if isinstance(
193 provider, lldb.runtime.objc.objc_runtime.SpecialSituation_Description
195 return provider.message()
196 try:
197 summary = provider.contents()
198 except:
199 summary = None
200 logger >> "summary got from provider: " + str(summary)
201 if summary is None or summary == "":
202 summary = "<variable is not CFBitVector>"
203 return summary
204 return "Summary Unavailable"
207 def __lldb_init_module(debugger, dict):
208 debugger.HandleCommand(
209 "type summary add -F CFBitVector.CFBitVector_SummaryProvider CFBitVectorRef CFMutableBitVectorRef"