APIs to GetValueAsSigned/Unsigned() in SBValue now also accept an SBError parameter to give more info about any problem
The synthetic children providers now use the new (safer) APIs to get the values of objects
As a side effect, fixed an issue in ValueObject where ResolveValue() was not always updating the value before reading it


git-svn-id: https://llvm.org/svn/llvm-project/llvdb/trunk@136861 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/examples/synthetic/StdVectorSynthProvider.py b/examples/synthetic/StdVectorSynthProvider.py
index 91e634a..dc22690 100644
--- a/examples/synthetic/StdVectorSynthProvider.py
+++ b/examples/synthetic/StdVectorSynthProvider.py
@@ -1,25 +1,55 @@
 class StdVectorSynthProvider:
+
     def __init__(self, valobj, dict):
         self.valobj = valobj;
         self.update()
+
     def num_children(self):
-        start_val = int(self.Mstart.GetValue(),0)
-        finish_val = int(self.Mfinish.GetValue(),0)
-        return (finish_val-start_val)/self.data_size
+        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
+
+        # We might still get things wrong, so cap things at 256 items for now
+        # TODO: read a target "settings set" variable for this to allow it to
+        # be customized
+        num_children = (finish_val-start_val)/self.data_size
+        if num_children > 256:
+            return 256
+        return num_children
+
     def get_child_index(self,name):
         if name == "len":
             return self.num_children();
         else:
             return int(name.lstrip('[').rstrip(']'))
+
     def get_child_at_index(self,index):
         if index == self.num_children():
             return self.valobj.CreateValueFromExpression("len",str(self.num_children()))
         else:
             offset = index * self.data_size
-            return self.Mstart.CreateChildAtOffset('['+str(index)+']',offset,self.data_type)
+            return self.start.CreateChildAtOffset('['+str(index)+']',offset,self.data_type)
+
     def update(self):
-        self.Mimpl = self.valobj.GetChildMemberWithName('_M_impl')
-        self.Mstart = self.Mimpl.GetChildMemberWithName('_M_start')
-        self.Mfinish = self.Mimpl.GetChildMemberWithName('_M_finish')
-        self.data_type = self.Mstart.GetType().GetPointeeType()
+        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()