Author: enrico
Date: Wed Sep  4 12:48:52 2013
New Revision: 189964

URL: http://llvm.org/viewvc/llvm-project?rev=189964&view=rev
Log:
This is an example synthetic provider for libc++ unordered (multi) maps&set
Thanks to Jared Grubb for writing it and sharing it!


Added:
    lldb/trunk/examples/synthetic/unordered_multi.py

Added: lldb/trunk/examples/synthetic/unordered_multi.py
URL: 
http://llvm.org/viewvc/llvm-project/lldb/trunk/examples/synthetic/unordered_multi.py?rev=189964&view=auto
==============================================================================
--- lldb/trunk/examples/synthetic/unordered_multi.py (added)
+++ lldb/trunk/examples/synthetic/unordered_multi.py Wed Sep  4 12:48:52 2013
@@ -0,0 +1,110 @@
+import lldb
+
+_map_capping_size = 255
+
+class libcxx_hash_table_SynthProvider:
+       def __init__(self, valobj, dict):
+               self.valobj = valobj
+               self.num_elements = None
+               self.next_element = None
+               self.bucket_count = None
+
+       def update(self):
+               logger = lldb.formatters.Logger.Logger()
+               self.num_elements = None
+               self.next_element = None
+               self.bucket_count = None
+               try:
+                       # unordered_map is made up a a hash_map, which has 4 
pieces in it:
+                       #   bucket list :
+                       #      array of buckets
+                       #   p1 (pair):
+                       #      first - pointer to first loaded element
+                       #   p2 (pair):
+                       #      first - number of elements
+                       #      second - hash function
+                       #   p3 (pair):
+                       #      first - max_load_factor
+                       #      second - equality operator function
+                       #
+                       # For display, we actually dont need to go inside the 
buckets, since 'p1' has a way to iterate over all
+                       # the elements directly.
+                       #
+                       # We will calculate other values about the map because 
they will be useful for the summary.
+                       #
+                       table = self.valobj.GetChildMemberWithName('__table_')
+
+                       bl_ptr = 
table.GetChildMemberWithName('__bucket_list_').GetChildMemberWithName('__ptr_')
+                       self.bucket_array_ptr = 
bl_ptr.GetChildMemberWithName('__first_').GetValueAsUnsigned(0)
+                       self.bucket_count = 
bl_ptr.GetChildMemberWithName('__second_').GetChildMemberWithName('__data_').GetChildMemberWithName('__first_').GetValueAsUnsigned(0)
+                       logger >> "Bucket count = %r" % self.bucket_count
+
+                       self.begin_ptr = 
table.GetChildMemberWithName('__p1_').GetChildMemberWithName('__first_').GetChildMemberWithName('__next_')
+
+                       self.num_elements    = 
table.GetChildMemberWithName('__p2_').GetChildMemberWithName('__first_').GetValueAsUnsigned(0)
+                       self.max_load_factor = 
table.GetChildMemberWithName('__p3_').GetChildMemberWithName('__first_').GetValueAsUnsigned(0)
+                       logger >> "Num elements = %r" % self.num_elements
+
+                       # save the pointers as we get them
+                       #   -- dont access this first element if num_element==0!
+                       self.elements_cache = []
+                       if self.num_elements:
+                               self.next_element = self.begin_ptr
+                       else:
+                               self.next_element = None
+               except Exception, e:
+                       logger >> "Caught exception: %r" % e
+                       pass
+
+       def num_children(self):
+               global _map_capping_size
+               num_elements = self.num_elements
+               if num_elements is not None:
+                       if num_elements > _map_capping_size:
+                               num_elements = _map_capping_size
+               return num_elements
+
+       def has_children(self):
+               return True
+
+       def get_child_index(self,name):
+               logger = lldb.formatters.Logger.Logger()
+               try:
+                       return int(name.lstrip('[').rstrip(']'))
+               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
+
+               # extend
+               logger >> " : cache size starts with %d elements" % 
len(self.elements_cache)
+               while index >= len(self.elements_cache):
+                       # if we hit the end before we get the index, give up:
+                       if not self.next_element:
+                               logger >> " : hit end of list"
+                               return None
+
+                       node = self.next_element.Dereference()
+
+                       value = node.GetChildMemberWithName('__value_')
+                       hash_value = 
node.GetChildMemberWithName('__hash_').GetValueAsUnsigned()
+                       self.elements_cache.append((value, hash_value))
+
+                       self.next_element = 
node.GetChildMemberWithName('__next_')
+                       if not self.next_element.GetValueAsUnsigned(0):
+                               self.next_element = None
+
+               # hit the index! so we have the value
+               logger >> " : cache size ends with %d elements" % 
len(self.elements_cache)
+               value, hash_value = self.elements_cache[index]
+               return self.valobj.CreateValueFromData('[%d] <hash 
%d>'%(index,hash_value), value.GetData(), value.GetType())
+
+
+def __lldb_init_module(debugger,dict):
+       debugger.HandleCommand('type synthetic add -l 
unordered_multi.libcxx_hash_table_SynthProvider -x 
"^(std::__1::)unordered_(multi)?(map|set)<.+> >$" -w libcxx')


_______________________________________________
lldb-commits mailing list
lldb-commits@cs.uiuc.edu
http://lists.cs.uiuc.edu/mailman/listinfo/lldb-commits

Reply via email to