Run DCE after a LoopFlatten test to reduce spurious output [nfc]
[llvm-project.git] / lldb / examples / summaries / cocoa / CFBinaryHeap.py
blob3abebbfde82f0710eff7da992533726c7ea7435a
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 """
8 # example summary provider for CFBinaryHeap
9 # the real summary is now C++ code built into LLDB
10 import lldb
11 import ctypes
12 import lldb.runtime.objc.objc_runtime
13 import lldb.formatters.metrics
14 import lldb.formatters.Logger
16 statistics = lldb.formatters.metrics.Metrics()
17 statistics.add_metric("invalid_isa")
18 statistics.add_metric("invalid_pointer")
19 statistics.add_metric("unknown_class")
20 statistics.add_metric("code_notrun")
22 # despite the similary to synthetic children providers, these classes are not
23 # trying to provide anything but the length for an CFBinaryHeap, so they need not
24 # obey the interface specification for synthetic children providers
27 class CFBinaryHeapRef_SummaryProvider:
28 def adjust_for_architecture(self):
29 pass
31 def __init__(self, valobj, params):
32 logger = lldb.formatters.Logger.Logger()
33 self.valobj = valobj
34 self.sys_params = params
35 if not (self.sys_params.types_cache.NSUInteger):
36 if self.sys_params.is_64_bit:
37 self.sys_params.types_cache.NSUInteger = (
38 self.valobj.GetType().GetBasicType(lldb.eBasicTypeUnsignedLong)
40 else:
41 self.sys_params.types_cache.NSUInteger = (
42 self.valobj.GetType().GetBasicType(lldb.eBasicTypeUnsignedInt)
44 self.update()
46 def update(self):
47 logger = lldb.formatters.Logger.Logger()
48 self.adjust_for_architecture()
50 # 8 bytes on i386
51 # 16 bytes on x64
52 # most probably 2 pointers
53 def offset(self):
54 logger = lldb.formatters.Logger.Logger()
55 return 2 * self.sys_params.pointer_size
57 def length(self):
58 logger = lldb.formatters.Logger.Logger()
59 size = self.valobj.CreateChildAtOffset(
60 "count", self.offset(), self.sys_params.types_cache.NSUInteger
62 return size.GetValueAsUnsigned(0)
65 class CFBinaryHeapUnknown_SummaryProvider:
66 def adjust_for_architecture(self):
67 pass
69 def __init__(self, valobj, params):
70 logger = lldb.formatters.Logger.Logger()
71 self.valobj = valobj
72 self.sys_params = params
73 self.update()
75 def update(self):
76 logger = lldb.formatters.Logger.Logger()
77 self.adjust_for_architecture()
79 def length(self):
80 logger = lldb.formatters.Logger.Logger()
81 stream = lldb.SBStream()
82 self.valobj.GetExpressionPath(stream)
83 num_children_vo = self.valobj.CreateValueFromExpression(
84 "count", "(int)CFBinaryHeapGetCount(" + stream.GetData() + " )"
86 if num_children_vo.IsValid():
87 return num_children_vo.GetValueAsUnsigned(0)
88 return "<variable is not CFBinaryHeap>"
91 def GetSummary_Impl(valobj):
92 logger = lldb.formatters.Logger.Logger()
93 global statistics
95 class_data,
96 wrapper,
97 ) = lldb.runtime.objc.objc_runtime.Utilities.prepare_class_detection(
98 valobj, statistics
100 if wrapper:
101 return wrapper
103 name_string = class_data.class_name()
104 actual_name = class_data.class_name()
106 logger >> "name string got was " + str(name_string) + " but actual name is " + str(
107 actual_name
110 if class_data.is_cftype():
111 # CFBinaryHeap does not expose an actual NSWrapper type, so we have to check that this is
112 # an NSCFType and then check we are a pointer-to CFBinaryHeap
113 valobj_type = valobj.GetType()
114 if valobj_type.IsValid() and valobj_type.IsPointerType():
115 valobj_type = valobj_type.GetPointeeType()
116 if valobj_type.IsValid():
117 actual_name = valobj_type.GetName()
118 if actual_name == "__CFBinaryHeap":
119 wrapper = CFBinaryHeapRef_SummaryProvider(valobj, class_data.sys_params)
120 statistics.metric_hit("code_notrun", valobj)
121 return wrapper
122 wrapper = CFBinaryHeapUnknown_SummaryProvider(valobj, class_data.sys_params)
123 statistics.metric_hit("unknown_class", valobj.GetName() + " seen as " + name_string)
124 return wrapper
127 def CFBinaryHeap_SummaryProvider(valobj, dict):
128 logger = lldb.formatters.Logger.Logger()
129 provider = GetSummary_Impl(valobj)
130 if provider is not None:
131 if isinstance(
132 provider, lldb.runtime.objc.objc_runtime.SpecialSituation_Description
134 return provider.message()
135 try:
136 summary = provider.length()
137 except:
138 summary = None
139 logger >> "summary got from provider: " + str(summary)
140 # for some reason, one needs to clear some bits for the count
141 # to be correct when using CF(Mutable)BagRef on x64
142 # the bit mask was derived through experimentation
143 # (if counts start looking weird, then most probably
144 # the mask needs to be changed)
145 if summary is None:
146 summary = "<variable is not CFBinaryHeap>"
147 elif isinstance(summary, str):
148 pass
149 else:
150 if provider.sys_params.is_64_bit:
151 summary = summary & ~0x1FFF000000000000
152 if summary == 1:
153 return '@"1 item"'
154 else:
155 summary = '@"' + str(summary) + ' items"'
156 return summary
157 return "Summary Unavailable"
160 def __lldb_init_module(debugger, dict):
161 debugger.HandleCommand(
162 "type summary add -F CFBinaryHeap.CFBinaryHeap_SummaryProvider CFBinaryHeapRef"