xref: /openbsd-src/gnu/llvm/lldb/examples/synthetic/recognizer_function/example.py (revision f6aab3d83b51b91c24247ad2c2573574de475a82)
1*f6aab3d8Srobert# Formatters for classes that derive from Message.
2*f6aab3d8Srobert#
3*f6aab3d8Srobert# Usage:
4*f6aab3d8Srobert#   command script import ./example.py
5*f6aab3d8Srobert#   type summary add --expand --recognizer-function --python-function example.message_summary example.is_message_type
6*f6aab3d8Srobert#   type synth add --recognizer-function --python-class example.MessageChildProvider example.is_message_type
7*f6aab3d8Srobert
8*f6aab3d8Srobertimport sys
9*f6aab3d8Srobert
10*f6aab3d8Srobertdef is_message_type(t, internal_dict):
11*f6aab3d8Srobert  for base in t.get_bases_array():
12*f6aab3d8Srobert    if base.GetName() == "Message":
13*f6aab3d8Srobert      return True
14*f6aab3d8Srobert  return False
15*f6aab3d8Srobert
16*f6aab3d8Srobertdef message_summary(value, internal_dict):
17*f6aab3d8Srobert  # Could have used a summary string as well. All the work is done by the child
18*f6aab3d8Srobert  # provider.
19*f6aab3d8Srobert  return "Message"
20*f6aab3d8Srobert
21*f6aab3d8Srobertclass MessageChildProvider:
22*f6aab3d8Srobert  def __init__(self, value, internal_dict):
23*f6aab3d8Srobert    self.value = value
24*f6aab3d8Srobert    self.synthetic_children = self._analyze_children(value)
25*f6aab3d8Srobert
26*f6aab3d8Srobert  def has_children(self):
27*f6aab3d8Srobert    return self.num_children() > 0
28*f6aab3d8Srobert
29*f6aab3d8Srobert  def num_children(self):
30*f6aab3d8Srobert    return len(self.synthetic_children)
31*f6aab3d8Srobert
32*f6aab3d8Srobert  def get_child_index(self, name):
33*f6aab3d8Srobert    for index, child in enumerate(self.synthetic_children):
34*f6aab3d8Srobert      if child.GetName() == name:
35*f6aab3d8Srobert        return index
36*f6aab3d8Srobert    return None
37*f6aab3d8Srobert
38*f6aab3d8Srobert  def get_child_at_index(self, index):
39*f6aab3d8Srobert    return self.synthetic_children[index]
40*f6aab3d8Srobert
41*f6aab3d8Srobert  def _rename_sbvalue(self, value):
42*f6aab3d8Srobert    # We want to display the field with its original name without a trailing
43*f6aab3d8Srobert    # underscore. So we create a new SBValue with the same type and address but
44*f6aab3d8Srobert    # a different name.
45*f6aab3d8Srobert    name = value.GetName()
46*f6aab3d8Srobert    assert name.endswith("_")
47*f6aab3d8Srobert    new_name = name[:-1]
48*f6aab3d8Srobert    return value.CreateValueFromAddress(new_name, value.GetLoadAddress(),
49*f6aab3d8Srobert                                        value.GetType())
50*f6aab3d8Srobert
51*f6aab3d8Srobert  def _analyze_children(self, value):
52*f6aab3d8Srobert    result = []
53*f6aab3d8Srobert    for i in range(value.GetNumChildren()):
54*f6aab3d8Srobert      child = value.GetChildAtIndex(i)
55*f6aab3d8Srobert      child_name = child.GetName()
56*f6aab3d8Srobert      if child_name.startswith("_"):
57*f6aab3d8Srobert        continue  # Internal field, skip
58*f6aab3d8Srobert      # Normal field. Check presence bit.
59*f6aab3d8Srobert      presence_bit = value.GetChildMemberWithName("_has_" + child_name)
60*f6aab3d8Srobert      if presence_bit.GetValueAsUnsigned() != 0:
61*f6aab3d8Srobert        result.append(self._rename_sbvalue(child))
62*f6aab3d8Srobert    return result
63*f6aab3d8Srobert
64