blob: 1ddb943a38ab56bfe0a2ab410dd5556585fe9e33 [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 Granataeb4a4792012-02-23 23:10:27 +00008# summary provider for CFBag
9import lldb
10import ctypes
11import objc_runtime
12import metrics
13
14statistics = metrics.Metrics()
15statistics.add_metric('invalid_isa')
16statistics.add_metric('invalid_pointer')
17statistics.add_metric('unknown_class')
18statistics.add_metric('code_notrun')
19
20# despite the similary to synthetic children providers, these classes are not
21# trying to provide anything but the length for an CFBag, so they need not
22# obey the interface specification for synthetic children providers
23class CFBagRef_SummaryProvider:
24 def adjust_for_architecture(self):
Enrico Granatacfdafa32012-03-05 19:56:33 +000025 pass
Enrico Granataeb4a4792012-02-23 23:10:27 +000026
Enrico Granatacfdafa32012-03-05 19:56:33 +000027 def __init__(self, valobj, params):
Enrico Granataeb4a4792012-02-23 23:10:27 +000028 self.valobj = valobj;
Enrico Granatacfdafa32012-03-05 19:56:33 +000029 self.sys_params = params
30 if not(self.sys_params.types_cache.NSUInteger):
31 if self.sys_params.is_64_bit:
32 self.sys_params.types_cache.NSUInteger = self.valobj.GetType().GetBasicType(lldb.eBasicTypeUnsignedLong)
33 else:
34 self.sys_params.types_cache.NSUInteger = self.valobj.GetType().GetBasicType(lldb.eBasicTypeUnsignedInt)
Enrico Granataeb4a4792012-02-23 23:10:27 +000035 self.update();
36
37 def update(self):
38 self.adjust_for_architecture();
Enrico Granataeb4a4792012-02-23 23:10:27 +000039
40 # 12 bytes on i386
41 # 20 bytes on x64
42 # most probably 2 pointers and 4 bytes of data
43 def offset(self):
Enrico Granatacfdafa32012-03-05 19:56:33 +000044 if self.sys_params.is_64_bit:
Enrico Granataeb4a4792012-02-23 23:10:27 +000045 return 20
46 else:
47 return 12
48
49 def length(self):
50 size = self.valobj.CreateChildAtOffset("count",
51 self.offset(),
Enrico Granatacfdafa32012-03-05 19:56:33 +000052 self.sys_params.types_cache.NSUInteger)
Enrico Granataeb4a4792012-02-23 23:10:27 +000053 return size.GetValueAsUnsigned(0)
54
55
56class CFBagUnknown_SummaryProvider:
57 def adjust_for_architecture(self):
Enrico Granatacfdafa32012-03-05 19:56:33 +000058 pass
Enrico Granataeb4a4792012-02-23 23:10:27 +000059
Enrico Granatacfdafa32012-03-05 19:56:33 +000060 def __init__(self, valobj, params):
Enrico Granataeb4a4792012-02-23 23:10:27 +000061 self.valobj = valobj;
Enrico Granatacfdafa32012-03-05 19:56:33 +000062 self.sys_params = params
63 self.update();
Enrico Granataeb4a4792012-02-23 23:10:27 +000064
65 def update(self):
66 self.adjust_for_architecture();
Enrico Granataeb4a4792012-02-23 23:10:27 +000067
68 def length(self):
69 stream = lldb.SBStream()
70 self.valobj.GetExpressionPath(stream)
Enrico Granata3f1052b2012-03-13 21:52:00 +000071 num_children_vo = self.valobj.CreateValueFromExpression("count","(int)CFBagGetCount(" + stream.GetData() + " )")
72 if num_children_vo.IsValid():
73 return num_children_vo.GetValueAsUnsigned(0)
74 return "<variable is not CFBag>"
Enrico Granataeb4a4792012-02-23 23:10:27 +000075
76
77def GetSummary_Impl(valobj):
78 global statistics
Enrico Granata3f1052b2012-03-13 21:52:00 +000079 class_data,wrapper = objc_runtime.Utilities.prepare_class_detection(valobj,statistics)
80 if wrapper:
81 return wrapper
Enrico Granataeb4a4792012-02-23 23:10:27 +000082
83 name_string = class_data.class_name()
84 actual_name = name_string
Enrico Granata3f1052b2012-03-13 21:52:00 +000085 if class_data.is_cftype():
Enrico Granataeb4a4792012-02-23 23:10:27 +000086 # CFBag does not expose an actual NSWrapper type, so we have to check that this is
87 # an NSCFType and then check we are a pointer-to __CFBag
88 valobj_type = valobj.GetType()
89 if valobj_type.IsValid() and valobj_type.IsPointerType():
Enrico Granata3f1052b2012-03-13 21:52:00 +000090 valobj_type = valobj_type.GetPointeeType()
91 if valobj_type.IsValid():
92 actual_name = valobj_type.GetName()
93 if actual_name == '__CFBag' or \
94 actual_name == 'const struct __CFBag':
95 wrapper = CFBagRef_SummaryProvider(valobj, class_data.sys_params)
96 statistics.metric_hit('code_notrun',valobj)
97 return wrapper
Enrico Granatacfdafa32012-03-05 19:56:33 +000098 wrapper = CFBagUnknown_SummaryProvider(valobj, class_data.sys_params)
Enrico Granataeb4a4792012-02-23 23:10:27 +000099 statistics.metric_hit('unknown_class',str(valobj) + " seen as " + actual_name)
100 return wrapper;
101
102def CFBag_SummaryProvider (valobj,dict):
103 provider = GetSummary_Impl(valobj);
104 if provider != None:
Enrico Granata3f1052b2012-03-13 21:52:00 +0000105 if isinstance(provider,objc_runtime.SpecialSituation_Description):
106 return provider.message()
Enrico Granataeb4a4792012-02-23 23:10:27 +0000107 try:
108 summary = provider.length();
109 except:
110 summary = None
111 # for some reason, one needs to clear some bits for the count
112 # to be correct when using CF(Mutable)BagRef on x64
113 # the bit mask was derived through experimentation
114 # (if counts start looking weird, then most probably
115 # the mask needs to be changed)
116 if summary == None:
Enrico Granata3f1052b2012-03-13 21:52:00 +0000117 summary = '<variable is not CFBag>'
118 elif isinstance(summary,basestring):
119 pass
Enrico Granataeb4a4792012-02-23 23:10:27 +0000120 else:
Enrico Granatacfdafa32012-03-05 19:56:33 +0000121 if provider.sys_params.is_64_bit:
Enrico Granataeb4a4792012-02-23 23:10:27 +0000122 summary = summary & ~0x1fff000000000000
Enrico Granataeb06e252012-03-07 00:56:09 +0000123 if summary == 1:
Enrico Granata8c69c962012-03-13 00:25:59 +0000124 summary = '@"1 value"'
Enrico Granataeb06e252012-03-07 00:56:09 +0000125 else:
Enrico Granata8c69c962012-03-13 00:25:59 +0000126 summary = '@"' + str(summary) + ' values"'
Enrico Granataeb06e252012-03-07 00:56:09 +0000127 return summary
Enrico Granata3f1052b2012-03-13 21:52:00 +0000128 return 'Summary Unavailable'
Enrico Granataeb4a4792012-02-23 23:10:27 +0000129
130def __lldb_init_module(debugger,dict):
131 debugger.HandleCommand("type summary add -F CFBag.CFBag_SummaryProvider CFBagRef CFMutableBagRef")