xref: /openbsd-src/gnu/llvm/lldb/examples/summaries/cocoa/NSNotification.py (revision 061da546b983eb767bad15e67af1174fb0bcf31c)
1*061da546Spatrick"""
2*061da546SpatrickLLDB AppKit formatters
3*061da546Spatrick
4*061da546SpatrickPart of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
5*061da546SpatrickSee https://llvm.org/LICENSE.txt for license information.
6*061da546SpatrickSPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7*061da546Spatrick"""
8*061da546Spatrick# example summary provider for NSNotification
9*061da546Spatrick# the real summary is now C++ code built into LLDB
10*061da546Spatrickimport lldb.runtime.objc.objc_runtime
11*061da546Spatrickimport lldb.formatters.metrics
12*061da546Spatrickimport CFString
13*061da546Spatrickimport lldb
14*061da546Spatrickimport lldb.formatters.Logger
15*061da546Spatrick
16*061da546Spatrickstatistics = lldb.formatters.metrics.Metrics()
17*061da546Spatrickstatistics.add_metric('invalid_isa')
18*061da546Spatrickstatistics.add_metric('invalid_pointer')
19*061da546Spatrickstatistics.add_metric('unknown_class')
20*061da546Spatrickstatistics.add_metric('code_notrun')
21*061da546Spatrick
22*061da546Spatrick
23*061da546Spatrickclass NSConcreteNotification_SummaryProvider:
24*061da546Spatrick
25*061da546Spatrick    def adjust_for_architecture(self):
26*061da546Spatrick        pass
27*061da546Spatrick
28*061da546Spatrick    def __init__(self, valobj, params):
29*061da546Spatrick        logger = lldb.formatters.Logger.Logger()
30*061da546Spatrick        self.valobj = valobj
31*061da546Spatrick        self.sys_params = params
32*061da546Spatrick        if not (self.sys_params.types_cache.id):
33*061da546Spatrick            self.sys_params.types_cache.id = self.valobj.GetType(
34*061da546Spatrick            ).GetBasicType(lldb.eBasicTypeObjCID)
35*061da546Spatrick        self.update()
36*061da546Spatrick
37*061da546Spatrick    def update(self):
38*061da546Spatrick        logger = lldb.formatters.Logger.Logger()
39*061da546Spatrick        self.adjust_for_architecture()
40*061da546Spatrick
41*061da546Spatrick    # skip the ISA and go to the name pointer
42*061da546Spatrick    def offset(self):
43*061da546Spatrick        logger = lldb.formatters.Logger.Logger()
44*061da546Spatrick        return self.sys_params.pointer_size
45*061da546Spatrick
46*061da546Spatrick    def name(self):
47*061da546Spatrick        logger = lldb.formatters.Logger.Logger()
48*061da546Spatrick        string_ptr = self.valobj.CreateChildAtOffset(
49*061da546Spatrick            "name", self.offset(), self.sys_params.types_cache.id)
50*061da546Spatrick        return CFString.CFString_SummaryProvider(string_ptr, None)
51*061da546Spatrick
52*061da546Spatrick
53*061da546Spatrickclass NSNotificationUnknown_SummaryProvider:
54*061da546Spatrick
55*061da546Spatrick    def adjust_for_architecture(self):
56*061da546Spatrick        pass
57*061da546Spatrick
58*061da546Spatrick    def __init__(self, valobj, params):
59*061da546Spatrick        logger = lldb.formatters.Logger.Logger()
60*061da546Spatrick        self.valobj = valobj
61*061da546Spatrick        self.sys_params = params
62*061da546Spatrick        self.update()
63*061da546Spatrick
64*061da546Spatrick    def update(self):
65*061da546Spatrick        logger = lldb.formatters.Logger.Logger()
66*061da546Spatrick        self.adjust_for_architecture()
67*061da546Spatrick
68*061da546Spatrick    def name(self):
69*061da546Spatrick        logger = lldb.formatters.Logger.Logger()
70*061da546Spatrick        stream = lldb.SBStream()
71*061da546Spatrick        self.valobj.GetExpressionPath(stream)
72*061da546Spatrick        name_vo = self.valobj.CreateValueFromExpression(
73*061da546Spatrick            "name", "(NSString*)[" + stream.GetData() + " name]")
74*061da546Spatrick        if name_vo.IsValid():
75*061da546Spatrick            return CFString.CFString_SummaryProvider(name_vo, None)
76*061da546Spatrick        return '<variable is not NSNotification>'
77*061da546Spatrick
78*061da546Spatrick
79*061da546Spatrickdef GetSummary_Impl(valobj):
80*061da546Spatrick    logger = lldb.formatters.Logger.Logger()
81*061da546Spatrick    global statistics
82*061da546Spatrick    class_data, wrapper = lldb.runtime.objc.objc_runtime.Utilities.prepare_class_detection(
83*061da546Spatrick        valobj, statistics)
84*061da546Spatrick    if wrapper:
85*061da546Spatrick        return wrapper
86*061da546Spatrick
87*061da546Spatrick    name_string = class_data.class_name()
88*061da546Spatrick    logger >> "class name is: " + str(name_string)
89*061da546Spatrick
90*061da546Spatrick    if name_string == 'NSConcreteNotification':
91*061da546Spatrick        wrapper = NSConcreteNotification_SummaryProvider(
92*061da546Spatrick            valobj, class_data.sys_params)
93*061da546Spatrick        statistics.metric_hit('code_notrun', valobj)
94*061da546Spatrick    else:
95*061da546Spatrick        wrapper = NSNotificationUnknown_SummaryProvider(
96*061da546Spatrick            valobj, class_data.sys_params)
97*061da546Spatrick        statistics.metric_hit(
98*061da546Spatrick            'unknown_class',
99*061da546Spatrick            valobj.GetName() +
100*061da546Spatrick            " seen as " +
101*061da546Spatrick            name_string)
102*061da546Spatrick    return wrapper
103*061da546Spatrick
104*061da546Spatrick
105*061da546Spatrickdef NSNotification_SummaryProvider(valobj, dict):
106*061da546Spatrick    logger = lldb.formatters.Logger.Logger()
107*061da546Spatrick    provider = GetSummary_Impl(valobj)
108*061da546Spatrick    if provider is not None:
109*061da546Spatrick        if isinstance(
110*061da546Spatrick                provider,
111*061da546Spatrick                lldb.runtime.objc.objc_runtime.SpecialSituation_Description):
112*061da546Spatrick            return provider.message()
113*061da546Spatrick        try:
114*061da546Spatrick            summary = provider.name()
115*061da546Spatrick        except:
116*061da546Spatrick            summary = None
117*061da546Spatrick        logger >> "got summary " + str(summary)
118*061da546Spatrick        if summary is None:
119*061da546Spatrick            summary = '<variable is not NSNotification>'
120*061da546Spatrick        return str(summary)
121*061da546Spatrick    return 'Summary Unavailable'
122*061da546Spatrick
123*061da546Spatrick
124*061da546Spatrickdef __lldb_init_module(debugger, dict):
125*061da546Spatrick    debugger.HandleCommand(
126*061da546Spatrick        "type summary add -F NSNotification.NSNotification_SummaryProvider NSNotification")
127