llvm-project/lldb/examples/synthetic/StdListSynthProvider.py

65 lines
2.6 KiB
Python

import re
class StdListSynthProvider:
def __init__(self, valobj, dict):
self.valobj = valobj
self.update()
def num_children(self):
next_val = self.next.GetValueAsUnsigned(0)
prev_val = self.prev.GetValueAsUnsigned(0)
# After a std::list has been initialized, both next and prev will be non-NULL
if next_val == 0 or prev_val == 0:
return 0
if next_val == self.node_address:
return 0
if next_val == prev_val:
return 1
size = 2
current = self.next
while current.GetChildMemberWithName('_M_next').GetValueAsUnsigned(0) != self.node_address:
size = size + 1
current = current.GetChildMemberWithName('_M_next')
return (size - 1)
def get_child_index(self,name):
return int(name.lstrip('[').rstrip(']'))
def get_child_at_index(self,index):
if index >= self.num_children():
return None;
offset = index
current = self.next
while offset > 0:
current = current.GetChildMemberWithName('_M_next')
offset = offset - 1
return current.CreateChildAtOffset('['+str(index)+']',2*current.GetType().GetByteSize(),self.data_type)
def extract_type_name(self,name):
self.type_name = name[16:]
index = 2
count_of_template = 1
while index < len(self.type_name):
if self.type_name[index] == '<':
count_of_template = count_of_template + 1
elif self.type_name[index] == '>':
count_of_template = count_of_template - 1
elif self.type_name[index] == ',' and count_of_template == 1:
self.type_name = self.type_name[:index]
break
index = index + 1
self.type_name_nospaces = self.type_name.replace(", ", ",")
def update(self):
impl = self.valobj.GetChildMemberWithName('_M_impl')
node = impl.GetChildMemberWithName('_M_node')
self.extract_type_name(impl.GetType().GetName())
self.node_address = self.valobj.AddressOf().GetValueAsUnsigned(0)
self.next = node.GetChildMemberWithName('_M_next')
self.prev = node.GetChildMemberWithName('_M_prev')
self.data_type = node.GetTarget().FindFirstType(self.type_name)
# tries to fight against a difference in formatting type names between gcc and clang
if self.data_type.IsValid() == False:
self.data_type = node.GetTarget().FindFirstType(self.type_name_nospaces)
self.data_size = self.data_type.GetByteSize()