blob: 5fd83f8e89f165af4765c023c2c54b8750099375 [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 Granata50b5ee52013-03-16 00:50:25 +00008# example summary provider for NSBundle
9# the real summary is now C++ code built into LLDB
Enrico Granataeb4a4792012-02-23 23:10:27 +000010import lldb
11import ctypes
Enrico Granata28399ad2012-04-25 01:39:27 +000012import lldb.runtime.objc.objc_runtime
13import lldb.formatters.metrics
Enrico Granataeb4a4792012-02-23 23:10:27 +000014import NSURL
Enrico Granata28399ad2012-04-25 01:39:27 +000015import lldb.formatters.Logger
Enrico Granataeb4a4792012-02-23 23:10:27 +000016
Enrico Granata28399ad2012-04-25 01:39:27 +000017statistics = lldb.formatters.metrics.Metrics()
Enrico Granataeb4a4792012-02-23 23:10:27 +000018statistics.add_metric('invalid_isa')
19statistics.add_metric('invalid_pointer')
20statistics.add_metric('unknown_class')
21statistics.add_metric('code_notrun')
22
23# despite the similary to synthetic children providers, these classes are not
24# trying to provide anything but a summary for an NSURL, so they need not
25# obey the interface specification for synthetic children providers
26class NSBundleKnown_SummaryProvider:
27 def adjust_for_architecture(self):
Enrico Granatacfdafa32012-03-05 19:56:33 +000028 pass
Enrico Granataeb4a4792012-02-23 23:10:27 +000029
Enrico Granatacfdafa32012-03-05 19:56:33 +000030 def __init__(self, valobj, params):
Enrico Granata28399ad2012-04-25 01:39:27 +000031 logger = lldb.formatters.Logger.Logger()
Enrico Granataeb4a4792012-02-23 23:10:27 +000032 self.valobj = valobj;
Enrico Granatacfdafa32012-03-05 19:56:33 +000033 self.sys_params = params
34 if not(self.sys_params.types_cache.NSString):
35 self.sys_params.types_cache.NSString = self.valobj.GetTarget().FindFirstType('NSString').GetPointerType()
Enrico Granataeb4a4792012-02-23 23:10:27 +000036 self.update();
37
38 def update(self):
Enrico Granata28399ad2012-04-25 01:39:27 +000039 logger = lldb.formatters.Logger.Logger()
Enrico Granataeb4a4792012-02-23 23:10:27 +000040 self.adjust_for_architecture();
Enrico Granataeb4a4792012-02-23 23:10:27 +000041
42 # we need to skip the ISA, plus four other values
43 # that are luckily each a pointer in size
44 # which makes our computation trivial :-)
45 def offset(self):
Enrico Granata28399ad2012-04-25 01:39:27 +000046 logger = lldb.formatters.Logger.Logger()
Enrico Granatacfdafa32012-03-05 19:56:33 +000047 return 5 * self.sys_params.pointer_size
Enrico Granataeb4a4792012-02-23 23:10:27 +000048
49 def url_text(self):
Enrico Granata28399ad2012-04-25 01:39:27 +000050 logger = lldb.formatters.Logger.Logger()
Enrico Granataeb4a4792012-02-23 23:10:27 +000051 global statistics
52 text = self.valobj.CreateChildAtOffset("text",
53 self.offset(),
Enrico Granatacfdafa32012-03-05 19:56:33 +000054 self.sys_params.types_cache.NSString)
Enrico Granataeb4a4792012-02-23 23:10:27 +000055 my_string = text.GetSummary()
56 if (my_string == None) or (my_string == ''):
Sylvestre Ledruf6102892014-08-11 18:06:28 +000057 statistics.metric_hit('unknown_class',str(self.valobj.GetName()) + " triggered unknown pointer location")
Enrico Granatacfdafa32012-03-05 19:56:33 +000058 return NSBundleUnknown_SummaryProvider(self.valobj, self.sys_params).url_text()
Enrico Granataeb4a4792012-02-23 23:10:27 +000059 else:
60 statistics.metric_hit('code_notrun',self.valobj)
61 return my_string
62
63
64class NSBundleUnknown_SummaryProvider:
65 def adjust_for_architecture(self):
Enrico Granatacfdafa32012-03-05 19:56:33 +000066 pass
Enrico Granataeb4a4792012-02-23 23:10:27 +000067
Enrico Granatacfdafa32012-03-05 19:56:33 +000068 def __init__(self, valobj, params):
Enrico Granata28399ad2012-04-25 01:39:27 +000069 logger = lldb.formatters.Logger.Logger()
Enrico Granataeb4a4792012-02-23 23:10:27 +000070 self.valobj = valobj;
Enrico Granatacfdafa32012-03-05 19:56:33 +000071 self.sys_params = params
Enrico Granataeb4a4792012-02-23 23:10:27 +000072 self.update()
73
74 def update(self):
Enrico Granata28399ad2012-04-25 01:39:27 +000075 logger = lldb.formatters.Logger.Logger()
Enrico Granataeb4a4792012-02-23 23:10:27 +000076 self.adjust_for_architecture();
Enrico Granataeb4a4792012-02-23 23:10:27 +000077
78 def url_text(self):
Enrico Granata28399ad2012-04-25 01:39:27 +000079 logger = lldb.formatters.Logger.Logger()
Enrico Granataeb4a4792012-02-23 23:10:27 +000080 stream = lldb.SBStream()
81 self.valobj.GetExpressionPath(stream)
82 expr = "(NSString*)[" + stream.GetData() + " bundlePath]"
83 url_text_vo = self.valobj.CreateValueFromExpression("path",expr);
Enrico Granata3f1052b2012-03-13 21:52:00 +000084 if url_text_vo.IsValid():
85 return url_text_vo.GetSummary()
86 return '<variable is not NSBundle>'
Enrico Granataeb4a4792012-02-23 23:10:27 +000087
88
89def GetSummary_Impl(valobj):
Enrico Granata28399ad2012-04-25 01:39:27 +000090 logger = lldb.formatters.Logger.Logger()
Enrico Granataeb4a4792012-02-23 23:10:27 +000091 global statistics
Enrico Granata7d222212012-04-25 17:53:41 +000092 class_data,wrapper =lldb.runtime.objc.objc_runtime.Utilities.prepare_class_detection(valobj,statistics)
Enrico Granata3f1052b2012-03-13 21:52:00 +000093 if wrapper:
94 return wrapper
Enrico Granataeb4a4792012-02-23 23:10:27 +000095
96 name_string = class_data.class_name()
Enrico Granata247bd412012-04-02 16:39:29 +000097 logger >> "class name is: " + str(name_string)
98
Enrico Granataeb4a4792012-02-23 23:10:27 +000099 if name_string == 'NSBundle':
Enrico Granatacfdafa32012-03-05 19:56:33 +0000100 wrapper = NSBundleKnown_SummaryProvider(valobj, class_data.sys_params)
Enrico Granataeb4a4792012-02-23 23:10:27 +0000101 # [NSBundle mainBundle] does return an object that is
102 # not correctly filled out for our purposes, so we still
103 # end up having to run code in that case
104 #statistics.metric_hit('code_notrun',valobj)
105 else:
Enrico Granatacfdafa32012-03-05 19:56:33 +0000106 wrapper = NSBundleUnknown_SummaryProvider(valobj, class_data.sys_params)
Enrico Granataa7daeeb2012-03-30 00:51:12 +0000107 statistics.metric_hit('unknown_class',valobj.GetName() + " seen as " + name_string)
Enrico Granataeb4a4792012-02-23 23:10:27 +0000108 return wrapper;
109
110def NSBundle_SummaryProvider (valobj,dict):
Enrico Granata28399ad2012-04-25 01:39:27 +0000111 logger = lldb.formatters.Logger.Logger()
Enrico Granataeb4a4792012-02-23 23:10:27 +0000112 provider = GetSummary_Impl(valobj);
113 if provider != None:
Enrico Granata7d222212012-04-25 17:53:41 +0000114 if isinstance(provider,lldb.runtime.objc.objc_runtime.SpecialSituation_Description):
Enrico Granata3f1052b2012-03-13 21:52:00 +0000115 return provider.message()
116 try:
117 summary = provider.url_text();
118 except:
119 summary = None
Enrico Granata247bd412012-04-02 16:39:29 +0000120 logger >> "got summary " + str(summary)
Enrico Granata3f1052b2012-03-13 21:52:00 +0000121 if summary == None or summary == '':
122 summary = '<variable is not NSBundle>'
123 return summary
124 return 'Summary Unavailable'
Enrico Granataeb4a4792012-02-23 23:10:27 +0000125
126def __lldb_init_module(debugger,dict):
127 debugger.HandleCommand("type summary add -F NSBundle.NSBundle_SummaryProvider NSBundle")