blob: 4dd63b4a5c3202e8b1fb2638d9916d146a15788f [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 Granata6d37cc62013-03-19 00:27:22 +00008# example summary provider for NSDate
9# the real summary is now C++ code built into LLDB
Enrico Granata7bc0ec32012-02-29 03:28:49 +000010import lldb
11import ctypes
Enrico Granata28399ad2012-04-25 01:39:27 +000012import lldb.runtime.objc.objc_runtime
13import lldb.formatters.metrics
Enrico Granata7bc0ec32012-02-29 03:28:49 +000014import struct
15import time
16import datetime
Enrico Granata8d5c83f2012-03-02 00:55:53 +000017import CFString
Enrico Granata28399ad2012-04-25 01:39:27 +000018import lldb.formatters.Logger
Enrico Granata7bc0ec32012-02-29 03:28:49 +000019
Enrico Granata28399ad2012-04-25 01:39:27 +000020statistics = lldb.formatters.metrics.Metrics()
Enrico Granata7bc0ec32012-02-29 03:28:49 +000021statistics.add_metric('invalid_isa')
22statistics.add_metric('invalid_pointer')
23statistics.add_metric('unknown_class')
24statistics.add_metric('code_notrun')
25
26# Python promises to start counting time at midnight on Jan 1st on the epoch year
27# hence, all we need to know is the epoch year
28python_epoch = time.gmtime(0).tm_year
29
30osx_epoch = datetime.date(2001,1,1).timetuple()
31
32def mkgmtime(t):
Enrico Granata28399ad2012-04-25 01:39:27 +000033 logger = lldb.formatters.Logger.Logger()
Enrico Granata247bd412012-04-02 16:39:29 +000034 return time.mktime(t)-time.timezone
Enrico Granata7bc0ec32012-02-29 03:28:49 +000035
36osx_epoch = mkgmtime(osx_epoch)
37
38def osx_to_python_time(osx):
Enrico Granata28399ad2012-04-25 01:39:27 +000039 logger = lldb.formatters.Logger.Logger()
Enrico Granata896cd1d2012-03-01 19:32:33 +000040 if python_epoch <= 2001:
Enrico Granata7bc0ec32012-02-29 03:28:49 +000041 return osx + osx_epoch
42 else:
43 return osx - osx_epoch
44
Enrico Granata8c69c962012-03-13 00:25:59 +000045# represent a struct_time as a string in the format used by Xcode
46def xcode_format_time(X):
Enrico Granata28399ad2012-04-25 01:39:27 +000047 logger = lldb.formatters.Logger.Logger()
Enrico Granata8c69c962012-03-13 00:25:59 +000048 return time.strftime('%Y-%m-%d %H:%M:%S %Z',X)
49
50# represent a count-since-epoch as a string in the format used by Xcode
51def xcode_format_count(X):
Enrico Granata28399ad2012-04-25 01:39:27 +000052 logger = lldb.formatters.Logger.Logger()
Enrico Granata8c69c962012-03-13 00:25:59 +000053 return xcode_format_time(time.localtime(X))
Enrico Granata7bc0ec32012-02-29 03:28:49 +000054
55# despite the similary to synthetic children providers, these classes are not
Enrico Granata896cd1d2012-03-01 19:32:33 +000056# trying to provide anything but the summary for NSDate, so they need not
Enrico Granata7bc0ec32012-02-29 03:28:49 +000057# obey the interface specification for synthetic children providers
58class NSTaggedDate_SummaryProvider:
59 def adjust_for_architecture(self):
Enrico Granatacfdafa32012-03-05 19:56:33 +000060 pass
Enrico Granata7bc0ec32012-02-29 03:28:49 +000061
Enrico Granatacfdafa32012-03-05 19:56:33 +000062 def __init__(self, valobj, info_bits, data, params):
Enrico Granata28399ad2012-04-25 01:39:27 +000063 logger = lldb.formatters.Logger.Logger()
Enrico Granata7bc0ec32012-02-29 03:28:49 +000064 self.valobj = valobj;
Enrico Granatacfdafa32012-03-05 19:56:33 +000065 self.sys_params = params
Enrico Granata7bc0ec32012-02-29 03:28:49 +000066 self.update();
Enrico Granata896cd1d2012-03-01 19:32:33 +000067 # NSDate is not using its info_bits for info like NSNumber is
68 # so we need to regroup info_bits and data
69 self.data = ((data << 8) | (info_bits << 4))
Enrico Granata7bc0ec32012-02-29 03:28:49 +000070
71 def update(self):
Enrico Granata28399ad2012-04-25 01:39:27 +000072 logger = lldb.formatters.Logger.Logger()
Enrico Granata7bc0ec32012-02-29 03:28:49 +000073 self.adjust_for_architecture();
Enrico Granata7bc0ec32012-02-29 03:28:49 +000074
75 def value(self):
Enrico Granata28399ad2012-04-25 01:39:27 +000076 logger = lldb.formatters.Logger.Logger()
Enrico Granata7bc0ec32012-02-29 03:28:49 +000077 # the value of the date-time object is wrapped into the pointer value
Enrico Granata896cd1d2012-03-01 19:32:33 +000078 # unfortunately, it is made as a time-delta after Jan 1 2001 midnight GMT
Enrico Granata7bc0ec32012-02-29 03:28:49 +000079 # while all Python knows about is the "epoch", which is a platform-dependent
80 # year (1970 of *nix) whose Jan 1 at midnight is taken as reference
Enrico Granata896cd1d2012-03-01 19:32:33 +000081 value_double = struct.unpack('d', struct.pack('Q', self.data))[0]
Enrico Granata39cf67e2012-09-04 20:02:39 +000082 if value_double == -63114076800.0:
83 return '0001-12-30 00:00:00 +0000'
Enrico Granata8c69c962012-03-13 00:25:59 +000084 return xcode_format_count(osx_to_python_time(value_double))
Enrico Granata7bc0ec32012-02-29 03:28:49 +000085
86
87class NSUntaggedDate_SummaryProvider:
88 def adjust_for_architecture(self):
Enrico Granatacfdafa32012-03-05 19:56:33 +000089 pass
Enrico Granata7bc0ec32012-02-29 03:28:49 +000090
Enrico Granatacfdafa32012-03-05 19:56:33 +000091 def __init__(self, valobj, params):
Enrico Granata28399ad2012-04-25 01:39:27 +000092 logger = lldb.formatters.Logger.Logger()
Enrico Granata7bc0ec32012-02-29 03:28:49 +000093 self.valobj = valobj;
Enrico Granatacfdafa32012-03-05 19:56:33 +000094 self.sys_params = params
95 if not (self.sys_params.types_cache.double):
96 self.sys_params.types_cache.double = self.valobj.GetType().GetBasicType(lldb.eBasicTypeDouble)
Enrico Granata7bc0ec32012-02-29 03:28:49 +000097 self.update()
98
99 def update(self):
Enrico Granata28399ad2012-04-25 01:39:27 +0000100 logger = lldb.formatters.Logger.Logger()
Enrico Granata7bc0ec32012-02-29 03:28:49 +0000101 self.adjust_for_architecture();
Enrico Granata7bc0ec32012-02-29 03:28:49 +0000102
103 def offset(self):
Enrico Granata28399ad2012-04-25 01:39:27 +0000104 logger = lldb.formatters.Logger.Logger()
Enrico Granatacfdafa32012-03-05 19:56:33 +0000105 return self.sys_params.pointer_size
Enrico Granata7bc0ec32012-02-29 03:28:49 +0000106
107 def value(self):
Enrico Granata28399ad2012-04-25 01:39:27 +0000108 logger = lldb.formatters.Logger.Logger()
Enrico Granata7bc0ec32012-02-29 03:28:49 +0000109 value = self.valobj.CreateChildAtOffset("value",
110 self.offset(),
Enrico Granatacfdafa32012-03-05 19:56:33 +0000111 self.sys_params.types_cache.double)
Enrico Granata7b3d2052012-10-24 19:05:32 +0000112 value_double = struct.unpack('d', struct.pack('Q', value.GetData().uint64[0]))[0]
Enrico Granata39cf67e2012-09-04 20:02:39 +0000113 if value_double == -63114076800.0:
114 return '0001-12-30 00:00:00 +0000'
Enrico Granata8c69c962012-03-13 00:25:59 +0000115 return xcode_format_count(osx_to_python_time(value_double))
Enrico Granata7bc0ec32012-02-29 03:28:49 +0000116
Enrico Granata896cd1d2012-03-01 19:32:33 +0000117class NSCalendarDate_SummaryProvider:
118 def adjust_for_architecture(self):
Enrico Granatacfdafa32012-03-05 19:56:33 +0000119 pass
Enrico Granata896cd1d2012-03-01 19:32:33 +0000120
Enrico Granatacfdafa32012-03-05 19:56:33 +0000121 def __init__(self, valobj, params):
Enrico Granata28399ad2012-04-25 01:39:27 +0000122 logger = lldb.formatters.Logger.Logger()
Enrico Granata896cd1d2012-03-01 19:32:33 +0000123 self.valobj = valobj;
Enrico Granatacfdafa32012-03-05 19:56:33 +0000124 self.sys_params = params
125 if not (self.sys_params.types_cache.double):
126 self.sys_params.types_cache.double = self.valobj.GetType().GetBasicType(lldb.eBasicTypeDouble)
Enrico Granata896cd1d2012-03-01 19:32:33 +0000127 self.update()
128
129 def update(self):
Enrico Granata28399ad2012-04-25 01:39:27 +0000130 logger = lldb.formatters.Logger.Logger()
Enrico Granata896cd1d2012-03-01 19:32:33 +0000131 self.adjust_for_architecture();
Enrico Granata896cd1d2012-03-01 19:32:33 +0000132
133 def offset(self):
Enrico Granata28399ad2012-04-25 01:39:27 +0000134 logger = lldb.formatters.Logger.Logger()
Enrico Granatacfdafa32012-03-05 19:56:33 +0000135 return 2*self.sys_params.pointer_size
Enrico Granata896cd1d2012-03-01 19:32:33 +0000136
137 def value(self):
Enrico Granata28399ad2012-04-25 01:39:27 +0000138 logger = lldb.formatters.Logger.Logger()
Enrico Granata896cd1d2012-03-01 19:32:33 +0000139 value = self.valobj.CreateChildAtOffset("value",
140 self.offset(),
Enrico Granatacfdafa32012-03-05 19:56:33 +0000141 self.sys_params.types_cache.double)
Enrico Granata7b3d2052012-10-24 19:05:32 +0000142 value_double = struct.unpack('d', struct.pack('Q', value.GetData().uint64[0]))[0]
Enrico Granata8c69c962012-03-13 00:25:59 +0000143 return xcode_format_count(osx_to_python_time(value_double))
Enrico Granata896cd1d2012-03-01 19:32:33 +0000144
Enrico Granata8d5c83f2012-03-02 00:55:53 +0000145class NSTimeZoneClass_SummaryProvider:
146 def adjust_for_architecture(self):
Enrico Granatacfdafa32012-03-05 19:56:33 +0000147 pass
Enrico Granata8d5c83f2012-03-02 00:55:53 +0000148
Enrico Granatacfdafa32012-03-05 19:56:33 +0000149 def __init__(self, valobj, params):
Enrico Granata28399ad2012-04-25 01:39:27 +0000150 logger = lldb.formatters.Logger.Logger()
Enrico Granata8d5c83f2012-03-02 00:55:53 +0000151 self.valobj = valobj;
Enrico Granatacfdafa32012-03-05 19:56:33 +0000152 self.sys_params = params
153 if not (self.sys_params.types_cache.voidptr):
154 self.sys_params.types_cache.voidptr = self.valobj.GetType().GetBasicType(lldb.eBasicTypeVoid).GetPointerType()
Enrico Granata8d5c83f2012-03-02 00:55:53 +0000155 self.update()
156
157 def update(self):
Enrico Granata28399ad2012-04-25 01:39:27 +0000158 logger = lldb.formatters.Logger.Logger()
Enrico Granata8d5c83f2012-03-02 00:55:53 +0000159 self.adjust_for_architecture();
Enrico Granata8d5c83f2012-03-02 00:55:53 +0000160
161 def offset(self):
Enrico Granata28399ad2012-04-25 01:39:27 +0000162 logger = lldb.formatters.Logger.Logger()
Enrico Granatacfdafa32012-03-05 19:56:33 +0000163 return self.sys_params.pointer_size
Enrico Granata8d5c83f2012-03-02 00:55:53 +0000164
165 def timezone(self):
Enrico Granata28399ad2012-04-25 01:39:27 +0000166 logger = lldb.formatters.Logger.Logger()
Enrico Granata8d5c83f2012-03-02 00:55:53 +0000167 tz_string = self.valobj.CreateChildAtOffset("tz_name",
168 self.offset(),
Enrico Granatacfdafa32012-03-05 19:56:33 +0000169 self.sys_params.types_cache.voidptr)
Enrico Granata8d5c83f2012-03-02 00:55:53 +0000170 return CFString.CFString_SummaryProvider(tz_string,None)
Enrico Granata896cd1d2012-03-01 19:32:33 +0000171
Enrico Granata7bc0ec32012-02-29 03:28:49 +0000172class NSUnknownDate_SummaryProvider:
173 def adjust_for_architecture(self):
Enrico Granatacfdafa32012-03-05 19:56:33 +0000174 pass
Enrico Granata7bc0ec32012-02-29 03:28:49 +0000175
176 def __init__(self, valobj):
Enrico Granata28399ad2012-04-25 01:39:27 +0000177 logger = lldb.formatters.Logger.Logger()
Enrico Granata7bc0ec32012-02-29 03:28:49 +0000178 self.valobj = valobj;
179 self.update()
180
181 def update(self):
Enrico Granata28399ad2012-04-25 01:39:27 +0000182 logger = lldb.formatters.Logger.Logger()
Enrico Granata7bc0ec32012-02-29 03:28:49 +0000183 self.adjust_for_architecture();
Enrico Granata7bc0ec32012-02-29 03:28:49 +0000184
185 def value(self):
Enrico Granata28399ad2012-04-25 01:39:27 +0000186 logger = lldb.formatters.Logger.Logger()
Enrico Granata7bc0ec32012-02-29 03:28:49 +0000187 stream = lldb.SBStream()
188 self.valobj.GetExpressionPath(stream)
189 expr = "(NSString*)[" + stream.GetData() + " description]"
190 num_children_vo = self.valobj.CreateValueFromExpression("str",expr);
Enrico Granata3f1052b2012-03-13 21:52:00 +0000191 if num_children_vo.IsValid():
192 return num_children_vo.GetSummary()
193 return '<variable is not NSDate>'
Enrico Granata7bc0ec32012-02-29 03:28:49 +0000194
195def GetSummary_Impl(valobj):
Enrico Granata28399ad2012-04-25 01:39:27 +0000196 logger = lldb.formatters.Logger.Logger()
Enrico Granata7bc0ec32012-02-29 03:28:49 +0000197 global statistics
Enrico Granata7d222212012-04-25 17:53:41 +0000198 class_data,wrapper =lldb.runtime.objc.objc_runtime.Utilities.prepare_class_detection(valobj,statistics)
Enrico Granata3f1052b2012-03-13 21:52:00 +0000199 if wrapper:
200 return wrapper
Enrico Granata7bc0ec32012-02-29 03:28:49 +0000201
202 name_string = class_data.class_name()
Enrico Granata247bd412012-04-02 16:39:29 +0000203 logger >> "class name is: " + str(name_string)
204
Enrico Granata7bc0ec32012-02-29 03:28:49 +0000205 if name_string == 'NSDate' or name_string == '__NSDate' or name_string == '__NSTaggedDate':
206 if class_data.is_tagged():
Enrico Granatacfdafa32012-03-05 19:56:33 +0000207 wrapper = NSTaggedDate_SummaryProvider(valobj,class_data.info_bits(),class_data.value(), class_data.sys_params)
Enrico Granata7bc0ec32012-02-29 03:28:49 +0000208 statistics.metric_hit('code_notrun',valobj)
209 else:
Enrico Granatacfdafa32012-03-05 19:56:33 +0000210 wrapper = NSUntaggedDate_SummaryProvider(valobj, class_data.sys_params)
Enrico Granata7bc0ec32012-02-29 03:28:49 +0000211 statistics.metric_hit('code_notrun',valobj)
Enrico Granata896cd1d2012-03-01 19:32:33 +0000212 elif name_string == 'NSCalendarDate':
Enrico Granatacfdafa32012-03-05 19:56:33 +0000213 wrapper = NSCalendarDate_SummaryProvider(valobj, class_data.sys_params)
Enrico Granata896cd1d2012-03-01 19:32:33 +0000214 statistics.metric_hit('code_notrun',valobj)
Enrico Granata8d5c83f2012-03-02 00:55:53 +0000215 elif name_string == '__NSTimeZone':
Enrico Granatacfdafa32012-03-05 19:56:33 +0000216 wrapper = NSTimeZoneClass_SummaryProvider(valobj, class_data.sys_params)
Enrico Granata8d5c83f2012-03-02 00:55:53 +0000217 statistics.metric_hit('code_notrun',valobj)
Enrico Granata7bc0ec32012-02-29 03:28:49 +0000218 else:
Enrico Granata73076f92012-04-26 01:40:38 +0000219 wrapper = NSUnknownDate_SummaryProvider(valobj)
Enrico Granataa7daeeb2012-03-30 00:51:12 +0000220 statistics.metric_hit('unknown_class',valobj.GetName() + " seen as " + name_string)
Enrico Granata7bc0ec32012-02-29 03:28:49 +0000221 return wrapper;
222
223
224def NSDate_SummaryProvider (valobj,dict):
Enrico Granata28399ad2012-04-25 01:39:27 +0000225 logger = lldb.formatters.Logger.Logger()
Enrico Granata7bc0ec32012-02-29 03:28:49 +0000226 provider = GetSummary_Impl(valobj);
227 if provider != None:
Enrico Granata7d222212012-04-25 17:53:41 +0000228 if isinstance(provider,lldb.runtime.objc.objc_runtime.SpecialSituation_Description):
Enrico Granata3f1052b2012-03-13 21:52:00 +0000229 return provider.message()
230 try:
231 summary = provider.value();
232 except:
233 summary = None
234 if summary == None:
235 summary = '<variable is not NSDate>'
236 return str(summary)
237 return 'Summary Unavailable'
Enrico Granata7bc0ec32012-02-29 03:28:49 +0000238
Enrico Granata8d5c83f2012-03-02 00:55:53 +0000239def NSTimeZone_SummaryProvider (valobj,dict):
Enrico Granata28399ad2012-04-25 01:39:27 +0000240 logger = lldb.formatters.Logger.Logger()
Enrico Granata8d5c83f2012-03-02 00:55:53 +0000241 provider = GetSummary_Impl(valobj);
242 if provider != None:
Enrico Granata7d222212012-04-25 17:53:41 +0000243 if isinstance(provider,lldb.runtime.objc.objc_runtime.SpecialSituation_Description):
Enrico Granata3f1052b2012-03-13 21:52:00 +0000244 return provider.message()
245 try:
246 summary = provider.timezone();
247 except:
248 summary = None
Enrico Granata247bd412012-04-02 16:39:29 +0000249 logger >> "got summary " + str(summary)
Enrico Granata3f1052b2012-03-13 21:52:00 +0000250 if summary == None:
251 summary = '<variable is not NSTimeZone>'
252 return str(summary)
253 return 'Summary Unavailable'
Enrico Granata8d5c83f2012-03-02 00:55:53 +0000254
255
Enrico Granata896cd1d2012-03-01 19:32:33 +0000256def CFAbsoluteTime_SummaryProvider (valobj,dict):
Enrico Granata28399ad2012-04-25 01:39:27 +0000257 logger = lldb.formatters.Logger.Logger()
Enrico Granata896cd1d2012-03-01 19:32:33 +0000258 try:
Enrico Granata7b3d2052012-10-24 19:05:32 +0000259 value_double = struct.unpack('d', struct.pack('Q', valobj.GetData().uint64[0]))[0]
Enrico Granata8c69c962012-03-13 00:25:59 +0000260 return xcode_format_count(osx_to_python_time(value_double))
Enrico Granata896cd1d2012-03-01 19:32:33 +0000261 except:
Enrico Granata3f1052b2012-03-13 21:52:00 +0000262 return 'Summary Unavailable'
Enrico Granata896cd1d2012-03-01 19:32:33 +0000263
Enrico Granata7bc0ec32012-02-29 03:28:49 +0000264
265def __lldb_init_module(debugger,dict):
266 debugger.HandleCommand("type summary add -F NSDate.NSDate_SummaryProvider NSDate")
Enrico Granata896cd1d2012-03-01 19:32:33 +0000267 debugger.HandleCommand("type summary add -F NSDate.CFAbsoluteTime_SummaryProvider CFAbsoluteTime")
Enrico Granata8d5c83f2012-03-02 00:55:53 +0000268 debugger.HandleCommand("type summary add -F NSDate.NSTimeZone_SummaryProvider NSTimeZone CFTimeZoneRef")
Enrico Granata7bc0ec32012-02-29 03:28:49 +0000269