blob: 319d7561e5529ee7979c65b1bef2aabd4d2132bb [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 NSNotification
9# the real summary is now C++ code built into LLDB
Enrico Granata28399ad2012-04-25 01:39:27 +000010import lldb.runtime.objc.objc_runtime
11import lldb.formatters.metrics
Enrico Granataeb4a4792012-02-23 23:10:27 +000012import CFString
13import lldb
Enrico Granata28399ad2012-04-25 01:39:27 +000014import lldb.formatters.Logger
Enrico Granataeb4a4792012-02-23 23:10:27 +000015
Enrico Granata28399ad2012-04-25 01:39:27 +000016statistics = lldb.formatters.metrics.Metrics()
Enrico Granataeb4a4792012-02-23 23:10:27 +000017statistics.add_metric('invalid_isa')
18statistics.add_metric('invalid_pointer')
19statistics.add_metric('unknown_class')
20statistics.add_metric('code_notrun')
21
Kate Stoneb9c1b512016-09-06 20:57:50 +000022
Enrico Granataeb4a4792012-02-23 23:10:27 +000023class NSConcreteNotification_SummaryProvider:
Enrico Granataeb4a4792012-02-23 23:10:27 +000024
Kate Stoneb9c1b512016-09-06 20:57:50 +000025 def adjust_for_architecture(self):
26 pass
Enrico Granataeb4a4792012-02-23 23:10:27 +000027
Kate Stoneb9c1b512016-09-06 20:57:50 +000028 def __init__(self, valobj, params):
29 logger = lldb.formatters.Logger.Logger()
30 self.valobj = valobj
31 self.sys_params = params
32 if not (self.sys_params.types_cache.id):
33 self.sys_params.types_cache.id = self.valobj.GetType(
34 ).GetBasicType(lldb.eBasicTypeObjCID)
35 self.update()
Enrico Granataeb4a4792012-02-23 23:10:27 +000036
Kate Stoneb9c1b512016-09-06 20:57:50 +000037 def update(self):
38 logger = lldb.formatters.Logger.Logger()
39 self.adjust_for_architecture()
Enrico Granataeb55ad42012-03-09 00:45:19 +000040
Kate Stoneb9c1b512016-09-06 20:57:50 +000041 # skip the ISA and go to the name pointer
42 def offset(self):
43 logger = lldb.formatters.Logger.Logger()
44 return self.sys_params.pointer_size
45
46 def name(self):
47 logger = lldb.formatters.Logger.Logger()
48 string_ptr = self.valobj.CreateChildAtOffset(
49 "name", self.offset(), self.sys_params.types_cache.id)
50 return CFString.CFString_SummaryProvider(string_ptr, None)
Enrico Granataeb4a4792012-02-23 23:10:27 +000051
52
53class NSNotificationUnknown_SummaryProvider:
Enrico Granataeb4a4792012-02-23 23:10:27 +000054
Kate Stoneb9c1b512016-09-06 20:57:50 +000055 def adjust_for_architecture(self):
56 pass
Enrico Granataeb4a4792012-02-23 23:10:27 +000057
Kate Stoneb9c1b512016-09-06 20:57:50 +000058 def __init__(self, valobj, params):
59 logger = lldb.formatters.Logger.Logger()
60 self.valobj = valobj
61 self.sys_params = params
62 self.update()
Enrico Granataeb4a4792012-02-23 23:10:27 +000063
Kate Stoneb9c1b512016-09-06 20:57:50 +000064 def update(self):
65 logger = lldb.formatters.Logger.Logger()
66 self.adjust_for_architecture()
67
68 def name(self):
69 logger = lldb.formatters.Logger.Logger()
70 stream = lldb.SBStream()
71 self.valobj.GetExpressionPath(stream)
72 name_vo = self.valobj.CreateValueFromExpression(
73 "name", "(NSString*)[" + stream.GetData() + " name]")
74 if name_vo.IsValid():
75 return CFString.CFString_SummaryProvider(name_vo, None)
76 return '<variable is not NSNotification>'
Enrico Granataeb4a4792012-02-23 23:10:27 +000077
78
79def GetSummary_Impl(valobj):
Kate Stoneb9c1b512016-09-06 20:57:50 +000080 logger = lldb.formatters.Logger.Logger()
81 global statistics
82 class_data, wrapper = lldb.runtime.objc.objc_runtime.Utilities.prepare_class_detection(
83 valobj, statistics)
84 if wrapper:
85 return wrapper
Enrico Granata247bd412012-04-02 16:39:29 +000086
Kate Stoneb9c1b512016-09-06 20:57:50 +000087 name_string = class_data.class_name()
88 logger >> "class name is: " + str(name_string)
Enrico Granataeb4a4792012-02-23 23:10:27 +000089
Kate Stoneb9c1b512016-09-06 20:57:50 +000090 if name_string == 'NSConcreteNotification':
91 wrapper = NSConcreteNotification_SummaryProvider(
92 valobj, class_data.sys_params)
93 statistics.metric_hit('code_notrun', valobj)
94 else:
95 wrapper = NSNotificationUnknown_SummaryProvider(
96 valobj, class_data.sys_params)
97 statistics.metric_hit(
98 'unknown_class',
99 valobj.GetName() +
100 " seen as " +
101 name_string)
102 return wrapper
Enrico Granataeb4a4792012-02-23 23:10:27 +0000103
Kate Stoneb9c1b512016-09-06 20:57:50 +0000104
105def NSNotification_SummaryProvider(valobj, dict):
106 logger = lldb.formatters.Logger.Logger()
107 provider = GetSummary_Impl(valobj)
108 if provider is not None:
109 if isinstance(
110 provider,
111 lldb.runtime.objc.objc_runtime.SpecialSituation_Description):
112 return provider.message()
113 try:
114 summary = provider.name()
115 except:
116 summary = None
117 logger >> "got summary " + str(summary)
118 if summary is None:
119 summary = '<variable is not NSNotification>'
120 return str(summary)
121 return 'Summary Unavailable'
122
123
124def __lldb_init_module(debugger, dict):
125 debugger.HandleCommand(
126 "type summary add -F NSNotification.NSNotification_SummaryProvider NSNotification")