Skip to content

Commit a2e7347

Browse files
authored
Merge pull request #40568 from broadwaylamb/demangle-node-lldb-provider
[lldb] Add a formatter for `swift::Demangle::Node`
2 parents 80223ed + 1ecb947 commit a2e7347

File tree

1 file changed

+130
-0
lines changed

1 file changed

+130
-0
lines changed

utils/lldb/lldbSwiftDataFormatters.py

Lines changed: 130 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,12 +5,21 @@
55
"""
66

77
import sys
8+
from enum import Enum
89

910

1011
def __lldb_init_module(debugger, internal_dict):
12+
debugger.HandleCommand('type category define -e swift -l c++')
13+
1114
tName = 'lldbSwiftDataFormatters.SmallBitVectorSummaryProvider'
1215
debugger.HandleCommand('type summary add -w llvm '
1316
'-F %s -x "^llvm::SmallBitVector$"' % tName)
17+
debugger.HandleCommand('type summary add --skip-references -w swift '
18+
'-F lldbSwiftDataFormatters.DemangleNodeSummaryProvider '
19+
'-x "^swift::Demangle::Node$"')
20+
debugger.HandleCommand('type synthetic add --skip-references -w swift '
21+
'-l lldbSwiftDataFormatters.DemangleNodeSynthProvider '
22+
'-x "^swift::Demangle::Node$"')
1423

1524

1625
def SmallBitVectorSummaryProvider(valobj, internal_dict):
@@ -45,3 +54,124 @@ def SmallBitVectorSummaryProvider(valobj, internal_dict):
4554
res += '0'
4655
res += "]"
4756
return res
57+
58+
59+
class DemangleNodePayloadKind(Enum):
60+
NONE = 0
61+
TEXT = 1
62+
INDEX = 2
63+
ONE_CHILD = 3
64+
TWO_CHILDREN = 4
65+
MANY_CHILDREN = 5
66+
67+
68+
class DemangleNodeSynthProvider:
69+
""" Provider for swift::Demangle::Node """
70+
71+
def __init__(self, valobj, internal_dict):
72+
self.valobj = valobj
73+
self.update() # initialize this provider
74+
75+
def num_children(self):
76+
if self.payload_kind in [DemangleNodePayloadKind.TEXT,
77+
DemangleNodePayloadKind.INDEX,
78+
DemangleNodePayloadKind.ONE_CHILD]:
79+
return 2
80+
if self.payload_kind is DemangleNodePayloadKind.TWO_CHILDREN:
81+
return 3
82+
if self.payload_kind is DemangleNodePayloadKind.MANY_CHILDREN:
83+
return self.payload.GetChildMemberWithName('Children'). \
84+
GetChildMemberWithName('Number').GetValueAsUnsigned() + 1
85+
return 1
86+
87+
def get_child_index(self, name):
88+
if name == 'NodeKind':
89+
return 0
90+
91+
if self.payload_kind is DemangleNodePayloadKind.TEXT and name == 'Text':
92+
return 1
93+
if self.payload_kind is DemangleNodePayloadKind.INDEX and name == 'Index':
94+
return 1
95+
if self.payload_kind is DemangleNodePayloadKind.NONE:
96+
return None
97+
try:
98+
return int(name.lstrip('[').rstrip(']')) + 1
99+
except ValueError:
100+
return None
101+
102+
def get_child_at_index(self, index):
103+
if index == 0:
104+
return self.valobj.GetChildMemberWithName('NodeKind')
105+
106+
index -= 1
107+
108+
if self.payload_kind is DemangleNodePayloadKind.TEXT and index == 0:
109+
return self.payload.GetChildMemberWithName('Text')
110+
if self.payload_kind is DemangleNodePayloadKind.INDEX and index == 0:
111+
return self.payload.GetChildMemberWithName('Index')
112+
if self.payload_kind is DemangleNodePayloadKind.ONE_CHILD \
113+
and index == 0:
114+
return self.payload \
115+
.GetChildMemberWithName('InlineChildren') \
116+
.GetChildAtIndex(0)
117+
if self.payload_kind is DemangleNodePayloadKind.TWO_CHILDREN \
118+
and 0 <= index <= 1:
119+
return self.payload \
120+
.GetChildMemberWithName('InlineChildren') \
121+
.GetChildAtIndex(index)
122+
if self.payload_kind is DemangleNodePayloadKind.MANY_CHILDREN \
123+
and index >= 0:
124+
node_vector = self.payload.GetChildMemberWithName('Children')
125+
length = node_vector.GetChildMemberWithName('Number')
126+
if index >= length.GetValueAsUnsigned():
127+
return None
128+
nodes_ptr = node_vector.GetChildMemberWithName('Nodes')
129+
offset = self.node_ptr_size * index
130+
return nodes_ptr.CreateChildAtOffset('[' + str(index) + ']',
131+
offset, self.node_ptr_type)
132+
return None
133+
134+
def update(self):
135+
self.payload_kind = DemangleNodePayloadKind(
136+
self.valobj.GetChildMemberWithName('NodePayloadKind').GetValueAsUnsigned()
137+
)
138+
valobj_type = self.valobj.GetType()
139+
if valobj_type.IsPointerType():
140+
self.node_ptr_type = valobj_type
141+
else:
142+
self.node_ptr_type = valobj_type.GetPointerType()
143+
self.node_ptr_size = self.node_ptr_type.GetByteSize()
144+
self.payload = self.valobj.GetChildAtIndex(0)
145+
146+
147+
def DemangleNodeSummaryProvider(valobj, internal_dict):
148+
valobj = valobj.GetNonSyntheticValue()
149+
result = valobj.GetChildMemberWithName('NodeKind').GetValue()
150+
result += ', '
151+
payload_kind = DemangleNodePayloadKind(
152+
valobj.GetChildMemberWithName('NodePayloadKind').GetValueAsUnsigned()
153+
)
154+
if payload_kind is DemangleNodePayloadKind.NONE:
155+
result += '0 children'
156+
if payload_kind is DemangleNodePayloadKind.TEXT:
157+
result += 'Text='
158+
result += valobj \
159+
.GetChildAtIndex(0) \
160+
.GetChildMemberWithName('Text') \
161+
.GetSummary()
162+
if payload_kind is DemangleNodePayloadKind.INDEX:
163+
result += 'Index='
164+
index = valobj \
165+
.GetChildAtIndex(0) \
166+
.GetChildMemberWithName('Index') \
167+
.GetValueAsUnsigned()
168+
result += str(index)
169+
if payload_kind is DemangleNodePayloadKind.ONE_CHILD:
170+
result += '1 child'
171+
if payload_kind in [DemangleNodePayloadKind.TWO_CHILDREN,
172+
DemangleNodePayloadKind.MANY_CHILDREN]:
173+
num_children = \
174+
DemangleNodeSynthProvider(valobj, internal_dict).num_children() - 1
175+
result += str(num_children)
176+
result += ' children'
177+
return result

0 commit comments

Comments
 (0)