summaryrefslogtreecommitdiffstats
path: root/lldb/examples/synthetic/gnu_libstdcpp.py
diff options
context:
space:
mode:
authorSiva Chandra <sivachandra@google.com>2015-03-17 21:23:17 +0000
committerSiva Chandra <sivachandra@google.com>2015-03-17 21:23:17 +0000
commit8d88d081978aa962307114e0ea663f7e69fc3af8 (patch)
tree5bdb698af28958f85bf69947a973e209d78ee670 /lldb/examples/synthetic/gnu_libstdcpp.py
parentab5e6c9925393136186ced8fad3369a35dd234e0 (diff)
downloadbcm5719-llvm-8d88d081978aa962307114e0ea663f7e69fc3af8.tar.gz
bcm5719-llvm-8d88d081978aa962307114e0ea663f7e69fc3af8.zip
Implement formatter for std::vector<bool, ...> of libstdc++ in Python.
Summary: The existing formatter in C++ has been removed as it was not being used. The associated test TestDataFormatterStdVBool.py has been enabled for both Clang and GCC on Linux. Test Plan: dotest.py -p TestDataFormatterStdVBool Reviewers: vharron, clayborg Reviewed By: clayborg Subscribers: lldb-commits Differential Revision: http://reviews.llvm.org/D8390 llvm-svn: 232548
Diffstat (limited to 'lldb/examples/synthetic/gnu_libstdcpp.py')
-rw-r--r--lldb/examples/synthetic/gnu_libstdcpp.py194
1 files changed, 126 insertions, 68 deletions
diff --git a/lldb/examples/synthetic/gnu_libstdcpp.py b/lldb/examples/synthetic/gnu_libstdcpp.py
index a52277c00e1..710783ef78f 100644
--- a/lldb/examples/synthetic/gnu_libstdcpp.py
+++ b/lldb/examples/synthetic/gnu_libstdcpp.py
@@ -137,50 +137,134 @@ class StdListSynthProvider:
class StdVectorSynthProvider:
+ class StdVectorImplementation(object):
+ def __init__(self, valobj):
+ self.valobj = valobj
+ self.count = None
+
+ def num_children(self):
+ if self.count == None:
+ self.count = self.num_children_impl()
+ return self.count
+
+ def num_children_impl(self):
+ try:
+ start_val = self.start.GetValueAsUnsigned(0)
+ finish_val = self.finish.GetValueAsUnsigned(0)
+ end_val = self.end.GetValueAsUnsigned(0)
+ # Before a vector has been constructed, it will contain bad values
+ # so we really need to be careful about the length we return since
+ # unitialized data can cause us to return a huge number. We need
+ # to also check for any of the start, finish or end of storage values
+ # being zero (NULL). If any are, then this vector has not been
+ # initialized yet and we should return zero
+
+ # Make sure nothing is NULL
+ if start_val == 0 or finish_val == 0 or end_val == 0:
+ return 0
+ # Make sure start is less than finish
+ if start_val >= finish_val:
+ return 0
+ # Make sure finish is less than or equal to end of storage
+ if finish_val > end_val:
+ return 0
+
+ # if we have a struct (or other data type that the compiler pads to native word size)
+ # this check might fail, unless the sizeof() we get is itself incremented to take the
+ # padding bytes into account - on current clang it looks like this is the case
+ num_children = (finish_val-start_val)
+ if (num_children % self.data_size) != 0:
+ return 0
+ else:
+ num_children = num_children/self.data_size
+ return num_children
+ except:
+ return 0;
+
+ def get_child_at_index(self, index):
+ logger = lldb.formatters.Logger.Logger()
+ logger >> "Retrieving child " + str(index)
+ if index < 0:
+ return None;
+ if index >= self.num_children():
+ return None;
+ try:
+ offset = index * self.data_size
+ return self.start.CreateChildAtOffset('['+str(index)+']',offset,self.data_type)
+ except:
+ return None
+
+ def update(self):
+ # preemptively setting this to None - we might end up changing our mind later
+ self.count = None
+ try:
+ impl = self.valobj.GetChildMemberWithName('_M_impl')
+ self.start = impl.GetChildMemberWithName('_M_start')
+ self.finish = impl.GetChildMemberWithName('_M_finish')
+ self.end = impl.GetChildMemberWithName('_M_end_of_storage')
+ self.data_type = self.start.GetType().GetPointeeType()
+ self.data_size = self.data_type.GetByteSize()
+ # if any of these objects is invalid, it means there is no point in trying to fetch anything
+ if self.start.IsValid() and self.finish.IsValid() and self.end.IsValid() and self.data_type.IsValid():
+ self.count = None
+ else:
+ self.count = 0
+ except:
+ pass
+ return True
+
+ class StdVBoolImplementation(object):
+ def __init__(self, valobj, bool_type):
+ self.valobj = valobj
+ self.bool_type = bool_type
+ self.valid = False
+
+ def num_children(self):
+ if self.valid:
+ start = self.start_p.GetValueAsUnsigned(0)
+ finish = self.finish_p.GetValueAsUnsigned(0)
+ offset = self.offset.GetValueAsUnsigned(0)
+ if finish >= start:
+ return (finish - start) * 8 + offset
+ return 0
+
+ def get_child_at_index(self, index):
+ if index >= self.num_children():
+ return None
+ byte_offset = index / 8
+ bit_offset = index % 8
+ data = self.start_p.GetPointeeData()
+ bit = data.GetUnsignedInt8(lldb.SBError(), byte_offset) & (1 << bit_offset)
+ if bit != 0:
+ value_expr = "(bool)true"
+ else:
+ value_expr = "(bool)false"
+ return self.valobj.CreateValueFromExpression("[%d]" % index, value_expr)
+
+ def update(self):
+ try:
+ m_impl = self.valobj.GetChildMemberWithName('_M_impl')
+ self.m_start = m_impl.GetChildMemberWithName('_M_start')
+ self.m_finish = m_impl.GetChildMemberWithName('_M_finish')
+ self.start_p = self.m_start.GetChildMemberWithName('_M_p')
+ self.finish_p = self.m_finish.GetChildMemberWithName('_M_p')
+ self.offset = self.m_finish.GetChildMemberWithName('_M_offset')
+ self.valid = True
+ except:
+ self.valid = False
+ return True
+
def __init__(self, valobj, dict):
logger = lldb.formatters.Logger.Logger()
- self.count = None
- self.valobj = valobj
+ first_template_arg_type = valobj.GetType().GetTemplateArgumentType(0)
+ if str(first_template_arg_type.GetName()) == "bool":
+ self.impl = self.StdVBoolImplementation(valobj, first_template_arg_type)
+ else:
+ self.impl = self.StdVectorImplementation(valobj)
logger >> "Providing synthetic children for a vector named " + str(valobj.GetName())
def num_children(self):
- if self.count == None:
- self.count = self.num_children_impl()
- return self.count
-
- def num_children_impl(self):
- try:
- start_val = self.start.GetValueAsUnsigned(0)
- finish_val = self.finish.GetValueAsUnsigned(0)
- end_val = self.end.GetValueAsUnsigned(0)
- # Before a vector has been constructed, it will contain bad values
- # so we really need to be careful about the length we return since
- # unitialized data can cause us to return a huge number. We need
- # to also check for any of the start, finish or end of storage values
- # being zero (NULL). If any are, then this vector has not been
- # initialized yet and we should return zero
-
- # Make sure nothing is NULL
- if start_val == 0 or finish_val == 0 or end_val == 0:
- return 0
- # Make sure start is less than finish
- if start_val >= finish_val:
- return 0
- # Make sure finish is less than or equal to end of storage
- if finish_val > end_val:
- return 0
-
- # if we have a struct (or other data type that the compiler pads to native word size)
- # this check might fail, unless the sizeof() we get is itself incremented to take the
- # padding bytes into account - on current clang it looks like this is the case
- num_children = (finish_val-start_val)
- if (num_children % self.data_size) != 0:
- return 0
- else:
- num_children = num_children/self.data_size
- return num_children
- except:
- return 0;
+ return self.impl.num_children()
def get_child_index(self,name):
try:
@@ -188,37 +272,11 @@ class StdVectorSynthProvider:
except:
return -1
- def get_child_at_index(self,index):
- logger = lldb.formatters.Logger.Logger()
- logger >> "Retrieving child " + str(index)
- if index < 0:
- return None;
- if index >= self.num_children():
- return None;
- try:
- offset = index * self.data_size
- return self.start.CreateChildAtOffset('['+str(index)+']',offset,self.data_type)
- except:
- return None
+ def get_child_at_index(self, index):
+ return self.impl.get_child_at_index(index)
def update(self):
- # preemptively setting this to None - we might end up changing our mind later
- self.count = None
- try:
- impl = self.valobj.GetChildMemberWithName('_M_impl')
- self.start = impl.GetChildMemberWithName('_M_start')
- self.finish = impl.GetChildMemberWithName('_M_finish')
- self.end = impl.GetChildMemberWithName('_M_end_of_storage')
- self.data_type = self.start.GetType().GetPointeeType()
- self.data_size = self.data_type.GetByteSize()
- # if any of these objects is invalid, it means there is no point in trying to fetch anything
- if self.start.IsValid() and self.finish.IsValid() and self.end.IsValid() and self.data_type.IsValid():
- self.count = None
- else:
- self.count = 0
- except:
- pass
-
+ return self.impl.update()
def has_children(self):
return True
OpenPOWER on IntegriCloud