<rdar://problem/13434476>

Making value objects properly iterable in constructs of the form
[ x for x in value_with_children ]

This would previously cause an endless loop because lacking a proper iterator object, Python will keep calling __getitem__() with increasing values of the index until it gets an IndexError
since SBValue::GetValueForExpressionPath() supports synthetic array members, no array index will ever really cause an IndexError to be raised, hence the endless iteration

class value_iter is an implementation of __iter__() that provides a terminating iterator over a value

llvm-svn: 177885
diff --git a/lldb/scripts/Python/python-extensions.swig b/lldb/scripts/Python/python-extensions.swig
index 29eae6d..29e39ba 100644
--- a/lldb/scripts/Python/python-extensions.swig
+++ b/lldb/scripts/Python/python-extensions.swig
@@ -553,6 +553,24 @@
         self.line = line
         self.col = col
 
+class value_iter(object):
+    def __iter__(self):
+        return self
+    
+    def next(self):
+        if self.index >= self.length:
+            raise StopIteration()
+        child_sbvalue = self.sbvalue.GetChildAtIndex(self.index)
+        self.index += 1
+        return value(child_sbvalue)
+        
+    def __init__(self,value):
+        self.index = 0
+        self.sbvalue = value
+        if type(self.sbvalue) is value:
+            self.sbvalue = self.sbvalue.sbvalue
+        self.length = self.sbvalue.GetNumChildren()
+
 class value(object):
     '''A class designed to wrap lldb.SBValue() objects so the resulting object
     can be used as a variable would be in code. So if you have a Point structure
@@ -578,15 +596,21 @@
 
     def __getitem__(self, key):
         # Allow array access if this value has children...
-        if type(key) is int:
-            return value(self.sbvalue.GetValueForExpressionPath("[%i]" % key))
         if type(key) is value:
-            return value(self.sbvalue.GetValueForExpressionPath("[%i]" % int(key)))
+            key = int(key)
+        if type(key) is int:
+            child_sbvalue = (self.sbvalue.GetValueForExpressionPath("[%i]" % key))
+            if child_sbvalue and child_sbvalue.IsValid():
+                return value(child_sbvalue)
+            raise IndexError("Index '%d' is out of range" % key)
         raise TypeError("No array item of type %s" % str(type(key)))
 
+    def __iter__(self):
+        return value_iter(self.sbvalue)
+
     def __getattr__(self, name):
         child_sbvalue = self.sbvalue.GetChildMemberWithName (name)
-        if child_sbvalue:
+        if child_sbvalue and child_sbvalue.IsValid():
             return value(child_sbvalue)
         raise AttributeError("Attribute '%s' is not defined" % name)
 
@@ -732,6 +756,9 @@
     def __hex__(self):
         return '0x%x' % self.sbvalue.GetValueAsUnsigned()
 
+    def __len__(self):
+        return self.sbvalue.GetNumChildren()
+
     def __eq__(self, other):
         if type(other) is int:
                 return int(self) == other