OSDN Git Service

debugger: speed up dumpers
authorhjk <qtc-committer@nokia.com>
Wed, 17 Aug 2011 12:55:41 +0000 (14:55 +0200)
committerhjk <qthjk@ovi.com>
Fri, 19 Aug 2011 12:23:09 +0000 (14:23 +0200)
Change-Id: I1dfd882fd996589d0b044c9014ae445470b36e8f
Reviewed-on: http://codereview.qt.nokia.com/3221
Reviewed-by: Qt Sanity Bot <qt_sanity_bot@ovi.com>
Reviewed-by: hjk <qthjk@ovi.com>
share/qtcreator/dumper/bridge.py
share/qtcreator/dumper/dumper.py
share/qtcreator/dumper/qttypes.py

index f8e159e..f2188f7 100644 (file)
@@ -1,14 +1,32 @@
 
+cdbLoaded = False
+lldbLoaded = False
+gdbLoaded = False
+
 try:
-    import lldb_bridge
+    #import cdb_bridge
+    cdbLoaded = True
 
 except:
     pass
 
+try:
+    #import lldb_bridge
+    lldbLoaded = True
+
+except:
+    pass
 
-#try:
-if True:
+
+try:
     import gdb
+    #gdbLoaded = True
+
+    #######################################################################
+    #
+    # Infrastructure
+    #
+    #######################################################################
 
     def registerCommand(name, func):
 
@@ -111,7 +129,9 @@ if True:
                         name1 = name
                         shadowed[name] = 1
                     #warn("SYMBOL %s  (%s, %s)): " % (symbol, name, symbol.name))
-                    item = Item(0, "local", name1, name1)
+                    item = LocalItem()
+                    item.iname = "local." + name1
+                    item.name = name1
                     try:
                         item.value = frame.read_var(name, block)  # this is a gdb value
                     except:
@@ -179,7 +199,9 @@ if True:
             #warn("VARLIST: %s " % varList)
             for name in varList:
                 #warn("NAME %s " % name)
-                item = Item(0, "local", name, name)
+                item = LocalItem()
+                item.iname = "local." + name
+                item.name = name
                 try:
                     item.value = frame.read_var(name)  # this is a gdb value
                 except RuntimeError:
@@ -232,8 +254,87 @@ if True:
         removeTempFile(filename, file)
         return lines
 
+    #######################################################################
+    #
+    # Types
+    #
+    #######################################################################
+
+    PointerCode = gdb.TYPE_CODE_PTR
+    ArrayCode = gdb.TYPE_CODE_ARRAY
+    StructCode = gdb.TYPE_CODE_STRUCT
+    UnionCode = gdb.TYPE_CODE_UNION
+    EnumCode = gdb.TYPE_CODE_ENUM
+    FlagsCode = gdb.TYPE_CODE_FLAGS
+    FunctionCode = gdb.TYPE_CODE_FUNC
+    IntCode = gdb.TYPE_CODE_INT
+    FloatCode = gdb.TYPE_CODE_FLT # Parts of GDB assume that this means complex.
+    VoidCode = gdb.TYPE_CODE_VOID
+    #SetCode = gdb.TYPE_CODE_SET
+    RangeCode = gdb.TYPE_CODE_RANGE
+    StringCode = gdb.TYPE_CODE_STRING
+    #BitStringCode = gdb.TYPE_CODE_BITSTRING
+    #ErrorTypeCode = gdb.TYPE_CODE_ERROR
+    MethodCode = gdb.TYPE_CODE_METHOD
+    #MethodPointerCode = gdb.TYPE_CODE_METHODPTR
+    #MemberPointerCode = gdb.TYPE_CODE_MEMBERPTR
+    ReferenceCode = gdb.TYPE_CODE_REF
+    CharCode = gdb.TYPE_CODE_CHAR
+    BoolCode = gdb.TYPE_CODE_BOOL
+    ComplexCode = gdb.TYPE_CODE_COMPLEX # Fortran ?
+    TypedefCode = gdb.TYPE_CODE_TYPEDEF
+    NamespaceCode = gdb.TYPE_CODE_NAMESPACE
+    #Code = gdb.TYPE_CODE_DECFLOAT # Decimal floating point.
+    #Code = gdb.TYPE_CODE_MODULE # Fortran
+    #Code = gdb.TYPE_CODE_INTERNAL_FUNCTION
 
+    #######################################################################
+    #
+    # Step Command
+    #
+    #######################################################################
+
+    def sal(args):
+        (cmd, addr) = arg.split(",")
+        lines = catchCliOutput("info line *" + addr)
+        fromAddr = "0x0"
+        toAddr = "0x0"
+        for line in lines:
+            pos0from = line.find(" starts at address") + 19
+            pos1from = line.find(" ", pos0from)
+            pos0to = line.find(" ends at", pos1from) + 9
+            pos1to = line.find(" ", pos0to)
+            if pos1to > 0:
+                fromAddr = line[pos0from : pos1from]
+                toAddr = line[pos0to : pos1to]
+        gdb.execute("maint packet sal%s,%s,%s" % (cmd,fromAddr, toAddr))
+
+    registerCommand("sal", sal)
+
+
+    #######################################################################
+    #
+    # Convenience
+    #
+    #######################################################################
+
+    # Just convienience for 'python print ...'
+    class PPCommand(gdb.Command):
+        def __init__(self):
+            super(PPCommand, self).__init__("pp", gdb.COMMAND_OBSCURE)
+        def invoke(self, args, from_tty):
+            print(eval(args))
+
+    registerCommand("pp", pp)
         
+    # Just convienience for 'python print gdb.parse_and_eval(...)'
+    class PPPCommand(gdb.Command):
+        def __init__(self):
+            super(PPPCommand, self).__init__("ppp", gdb.COMMAND_OBSCURE)
+        def invoke(self, args, from_tty):
+            print(gdb.parse_and_eval(args))
+
+    PPPCommand()
 
-#except:
-#    pass
+except:
+    pass
index 5cc9f86..b9e910c 100644 (file)
@@ -1,5 +1,3 @@
-from __future__ import with_statement
-
 import sys
 import base64
 import __builtin__
@@ -256,25 +254,31 @@ class NoAddress:
         self.d = d
 
     def __enter__(self):
-        self.savedPrintsAddress = self.d.printsAddress
-        self.d.printsAddress = False
+        self.savedPrintsAddress = self.d.currentPrintsAddress
+        self.d.currentPrintsAddress = False
 
     def __exit__(self, exType, exValue, exTraceBack):
-        self.d.printsAddress = self.savedPrintsAddress
+        self.d.currentPrintsAddress = self.savedPrintsAddress
 
 
 class SubItem:
-    def __init__(self, d):
+    def __init__(self, d, component):
         self.d = d
+        self.iname = "%s.%s" % (d.currentIName, component)
+        self.name = component
 
     def __enter__(self):
         self.d.put('{')
+        #if not self.name is None:
+        if isinstance(self.name, str):
+            self.d.put('name="%s",' % self.name)
+        self.savedIName = self.d.currentIName
         self.savedValue = self.d.currentValue
         self.savedValuePriority = self.d.currentValuePriority
         self.savedValueEncoding = self.d.currentValueEncoding
         self.savedType = self.d.currentType
         self.savedTypePriority = self.d.currentTypePriority
-        self.d.currentValue = "<not accessible>"
+        self.d.currentIName = self.iname
         self.d.currentValuePriority = -100
         self.d.currentValueEncoding = None
         self.d.currentType = ""
@@ -287,22 +291,26 @@ class SubItem:
             showException("SUBITEM", exType, exValue, exTraceBack)
         try:
             #warn("TYPE VALUE: %s" % self.d.currentValue)
-            type = stripClassTag(str(self.d.currentType))
-            #warn("TYPE: '%s'  DEFAULT: '%s'" % (type, self.d.currentChildType))
-
-            if len(type) > 0 and type != self.d.currentChildType:
-                self.d.put('type="%s",' % type) # str(type.unqualified()) ?
-                if not type in typeInfoCache and type != " ": # FIXME: Move to lookupType
-                    typeObj = lookupType(type)
+            typeName = stripClassTag(self.d.currentType)
+            #warn("TYPE: '%s'  DEFAULT: '%s' % (typeName, self.d.currentChildType))
+
+            if len(typeName) > 0 and typeName != self.d.currentChildType:
+                self.d.put('type="%s",' % typeName) # str(type.unqualified()) ?
+                if not typeName in typeInfoCache \
+                        and typeName != " ": # FIXME: Move to lookupType
+                    typeObj = lookupType(typeName)
                     if not typeObj is None:
-                        typeInfoCache[type] = TypeInfo(typeObj)
-            if not self.d.currentValueEncoding is None:
-                self.d.put('valueencoded="%d",' % self.d.currentValueEncoding)
-            if not self.d.currentValue is None:
+                        typeInfoCache[typeName] = TypeInfo(typeObj)
+            if  self.d.currentValue is None:
+                self.d.put('value="<not accessible>",numchild="0",')
+            else:
+                if not self.d.currentValueEncoding is None:
+                    self.d.put('valueencoded="%d",' % self.d.currentValueEncoding)
                 self.d.put('value="%s",' % self.d.currentValue)
         except:
             pass
         self.d.put('},')
+        self.d.currentIName = self.savedIName
         self.d.currentValue = self.savedValue
         self.d.currentValuePriority = self.savedValuePriority
         self.d.currentValueEncoding = self.savedValueEncoding
@@ -310,70 +318,85 @@ class SubItem:
         self.d.currentTypePriority = self.savedTypePriority
         return True
 
+class TopLevelItem(SubItem):
+    def __init__(self, d, iname):
+        self.d = d
+        self.iname = iname
+        self.name = None
+
+class UnnamedSubItem(SubItem):
+    def __init__(self, d, component):
+        self.d = d
+        self.iname = "%s.%s" % (self.d.currentIName, component)
+        self.name = None
 
 class Children:
-    def __init__(self, d, numChild = 1, childType = None, childNumChild = None):
+    def __init__(self, d, numChild = 1, childType = None, childNumChild = None,
+            maxNumChild = None, addrBase = None, addrStep = None):
         self.d = d
         self.numChild = numChild
-        self.childType = childType
         self.childNumChild = childNumChild
+        self.maxNumChild = maxNumChild
+        self.addrBase = addrBase
+        self.addrStep = addrStep
+        self.printsAddress = True
+        if not childType is None:
+            self.childType = stripClassTag(str(childType))
+            self.d.put('childtype="%s",' % self.childType)
+            if isSimpleType(childType):
+                self.d.put('childnumchild="0",')
+                self.childNumChild = 0
+            elif childType.code == gdb.TYPE_CODE_PTR:
+                self.d.put('childnumchild="1",')
+                self.childNumChild = 1
+        else:
+            self.childType = None
+        try:
+            if not addrBase is None and not addrStep is None:
+                self.d.put('addrbase="0x%x",' % long(addrBase))
+                self.d.put('addrstep="0x%x",' % long(addrStep))
+                self.printsAddress = False
+        except:
+            warn("ADDRBASE: %s" % addrBase)
         #warn("CHILDREN: %s %s %s" % (numChild, childType, childNumChild))
 
     def __enter__(self):
-        childType = ""
-        childNumChild = -1
-        if type(self.numChild) is list:
-            numChild = self.numChild[0]
-            maxNumChild = self.numChild[1]
-        else:
-            numChild = self.numChild
-            maxNumChild = self.numChild
-        if numChild == 0:
-            self.childType = None
-        if not self.childType is None:
-            childType = stripClassTag(str(self.childType))
-            self.d.put('childtype="%s",' % childType)
-            if isSimpleType(self.childType):
-                self.d.put('childnumchild="0",')
-                childNumChild = 0
-            elif self.childType.code == gdb.TYPE_CODE_PTR:
-                self.d.put('childnumchild="1",')
-                childNumChild = 1
-        if not self.childNumChild is None:
-            self.d.put('childnumchild="%s",' % self.childNumChild)
-            childNumChild = self.childNumChild
         self.savedChildType = self.d.currentChildType
         self.savedChildNumChild = self.d.currentChildNumChild
-        self.savedNumChilds = self.d.currentNumChilds
-        self.savedMaxNumChilds = self.d.currentNumChilds
-        self.d.currentChildType = childType
-        self.d.currentChildNumChild = childNumChild
-        self.d.currentNumChilds = numChild
-        self.d.currentMaxNumChilds = maxNumChild
+        self.savedNumChild = self.d.currentNumChild
+        self.savedMaxNumChild = self.d.currentMaxNumChild
+        self.savedPrintsAddress = self.d.currentPrintsAddress
+        self.d.currentChildType = self.childType
+        self.d.currentChildNumChild = self.childNumChild
+        self.d.currentNumChild = self.numChild
+        self.d.currentMaxNumChild = self.maxNumChild
+        self.d.currentPrintsAddress = self.printsAddress
         self.d.put("children=[")
 
     def __exit__(self, exType, exValue, exTraceBack):
         if self.d.passExceptions and not exType is None:
             showException("CHILDREN", exType, exValue, exTraceBack)
-        if self.d.currentMaxNumChilds < self.d.currentNumChilds:
-            self.d.putEllipsis()
+        if not self.d.currentMaxNumChild is None:
+            if self.d.currentMaxNumChild < self.d.currentNumChild:
+                self.d.put('{name="<incomplete>",value="",type="",numchild="0"},')
         self.d.currentChildType = self.savedChildType
         self.d.currentChildNumChild = self.savedChildNumChild
-        self.d.currentNumChilds = self.savedNumChilds
-        self.d.currentMaxNumChilds = self.savedMaxNumChilds
+        self.d.currentNumChild = self.savedNumChild
+        self.d.currentMaxNumChild = self.savedMaxNumChild
+        self.d.currentPrintsAddress = self.savedPrintsAddress
         self.d.put('],')
         return True
 
 
 # Creates a list of field names of an anon union or struct
-def listOfFields(type):
-    fields = []
-    for field in type.fields():
-        if len(field.name) > 0:
-            fields += field.name
-        else:
-            fields += listOfFields(field.type)
-    return fields
+#def listOfFields(type):
+#    fields = []
+#    for field in type.fields():
+#        if len(field.name) > 0:
+#            fields += field.name
+#        else:
+#            fields += listOfFields(field.type)
+#    return fields
 
 
 def value(expr):
@@ -391,13 +414,11 @@ def isSimpleType(typeobj):
         or code == gdb.TYPE_CODE_FLT \
         or code == gdb.TYPE_CODE_ENUM
 
-def isStringType(d, typeobj):
-    type = str(typeobj)
-    return type == d.ns + "QString" \
-        or type == d.ns + "QByteArray" \
-        or type == "std::string" \
-        or type == "std::wstring" \
-        or type == "wstring"
+    #return code == BoolCode \
+    #    or code == CharCode \
+    #    or code == IntCode \
+    #    or code == FloatCode \
+    #    or code == EnumCode
 
 def warn(message):
     if True or verbosity > 0:
@@ -446,34 +467,26 @@ def isNull(p):
     return long(p) == 0
 
 movableTypes = set([
-    "QBrush", "QBitArray", "QByteArray",
-    "QCustomTypeInfo", "QChar",
-    "QDate", "QDateTime",
-    "QFileInfo", "QFixed", "QFixedPoint", "QFixedSize",
-    "QHashDummyValue",
-    "QIcon", "QImage",
-    "QLine", "QLineF", "QLatin1Char", "QLocale",
-    "QMatrix", "QModelIndex",
-    "QPoint", "QPointF", "QPen", "QPersistentModelIndex",
-    "QResourceRoot", "QRect", "QRectF", "QRegExp",
-    "QSize", "QSizeF", "QString",
-    "QTime", "QTextBlock",
-    "QUrl",
-    "QVariant",
+    "QBrush", "QBitArray", "QByteArray", "QCustomTypeInfo", "QChar", "QDate",
+    "QDateTime", "QFileInfo", "QFixed", "QFixedPoint", "QFixedSize",
+    "QHashDummyValue", "QIcon", "QImage", "QLine", "QLineF", "QLatin1Char",
+    "QLocale", "QMatrix", "QModelIndex", "QPoint", "QPointF", "QPen",
+    "QPersistentModelIndex", "QResourceRoot", "QRect", "QRectF", "QRegExp",
+    "QSize", "QSizeF", "QString", "QTime", "QTextBlock", "QUrl", "QVariant",
     "QXmlStreamAttribute", "QXmlStreamNamespaceDeclaration",
-    "QXmlStreamNotationDeclaration", "QXmlStreamEntityDeclaration"])
-
-
-def stripClassTag(type):
-    if type.startswith("class "):
-        return type[6:]
-    if type.startswith("struct "):
-        return type[7:]
-    if type.startswith("const "):
-        return type[6:]
-    if type.startswith("volatile "):
-        return type[9:]
-    return type
+    "QXmlStreamNotationDeclaration", "QXmlStreamEntityDeclaration"
+])
+
+def stripClassTag(typeName):
+    if typeName.startswith("class "):
+        return typeName[6:]
+    if typeName.startswith("struct "):
+        return typeName[7:]
+    if typeName.startswith("const "):
+        return typeName[6:]
+    if typeName.startswith("volatile "):
+        return typeName[9:]
+    return typeName
 
 def checkPointerRange(p, n):
     for i in xrange(n):
@@ -656,7 +669,8 @@ def qByteArrayData(value):
         size = qByteArrayData['size']
         alloc = qByteArrayData['alloc']
         charPointerType = lookupType('char *')
-        data = qByteArrayData['d'].cast(charPointerType) + qByteArrayData['offset'] + charPointerType.sizeof
+        data = qByteArrayData['d'].cast(charPointerType) \
+             + qByteArrayData['offset'] + charPointerType.sizeof
         return data, size, alloc
 
 def encodeByteArray(value):
@@ -704,15 +718,15 @@ def encodeString(value):
 
 def stripTypedefs(type):
     type = type.unqualified()
-    while type.code == gdb.TYPE_CODE_TYPEDEF:
+    while type.code == TypedefCode:
         type = type.strip_typedefs().unqualified()
     return type
 
 def extractFields(type):
     # Insufficient, see http://sourceware.org/bugzilla/show_bug.cgi?id=10953:
-    #fields = value.type.fields()
+    #fields = type.fields()
     # Insufficient, see http://sourceware.org/bugzilla/show_bug.cgi?id=11777:
-    #fields = stripTypedefs(value.type).fields()
+    #fields = defsype).fields()
     # This seems to work.
     #warn("TYPE 0: %s" % type)
     type = stripTypedefs(type)
@@ -724,7 +738,7 @@ def extractFields(type):
     type0 = lookupType(str(type))
     if not type0 is None:
         type = type0
-    if type.code == gdb.TYPE_CODE_FUNC:
+    if type.code == FunctionCode:
         return []
     #warn("TYPE 2: %s" % type)
     fields = type.fields()
@@ -737,15 +751,19 @@ def extractFields(type):
 #
 #######################################################################
 
-class Item:
-    def __init__(self, value, parentiname, iname = None, name = None):
-        self.value = value
-        if iname is None:
-            self.iname = parentiname
-        else:
-            self.iname = "%s.%s" % (parentiname, iname)
-        self.name = name
+#class Item:
+#    def __init__(self, value, parentiname, component):
+#        self.value = value
+#        self.iname = "%s.%s" % (parentiname, component)
 
+#class SameItem:
+#    def __init__(self, value, iname):
+#        self.value = value
+#        self.iname = iname
+
+class LocalItem:
+   def __init__(self):
+        pass
 
 #######################################################################
 #
@@ -867,30 +885,6 @@ registerCommand("p2", p2)
 
 #######################################################################
 #
-# Step Command
-#
-#######################################################################
-
-def sal(args):
-    (cmd, addr) = arg.split(",")
-    lines = catchCliOutput("info line *" + addr)
-    fromAddr = "0x0"
-    toAddr = "0x0"
-    for line in lines:
-        pos0from = line.find(" starts at address") + 19
-        pos1from = line.find(" ", pos0from)
-        pos0to = line.find(" ends at", pos1from) + 9
-        pos1to = line.find(" ", pos0to)
-        if pos1to > 0:
-            fromAddr = line[pos0from : pos1from]
-            toAddr = line[pos0to : pos1to]
-    gdb.execute("maint packet sal%s,%s,%s" % (cmd,fromAddr, toAddr))
-
-registerCommand("sal", sal)
-
-
-#######################################################################
-#
 # The Dumper Class
 #
 #######################################################################
@@ -899,11 +893,12 @@ registerCommand("sal", sal)
 class Dumper:
     def __init__(self, args):
         self.output = []
-        self.printsAddress = True
+        self.currentIName = ""
+        self.currentPrintsAddress = True
         self.currentChildType = ""
         self.currentChildNumChild = -1
-        self.currentMaxNumChilds = -1
-        self.currentNumChilds = -1
+        self.currentMaxNumChild = -1
+        self.currentNumChild = -1
         self.currentValue = None
         self.currentValuePriority = -100
         self.currentValueEncoding = None
@@ -945,6 +940,7 @@ class Dumper:
 
         self.useFancy = "fancy" in options
         self.passExceptions = "pe" in options
+        self.passExceptions = True
         self.autoDerefPointers = "autoderef" in options
         self.partialUpdate = "partial" in options
         self.tooltipOnly = "tooltiponly" in options
@@ -973,7 +969,9 @@ class Dumper:
             #fullUpdateNeeded = False
             try:
                 frame = gdb.selected_frame()
-                item = Item(0, "local", name, name)
+                item = LocalItem()
+                item.iname = "local." + name
+                item.name = name
                 item.value = frame.read_var(name)
                 locals = [item]
                 #warn("PARTIAL LOCALS: %s" % locals)
@@ -988,84 +986,57 @@ class Dumper:
         # Take care of the return value of the last function call.
         if len(resultVarName) > 0:
             try:
-                value = parseAndEvaluate(resultVarName)
-                locals.append(Item(value, "return", resultVarName, "return"))
+                item = LocalItem()
+                item.name = resultVarName
+                item.iname = "return." + resultVarName
+                item.value = parseAndEvaluate(resultVarName)
+                locals.append(item)
             except:
                 # Don't bother. It's only supplementary information anyway.
                 pass
 
         for item in locals:
-          item.value = upcast(item.value)
-          with OutputSafer(self, "", ""):
-            self.anonNumber = -1
-            #warn("ITEM NAME %s: " % item.name)
-            try:
-                #warn("ITEM VALUE %s: " % item.value)
-                # Throw on funny stuff, catch below.
-                # Unfortunately, this fails also with a "Unicode encoding error"
-                # in testArray().
-                #dummy = str(item.value)
-                pass
-            except:
-                # Locals with failing memory access.
-                # FIXME: Isn't this taken care off by the SubItem destructor?
-                with SubItem(self):
-                    self.put('iname="%s",' % item.iname)
-                    self.put('name="%s",' % item.name)
-                    self.put('addr="<not accessible>",')
-                    self.put('numchild="0"')
-                    self.putValue("<not accessible>")
-                    self.putType(item.value.type)
-                continue
-
-            type = item.value.type
-            if type.code == gdb.TYPE_CODE_PTR \
-                    and item.name == "argv" and str(type) == "char **":
+            value = upcast(item.value)
+            with OutputSafer(self, "", ""):
+                self.anonNumber = -1
+
+                type = value.type.unqualified()
+                typeName = str(type)
+
                 # Special handling for char** argv.
-                n = 0
-                p = item.value
-                # p is 0 for "optimized out" cases. Or contains rubbish.
-                try:
-                    if not isNull(p):
-                        while not isNull(p.dereference()) and n <= 100:
-                            p += 1
-                            n += 1
-                except:
-                    pass
-
-                with SubItem(self):
-                    self.put('iname="%s",' % item.iname)
-                    self.putName(item.name)
-                    self.putItemCount(n, 100)
-                    self.putType(type)
-                    self.putNumChild(n)
-                    if self.isExpanded(item):
-                        p = item.value
-                        with Children(self, n):
-                            for i in xrange(n):
-                                value = p.dereference()
-                                self.putSubItem(Item(value, item.iname, i, None))
+                if type.code == gdb.TYPE_CODE_PTR \
+                        and item.iname == "local.argv" \
+                        and typeName == "char **":
+                    n = 0
+                    p = value
+                    # p is 0 for "optimized out" cases. Or contains rubbish.
+                    try:
+                        if not isNull(p):
+                            while not isNull(p.dereference()) and n <= 100:
                                 p += 1
-                            if n > 100:
-                                self.putEllipsis()
+                                n += 1
+                    except:
+                        pass
 
-            else:
-                # A "normal" local variable or parameter.
-                try:
-                   addr = cleanAddress(item.value.address)
-                   with SubItem(self):
-                       self.put('iname="%s",' % item.iname)
-                       self.put('addr="%s",' % addr)
-                       self.putItem(item)
-                except AttributeError:
-                    # Thrown by cleanAddress with message "'NoneType' object
-                    # has no attribute 'cast'" for optimized-out values.
-                    with SubItem(self):
+                    with TopLevelItem(self, item.iname):
+                        self.put('iname="local.argv",name="argv",')
+                        self.putItemCount(n, 100)
+                        self.putType(typeName)
+                        self.putNumChild(n)
+                        if self.currentIName in self.expandedINames:
+                            p = value
+                            with Children(self, n):
+                                for i in xrange(n):
+                                    self.putSubItem(i, p.dereference())
+                                    p += 1
+                    continue
+
+                else:
+                    # A "normal" local variable or parameter.
+                    with TopLevelItem(self, item.iname):
                         self.put('iname="%s",' % item.iname)
                         self.put('name="%s",' % item.name)
-                        self.put('addr="<optimized out>",')
-                        self.putValue("<optimized out>")
-                        self.putType(item.value.type)
+                        self.putItem(value)
 
         #
         # Watchers
@@ -1079,8 +1050,6 @@ class Dumper:
         #print('data=[' + locals + sep + watchers + ']\n')
 
     def checkForQObjectBase(self, type):
-        if type.code != gdb.TYPE_CODE_STRUCT:
-            return False
         name = str(type)
         if name in qqQObjectCache:
             return qqQObjectCache[name]
@@ -1092,6 +1061,9 @@ class Dumper:
             qqQObjectCache[name] = False
             return False
         base = fields[0].type.strip_typedefs()
+        #if base.code != gdb.TYPE_CODE_STRUCT:
+        if base.code != StructCode:
+            return False
         # Prevent infinite recursion in Qt 3.3.8
         if str(base) == name:
             return False
@@ -1106,7 +1078,7 @@ class Dumper:
         #warn("HANDLING WATCH %s, INAME: '%s'" % (exp, iname))
         if exp.startswith("[") and exp.endswith("]"):
             #warn("EVAL: EXP: %s" % exp)
-            with SubItem(self):
+            with TopLevelItem(self, iname):
                 self.put('iname="%s",' % iname)
                 self.put('wname="%s",' % escapedExp)
                 try:
@@ -1125,14 +1097,12 @@ class Dumper:
                     self.putValue("<syntax error>")
                     self.putNoType()
                     self.putNumChild(0)
-                    with Children(self, 0):
-                        pass
+                    self.put("children=[],")
             return
 
-        with SubItem(self):
+        with TopLevelItem(self, iname):
             self.put('iname="%s",' % iname)
             self.put('wname="%s",' % escapedExp)
-            handled = False
             if len(exp) == 0: # The <Edit> case
                 self.putValue(" ")
                 self.putNoType()
@@ -1140,15 +1110,12 @@ class Dumper:
             else:
                 try:
                     value = parseAndEvaluate(exp)
-                    item = Item(value, iname, None, None)
-                    #if not value is None:
-                    #    self.putAddress(value.address)
-                    self.putItem(item)
+                    self.putItem(value)
                 except RuntimeError:
                     self.currentType = " "
                     self.currentValue = "<no such value>"
                     self.currentChildNumChild = -1
-                    self.currentNumChilds = 0
+                    self.currentNumChild = 0
                     self.putNumChild(0)
 
 
@@ -1159,7 +1126,9 @@ class Dumper:
         self.put('%s="%s",' % (name, value))
 
     def childRange(self):
-        return xrange(min(self.currentMaxNumChilds, self.currentNumChilds))
+        if self.currentMaxNumChild is None:
+            return xrange(0, self.currentNumChild)
+        return xrange(min(self.currentMaxNumChild, self.currentNumChild))
 
     # Convenience function.
     def putItemCount(self, count, maximum = 1000000000):
@@ -1169,13 +1138,10 @@ class Dumper:
         else:
             self.putValue('<%s items>' % count)
 
-    def putEllipsis(self):
-        self.put('{name="<incomplete>",value="",type="",numchild="0"},')
-
     def putType(self, type, priority = 0):
         # Higher priority values override lower ones.
         if priority >= self.currentTypePriority:
-            self.currentType = type
+            self.currentType = str(type)
             self.currentTypePriority = priority
 
     def putNoType(self):
@@ -1184,11 +1150,11 @@ class Dumper:
         self.putBetterType(" ")
 
     def putBetterType(self, type, priority = 0):
-        self.currentType = type
+        self.currentType = str(type)
         self.currentTypePriority = self.currentTypePriority + 1
 
     def putAddress(self, addr):
-        if self.printsAddress:
+        if self.currentPrintsAddress:
             try:
                 # addr can be "None", long(None) fails.
                 self.put('addr="0x%x",' % long(addr))
@@ -1235,25 +1201,22 @@ class Dumper:
     def putName(self, name):
         self.put('name="%s",' % name)
 
-    def isExpanded(self, item):
+    def isExpanded(self):
         #warn("IS EXPANDED: %s in %s" % (item.iname, self.expandedINames))
-        if item.iname is None:
-            raise "Illegal iname 'None'"
-        if item.iname.startswith("None"):
-            raise "Illegal iname '%s'" % item.iname
+        #if item.iname is None:
+        #    raise "Illegal iname 'None'"
+        #if item.iname.startswith("None"):
+        #    raise "Illegal iname '%s'" % item.iname
         #warn("   --> %s" % (item.iname in self.expandedINames))
-        return item.iname in self.expandedINames
+        return self.currentIName in self.expandedINames
 
-    def isExpandedIName(self, iname):
+    def isExpandedSubItem(self, component):
+        iname = "%s.%s" % (self.currentIName, component)
+        #warn("IS EXPANDED: %s in %s" % (iname, self.expandedINames))
         return iname in self.expandedINames
 
-    def stripNamespaceFromType(self, typeobj):
-        # This breaks for dumpers type names containing '__star'.
-        # But this should not happen as identifiers containing two
-        # subsequent underscores are reserved for the implemention.
-        if typeobj.code == gdb.TYPE_CODE_PTR:
-            return self.stripNamespaceFromType(typeobj.target()) + "__star"
-        type = stripClassTag(str(typeobj))
+    def stripNamespaceFromType(self, typeName):
+        type = stripClassTag(typeName)
         if len(self.ns) > 0 and type.startswith(self.ns):
             type = type[len(self.ns):]
         pos = type.find("<")
@@ -1265,47 +1228,46 @@ class Dumper:
         return type
 
     def isMovableType(self, type):
-        if type.code == gdb.TYPE_CODE_PTR:
+        if type.code == PointerCode:
             return True
         if isSimpleType(type):
             return True
         return self.stripNamespaceFromType(type) in movableTypes
 
     def putIntItem(self, name, value):
-        with SubItem(self):
-            self.putName(name)
+        with SubItem(self, name):
             self.putValue(value)
             self.putAddress(value.address)
             self.putType("int")
             self.putNumChild(0)
 
     def putBoolItem(self, name, value):
-        with SubItem(self):
-            self.putName(name)
+        with SubItem(self, name):
             self.putValue(value)
             self.putType("bool")
             self.putNumChild(0)
 
-    def itemFormat(self, item):
-        format = self.formats.get(item.iname)
+    def currentItemFormat(self):
+        format = self.formats.get(self.currentIName)
         if format is None:
-            format = self.typeformats.get(stripClassTag(str(item.value.type)))
+            format = self.typeformats.get(stripClassTag(str(self.currentType)))
         return format
 
-    def putSubItem(self, item):
-        with SubItem(self):
-            self.putItem(item)
+    def putSubItem(self, component, value):
+        with SubItem(self, component):
+            self.putItem(value)
 
-    def putCallItem(self, name, item, func, *args):
-        result = call2(item.value, func, args)
-        self.putSubItem(Item(result, item.iname, name, name))
-
-    def putItem(self, item):
-        name = getattr(item, "name", None)
-        if not name is None:
+    def putNamedSubItem(self, component, value, name):
+        with SubItem(self, component):
             self.putName(name)
+            self.putItem(value)
+    def putCallItem(self, name, value, func, *args):
+        result = call2(value, func, args)
+        with SubItem(self, name):
+            self.putItem(result)
 
-        if item.value is None:
+    def putItem(self, value):
+        if value is None:
             # Happens for non-available watchers in gdb versions that
             # need to use gdb.execute instead of gdb.parse_and_eval
             self.putValue("<not available>")
@@ -1313,66 +1275,65 @@ class Dumper:
             self.putNumChild(0)
             return
 
-        # FIXME: Gui shows references stripped?
-        #warn(" ")
-        #warn("REAL INAME: %s " % item.iname)
-        #warn("REAL NAME: %s " % name)
-        #warn("REAL TYPE: %s " % item.value.type)
-        #warn("REAL CODE: %s " % item.value.type.code)
-        #warn("REAL VALUE: %s " % item.value)
-        #try:
-        #    warn("REAL VALUE: %s " % item.value)
-        #except:
-        #    #UnicodeEncodeError:
-        #    warn("REAL VALUE: <unprintable>")
-
-        value = item.value
-        realtype = value.type
         type = value.type.unqualified()
+        typeName = str(type)
 
-        typedefStrippedType = stripTypedefs(type)
+        # FIXME: Gui shows references stripped?
+        #warn(" ")
+        #warn("REAL INAME: %s " % self.currentIName)
+        #warn("REAL TYPE: %s " % value.type)
+        #warn("REAL CODE: %s " % value.type.code)
+        #warn("REAL VALUE: %s " % value)
 
-        if typedefStrippedType.code == gdb.TYPE_CODE_REF:
-            try:
+        if type.code == gdb.TYPE_CODE_REF:
+            #try:
                 # This throws "RuntimeError: Attempt to dereference a
                 # generic pointer." with MinGW's gcc 4.5 when it "identifies"
                 # a "QWidget &" as "void &".
-                type = type.target()
-                typedefStrippedType = typedefStrippedType.target()
-                value = value.cast(typedefStrippedType)
-                item.value = value
-            except RuntimeError:
-                value = item.value
-                type = value.type
-
-        if typedefStrippedType.code == gdb.TYPE_CODE_INT:
+                self.putItem(value.cast(type.target()))
+                return
+            #except RuntimeError:
+            #    pass
+
+        #if type.code == gdb.TYPE_CODE_INT or type.code == gdb.TYPE_CODE_CHAR:
+        if type.code == IntCode or type.code == CharCode:
             self.putAddress(value.address)
-            self.putType(realtype)
+            self.putType(typeName)
             self.putValue(int(value))
             self.putNumChild(0)
             return
 
-        if typedefStrippedType.code == gdb.TYPE_CODE_CHAR:
-            self.putType(realtype)
-            self.putValue(int(value))
+        if type.code == gdb.TYPE_CODE_FLT or type.code == gdb.TYPE_CODE_BOOL:
+        #if type.code == FloatCode or type.code == BoolCode:
             self.putAddress(value.address)
+            self.putType(typeName)
+            self.putValue(value)
             self.putNumChild(0)
             return
 
-        if typedefStrippedType.code == gdb.TYPE_CODE_FLT \
-                or typedefStrippedType.code == gdb.TYPE_CODE_BOOL:
-            self.putType(realtype)
-            self.putValue(value)
-            self.putAddress(value.address)
+        if type.code == gdb.TYPE_CODE_ENUM:
+        #if type.code == EnumCode:
+            self.putType(typeName)
+            self.putValue("%s (%d)" % (value, value))
             self.putNumChild(0)
             return
 
-        if typedefStrippedType.code == gdb.TYPE_CODE_ARRAY:
-            targettype = realtype.target()
+        if type.code == gdb.TYPE_CODE_TYPEDEF:
+        #if type.code == TypedefCode:
+            self.putItem(value.cast(type.strip_typedefs()))
+            self.putBetterType(typeName)
+            return
+
+        format = self.formats.get(self.currentIName)
+        if format is None:
+            format = self.typeformats.get(stripClassTag(typeName))
+
+        if type.code == gdb.TYPE_CODE_ARRAY:
+            targettype = type.target()
             self.putAddress(value.address)
-            self.putType(realtype)
+            self.putType(typeName)
             self.putNumChild(1)
-            format = self.itemFormat(item)
+            format = self.currentItemFormat()
             if format == 0:
                 # Explicitly requested Latin1 formatting.
                 self.putValue(encodeCharArray(value, 100), Hex2EncodedLatin1)
@@ -1384,65 +1345,32 @@ class Dumper:
                 self.putValue(encodeCharArray(value, 100), Hex2EncodedLocal8Bit)
             else:
                 self.putValue("@0x%x" % long(value.cast(targettype.pointer())))
-            if self.isExpanded(item):
-                self.put('addrbase="0x%x",' % long(value.cast(targettype.pointer())))
-                self.put('addrstep="%s",' % targettype.sizeof)
-                with Children(self, 1, targettype):
-                    child = Item(value, item.iname, None, item.name)
-                    self.putFields(child)
-            return
-
-        if typedefStrippedType.code == gdb.TYPE_CODE_ENUM:
-            self.putType(realtype)
-            self.putValue("%s (%d)" % (value, value))
-            self.putNumChild(0)
+            if self.currentIName in self.expandedINames:
+                i = 0
+                with Children(self, childType=targettype,
+                        addrBase=value.cast(targettype.pointer()),
+                        addrStep=targettype.sizeof):
+                    self.putFields(value)
+                    i = i + 1
             return
 
-        # Is this derived from QObject?
-        isQObjectDerived = self.checkForQObjectBase(typedefStrippedType)
-
-        nsStrippedType = self.stripNamespaceFromType(typedefStrippedType)\
-            .replace("::", "__")
-
-        #warn(" STRIPPED: %s" % nsStrippedType)
-        #warn(" DUMPERS: %s" % (nsStrippedType in qqDumpers))
-
-        format = self.itemFormat(item)
-        if self.useFancy \
-                and ((format is None) or (format >= 1)) \
-                and ((nsStrippedType in qqDumpers) \
-                    or (str(type) in qqDumpers) \
-                    or isQObjectDerived):
-            #warn("IS DUMPABLE: %s " % type)
-            #self.putAddress(value.address)
-            self.putType(realtype)
-            self.putAddress(value.address)
-            if nsStrippedType in qqDumpers:
-                qqDumpers[nsStrippedType](self, item)
-            if str(type) in qqDumpers:
-                qqDumpers[str(type)](self, item)
-            elif isQObjectDerived:
-                # value has references stripped off item.value.
-                item1 = Item(value, item.iname)
-                qdump__QObject(self, item1)
-            #warn(" RESULT: %s " % self.output)
-            return
-
-        if typedefStrippedType.code == gdb.TYPE_CODE_PTR:
-            #warn("POINTER: %s" % format)
-            target = stripTypedefs(type.target())
+        if type.code == gdb.TYPE_CODE_PTR:
+            #warn("POINTER: %s" % value)
 
             if isNull(value):
                 #warn("NULL POINTER")
-                self.putType(realtype)
+                self.putAddress(value.address)
+                self.putType(typeName)
                 self.putValue("0x0")
                 self.putNumChild(0)
-                self.putAddress(value.address)
                 return
 
-            if target.code == gdb.TYPE_CODE_VOID:
+            innerType = type.target()
+            innerTypeName = str(innerType.unqualified())
+
+            if innerType.code == gdb.TYPE_CODE_VOID:
                 #warn("VOID POINTER: %s" % format)
-                self.putType(realtype)
+                self.putType(typeName)
                 self.putValue(str(value))
                 self.putNumChild(0)
                 self.putAddress(value.address)
@@ -1451,21 +1379,20 @@ class Dumper:
             if format == 0:
                 # Explicitly requested bald pointer.
                 self.putAddress(value.address)
-                self.putType(realtype)
+                self.putType(typeName)
                 self.putPointerValue(value.address)
                 self.putNumChild(1)
-                if self.isExpanded(item):
+                if self.currentIName in self.expandedINames:
                     with Children(self):
-                        with SubItem(self):
-                            self.putItem(Item(item.value.dereference(),
-                                item.iname, "*", "*"))
-                            #self.putAddress(item.value)
+                        with SubItem(self, '*'):
+                            self.putItem(value.dereference())
+                            #self.putAddress(value)
                 return
 
             if format == 1:
                 # Explicityly requested Latin1 formatting.
                 self.putAddress(value.address)
-                self.putType(realtype)
+                self.putType(typeName)
                 self.putValue(encodeCharArray(value, 100), Hex2EncodedLatin1)
                 self.putNumChild(0)
                 return
@@ -1473,7 +1400,7 @@ class Dumper:
             if format == 2:
                 # Explicityly requested UTF-8 formatting.
                 self.putAddress(value.address)
-                self.putType(realtype)
+                self.putType(typeName)
                 self.putValue(encodeCharArray(value, 100), Hex2EncodedUtf8)
                 self.putNumChild(0)
                 return
@@ -1481,7 +1408,7 @@ class Dumper:
             if format == 3:
                 # Explicityly requested local 8 bit formatting.
                 self.putAddress(value.address)
-                self.putType(realtype)
+                self.putType(typeName)
                 self.putValue(encodeCharArray(value, 100), Hex2EncodedLocal8Bit)
                 self.putNumChild(0)
                 return
@@ -1489,7 +1416,7 @@ class Dumper:
             if format == 4:
                 # Explitly requested UTF-16 formatting.
                 self.putAddress(value.address)
-                self.putType(realtype)
+                self.putType(typeName)
                 self.putValue(encodeChar2Array(value, 100), Hex4EncodedBigEndian)
                 self.putNumChild(0)
                 return
@@ -1497,26 +1424,25 @@ class Dumper:
             if format == 5:
                 # Explitly requested UCS-4 formatting.
                 self.putAddress(value.address)
-                self.putType(realtype)
+                self.putType(typeName)
                 self.putValue(encodeChar4Array(value, 100), Hex8EncodedBigEndian)
                 self.putNumChild(0)
                 return
 
-            if (str(typedefStrippedType)
-                    .replace("(anonymous namespace)", "").find("(") != -1):
+            if (typeName.replace("(anonymous namespace)", "").find("(") != -1):
                 # A function pointer with format None.
-                self.putValue(str(item.value))
+                self.putValue(str(value))
                 self.putAddress(value.address)
-                self.putType(realtype)
+                self.putType(typeName)
                 self.putNumChild(0)
                 return
 
             #warn("AUTODEREF: %s" % self.autoDerefPointers)
-            if self.autoDerefPointers or name == "this":
+            #warn("INAME: %s" % self.currentIName)
+            if self.autoDerefPointers or self.currentIName.endswith('.this'):
                 ## Generic pointer type with format None
-                #warn("GENERIC AUTODEREF POINTER: %s" % value.address)
-                innerType = realtype.target()
-                innerTypeName = str(innerType.unqualified())
+                #warn("GENERIC AUTODEREF POINTER: %s AT %s TO %s"
+                #    % (type, value.address, innerTypeName))
                 # Never dereference char types.
                 if innerTypeName != "char" \
                         and innerTypeName != "signed char" \
@@ -1524,9 +1450,8 @@ class Dumper:
                         and innerTypeName != "wchar_t":
                     self.putType(innerType)
                     savedCurrentChildType = self.currentChildType
-                    self.currentChildType = stripClassTag(str(innerType))
-                    self.putItem(
-                        Item(item.value.dereference(), item.iname, None, None))
+                    self.currentChildType = stripClassTag(innerTypeName)
+                    self.putItem(value.dereference())
                     self.currentChildType = savedCurrentChildType
                     self.putPointerValue(value.address)
                     self.put('origaddr="%s",' % value)
@@ -1534,39 +1459,70 @@ class Dumper:
 
             # Fall back to plain pointer printing.
             #warn("GENERIC PLAIN POINTER: %s" % value.type)
-            self.putType(realtype)
+            self.putType(typeName)
             self.putAddress(value.address)
             self.putNumChild(1)
-            if self.isExpanded(item):
+            if self.currentIName in self.expandedINames:
                 with Children(self):
-                    with SubItem(self):
-                        self.putItem(Item(item.value.dereference(),
-                            item.iname, "*", "*"))
-                        self.putAddress(item.value)
+                    with SubItem(self, "*"):
+                        self.put('name="*",')
+                        self.putItem(value.dereference())
+                        self.putAddress(value)
             self.putPointerValue(value.address)
             return
 
-        if str(typedefStrippedType).startswith("<anon"):
+        if typeName.startswith("<anon"):
             # Anonymous union. We need a dummy name to distinguish
             # multiple anonymous unions in the struct.
-            self.putType(realtype)
+            self.putType(type)
             self.putValue("{...}")
             self.anonNumber += 1
             with Children(self, 1):
-                self.listAnonymous(item, "#%d" % self.anonNumber, type)
+                self.listAnonymous(value, "#%d" % self.anonNumber, type)
+            return
+
+        if type.code != gdb.TYPE_CODE_STRUCT:
+            warning("WRONG ASSUMPTION HERE: %s " % gdb.TYPE_CODE_STRUCT)
+            check(False)
+
+        # Is this derived from QObject?
+        isQObjectDerived = self.checkForQObjectBase(type)
+
+        nsStrippedType = self.stripNamespaceFromType(typeName)\
+            .replace("::", "__")
+
+        #warn(" STRIPPED: %s" % nsStrippedType)
+        #warn(" DUMPERS: %s" % (nsStrippedType in qqDumpers))
+
+        if self.useFancy \
+                and (format is None or format >= 1) \
+                and (nsStrippedType in qqDumpers \
+                    or typeName in qqDumpers \
+                    or isQObjectDerived):
+            #warn("IS DUMPABLE: %s " % type)
+            #self.putAddress(value.address)
+            self.putAddress(value.address)
+            self.putType(typeName)
+            if nsStrippedType in qqDumpers:
+                qqDumpers[nsStrippedType](self, value)
+            if typeName in qqDumpers:
+                qqDumpers[typeName](self, value)
+            elif isQObjectDerived:
+                # FIXME: value has references stripped off item.value.
+                #item1 = Item(value, item.iname)
+                qdump__QObject(self, value)
+            #warn(" RESULT: %s " % self.output)
             return
 
-        #warn("GENERIC STRUCT: %s" % realtype)
-        #warn("INAME: %s " % item.iname)
+        #warn("GENERIC STRUCT: %s" % type)
+        #warn("INAME: %s " % self.currentIName)
         #warn("INAMES: %s " % self.expandedINames)
-        #warn("EXPANDED: %s " % (item.iname in self.expandedINames))
-        fields = extractFields(typedefStrippedType)
+        #warn("EXPANDED: %s " % (self.currentIName in self.expandedINames))
+        #fields = extractFields(type)
+        fields = type.fields()
 
-        self.putType(realtype)
-        try:
-            self.putAddress(item.value.address)
-        except:
-            pass
+        self.putType(typeName)
+        self.putAddress(value.address)
         self.putValue("{...}")
 
         if False:
@@ -1579,27 +1535,29 @@ class Dumper:
             numfields = len(fields)
         self.putNumChild(numfields)
 
-
-        if self.isExpanded(item):
+        if self.currentIName in self.expandedINames:
             innerType = None
             if len(fields) == 1 and fields[0].name is None:
                 innerType = type.target()
-            with Children(self, 1, innerType):
-                child = Item(value, item.iname, None, item.name)
-                self.putFields(child)
+            with Children(self, 1, childType=innerType):
+                self.putFields(value)
 
-    def putPlainChildren(self, item):
+    def putPlainChildren(self, value):
         self.putValue(" ", None, -99)
         self.putNumChild(1)
-        self.putAddress(item.value.address)
-        if self.isExpanded(item):
+        self.putAddress(value.address)
+        if self.currentIName in self.expandedINames:
             with Children(self):
-               self.putFields(item)
+               self.putFields(value)
 
-    def putFields(self, item, dumpBase = True):
-            value = item.value
+    def putFields(self, value, dumpBase = True):
             type = stripTypedefs(value.type)
-            fields = extractFields(value.type)
+            # Insufficient, see http://sourceware.org/bugzilla/show_bug.cgi?id=10953:
+            #fields = value.type.fields()
+            #fields = type.fields()
+            fields = extractFields(type)
+            #warn("TYPE: %s" % type)
+            #warn("FIELDS: %s" % fields)
             baseNumber = 0
             for field in fields:
                 #warn("FIELD: %s" % field)
@@ -1613,7 +1571,8 @@ class Dumper:
                     innerType = type.target()
                     p = value.cast(innerType.pointer())
                     for i in xrange(type.sizeof / innerType.sizeof):
-                        self.putSubItem(Item(p.dereference(), item.iname, i, None))
+                        with SubItem(self, i):
+                            self.putItem(p.dereference())
                         p = p + 1
                     continue
 
@@ -1626,65 +1585,61 @@ class Dumper:
                 # The 'field.is_base_class' attribute exists in gdb 7.0.X
                 # and later only. Symbian gdb is 6.8 as of 20.10.2010.
                 # TODO: Remove once Symbian gdb is up to date.
-                if hasattr(field, 'is_base_class'):
-                    isBaseClass = field.is_base_class
-                else:
-                    isBaseClass = field.name == stripClassTag(str(field.type))
-                if isBaseClass:
+                #if hasattr(field, 'is_base_class'):
+                #    isBaseClass = field.is_base_class
+                #else:
+                #    isBaseClass = field.name == stripClassTag(str(field.type))
+                if field.is_base_class:
                     # Field is base type. We cannot use field.name as part
                     # of the iname as it might contain spaces and other
                     # strange characters.
                     if dumpBase:
-                        child = Item(value.cast(field.type),
-                            item.iname, "@%d" % baseNumber, field.name)
                         baseNumber += 1
-                        with SubItem(self):
-                            self.put('iname="%s",' % child.iname)
-                            self.putItem(child)
+                        with UnnamedSubItem(self, "@%d" % baseNumber):
+                            self.put('iname="%s",' % self.currentIName)
+                            self.put('name="%s",' % field.name)
+                            self.putItem(value.cast(field.type))
                 elif len(field.name) == 0:
                     # Anonymous union. We need a dummy name to distinguish
                     # multiple anonymous unions in the struct.
                     self.anonNumber += 1
-                    self.listAnonymous(item, "#%d" % self.anonNumber,
+                    self.listAnonymous(value, "#%d" % self.anonNumber,
                         field.type)
                 else:
                     # Named field.
-                    with SubItem(self):
-                        child = Item(upcast(value[field.name]),
-                            item.iname, field.name, field.name)
-                        bitsize = getattr(field, "bitsize", None)
-                        if not bitsize is None:
-                            self.put("bitsize=\"%s\",bitpos=\"%s\","
-                                    % (bitsize, bitpos))
-                        self.putItem(child)
+                    with SubItem(self, field.name):
+                        #bitsize = getattr(field, "bitsize", None)
+                        #if not bitsize is None:
+                        #    self.put("bitsize=\"%s\",bitpos=\"%s\","
+                        #            % (bitsize, bitpos))
+                        self.putItem(upcast(value[field.name]))
 
 
-    def listAnonymous(self, item, name, type):
+    def listAnonymous(self, value, name, type):
         for field in type.fields():
             #warn("FIELD NAME: %s" % field.name)
             if len(field.name) > 0:
-                value = item.value[field.name]
-                child = Item(value, item.iname, field.name, field.name)
-                with SubItem(self):
+                with SubItem(self, field.name):
                     #self.putAddress(value.address)
-                    self.putItem(child)
+                    self.putItem(value[field.name])
             else:
                 # Further nested.
                 self.anonNumber += 1
                 name = "#%d" % self.anonNumber
-                iname = "%s.%s" % (item.iname, name)
-                child = Item(item.value, iname, None, name)
-                with SubItem(self):
+                #iname = "%s.%s" % (selitem.iname, name)
+                #child = SameItem(item.value, iname)
+                with SubItem(self, name):
                     self.put('name="%s",' % name)
                     self.putValue(" ")
-                    if str(field.type).endswith("<anonymous union>"):
+                    fieldTypeName = str(field.type)
+                    if fieldTypeName.endswith("<anonymous union>"):
                         self.putType("<anonymous union>")
-                    elif str(field.type).endswith("<anonymous struct>"):
+                    elif fieldTypeName.endswith("<anonymous struct>"):
                         self.putType("<anonymous struct>")
                     else:
-                        self.putType(field.type)
+                        self.putType(fieldTypeName)
                     with Children(self, 1):
-                        self.listAnonymous(child, name, field.type)
+                        self.listAnonymous(value, name, field.type)
 
 #######################################################################
 #
index 78d27e0..912b672 100644 (file)
@@ -9,76 +9,75 @@
 
 from __future__ import with_statement
 
-def qdump__QAtomicInt(d, item):
-    d.putValue(item.value["_q_value"])
+def qdump__QAtomicInt(d, value):
+    d.putValue(value["_q_value"])
     d.putNumChild(0)
 
 
-def qdump__QBasicAtomicInt(d, item):
-    d.putValue(item.value["_q_value"])
+def qdump__QBasicAtomicInt(d, value):
+    d.putValue(value["_q_value"])
     d.putNumChild(0)
 
 
-def qdump__QBasicAtomicPointer(d, item):
-    innerType = templateArgument(item.value.type.unqualified(), 0)
-    d.putType(item.value.type)
-    p = cleanAddress(item.value["_q_value"])
+def qdump__QBasicAtomicPointer(d, value):
+    d.putType(value.type)
+    p = cleanAddress(value["_q_value"])
     d.putValue(p)
-    d.putPointerValue(item.value.address)
+    d.putPointerValue(value.address)
     d.putNumChild(p)
-    if d.isExpanded(item):
+    if d.isExpanded():
         with Children(d):
-           d.putItem(item.value["_q_value"])
+           d.putItem(value["_q_value"])
 
 
-def qdump__QByteArray(d, item):
-    d.putByteArrayValue(item.value)
-    data, size, alloc = qByteArrayData(item.value)
+def qdump__QByteArray(d, value):
+    d.putByteArrayValue(value)
+    data, size, alloc = qByteArrayData(value)
     d.putNumChild(size)
 
-    if d.isExpanded(item):
+    if d.isExpanded():
         innerType = lookupType("char")
-        with Children(d, [size, 1000], innerType):
+        with Children(d, numChild=size, maxNumChild=1000, childType=innerType,
+                addrBase=cleanAddress(data), addrStep=1):
             p = gdb.Value(data.cast(innerType.pointer()))
             for i in d.childRange():
-                d.putSubItem(Item(p.dereference(), item.iname, i))
+                d.put('{value="%d"},' % p.dereference())
                 p += 1
 
 
-def qdump__QChar(d, item):
-    ucs = int(item.value["ucs"])
+def qdump__QChar(d, value):
+    ucs = int(value["ucs"])
     d.putValue("'%c' (%d)" % (printableChar(ucs), ucs))
     d.putNumChild(0)
 
 
 
-def qdump__QAbstractItemModel(d, item):
+def qdump__QAbstractItemModel(d, value):
     # Create a default-constructed QModelIndex on the stack.
     try:
         ri = makeValue(d.ns + "QModelIndex", "-1, -1, 0, 0")
-        this_ = makeExpression(item.value)
+        this_ = makeExpression(value)
         ri_ = makeExpression(ri)
         rowCount = int(parseAndEvaluate("%s.rowCount(%s)" % (this_, ri_)))
         columnCount = int(parseAndEvaluate("%s.columnCount(%s)" % (this_, ri_)))
     except:
-        d.putPlainChildren(item)
+        d.putPlainChildren(value)
         return
     d.putValue("%d x %d" % (rowCount, columnCount))
     d.putNumChild(rowCount * columnCount)
-    if d.isExpanded(item):
-        with Children(d, rowCount * columnCount, ri.type):
+    if d.isExpanded():
+        with Children(d, numChild=rowCount * columnCount, childType=ri.type):
             i = 0
             for row in xrange(rowCount):
                 for column in xrange(columnCount):
-                    with SubItem(d):
-                        d.putField("iname", "%s.%d" % (item.iname, i))
+                    with SubItem(d, i):
                         d.putName("[%s, %s]" % (row, column))
                         mi = parseAndEvaluate("%s.index(%d,%d,%s)"
                             % (this_, row, column, ri_))
                         #warn("MI: %s " % mi)
                         #name = "[%d,%d]" % (row, column)
                         #d.putValue("%s" % mi)
-                        d.putItem(Item(mi, item.iname, i))
+                        d.putItem(mi)
                         i = i + 1
                         #warn("MI: %s " % mi)
                         #d.putName("[%d,%d]" % (row, column))
@@ -87,11 +86,11 @@ def qdump__QAbstractItemModel(d, item):
                         #d.putType(mi.type)
     #gdb.execute("call free($ri)")
 
-def qdump__QModelIndex(d, item):
-    r = item.value["r"]
-    c = item.value["c"]
-    p = item.value["p"]
-    m = item.value["m"]
+def qdump__QModelIndex(d, value):
+    r = value["r"]
+    c = value["c"]
+    p = value["p"]
+    m = value["m"]
     mm = m.dereference()
     mm = mm.cast(mm.type.unqualified())
     try:
@@ -101,168 +100,165 @@ def qdump__QModelIndex(d, item):
         rowCount = int(parseAndEvaluate("%s.rowCount(%s)" % (mm_, mi_)))
         columnCount = int(parseAndEvaluate("%s.columnCount(%s)" % (mm_, mi_)))
     except:
-        d.putPlainChildren(item)
+        d.putPlainChildren(value)
         return
 
     try:
         # Access DisplayRole as value
-        value = parseAndEvaluate("%s.data(%s, 0)" % (mm_, mi_))
-        v = value["d"]["data"]["ptr"]
+        val = parseAndEvaluate("%s.data(%s, 0)" % (mm_, mi_))
+        v = val["d"]["data"]["ptr"]
         d.putStringValue(makeValue(d.ns + 'QString', v))
     except:
         d.putValue("(invalid)")
 
     if r >= 0 and c >= 0 and not isNull(m):
         d.putNumChild(rowCount * columnCount)
-        if d.isExpanded(item):
+        if d.isExpanded():
             with Children(d):
                 i = 0
                 for row in xrange(rowCount):
                     for column in xrange(columnCount):
-                        with SubItem(d):
-                            d.putField("iname", "%s.%d" % (item.iname, i))
+                        with UnnamedSubItem(d, i):
                             d.putName("[%s, %s]" % (row, column))
                             mi2 = parseAndEvaluate("%s.index(%d,%d,%s)"
                                 % (mm_, row, column, mi_))
-                            d.putItem(Item(mi2, item.iname, i))
+                            d.putItem(mi2)
                             i = i + 1
-                #d.putCallItem("parent", item, "parent")
-                #with SubItem(d):
-                #    d.putName("model")
+                #d.putCallItem("parent", val, "parent")
+                #with SubItem(d, "model"):
                 #    d.putValue(m)
                 #    d.putType(d.ns + "QAbstractItemModel*")
                 #    d.putNumChild(1)
     else:
         d.putValue("(invalid)")
         d.putNumChild(0)
-        if d.isExpanded(item):
+        if d.isExpanded():
             with Children(d):
                 pass
     #gdb.execute("call free($mi)")
 
 
-def qdump__QDate(d, item):
-    if int(item.value["jd"]) == 0:
+def qdump__QDate(d, value):
+    if int(value["jd"]) == 0:
         d.putValue("(null)")
         d.putNumChild(0)
         return
     qt = d.ns + "Qt::"
-    d.putStringValue(call(item.value, "toString", qt + "TextDate"))
+    d.putStringValue(call(value, "toString", qt + "TextDate"))
     d.putNumChild(1)
-    if d.isExpanded(item):
+    if d.isExpanded():
         # FIXME: This improperly uses complex return values.
-        with Children(d, 4):
-            d.putCallItem("toString", item, "toString", qt + "TextDate")
-            d.putCallItem("(ISO)", item, "toString", qt + "ISODate")
-            d.putCallItem("(SystemLocale)", item, "toString",
+        with Children(d):
+            d.putCallItem("toString", value, "toString", qt + "TextDate")
+            d.putCallItem("(ISO)", value, "toString", qt + "ISODate")
+            d.putCallItem("(SystemLocale)", value, "toString",
                 qt + "SystemLocaleDate")
-            d.putCallItem("(Locale)", item, "toString", qt + "LocaleDate")
+            d.putCallItem("(Locale)", value, "toString", qt + "LocaleDate")
 
 
-def qdump__QTime(d, item):
-    if int(item.value["mds"]) == -1:
+def qdump__QTime(d, value):
+    if int(value["mds"]) == -1:
         d.putValue("(null)")
         d.putNumChild(0)
         return
     qt = d.ns + "Qt::"
-    d.putStringValue(call(item.value, "toString", qt + "TextDate"))
+    d.putStringValue(call(value, "toString", qt + "TextDate"))
     d.putNumChild(1)
-    if d.isExpanded(item):
+    if d.isExpanded():
         # FIXME: This improperly uses complex return values.
-        with Children(d, 8):
-            d.putCallItem("toString", item, "toString", qt + "TextDate")
-            d.putCallItem("(ISO)", item, "toString", qt + "ISODate")
-            d.putCallItem("(SystemLocale)", item, "toString",
+        with Children(d):
+            d.putCallItem("toString", value, "toString", qt + "TextDate")
+            d.putCallItem("(ISO)", value, "toString", qt + "ISODate")
+            d.putCallItem("(SystemLocale)", value, "toString",
                  qt + "SystemLocaleDate")
-            d.putCallItem("(Locale)", item, "toString", qt + "LocaleDate")
-            d.putCallItem("toUTC", item, "toTimeSpec", qt + "UTC")
+            d.putCallItem("(Locale)", value, "toString", qt + "LocaleDate")
+            d.putCallItem("toUTC", value, "toTimeSpec", qt + "UTC")
 
 
-def qdump__QDateTime(d, item):
+def qdump__QDateTime(d, value):
     try:
         # Fails without debug info.
-        if int(item.value["d"]["d"].dereference()["time"]["mds"]) == -1:
+        if int(value["d"]["d"].dereference()["time"]["mds"]) == -1:
             d.putValue("(null)")
             d.putNumChild(0)
             return
     except:
-        d.putPlainChildren(item)
+        d.putPlainChildren(value)
         return
     qt = d.ns + "Qt::"
-    d.putStringValue(call(item.value, "toString", qt + "TextDate"))
+    d.putStringValue(call(value, "toString", qt + "TextDate"))
     d.putNumChild(1)
-    if d.isExpanded(item):
+    if d.isExpanded():
         # FIXME: This improperly uses complex return values.
-        with Children(d, 8):
-            d.putCallItem("toTime_t", item, "toTime_t")
-            d.putCallItem("toString", item, "toString", qt + "TextDate")
-            d.putCallItem("(ISO)", item, "toString", qt + "ISODate")
-            d.putCallItem("(SystemLocale)", item, "toString", qt + "SystemLocaleDate")
-            d.putCallItem("(Locale)", item, "toString", qt + "LocaleDate")
-            d.putCallItem("toUTC", item, "toTimeSpec", qt + "UTC")
-            d.putCallItem("toLocalTime", item, "toTimeSpec", qt + "LocalTime")
-
-
-def qdump__QDir(d, item):
-    d.putStringValue(item.value["d_ptr"]["d"].dereference()["path"])
+        with Children(d):
+            d.putCallItem("toTime_t", value, "toTime_t")
+            d.putCallItem("toString", value, "toString", qt + "TextDate")
+            d.putCallItem("(ISO)", value, "toString", qt + "ISODate")
+            d.putCallItem("(SystemLocale)", value, "toString", qt + "SystemLocaleDate")
+            d.putCallItem("(Locale)", value, "toString", qt + "LocaleDate")
+            d.putCallItem("toUTC", value, "toTimeSpec", qt + "UTC")
+            d.putCallItem("toLocalTime", value, "toTimeSpec", qt + "LocalTime")
+
+
+def qdump__QDir(d, value):
+    d.putStringValue(value["d_ptr"]["d"].dereference()["path"])
     d.putNumChild(2)
-    if d.isExpanded(item):
-        with Children(d, 2):
-            d.putCallItem("absolutePath", item, "absolutePath")
-            d.putCallItem("canonicalPath", item, "canonicalPath")
+    if d.isExpanded():
+        with Children(d):
+            d.putCallItem("absolutePath", value, "absolutePath")
+            d.putCallItem("canonicalPath", value, "canonicalPath")
 
 
-def qdump__QFile(d, item):
+def qdump__QFile(d, value):
     ptype = lookupType(d.ns + "QFilePrivate")
-    d_ptr = item.value["d_ptr"]["d"].dereference()
+    d_ptr = value["d_ptr"]["d"].dereference()
     d.putStringValue(d_ptr.cast(ptype)["fileName"])
     d.putNumChild(1)
-    if d.isExpanded(item):
-        with Children(d, 1):
-            d.putCallItem("exists", item, "exists()")
+    if d.isExpanded():
+        with Children(d):
+            d.putCallItem("exists", value, "exists()")
 
 
-def qdump__QFileInfo(d, item):
+def qdump__QFileInfo(d, value):
     try:
-        d.putStringValue(item.value["d_ptr"]["d"].dereference()["fileName"])
+        d.putStringValue(value["d_ptr"]["d"].dereference()["fileName"])
     except:
-        d.putPlainChildren(item)
+        d.putPlainChildren(value)
         return
     d.putNumChild(3)
-    if d.isExpanded(item):
-        with Children(d, 10, lookupType(d.ns + "QString")):
-            d.putCallItem("absolutePath", item, "absolutePath")
-            d.putCallItem("absoluteFilePath", item, "absoluteFilePath")
-            d.putCallItem("canonicalPath", item, "canonicalPath")
-            d.putCallItem("canonicalFilePath", item, "canonicalFilePath")
-            d.putCallItem("completeBaseName", item, "completeBaseName")
-            d.putCallItem("completeSuffix", item, "completeSuffix")
-            d.putCallItem("baseName", item, "baseName")
+    if d.isExpanded():
+        with Children(d, childType=lookupType(d.ns + "QString")):
+            d.putCallItem("absolutePath", value, "absolutePath")
+            d.putCallItem("absoluteFilePath", value, "absoluteFilePath")
+            d.putCallItem("canonicalPath", value, "canonicalPath")
+            d.putCallItem("canonicalFilePath", value, "canonicalFilePath")
+            d.putCallItem("completeBaseName", value, "completeBaseName")
+            d.putCallItem("completeSuffix", value, "completeSuffix")
+            d.putCallItem("baseName", value, "baseName")
             if False:
                 #ifdef Q_OS_MACX
-                d.putCallItem("isBundle", item, "isBundle")
-                d.putCallItem("bundleName", item, "bundleName")
-            d.putCallItem("fileName", item, "fileName")
-            d.putCallItem("filePath", item, "filePath")
+                d.putCallItem("isBundle", value, "isBundle")
+                d.putCallItem("bundleName", value, "bundleName")
+            d.putCallItem("fileName", value, "fileName")
+            d.putCallItem("filePath", value, "filePath")
             # Crashes gdb (archer-tromey-python, at dad6b53fe)
-            #d.putCallItem("group", item, "group")
-            #d.putCallItem("owner", item, "owner")
-            d.putCallItem("path", item, "path")
+            #d.putCallItem("group", value, "group")
+            #d.putCallItem("owner", value, "owner")
+            d.putCallItem("path", value, "path")
 
-            d.putCallItem("groupid", item, "groupId")
-            d.putCallItem("ownerid", item, "ownerId")
+            d.putCallItem("groupid", value, "groupId")
+            d.putCallItem("ownerid", value, "ownerId")
 
             #QFile::Permissions permissions () const
-            perms = call(item.value, "permissions")
+            perms = call(value, "permissions")
             if perms is None:
                 d.putValue("<not available>")
             else:
-                with SubItem(d):
-                    d.putName("permissions")
+                with SubItem(d, "permissions"):
                     d.putValue(" ")
                     d.putType(d.ns + "QFile::Permissions")
                     d.putNumChild(10)
-                    if d.isExpandedIName(item.iname + ".permissions"):
+                    if d.isExpanded():
                         with Children(d, 10):
                             perms = perms['i']
                             d.putBoolItem("ReadOwner",  perms & 0x4000)
@@ -280,25 +276,25 @@ def qdump__QFileInfo(d, item):
 
             #QDir absoluteDir () const
             #QDir dir () const
-            d.putCallItem("caching", item, "caching")
-            d.putCallItem("exists", item, "exists")
-            d.putCallItem("isAbsolute", item, "isAbsolute")
-            d.putCallItem("isDir", item, "isDir")
-            d.putCallItem("isExecutable", item, "isExecutable")
-            d.putCallItem("isFile", item, "isFile")
-            d.putCallItem("isHidden", item, "isHidden")
-            d.putCallItem("isReadable", item, "isReadable")
-            d.putCallItem("isRelative", item, "isRelative")
-            d.putCallItem("isRoot", item, "isRoot")
-            d.putCallItem("isSymLink", item, "isSymLink")
-            d.putCallItem("isWritable", item, "isWritable")
-            d.putCallItem("created", item, "created")
-            d.putCallItem("lastModified", item, "lastModified")
-            d.putCallItem("lastRead", item, "lastRead")
-
-
-def qdump__QFixed(d, item):
-    v = int(item.value["val"])
+            d.putCallItem("caching", value, "caching")
+            d.putCallItem("exists", value, "exists")
+            d.putCallItem("isAbsolute", value, "isAbsolute")
+            d.putCallItem("isDir", value, "isDir")
+            d.putCallItem("isExecutable", value, "isExecutable")
+            d.putCallItem("isFile", value, "isFile")
+            d.putCallItem("isHidden", value, "isHidden")
+            d.putCallItem("isReadable", value, "isReadable")
+            d.putCallItem("isRelative", value, "isRelative")
+            d.putCallItem("isRoot", value, "isRoot")
+            d.putCallItem("isSymLink", value, "isSymLink")
+            d.putCallItem("isWritable", value, "isWritable")
+            d.putCallItem("created", value, "created")
+            d.putCallItem("lastModified", value, "lastModified")
+            d.putCallItem("lastRead", value, "lastRead")
+
+
+def qdump__QFixed(d, value):
+    v = int(value["val"])
     d.putValue("%s/64 = %s" % (v, v/64.0))
     d.putNumChild(0)
 
@@ -325,23 +321,23 @@ def qdump__QFixed(d, item):
 #
 # i.e. there's something broken in stock 7.2 that is was ok in 7.1 and is ok later.
 
-def qdump__QFlags(d, item):
-    i = item.value["i"]
+def qdump__QFlags(d, value):
+    i = value["i"]
     try:
-        enumType = templateArgument(item.value.type.unqualified(), 0)
+        enumType = templateArgument(value.type.unqualified(), 0)
         d.putValue("%s (%s)" % (i.cast(enumType), i))
     except:
         d.putValue("%s" % i)
     d.putNumChild(0)
 
 
-def qdump__QHash(d, item):
+def qdump__QHash(d, value):
 
     def hashDataFirstNode(value):
-        value = value.cast(hashDataType)
-        bucket = value["buckets"]
-        e = value.cast(hashNodeType)
-        for n in xrange(value["numBuckets"] - 1, -1, -1):
+        val = value.cast(hashDataType)
+        bucket = val["buckets"]
+        e = val.cast(hashNodeType)
+        for n in xrange(val["numBuckets"] - 1, -1, -1):
             n = n - 1
             if n < 0:
                 break
@@ -364,11 +360,11 @@ def qdump__QHash(d, item):
             bucket += 1
         return node
 
-    keyType = templateArgument(item.value.type, 0)
-    valueType = templateArgument(item.value.type, 1)
+    keyType = templateArgument(value.type, 0)
+    valueType = templateArgument(value.type, 1)
 
-    d_ptr = item.value["d"]
-    e_ptr = item.value["e"]
+    d_ptr = value["d"]
+    e_ptr = value["e"]
     size = d_ptr["size"]
 
     hashDataType = d_ptr.type
@@ -379,53 +375,50 @@ def qdump__QHash(d, item):
 
     d.putItemCount(size)
     d.putNumChild(size)
-    if d.isExpanded(item):
+    if d.isExpanded():
         isSimpleKey = isSimpleType(keyType)
         isSimpleValue = isSimpleType(valueType)
-        node = hashDataFirstNode(item.value)
+        node = hashDataFirstNode(value)
         innerType = e_ptr.dereference().type
         childType = innerType
         if isSimpleKey and isSimpleValue:
             childType = isSimpleValue
-        with Children(d, [size, 1000], childType):
+        with Children(d, size, maxNumChild=1000, childType=childType):
             for i in d.childRange():
                 it = node.dereference().cast(innerType)
-                with SubItem(d):
+                with SubItem(d, i):
                     key = it["key"]
-                    value = it["value"]
+                    val = it["value"]
                     if isSimpleKey and isSimpleValue:
                         d.putName(key)
-                        d.putItem(Item(value, item.iname, i))
+                        d.putItem(val)
                         d.putType(valueType)
                     else:
-                        d.putItem(Item(it, item.iname, i))
+                        d.putItem(it)
                 node = hashDataNextNode(node)
 
 
-def qdump__QHashNode(d, item):
-    keyType = templateArgument(item.value.type, 0)
-    valueType = templateArgument(item.value.type, 1)
-    key = item.value["key"]
-    value = item.value["value"]
+def qdump__QHashNode(d, value):
+    keyType = templateArgument(value.type, 0)
+    valueType = templateArgument(value.type, 1)
+    key = value["key"]
+    val = value["value"]
 
     if isSimpleType(keyType) and isSimpleType(valueType):
-        d.putItem(Item(value, "data", item.iname))
+        d.putName(key)
+        d.putValue(val)
     else:
         d.putValue(" ")
 
     d.putNumChild(2)
-    if d.isExpanded(item):
+    if d.isExpanded():
         with Children(d):
-            with SubItem(d):
-                d.putName("key")
-                d.putItem(Item(key, item.iname, "key"))
-            with SubItem(d):
-                d.putName("value")
-                d.putItem(Item(value, item.iname, "value"))
+            d.putSubItem("key", key)
+            d.putSubItem("value", val)
 
 
-def qdump__QHostAddress(d, item):
-    data = item.value["d"]["d"].dereference()
+def qdump__QHostAddress(d, value):
+    data = value["d"]["d"].dereference()
     if int(data["ipString"]["d"]["size"]):
         d.putStringValue(data["ipString"])
     else:
@@ -436,13 +429,13 @@ def qdump__QHostAddress(d, item):
         a, n1 = divmod(a, 256)
         d.putValue("%d.%d.%d.%d" % (n1, n2, n3, n4));
     d.putNumChild(1)
-    if d.isExpanded(item):
+    if d.isExpanded():
         with Children(d):
-           d.putFields(Item(data, item.iname))
+           d.putFields(data)
 
 
-def qdump__QList(d, item):
-    d_ptr = item.value["d"]
+def qdump__QList(d, value):
+    d_ptr = value["d"]
     begin = d_ptr["begin"]
     end = d_ptr["end"]
     array = d_ptr["array"]
@@ -455,7 +448,7 @@ def qdump__QList(d, item):
     checkRef(d_ptr["ref"])
 
     # Additional checks on pointer arrays.
-    innerType = templateArgument(item.value.type, 0)
+    innerType = templateArgument(value.type, 0)
     innerTypeIsPointer = innerType.code == gdb.TYPE_CODE_PTR \
         and str(innerType.target().unqualified()) != "char"
     if innerTypeIsPointer:
@@ -464,7 +457,7 @@ def qdump__QList(d, item):
 
     d.putItemCount(size)
     d.putNumChild(size)
-    if d.isExpanded(item):
+    if d.isExpanded():
         innerSize = innerType.sizeof
         # The exact condition here is:
         #  QTypeInfo<T>::isLarge || QTypeInfo<T>::isStatic
@@ -480,27 +473,25 @@ def qdump__QList(d, item):
         else:
             inner = innerType
         # about 0.5s / 1000 items
-        with Children(d, [size, 2000], inner):
+        with Children(d, size, maxNumChild=2000, childType=inner):
             for i in d.childRange():
                 if isInternal:
-                    pp = p.cast(innerTypePointer).dereference();
-                    d.putSubItem(Item(pp, item.iname, i))
+                    d.putSubItem(i, p.cast(innerTypePointer).dereference())
                 else:
-                    pp = p.cast(innerTypePointer.pointer()).dereference()
-                    d.putSubItem(Item(pp, item.iname, i))
+                    d.putSubItem(i, p.cast(innerTypePointer.pointer()).dereference())
                 p += 1
 
 def qform__QImage():
     return "Normal,Displayed"
 
-def qdump__QImage(d, item):
+def qdump__QImage(d, value):
     try:
-        painters = item.value["painters"]
+        painters = value["painters"]
     except:
-        d.putPlainChildren(item)
+        d.putPlainChildren(value)
         return
     check(0 <= painters and painters < 1000)
-    d_ptr = item.value["d"]
+    d_ptr = value["d"]
     if isNull(d_ptr):
         d.putValue("(null)")
     else:
@@ -510,14 +501,13 @@ def qdump__QImage(d, item):
     nbytes = d_ptr["nbytes"]
     d.putNumChild(0)
     #d.putNumChild(1)
-    if d.isExpanded(item):
+    if d.isExpanded():
         with Children(d):
-            with SubItem(d):
-                d.putName("data")
+            with SubItem(d, "data"):
                 d.putNoType()
                 d.putNumChild(0)
                 d.putValue("size: %s bytes" % nbytes);
-    format = d.itemFormat(item)
+    format = d.currentItemFormat()
     if format == 1:
         d.putDisplay(StopDisplay)
     elif format == 2:
@@ -545,25 +535,25 @@ def qdump__QImage(d, item):
                 % (d_ptr["width"], d_ptr["height"], d_ptr["format"], filename))
 
 
-def qdump__QLinkedList(d, item):
-    d_ptr = item.value["d"]
-    e_ptr = item.value["e"]
+def qdump__QLinkedList(d, value):
+    d_ptr = value["d"]
+    e_ptr = value["e"]
     n = d_ptr["size"]
     check(0 <= n and n <= 100*1000*1000)
     checkRef(d_ptr["ref"])
     d.putItemCount(n)
     d.putNumChild(n)
-    if d.isExpanded(item):
-        innerType = templateArgument(item.value.type, 0)
-        with Children(d, [n, 1000], innerType):
+    if d.isExpanded():
+        innerType = templateArgument(value.type, 0)
+        with Children(d, n, maxNumChild=1000, childType=innerType):
             p = e_ptr["n"]
             for i in d.childRange():
-                d.putSubItem(Item(p["t"], item.iname, i))
+                d.putSubItem(i, p["t"])
                 p = p["n"]
 
 qqLocalesCount = None
 
-def qdump__QLocale(d, item):
+def qdump__QLocale(d, value):
     # Check for uninitialized 'index' variable. Retrieve size of QLocale data array
     # from variable in qlocale.cpp (default: 368/Qt 4.8), 368 being 'System'.
     global qqLocalesCount
@@ -572,58 +562,54 @@ def qdump__QLocale(d, item):
             qqLocalesCount = int(value(qtNamespace() + 'locale_data_size'))
         except:
             qqLocalesCount = 368
-    index = int(item.value["p"]["index"])
+    index = int(value["p"]["index"])
     check(index >= 0 and index <= qqLocalesCount)
-    d.putStringValue(call(item.value, "name"))
+    d.putStringValue(call(value, "name"))
     d.putNumChild(0)
     return
     # FIXME: Poke back for variants.
-    if d.isExpanded(item):
-        with Children(d, 1, lookupType(d.ns + "QChar"), 0):
-            d.putCallItem("country", item, "country")
-            d.putCallItem("language", item, "language")
-            d.putCallItem("measurementSystem", item, "measurementSystem")
-            d.putCallItem("numberOptions", item, "numberOptions")
-            d.putCallItem("timeFormat_(short)", item,
+    if d.isExpanded():
+        with Children(d, childType=lookupType(d.ns + "QChar"), childNumChild=0):
+            d.putCallItem("country", value, "country")
+            d.putCallItem("language", value, "language")
+            d.putCallItem("measurementSystem", value, "measurementSystem")
+            d.putCallItem("numberOptions", value, "numberOptions")
+            d.putCallItem("timeFormat_(short)", value,
                 "timeFormat", d.ns + "QLocale::ShortFormat")
-            d.putCallItem("timeFormat_(long)", item,
+            d.putCallItem("timeFormat_(long)", value,
                 "timeFormat", d.ns + "QLocale::LongFormat")
-            d.putCallItem("decimalPoint", item, "decimalPoint")
-            d.putCallItem("exponential", item, "exponential")
-            d.putCallItem("percent", item, "percent")
-            d.putCallItem("zeroDigit", item, "zeroDigit")
-            d.putCallItem("groupSeparator", item, "groupSeparator")
-            d.putCallItem("negativeSign", item, "negativeSign")
+            d.putCallItem("decimalPoint", value, "decimalPoint")
+            d.putCallItem("exponential", value, "exponential")
+            d.putCallItem("percent", value, "percent")
+            d.putCallItem("zeroDigit", value, "zeroDigit")
+            d.putCallItem("groupSeparator", value, "groupSeparator")
+            d.putCallItem("negativeSign", value, "negativeSign")
 
 
-def qdump__QMapNode(d, item):
+def qdump__QMapNode(d, value):
     d.putValue(" ")
     d.putNumChild(2)
-    if d.isExpanded(item):
-        with Children(d, 2):
-            with SubItem(d):
-                d.putName("key")
-                d.putItem(Item(item.value["key"], item.iname, "name"))
-            with SubItem(d):
-                d.putName("value")
-                d.putItem(Item(item.value["value"], item.iname, "value"))
-
-
-def qdumpHelper__QMap(d, item, forceLong):
-    d_ptr = item.value["d"].dereference()
-    e_ptr = item.value["e"].dereference()
+    if d.isExpanded():
+        with Children(d):
+            d.putSubItem("key", value["key"])
+            d.putSubItem("value", value["value"])
+
+
+def qdumpHelper__QMap(d, value, forceLong):
+    d_ptr = value["d"].dereference()
+    e_ptr = value["e"].dereference()
     n = d_ptr["size"]
     check(0 <= n and n <= 100*1000*1000)
     checkRef(d_ptr["ref"])
 
     d.putItemCount(n)
     d.putNumChild(n)
-    if d.isExpanded(item):
+    if d.isExpanded():
         if n > 1000:
             n = 1000
 
-        keyType = templateArgument(item.value.type, 0)
-        valueType = templateArgument(item.value.type, 1)
+        keyType = templateArgument(value.type, 0)
+        valueType = templateArgument(value.type, 1)
 
         isSimpleKey = isSimpleType(keyType)
         isSimpleValue = isSimpleType(valueType)
@@ -642,33 +628,33 @@ def qdumpHelper__QMap(d, item, forceLong):
         else:
             innerType = nodeType
 
-        with Children(d, n, innerType):
+        with Children(d, n, childType=innerType):
             for i in xrange(n):
                 itd = it.dereference()
                 base = it.cast(charPtr) - payloadSize
                 node = base.cast(nodeType.pointer()).dereference()
-                with SubItem(d):
+                with SubItem(d, i):
                     key = node["key"]
-                    value = node["value"]
-                    #if isSimpleType(item.value.type):
-                    # or isStringType(d, item.value.type):
+                    val = node["value"]
+                    #if isSimpleType(value.type):
+                    # or isStringType(d, value.type):
                     if isSimpleKey and isSimpleValue:
                         #d.putType(valueType)
                         if forceLong:
                             d.putName("[%s] %s" % (i, key))
                         else:
                             d.putName(key)
-                        d.putItem(Item(value, item.iname, i))
+                        d.putItem(val)
                     else:
-                        d.putItem(Item(node, item.iname, i))
+                        d.putItem(node)
                 it = it.dereference()["forward"].dereference()
 
 
-def qdump__QMap(d, item):
-    qdumpHelper__QMap(d, item, False)
+def qdump__QMap(d, value):
+    qdumpHelper__QMap(d, value, False)
 
-def qdump__QMultiMap(d, item):
-    qdumpHelper__QMap(d, item, True)
+def qdump__QMultiMap(d, value):
+    qdumpHelper__QMap(d, value, True)
 
 
 def extractCString(table, offset):
@@ -682,17 +668,17 @@ def extractCString(table, offset):
     return result
 
 
-def qdump__QObject(d, item):
-    #warn("OBJECT: %s " % item.value)
+def qdump__QObject(d, value):
+    #warn("OBJECT: %s " % value)
     try:
         privateTypeName = d.ns + "QObjectPrivate"
         privateType = lookupType(privateTypeName)
-        staticMetaObject = item.value["staticMetaObject"]
-        d_ptr = item.value["d_ptr"]["d"].cast(privateType.pointer()).dereference()
+        staticMetaObject = value["staticMetaObject"]
+        d_ptr = value["d_ptr"]["d"].cast(privateType.pointer()).dereference()
         #warn("D_PTR: %s " % d_ptr)
         objectName = d_ptr["objectName"]
     except:
-        d.putPlainChildren(item)
+        d.putPlainChildren(value)
         return
     #warn("SMO: %s " % staticMetaObject)
     #warn("SMO DATA: %s " % staticMetaObject["d"]["stringdata"])
@@ -704,10 +690,10 @@ def qdump__QObject(d, item):
 
     if privateType is None:
         d.putNumChild(4)
-        #d.putValue(cleanAddress(item.value.address))
-        if d.isExpanded(item):
+        #d.putValue(cleanAddress(value.address))
+        if d.isExpanded():
             with Children(d):
-                d.putFields(item)
+                d.putFields(value)
         return
     #warn("OBJECTNAME: %s " % objectName)
     #warn("D_PTR: %s " % d_ptr)
@@ -721,39 +707,36 @@ def qdump__QObject(d, item):
     #extradata = mo["d"]["extradata"]   # Capitalization!
     #warn("METADATA: %s " % metaData)
     #warn("STRINGDATA: %s " % metaStringData)
-    #warn("TYPE: %s " % item.value.type)
-    #warn("INAME: %s " % item.iname)
+    #warn("TYPE: %s " % value.type)
+    #warn("INAME: %s " % d.currentIName())
     #d.putValue("")
     d.putStringValue(objectName)
     #QSignalMapper::staticMetaObject
     #checkRef(d_ptr["ref"])
     d.putNumChild(4)
-    if d.isExpanded(item):
+    if d.isExpanded():
       with Children(d):
 
-        # Local data
+        # Local data.
         if privateTypeName != d.ns + "QObjectPrivate":
             if not privateType is None:
-              with SubItem(d):
-                d.putName("data")
+              with SubItem(d, "data"):
                 d.putValue(" ")
                 d.putNoType()
                 d.putNumChild(1)
-                iname = item.iname + ".data"
-                if d.isExpandedIName(iname):
+                if d.isExpanded():
                     with Children(d):
-                        child = Item(d_ptr, iname)
-                        d.putFields(child, False)
+                        d.putFields(d_ptr, False)
 
 
-        d.putFields(item)
+        d.putFields(value)
         # Parent and children.
-        if stripClassTag(str(item.value.type)) == d.ns + "QObject":
-            d.putSubItem(Item(d_ptr["parent"], item.iname, "parent", "parent"))
-            d.putSubItem(Item(d_ptr["children"], item.iname, "children", "children"))
+        if stripClassTag(str(value.type)) == d.ns + "QObject":
+            d.putSubItem("parent", d_ptr["parent"])
+            d.putSubItem("children", d_ptr["children"])
 
         # Properties.
-        with SubItem(d):
+        with SubItem(d, "properties"):
             # Prolog
             extraData = d_ptr["extraData"]   # Capitalization!
             if isNull(extraData):
@@ -776,12 +759,11 @@ def qdump__QObject(d, item):
             #warn("PROPERTY COUNT: %s" % staticPropertyCount)
             propertyCount = staticPropertyCount + dynamicPropertyCount
 
-            d.putName("properties")
             d.putNoType()
             d.putItemCount(propertyCount)
             d.putNumChild(propertyCount)
 
-            if d.isExpandedIName(item.iname + ".properties"):
+            if d.isExpanded():
                 # FIXME: Make this global. Don't leak.
                 variant = "'%sQVariant'" % d.ns
                 # Avoid malloc symbol clash with QVector
@@ -789,7 +771,7 @@ def qdump__QObject(d, item):
                     % (variant, variant))
                 gdb.execute("set $d.d.is_shared = 0")
 
-                with Children(d, [propertyCount, 500]):
+                with Children(d):
                     # Dynamic properties.
                     if dynamicPropertyCount != 0:
                         dummyType = lookupType("void").pointer().pointer()
@@ -801,7 +783,7 @@ def qdump__QObject(d, item):
                         p = namesArray.cast(dummyType) + namesBegin
                         q = valuesArray.cast(dummyType) + valuesBegin
                         for i in xrange(dynamicPropertyCount):
-                            with SubItem(d):
+                            with SubItem(d, i):
                                 pp = p.cast(namesType.pointer()).dereference();
                                 d.putField("key", encodeByteArray(pp))
                                 d.putField("keyencoded", Hex2EncodedLatin1)
@@ -810,9 +792,8 @@ def qdump__QObject(d, item):
                                 d.putField("addr", cleanAddress(qq))
                                 d.putField("exp", "*(%s*)%s"
                                      % (variant, cleanAddress(qq)))
-                                name = "%s.properties.%d" % (item.iname, i)
-                                t = qdump__QVariant(d, Item(qq, name))
-                                # Override the "QVariant (foo)" output
+                                t = qdump__QVariant(d, qq)
+                                # Override the "QVariant (foo)" output.
                                 d.putBetterType(t)
                             p += 1
                             q += 1
@@ -821,66 +802,60 @@ def qdump__QObject(d, item):
                     propertyData = metaData[7]
                     for i in xrange(staticPropertyCount):
                       with NoAddress(d):
-                        with SubItem(d):
-                            offset = propertyData + 3 * i
-                            propertyName = extractCString(metaStringData,
-                                                          metaData[offset])
-                            propertyType = extractCString(metaStringData,
-                                                          metaData[offset + 1])
-                            d.putName(propertyName)
+                        offset = propertyData + 3 * i
+                        propertyName = extractCString(metaStringData,
+                                                      metaData[offset])
+                        propertyType = extractCString(metaStringData,
+                                                      metaData[offset + 1])
+                        with SubItem(d, propertyName):
                             #flags = metaData[offset + 2]
                             #warn("FLAGS: %s " % flags)
                             #warn("PROPERTY: %s %s " % (propertyType, propertyName))
                             # #exp = '((\'%sQObject\'*)%s)->property("%s")' \
-                            #     % (d.ns, item.value.address, propertyName)
+                            #     % (d.ns, value.address, propertyName)
                             #exp = '"((\'%sQObject\'*)%s)"' %
-                            #(d.ns, item.value.address,)
+                            #(d.ns, value.address,)
                             #warn("EXPRESSION:  %s" % exp)
-                            value = call(item.value, "property",
+                            prop = call(value, "property",
                                 str(cleanAddress(metaStringData + metaData[offset])))
-                            value1 = value["d"]
+                            value1 = prop["d"]
                             #warn("   CODE: %s" % value1["type"])
                             # Type 1 and 2 are bool and int.
                             # Try to save a few cycles in this case:
                             if int(value1["type"]) > 2:
-                                # Poke back value
+                                # Poke back prop
                                 gdb.execute("set $d.d.data.ull = %s"
                                         % value1["data"]["ull"])
                                 gdb.execute("set $d.d.type = %s"
                                         % value1["type"])
                                 gdb.execute("set $d.d.is_null = %s"
                                         % value1["is_null"])
-                                value = parseAndEvaluate("$d").dereference()
+                                prop = parseAndEvaluate("$d").dereference()
                             val, inner, innert, handled = \
-                                qdumpHelper__QVariant(d, value)
+                                qdumpHelper__QVariant(d, prop)
 
                             if handled:
                                 pass
                             elif len(inner):
                                 # Build-in types.
                                 d.putType(inner)
-                                name = "%s.properties.%d" \
-                                    % (item.iname, i + dynamicPropertyCount)
-                                d.putItem(Item(val, item.iname + ".properties",
-                                                    propertyName, propertyName))
-
+                                d.putItem(val)
                             else:
                                 # User types.
                            #    func = "typeToName(('%sQVariant::Type')%d)"
                            #       % (d.ns, variantType)
-                           #    type = str(call(item.value, func))
+                           #    type = str(call(value, func))
                            #    type = type[type.find('"') + 1 : type.rfind('"')]
                            #    type = type.replace("Q", d.ns + "Q") # HACK!
-                           #    data = call(item.value, "constData")
+                           #    data = call(value, "constData")
                            #    tdata = data.cast(lookupType(type).pointer())
                            #      .dereference()
                            #    d.putValue("(%s)" % tdata.type)
                            #    d.putType(tdata.type)
                            #    d.putNumChild(1)
-                           #    if d.isExpanded(item):
+                           #    if d.isExpanded():
                            #        with Children(d):
-                           #           d.putSubItem(Item(tdata, item.iname,
-                           #             "data", "data"))
+                           #           d.putSubItem("data", tdata)
                                 warn("FIXME: CUSTOM QOBJECT PROPERTY: %s %s"
                                     % (propertyType, innert))
                                 d.putType(propertyType)
@@ -888,8 +863,7 @@ def qdump__QObject(d, item):
                                 d.putNumChild(0)
 
         # Connections.
-        with SubItem(d):
-            d.putName("connections")
+        with SubItem(d, "connections"):
             d.putNoType()
             connections = d_ptr["connectionLists"]
             connectionListCount = 0
@@ -897,7 +871,7 @@ def qdump__QObject(d, item):
                 connectionListCount = connections["d"]["size"]
             d.putItemCount(connectionListCount, 0)
             d.putNumChild(connectionListCount)
-            if d.isExpandedIName(item.iname + ".connections"):
+            if d.isExpanded():
                 with Children(d):
                     vectorType = connections.type.target().fields()[0].type
                     innerType = templateArgument(vectorType, 0)
@@ -907,8 +881,7 @@ def qdump__QObject(d, item):
                     for i in xrange(connectionListCount):
                         first = p.dereference()["first"]
                         while not isNull(first):
-                            d.putSubItem(Item(first.dereference(),
-                                item.iname + ".connections", pp))
+                            d.putSubItem(i, first.dereference())
                             first = first["next"]
                             # We need to enforce some upper limit.
                             pp += 1
@@ -917,10 +890,9 @@ def qdump__QObject(d, item):
                         p += 1
 
 
-        # Signals
+        # Signals.
         signalCount = metaData[13]
-        with SubItem(d):
-            d.putName("signals")
+        with SubItem(d, "signals"):
             d.putItemCount(signalCount)
             d.putNoType()
             d.putNumChild(signalCount)
@@ -928,42 +900,37 @@ def qdump__QObject(d, item):
                 # FIXME: empty type does not work for childtype
                 #d.putField("childtype", ".")
                 d.putField("childnumchild", "0")
-            if d.isExpandedIName(item.iname + ".signals"):
+            if d.isExpanded():
                 with Children(d):
                     for signal in xrange(signalCount):
-                        with SubItem(d):
+                        with SubItem(d, signal):
                             offset = metaData[14 + 5 * signal]
-                            d.putField("iname", "%s.signals.%d"
-                                % (item.iname, signal))
                             d.putName("signal %d" % signal)
                             d.putNoType()
                             d.putValue(extractCString(metaStringData, offset))
                             d.putNumChild(0)  # FIXME: List the connections here.
 
-        # Slots
-        with SubItem(d):
+        # Slots.
+        with SubItem(d, "slots"):
             slotCount = metaData[4] - signalCount
-            d.putName("slots")
             d.putItemCount(slotCount)
             d.putNoType()
             d.putNumChild(slotCount)
             if slotCount:
                 #d.putField("childtype", ".")
                 d.putField("childnumchild", "0")
-            if d.isExpandedIName(item.iname + ".slots"):
+            if d.isExpanded():
                 with Children(d):
                     for slot in xrange(slotCount):
-                        with SubItem(d):
+                        with SubItem(d, slot):
                             offset = metaData[14 + 5 * (signalCount + slot)]
-                            d.putField("iname", "%s.slots.%d" % (item.iname, slot))
                             d.putName("slot %d" % slot)
                             d.putNoType()
                             d.putValue(extractCString(metaStringData, offset))
                             d.putNumChild(0)  # FIXME: List the connections here.
 
-        # Active connection
-        with SubItem(d):
-            d.putName("currentSender")
+        # Active connection.
+        with SubItem(d, "currentSender"):
             d.putNoType()
             sender = d_ptr["currentSender"]
             d.putValue(cleanAddress(sender))
@@ -971,14 +938,12 @@ def qdump__QObject(d, item):
                 d.putNumChild(0)
             else:
                 d.putNumChild(1)
-                iname = item.iname + ".currentSender"
-                if d.isExpandedIName(iname):
+                if d.isExpanded():
                     with Children(d):
                         # Sending object
-                        d.putSubItem(Item(sender["sender"], iname, "object", "object"))
+                        d.putSubItem("object", sender["sender"])
                         # Signal in sending object
-                        with SubItem(d):
-                            d.putName("signal")
+                        with SubItem(d, "signal"):
                             d.putValue(sender["signal"])
                             d.putNoType()
                             d.putNumChild(0)
@@ -1082,39 +1047,6 @@ def qdump__QObject(d, item):
 
 
 
-# static const char *sizePolicyEnumValue(QSizePolicy::Policy p)
-# {
-#     switch (p) {
-#     case QSizePolicy::Fixed:
-#         return "Fixed"
-#     case QSizePolicy::Minimum:
-#         return "Minimum"
-#     case QSizePolicy::Maximum:
-#         return "Maximum"
-#     case QSizePolicy::Preferred:
-#         return "Preferred"
-#     case QSizePolicy::Expanding:
-#         return "Expanding"
-#     case QSizePolicy::MinimumExpanding:
-#         return "MinimumExpanding"
-#     case QSizePolicy::Ignored:
-#         break
-#     }
-#     return "Ignored"
-# }
-#
-# static QString sizePolicyValue(const QSizePolicy &sp)
-# {
-#     QString rc
-#     QTextStream str(&rc)
-#     // Display as in Designer
-#     str << '[' << sizePolicyEnumValue(sp.horizontalPolicy())
-#         << ", " << sizePolicyEnumValue(sp.verticalPolicy())
-#         << ", " << sp.horizontalStretch() << ", " << sp.verticalStretch() << ']'
-#     return rc
-# }
-# #endif
-#
 # // Meta enumeration helpers
 # static inline void dumpMetaEnumType(QDumper &d, const QMetaEnum &me)
 # {
@@ -1152,10 +1084,10 @@ def qdump__QObject(d, item):
 #     d.putNumChild(0)
 # }
 
-def qdump__QPixmap(d, item):
-    painters = item.value["painters"]
+def qdump__QPixmap(d, value):
+    painters = value["painters"]
     check(0 <= painters and painters < 1000)
-    d_ptr = item.value["data"]["d"]
+    d_ptr = value["data"]["d"]
     if isNull(d_ptr):
         d.putValue("(null)")
     else:
@@ -1164,52 +1096,48 @@ def qdump__QPixmap(d, item):
     d.putNumChild(0)
 
 
-def qdump__QPoint(d, item):
-    x = item.value["xp"]
-    y = item.value["yp"]
+def qdump__QPoint(d, value):
+    x = value["xp"]
+    y = value["yp"]
     # should not be needed, but sometimes yield myns::QVariant::Private::Data::qreal
     x = x.cast(x.type.strip_typedefs())
     y = y.cast(y.type.strip_typedefs())
     d.putValue("(%s, %s)" % (x, y))
     d.putNumChild(2)
-    if d.isExpanded(item):
-        with Children(d, 2, x.type.strip_typedefs()):
-            d.putSubItem(Item(x, None, None, "x"))
-            d.putSubItem(Item(y, None, None, "y"))
+    if d.isExpanded():
+        with Children(d):
+            d.putFields(value)
 
 
-def qdump__QPointF(d, item):
-    qdump__QPoint(d, item)
+def qdump__QPointF(d, value):
+    qdump__QPoint(d, value)
 
 
-def qdump__QRect(d, item):
+def qdump__QRect(d, value):
     def pp(l):
         if l >= 0: return "+%s" % l
         return l
-    x1 = item.value["x1"]
-    y1 = item.value["y1"]
-    x2 = item.value["x2"]
-    y2 = item.value["y2"]
+    x1 = value["x1"]
+    y1 = value["y1"]
+    x2 = value["x2"]
+    y2 = value["y2"]
     w = x2 - x1 + 1
     h = y2 - y1 + 1
     d.putValue("%sx%s%s%s" % (w, h, pp(x1), pp(y1)))
     d.putNumChild(4)
-    if d.isExpanded(item):
-        with Children(d, 4, x1.type.strip_typedefs()):
-            d.putSubItem(Item(x1, None, None, "x1"))
-            d.putSubItem(Item(y1, None, None, "y1"))
-            d.putSubItem(Item(x2, None, None, "x2"))
-            d.putSubItem(Item(y2, None, None, "y2"))
+    if d.isExpanded():
+        with Children(d):
+            d.putFields(value)
 
 
-def qdump__QRectF(d, item):
+def qdump__QRectF(d, value):
     def pp(l):
         if l >= 0: return "+%s" % l
         return l
-    x = item.value["xp"]
-    y = item.value["yp"]
-    w = item.value["w"]
-    h = item.value["h"]
+    x = value["xp"]
+    y = value["yp"]
+    w = value["w"]
+    h = value["h"]
     # FIXME: workaround, see QPoint
     x = x.cast(x.type.strip_typedefs())
     y = y.cast(y.type.strip_typedefs())
@@ -1217,29 +1145,26 @@ def qdump__QRectF(d, item):
     h = h.cast(h.type.strip_typedefs())
     d.putValue("%sx%s%s%s" % (w, h, pp(x), pp(y)))
     d.putNumChild(4)
-    if d.isExpanded(item):
-        with Children(d, 4, x.type.strip_typedefs()):
-            d.putSubItem(Item(x, None, None, "x"))
-            d.putSubItem(Item(y, None, None, "y"))
-            d.putSubItem(Item(w, None, None, "w"))
-            d.putSubItem(Item(h, None, None, "h"))
+    if d.isExpanded():
+        with Children(d):
+            d.putFields(value)
 
 
-def qdump__QRegExp(d, item):
-    d.putStringValue(item.value["priv"]["engineKey"]["pattern"])
+def qdump__QRegExp(d, value):
+    d.putStringValue(value["priv"]["engineKey"]["pattern"])
     d.putNumChild(1)
-    if d.isExpanded(item):
-        with Children(d, 1):
+    if d.isExpanded():
+        with Children(d):
             # FIXME: Remove need to call
-            call(item.value, "capturedTexts") # create cache
-            caps = item.value["priv"]["capturedCache"]
-            syntax = item.value["priv"]["engineKey"]["patternSyntax"]
-            d.putSubItem(Item(syntax, None, None, "syntax"))
-            d.putSubItem(Item(caps, item.iname, "captures", "captures"))
+            call(value, "capturedTexts") # create cache
+            with SubItem(d, "syntax"):
+                d.putItem(value["priv"]["engineKey"]["patternSyntax"])
+            with SubItem(d, "captures"):
+                d.putItem(value["priv"]["capturedCache"])
 
 
-def qdump__QRegion(d, item):
-    p = item.value["d"].dereference()["qt_rgn"]
+def qdump__QRegion(d, value):
+    p = value["d"].dereference()["qt_rgn"]
     if isNull(p):
         d.putValue("<empty>")
         d.putNumChild(0)
@@ -1249,35 +1174,36 @@ def qdump__QRegion(d, item):
             n = int(p.dereference()["numRects"])
             d.putItemCount(n)
             d.putNumChild(n)
-            if d.isExpanded(item):
+            if d.isExpanded():
                 with Children(d):
-                    d.putFields(Item(p.dereference(), item.iname))
+                    d.putFields(p.dereference())
         except:
+            warn("NO DEBUG INFO")
             d.putValue(p)
-            d.putPlainChildren(item)
+            d.putPlainChildren(value)
 
 # qt_rgn might be 0
 # gdb.parse_and_eval("region")["d"].dereference()["qt_rgn"].dereference()
 
-def qdump__QScopedPointer(d, item):
+def qdump__QScopedPointer(d, value):
     d.putBetterType(d.currentType)
-    d.putItem(Item(item.value["d"], item.iname, None, None))
+    d.putItem(value["d"])
 
 
-def qdump__QSet(d, item):
+def qdump__QSet(d, value):
 
     def hashDataFirstNode(value):
-        value = value.cast(hashDataType)
-        bucket = value["buckets"]
+        val = value.cast(hashDataType)
+        bucket = val["buckets"]
         e = value.cast(hashNodeType)
-        for n in xrange(value["numBuckets"] - 1, -1, -1):
+        for n in xrange(val["numBuckets"] - 1, -1, -1):
             n = n - 1
             if n < 0:
                 break
             if bucket.dereference() != e:
                 return bucket.dereference()
             bucket = bucket + 1
-        return e;
+        return e
 
     def hashDataNextNode(node):
         next = node["next"]
@@ -1293,10 +1219,10 @@ def qdump__QSet(d, item):
             bucket += 1
         return node
 
-    keyType = templateArgument(item.value.type, 0)
+    keyType = templateArgument(value.type, 0)
 
-    d_ptr = item.value["q_hash"]["d"]
-    e_ptr = item.value["q_hash"]["e"]
+    d_ptr = value["q_hash"]["d"]
+    e_ptr = value["q_hash"]["e"]
     size = d_ptr["size"]
 
     hashDataType = d_ptr.type
@@ -1307,30 +1233,31 @@ def qdump__QSet(d, item):
 
     d.putItemCount(size)
     d.putNumChild(size)
-    if d.isExpanded(item):
+    if d.isExpanded():
         isSimpleKey = isSimpleType(keyType)
-        node = hashDataFirstNode(item.value)
+        node = hashDataFirstNode(value)
         innerType = e_ptr.dereference().type
-        with Children(d, [size, 1000], keyType):
+        with Children(d, size, numChild=1000, childType=keyType):
             for i in xrange(size):
                 it = node.dereference().cast(innerType)
-                with SubItem(d):
+                with SubItem(d, i):
                     key = it["key"]
                     if isSimpleKey:
                         d.putType(keyType)
-                        d.putItem(Item(key, None, None))
+                        d.putItem(key)
+                        d.putName(key)
                     else:
-                        d.putItem(Item(key, item.iname, i))
+                        d.putItem(key)
                 node = hashDataNextNode(node)
 
 
-def qdump__QSharedData(d, item):
-    d.putValue("ref: %s" % item.value["ref"]["_q_value"])
+def qdump__QSharedData(d, value):
+    d.putValue("ref: %s" % value["ref"]["_q_value"])
     d.putNumChild(0)
 
 
-def qdump__QSharedDataPointer(d, item):
-    d_ptr = item.value["d"]
+def qdump__QSharedDataPointer(d, value):
+    d_ptr = value["d"]
     if isNull(d_ptr):
         d.putValue("(null)")
         d.putNumChild(0)
@@ -1338,45 +1265,44 @@ def qdump__QSharedDataPointer(d, item):
         # This replaces the pointer by the pointee, making the
         # pointer transparent.
         try:
-            innerType = templateArgument(item.value.type, 0)
+            innerType = templateArgument(value.type, 0)
         except:
             d.putValue(d_ptr)
-            d.putPlainChildren(item)
+            d.putPlainChildren(value)
             return
-        value = gdb.Value(d_ptr.cast(innerType.pointer()))
         d.putBetterType(d.currentType)
-        d.putItem(Item(value.dereference(), item.iname, None))
+        d.putItem(gdb.Value(d_ptr.cast(innerType.pointer())).dereference())
+        # d.putItem(value.dereference())
 
 
-def qdump__QSharedPointer(d, item):
-    qdump__QWeakPointer(d, item)
+def qdump__QSharedPointer(d, value):
+    qdump__QWeakPointer(d, value)
 
 
-def qdump__QSize(d, item):
-    w = item.value["wd"]
-    h = item.value["ht"]
+def qdump__QSize(d, value):
+    w = value["wd"]
+    h = value["ht"]
     d.putValue("(%s, %s)" % (w, h))
     d.putNumChild(2)
-    if d.isExpanded(item):
-        with Children(d, 2, w.type):
-            d.putSubItem(Item(w, item.iname, "w", "w"))
-            d.putSubItem(Item(h, item.iname, "h", "h"))
+    if d.isExpanded():
+        with Children(d):
+            d.putFields(value)
 
 
-def qdump__QSizeF(d, item):
-    qdump__QSize(d, item)
+def qdump__QSizeF(d, value):
+    qdump__QSize(d, value)
 
 
-def qdump__QStack(d, item):
-    qdump__QVector(d, item)
+def qdump__QStack(d, value):
+    qdump__QVector(d, value)
 
 
-def qdump__QStandardItem(d, item):
+def qdump__QStandardItem(d, value):
     d.putBetterType(d.currentType)
     try:
-        d.putItem(Item(item.value["d_ptr"], item.iname, None, None))
+        d.putItem(value["d_ptr"])
     except:
-        d.putPlainChildren(item)
+        d.putPlainChildren(value)
 
 
 def qedit__QString(expr, value):
@@ -1394,20 +1320,19 @@ def qedit__QString(expr, value):
 def qform__QString():
     return "Inline,Separate Window"
 
-def qdump__QString(d, item):
-    d.putStringValue(item.value)
+def qdump__QString(d, value):
+    d.putStringValue(value)
     d.putNumChild(0)
-    format = d.itemFormat(item)
+    format = d.currentItemFormat()
     if format == 1:
         d.putDisplay(StopDisplay)
     elif format == 2:
         d.putField("editformat", 2)
-        str = encodeString(item.value)
-        d.putField("editvalue", str)
+        d.putField("editvalue", encodeString(value))
 
 
-def qdump__QStringList(d, item):
-    d_ptr = item.value['d']
+def qdump__QStringList(d, value):
+    d_ptr = value['d']
     begin = d_ptr['begin']
     end = d_ptr['end']
     size = end - begin
@@ -1418,32 +1343,32 @@ def qdump__QStringList(d, item):
     checkRef(d_ptr["ref"])
     d.putItemCount(size)
     d.putNumChild(size)
-    if d.isExpanded(item):
+    if d.isExpanded():
         innerType = lookupType(d.ns + "QString")
         ptr = gdb.Value(d_ptr["array"]).cast(innerType.pointer())
         ptr += d_ptr["begin"]
-        with Children(d, [size, 1000], innerType):
+        with Children(d, size, maxNumChild=1000, childType=innerType):
             for i in d.childRange():
-                d.putSubItem(Item(ptr.dereference(), item.iname, i))
+                d.putSubItem(i, ptr.dereference())
                 ptr += 1
 
 
-def qdump__QTemporaryFile(d, item):
-    qdump__QFile(d, item)
+def qdump__QTemporaryFile(d, value):
+    qdump__QFile(d, value)
 
 
-def qdump__QTextCodec(d, item):
-    value = call(item.value, "name")
+def qdump__QTextCodec(d, value):
+    name = call(value, "name")
     d.putValue(encodeByteArray(value), 6)
     d.putNumChild(2)
-    if d.isExpanded(item):
+    if d.isExpanded():
         with Children(d):
-            d.putCallItem("name", item, "name")
-            d.putCallItem("mibEnum", item, "mibEnum")
+            d.putCallItem("name", name, "name")
+            d.putCallItem("mibEnum", name, "mibEnum")
 
 
-def qdump__QTextCursor(d, item):
-    dd = item.value["d"]["d"]
+def qdump__QTextCursor(d, value):
+    dd = value["d"]["d"]
     if isNull(dd):
         d.putValue("(invalid)")
         d.putNumChild(0)
@@ -1452,40 +1377,39 @@ def qdump__QTextCursor(d, item):
             p = dd.dereference()
             d.putValue(p["position"])
         except:
-            d.putPlainChildren(item)
+            d.putPlainChildren(value)
             return
         d.putNumChild(1)
-        if d.isExpanded(item):
+        if d.isExpanded():
             with Children(d):
                 d.putIntItem("position", p["position"])
                 d.putIntItem("anchor", p["anchor"])
-                d.putCallItem("selected", item, "selectedText")
+                d.putCallItem("selected", value, "selectedText")
 
 
-def qdump__QTextDocument(d, item):
+def qdump__QTextDocument(d, value):
     d.putValue(" ")
     d.putNumChild(1)
-    if d.isExpanded(item):
+    if d.isExpanded():
         with Children(d):
-            d.putCallItem("blockCount", item, "blockCount")
-            d.putCallItem("characterCount", item, "characterCount")
-            d.putCallItem("lineCount", item, "lineCount")
-            d.putCallItem("revision", item, "revision")
-            d.putCallItem("toPlainText", item, "toPlainText")
+            d.putCallItem("blockCount", value, "blockCount")
+            d.putCallItem("characterCount", value, "characterCount")
+            d.putCallItem("lineCount", value, "lineCount")
+            d.putCallItem("revision", value, "revision")
+            d.putCallItem("toPlainText", value, "toPlainText")
 
 
-def qdump__QUrl(d, item):
+def qdump__QUrl(d, value):
     try:
-        data = item.value["d"].dereference()
+        data = value["d"].dereference()
         d.putByteArrayValue(data["encodedOriginal"])
     except:
-        d.putPlainChildren(item)
+        d.putPlainChildren(value)
         return
     d.putNumChild(1)
-    if d.isExpanded(item):
+    if d.isExpanded():
         with Children(d):
-           d.putFields(Item(data, item.iname))
-
+           d.putFields(data)
 
 
 def qdumpHelper_QVariant_0(d, data):
@@ -1633,11 +1557,11 @@ def qdumpHelper__QVariant(d, value):
     return (val, inner, innert, False)
 
 
-def qdump__QVariant(d, item):
-    d_ptr = item.value["d"]
+def qdump__QVariant(d, value):
+    d_ptr = value["d"]
     d_data = d_ptr["data"]
 
-    (val, inner, innert, handled) = qdumpHelper__QVariant(d, item.value)
+    (val, inner, innert, handled) = qdumpHelper__QVariant(d, value)
 
     if handled:
         return
@@ -1650,29 +1574,28 @@ def qdump__QVariant(d, item):
         else:
             v = d_data.cast(innerType)
         d.putValue(" ", None, -99)
-        d.putItem(Item(v, item.iname))
+        d.putItem(v)
         d.putBetterType("%sQVariant (%s)" % (d.ns, innert))
         return innert
 
     # User types.
-    type = str(call(item.value, "typeToName",
+    type = str(call(value, "typeToName",
         "('%sQVariant::Type')%d" % (d.ns, d_ptr["type"])))
     type = type[type.find('"') + 1 : type.rfind('"')]
     type = type.replace("Q", d.ns + "Q") # HACK!
     type = type.replace("uint", "unsigned int") # HACK!
     type = type.replace("COMMA", ",") # HACK!
     warn("TYPE: %s" % type)
-    data = call(item.value, "constData")
+    data = call(value, "constData")
     warn("DATA: %s" % data)
     d.putValue(" ", None, -99)
     d.putType("%sQVariant (%s)" % (d.ns, type))
     d.putNumChild(1)
     tdata = data.cast(lookupType(type).pointer()).dereference()
-    if d.isExpanded(item):
+    if d.isExpanded():
         with Children(d):
-            #warn("TDATA: %s" % tdata)
-          with NoAddress(d):
-            d.putSubItem(Item(tdata, item.iname, "data", "data"))
+            with NoAddress(d):
+                d.putSubItem("data", tdata)
     return tdata.type
 
 
@@ -1687,38 +1610,37 @@ def qedit__QVector(expr, value):
     gdb.execute(cmd)
 
 
-def qdump__QVector(d, item):
-    d_ptr = item.value["d"]
-    p_ptr = item.value["p"]
+def qdump__QVector(d, value):
+    d_ptr = value["d"]
+    p_ptr = value["p"]
     alloc = d_ptr["alloc"]
     size = d_ptr["size"]
 
     check(0 <= size and size <= alloc and alloc <= 1000 * 1000 * 1000)
     checkRef(d_ptr["ref"])
 
-    innerType = templateArgument(item.value.type, 0)
+    innerType = templateArgument(value.type, 0)
     d.putItemCount(size)
     d.putNumChild(size)
-    if d.isExpanded(item):
+    if d.isExpanded():
         p = gdb.Value(p_ptr["array"]).cast(innerType.pointer())
         charPtr = lookupType("char").pointer()
         d.putField("size", size)
-        d.putField("addrbase", cleanAddress(p))
-        d.putField("addrstep", (p+1).cast(charPtr) - p.cast(charPtr))
-        with Children(d, [size, 2000], innerType):
+        with Children(d, size, maxNumChild=2000, childType=innerType, addrBase=p,
+                addrStep=(p+1).cast(charPtr) - p.cast(charPtr)):
             for i in d.childRange():
-                d.putSubItem(Item(p.dereference(), item.iname, i))
+                d.putSubItem(i, p.dereference())
                 p += 1
 
 
-def qdump__QWeakPointer(d, item):
-    d_ptr = item.value["d"]
-    value = item.value["value"]
-    if isNull(d_ptr) and isNull(value):
+def qdump__QWeakPointer(d, value):
+    d_ptr = value["d"]
+    val = value["value"]
+    if isNull(d_ptr) and isNull(val):
         d.putValue("(null)")
         d.putNumChild(0)
         return
-    if isNull(d_ptr) or isNull(value):
+    if isNull(d_ptr) or isNull(val):
         d.putValue("<invalid>")
         d.putNumChild(0)
         return
@@ -1728,21 +1650,21 @@ def qdump__QWeakPointer(d, item):
     check(int(strongref) <= int(weakref))
     check(int(weakref) <= 10*1000*1000)
 
-    if isSimpleType(value.dereference().type):
+    if isSimpleType(val.dereference().type):
         d.putNumChild(3)
-        d.putItem(Item(value.dereference(), item.iname, None))
+        d.putItem(val.dereference())
     else:
         d.putValue("")
 
     d.putNumChild(3)
-    if d.isExpanded(item):
-        with Children(d, 3):
-            d.putSubItem(Item(value.dereference(), item.iname, "data", "data"))
+    if d.isExpanded():
+        with Children(d):
+            d.putSubItem("data", val.dereference())
             d.putIntItem("weakref", weakref)
             d.putIntItem("strongref", strongref)
 
 
-def qdump__QxXmlAttributes(d, item):
+def qdump__QxXmlAttributes(d, value):
     pass
 
 #######################################################################
@@ -1751,14 +1673,14 @@ def qdump__QxXmlAttributes(d, item):
 #
 #######################################################################
 
-def qdump__std__deque(d, item):
-    innerType = templateArgument(item.value.type, 0)
+def qdump__std__deque(d, value):
+    innerType = templateArgument(value.type, 0)
     innerSize = innerType.sizeof
     bufsize = 1
     if innerSize < 512:
         bufsize = 512 / innerSize
 
-    impl = item.value["_M_impl"]
+    impl = value["_M_impl"]
     start = impl["_M_start"]
     finish = impl["_M_finish"]
     size = (bufsize * (finish["_M_node"] - start["_M_node"] - 1)
@@ -1768,14 +1690,14 @@ def qdump__std__deque(d, item):
     check(0 <= size and size <= 1000 * 1000 * 1000)
     d.putItemCount(size)
     d.putNumChild(size)
-    if d.isExpanded(item):
-        with Children(d, [size, 2000], innerType):
+    if d.isExpanded():
+        with Children(d, size, maxNumChild=2000, childType=innerType):
             pcur = start["_M_cur"]
             pfirst = start["_M_first"]
             plast = start["_M_last"]
             pnode = start["_M_node"]
             for i in d.childRange():
-                d.putSubItem(Item(pcur.dereference(), item.iname, i))
+                d.putSubItem(i, pcur.dereference())
                 pcur += 1
                 if pcur == plast:
                     newnode = pnode + 1
@@ -1785,8 +1707,8 @@ def qdump__std__deque(d, item):
                     pcur = pfirst
 
 
-def qdump__std__list(d, item):
-    impl = item.value["_M_impl"]
+def qdump__std__list(d, value):
+    impl = value["_M_impl"]
     node = impl["_M_node"]
     head = node.address
     size = 0
@@ -1798,30 +1720,29 @@ def qdump__std__list(d, item):
     d.putItemCount(size, 1000)
     d.putNumChild(size)
 
-    if d.isExpanded(item):
+    if d.isExpanded():
         p = node["_M_next"]
-        innerType = templateArgument(item.value.type, 0)
-        with Children(d, [size, 1000], innerType):
+        innerType = templateArgument(value.type, 0)
+        with Children(d, size, maxNumChild=1000, childType=innerType):
             for i in d.childRange():
                 innerPointer = innerType.pointer()
-                value = (p + 1).cast(innerPointer).dereference()
-                d.putSubItem(Item(value, item.iname, i))
+                d.putSubItem(i, (p + 1).cast(innerPointer).dereference())
                 p = p["_M_next"]
 
 
-def qdump__std__map(d, item):
-    impl = item.value["_M_t"]["_M_impl"]
+def qdump__std__map(d, value):
+    impl = value["_M_t"]["_M_impl"]
     size = impl["_M_node_count"]
     check(0 <= size and size <= 100*1000*1000)
     d.putItemCount(size)
     d.putNumChild(size)
 
-    if d.isExpanded(item):
-        keyType = templateArgument(item.value.type, 0)
-        valueType = templateArgument(item.value.type, 1)
+    if d.isExpanded():
+        keyType = templateArgument(value.type, 0)
+        valueType = templateArgument(value.type, 1)
         # Does not work on gcc 4.4, the allocator type (fourth template
         # argument) seems not to be available.
-        #   pairType = templateArgument(templateArgument(item.value.type, 3), 0)
+        #   pairType = templateArgument(templateArgument(value.type, 3), 0)
         # So use this as workaround:
         pairType = templateArgument(impl.type, 1)
         isSimpleKey = isSimpleType(keyType)
@@ -1837,24 +1758,20 @@ def qdump__std__map(d, item):
         childNumChild = 2
         if isSimpleKey and isSimpleValue:
             childNumChild = None
-        with Children(d, [size, 1000], childType, childNumChild):
+        with Children(d, size, maxNumChild=1000,
+                childType=childType, childNumChild=childNumChild):
             for i in d.childRange():
-                pair = (node + 1).cast(pairPointer).dereference()
-
-                with SubItem(d):
+                with SubItem(d, i):
+                    pair = (node + 1).cast(pairPointer).dereference()
                     if isSimpleKey and isSimpleValue:
-                        d.putName(str(pair["first"]))
-                        d.putItem(Item(pair["second"], item.iname, i))
+                        d.putName(pair["first"])
+                        d.putItem(pair["second"])
                     else:
                         d.putValue(" ")
-                        if d.isExpandedIName("%s.%d" % (item.iname, i)):
-                            with Children(d, 2, None):
-                                iname = "%s.%d" % (item.iname, i)
-                                keyItem = Item(pair["first"], iname, "first", "first")
-                                valueItem = Item(pair["second"], iname, "second", "second")
-                                d.putSubItem(keyItem)
-                                d.putSubItem(valueItem)
-
+                        if d.isExpanded():
+                            with Children(d, 2):
+                                d.putSubItem("first", pair["first"])
+                                d.putSubItem("second", pair["second"])
                 if isNull(node["_M_right"]):
                     parent = node["_M_parent"]
                     while node == parent["_M_right"]:
@@ -1868,20 +1785,18 @@ def qdump__std__map(d, item):
                         node = node["_M_left"]
 
 
-def qdump__std__set(d, item):
-    impl = item.value["_M_t"]["_M_impl"]
+def qdump__std__set(d, value):
+    impl = value["_M_t"]["_M_impl"]
     size = impl["_M_node_count"]
     check(0 <= size and size <= 100*1000*1000)
     d.putItemCount(size)
     d.putNumChild(size)
-    if d.isExpanded(item):
-        valueType = templateArgument(item.value.type, 0)
+    if d.isExpanded():
+        valueType = templateArgument(value.type, 0)
         node = impl["_M_header"]["_M_left"]
-        with Children(d, [size, 1000], valueType):
+        with Children(d, size, maxNumChild=1000, childType=valueType):
             for i in d.childRange():
-                element = (node + 1).cast(valueType.pointer()).dereference()
-                d.putSubItem(Item(element, item.iname, i))
-
+                d.putSubItem(i, (node + 1).cast(valueType.pointer()).dereference())
                 if isNull(node["_M_right"]):
                     parent = node["_M_parent"]
                     while node == parent["_M_right"]:
@@ -1895,14 +1810,13 @@ def qdump__std__set(d, item):
                         node = node["_M_left"]
 
 
-def qdump__std__stack(d, item):
-    data = item.value["c"]
-    qdump__std__deque(d, Item(data, item.iname))
+def qdump__std__stack(d, value):
+    qdump__std__deque(d, value["c"])
 
 
-def qdump__std__string(d, item):
-    data = item.value["_M_dataplus"]["_M_p"]
-    baseType = item.value.type.unqualified().strip_typedefs()
+def qdump__std__string(d, value):
+    data = value["_M_dataplus"]["_M_p"]
+    baseType = value.type.unqualified().strip_typedefs()
     if baseType.code == gdb.TYPE_CODE_REF:
         baseType = baseType.target().unqualified().strip_typedefs()
     # We might encounter 'std::string' or 'std::basic_string<>'
@@ -1968,9 +1882,9 @@ def qedit__std__vector(expr, value):
     cmd = "set (%s[%d])*$d={%s}" % (innerType, n, value)
     gdb.execute(cmd)
 
-def qdump__std__vector(d, item):
-    impl = item.value["_M_impl"]
-    type = templateArgument(item.value.type, 0)
+def qdump__std__vector(d, value):
+    impl = value["_M_impl"]
+    type = templateArgument(value.type, 0)
     alloc = impl["_M_end_of_storage"]
     isBool = str(type) == 'bool'
     if isBool:
@@ -1994,17 +1908,18 @@ def qdump__std__vector(d, item):
 
     d.putItemCount(size)
     d.putNumChild(size)
-    if d.isExpanded(item):
+    if d.isExpanded():
         if isBool:
-            with Children(d, [size, 10000], type):
+            with Children(d, size, maxNumChild=10000, childType=type):
                 for i in d.childRange():
                     q = start + i / storagesize
                     d.putBoolItem(str(i), (q.dereference() >> (i % storagesize)) & 1)
         else:
-            with Children(d, [size, 10000], type):
+            with Children(d, size, maxNumChild=10000, childType=type,
+                    addrBase=start, addrStep=type.sizeof):
                 p = start
                 for i in d.childRange():
-                    d.putSubItem(Item(p.dereference(), item.iname, i))
+                    d.putSubItem(i, p.dereference())
                     p += 1
 
 
@@ -2015,29 +1930,29 @@ def qedit__std__string(expr, value):
 def qedit__string(expr, value):
     qdump__std__string(expr, value)
 
-def qdump__string(d, item):
-    qdump__std__string(d, item)
+def qdump__string(d, value):
+    qdump__std__string(d, value)
 
-def qdump__std__wstring(d, item):
-    qdump__std__string(d, item)
+def qdump__std__wstring(d, value):
+    qdump__std__string(d, value)
 
-def qdump__std__basic_string(d, item):
-    qdump__std__string(d, item)
+def qdump__std__basic_string(d, value):
+    qdump__std__string(d, value)
 
-def qdump__wstring(d, item):
-    qdump__std__string(d, item)
+def qdump__wstring(d, value):
+    qdump__std__string(d, value)
 
 
-def qdump____gnu_cxx__hash_set(d, item):
-    ht = item.value["_M_ht"]
+def qdump____gnu_cxx__hash_set(d, value):
+    ht = value["_M_ht"]
     size = ht["_M_num_elements"]
     check(0 <= size and size <= 1000 * 1000 * 1000)
     d.putItemCount(size)
     d.putNumChild(size)
-    type = templateArgument(item.value.type, 0)
+    type = templateArgument(value.type, 0)
     d.putType("__gnu__cxx::hash_set<%s>" % type)
-    if d.isExpanded(item):
-        with Children(d, [size, 1000], type):
+    if d.isExpanded():
+        with Children(d, size, maxNumChild=1000, childType=type):
             buckets = ht["_M_buckets"]["_M_impl"]
             bucketStart = buckets["_M_start"]
             bucketFinish = buckets["_M_finish"]
@@ -2047,7 +1962,7 @@ def qdump____gnu_cxx__hash_set(d, item):
                 if not isNull(p.dereference()):
                     cur = p.dereference()
                     while not isNull(cur):
-                        with SubItem(d):
+                        with SubItem(d, itemCount):
                             d.putValue(cur["_M_val"])
                             cur = cur["_M_next"]
                             itemCount += 1
@@ -2060,53 +1975,52 @@ def qdump____gnu_cxx__hash_set(d, item):
 #
 #######################################################################
 
-def qdump__boost__optional(d, item):
-    if item.value["m_initialized"] == False:
+def qdump__boost__optional(d, value):
+    if value["m_initialized"] == False:
         d.putValue("<uninitialized>")
         d.putNumChild(0)
     else:
-        d.putBetterType(item.value.type)
-        type = templateArgument(item.value.type, 0)
-        storage = item.value["m_storage"]
+        d.putBetterType(value.type)
+        type = templateArgument(value.type, 0)
+        storage = value["m_storage"]
         if type.code == gdb.TYPE_CODE_REF:
-            value = storage.cast(type.target().pointer()).dereference()
+            d.putItem(storage.cast(type.target().pointer()).dereference())
         else:
-            value = storage.cast(type)
-        d.putItem(Item(value, item.iname))
+            d.putItem(storage.cast(type))
 
-def qdump__boost__shared_ptr(d, item):
+def qdump__boost__shared_ptr(d, value):
     # s                  boost::shared_ptr<int>
     #    pn              boost::detail::shared_count
     #        pi_ 0x0     boost::detail::sp_counted_base *
     #    px      0x0     int *
-    if isNull(item.value["pn"]["pi_"]):
+    if isNull(value["pn"]["pi_"]):
         d.putValue("(null)")
         d.putNumChild(0)
         return
 
-    if isNull(item.value["px"]):
+    if isNull(value["px"]):
         d.putValue("(null)")
         d.putNumChild(0)
         return
 
-    countedbase = item.value["pn"]["pi_"].dereference()
+    countedbase = value["pn"]["pi_"].dereference()
     weakcount = countedbase["weak_count_"]
     usecount = countedbase["use_count_"]
     check(int(weakcount) >= 0)
     check(int(weakcount) <= int(usecount))
     check(int(usecount) <= 10*1000*1000)
 
-    value = item.value["px"].dereference()
-    if isSimpleType(value.type):
+    val = value["px"].dereference()
+    if isSimpleType(val.type):
         d.putNumChild(3)
-        d.putItem(Item(value, item.iname, None))
+        d.putItem(val)
     else:
         d.putValue("")
 
     d.putNumChild(3)
-    if d.isExpanded(item):
+    if d.isExpanded():
         with Children(d, 3):
-            d.putSubItem(Item(value, item.iname, "data", "data"))
+            d.putSubItem("data", val)
             d.putIntItem("weakcount", weakcount)
             d.putIntItem("usecount", usecount)
 
@@ -2127,18 +2041,18 @@ def encodeSymbianString(base, size):
             s += "%02x%02x" % (val % 256, val / 256)
     return s
 
-def qdump__TBuf(d, item):
-    size = item.value["iLength"] & 0xffff
-    base = item.value["iBuf"]
-    max = numericTemplateArgument(item.value.type, 0)
+def qdump__TBuf(d, value):
+    size = value["iLength"] & 0xffff
+    base = value["iBuf"]
+    max = numericTemplateArgument(value.type, 0)
     check(0 <= size and size <= max)
     d.putNumChild(0)
     d.putValue(encodeSymbianString(base, size), Hex4EncodedLittleEndian)
 
-def qdump__TLitC(d, item):
-    size = item.value["iTypeLength"] & 0xffff
-    base = item.value["iBuf"]
-    max = numericTemplateArgument(item.value.type, 0)
+def qdump__TLitC(d, value):
+    size = value["iTypeLength"] & 0xffff
+    base = value["iBuf"]
+    max = numericTemplateArgument(value.type, 0)
     check(0 <= size and size <= max)
     d.putNumChild(0)
     d.putValue(encodeSymbianString(base, size), Hex4EncodedLittleEndian)
@@ -2153,21 +2067,21 @@ def qdump__TLitC(d, item):
 def qform____m128():
     return "As Floats,As Doubles"
 
-def qdump____m128(d, item):
+def qdump____m128(d, value):
     d.putValue(" ")
     d.putNumChild(1)
-    if d.isExpanded(item):
-        format = d.itemFormat(item)
+    if d.isExpanded():
+        format = d.currentItemFormat()
         if format == 2: # As Double
             innerType = lookupType("double")
             count = 2
         else: # Default, As float
             innerType = lookupType("float")
             count = 4
-        p = item.value.address.cast(innerType.pointer())
-        with Children(d, count, innerType):
+        p = value.address.cast(innerType.pointer())
+        with Children(d, count, childType=innerType):
             for i in xrange(count):
-                d.putSubItem(Item(p.dereference(), item.iname))
+                d.putSubItem(i, p.dereference())
                 p += 1
 
 
@@ -2205,40 +2119,38 @@ def jstagAsString(tag):
 
 
 
-def qdump__QTJSC__JSValue(d, item):
+def qdump__QTJSC__JSValue(d, value):
     d.putValue(" ")
     d.putNumChild(1)
-    if d.isExpanded(item):
+    if d.isExpanded():
         with Children(d):
-            tag = item.value["u"]["asBits"]["tag"]
-            payload = item.value["u"]["asBits"]["payload"]
+            tag = value["u"]["asBits"]["tag"]
+            payload = value["u"]["asBits"]["payload"]
             #d.putIntItem("tag", tag)
-            with SubItem(d):
-                d.putName("tag")
+            with SubItem(d, "tag"):
                 d.putValue(jstagAsString(long(tag)))
                 d.putNoType()
                 d.putNumChild(0)
 
             d.putIntItem("payload", long(payload))
-            d.putFields(Item(item.value["u"], item.iname))
+            d.putFields(value["u"])
 
             if tag == -2:
                 cellType = lookupType("QTJSC::JSCell").pointer()
-                d.putSubItem(Item(payload.cast(cellType), item.iname, "cell", "cell"))
+                d.putSubItem("cell", payload.cast(cellType))
 
             try:
                 # FIXME: This might not always be a variant.
                 delegateType = lookupType(d.ns + "QScript::QVariantDelegate").pointer()
                 delegate = scriptObject["d"]["delegate"].cast(delegateType)
-                #d.putSubItem(Item(delegate, item.iname, "delegate", "delegate"))
-
+                #d.putSubItem("delegate", delegate)
                 variant = delegate["m_value"]
-                d.putSubItem(Item(variant, item.iname, "variant", "variant"))
+                d.putSubItem("variant", variant)
             except:
                 pass
 
 
-def qdump__QScriptValue(d, item):
+def qdump__QScriptValue(d, value):
     # structure:
     #  engine        QScriptEnginePrivate
     #  jscValue      QTJSC::JSValue
@@ -2249,7 +2161,7 @@ def qdump__QScriptValue(d, item):
     #  stringValue   QString
     #  type          QScriptValuePrivate::Type: { JavaScriptCore, Number, String }
     #d.putValue(" ")
-    dd = item.value["d_ptr"]["d"]
+    dd = value["d_ptr"]["d"]
     if isNull(dd):
         d.putValue("(invalid)")
         d.putNumChild(0)
@@ -2304,11 +2216,11 @@ def qdump__QScriptValue(d, item):
         # FIXME: This might not always be a variant.
         delegateType = lookupType(d.ns + "QScript::QVariantDelegate").pointer()
         delegate = scriptObject["d"]["delegate"].cast(delegateType)
-        #d.putSubItem(Item(delegate, item.iname, "delegate", "delegate"))
+        #d.putSubItem("delegate", delegate)
 
         variant = delegate["m_value"]
-        #d.putSubItem(Item(variant, item.iname, "variant", "variant"))
-        t = qdump__QVariant(d, Item(variant, "variant"))
+        #d.putSubItem("variant", variant)
+        t = qdump__QVariant(d, variant)
         # Override the "QVariant (foo)" output
         d.putBetterType("%sQScriptValue (%s)" % (d.ns, t))
         if t != "JSCoreValue":
@@ -2319,9 +2231,9 @@ def qdump__QScriptValue(d, item):
     # This is a "native" JSCore type for e.g. QDateTime.
     d.putValue("<native>")
     d.putNumChild(1)
-    if d.isExpanded(item):
+    if d.isExpanded():
         with Children(d):
-           d.putSubItem(Item(dd["jscValue"], item.iname, "jscValue", "jscValue"))
+           d.putSubItem("jscValue", dd["jscValue"])
 
 
 #######################################################################
@@ -2333,15 +2245,15 @@ def qdump__QScriptValue(d, item):
 #def qform__Eigen__Matrix():
 #    return "Transposed"
 
-def qdump__Eigen__Matrix(d, item):
-    innerType = templateArgument(item.value.type, 0)
-    storage = item.value["m_storage"]
-    options = numericTemplateArgument(item.value.type, 3)
+def qdump__Eigen__Matrix(d, value):
+    innerType = templateArgument(value.type, 0)
+    storage = value["m_storage"]
+    options = numericTemplateArgument(value.type, 3)
     rowMajor = (int(options) & 0x1)
     p = storage["m_data"]
     if p.type.code == gdb.TYPE_CODE_STRUCT: # Static
-        nrows = numericTemplateArgument(item.value.type, 1)
-        ncols = numericTemplateArgument(item.value.type, 2)
+        nrows = numericTemplateArgument(value.type, 1)
+        ncols = numericTemplateArgument(value.type, 2)
         p = p["array"].cast(innerType.pointer())
     else: # Dynamic
         ncols = storage["m_cols"]
@@ -2353,26 +2265,26 @@ def qdump__Eigen__Matrix(d, item):
     limit = 10000
     nncols = min(ncols, limit)
     nnrows = min(nrows, limit * limit / nncols)
-    if d.isExpanded(item):
-        #format = d.itemFormat(item) # format == 1 is "Transposed"
-        iname = item.iname
-        with Children(d, nrows * ncols, innerType):
+    if d.isExpanded():
+        #format = d.currentItemFormat() # format == 1 is "Transposed"
+        with Children(d, nrows * ncols, childType=innerType):
             if ncols == 1 or nrows == 1:
                 for i in range(0, min(nrows * ncols, 10000)):
-                    v = (p + i).dereference()
-                    d.putSubItem(Item(v, item.iname))
+                    d.putSubItem(i, (p + i).dereference())
             elif rowMajor == 1:
+                s = 0
                 for i in range(0, nnrows):
                     for j in range(0, nncols):
-                        name = "[%d,%d]" % (i, j)
                         v = (p + i * ncols + j).dereference()
-                        d.putSubItem(Item(v, item.iname, None, name))
+                        d.putNamedSubItem(s, v, "[%d,%d]" % (i, j))
+                        s = s + 1
             else:
+                s = 0
                 for j in range(0, nncols):
                     for i in range(0, nnrows):
-                        name = "[%d,%d]" % (i, j)
                         v = (p + i + j * nrows).dereference()
-                        d.putSubItem(Item(v, item.iname, None, name))
+                        d.putNamedSubItem(s, v, "[%d,%d]" % (i, j))
+                        s = s + 1
 
 
 #######################################################################
@@ -2384,44 +2296,37 @@ def qdump__Eigen__Matrix(d, item):
 if False:
 
     # FIXME: Make that work
-    def qdump__Color(d, item):
-        v = item.value
+    def qdump__Color(d, value):
+        v = value
         d.putValue("(%s, %s, %s; %s)" % (v["r"], v["g"], v["b"], v["a"]))
-        if d.isExpanded(item):
+        if d.isExpanded():
             with Children(d):
-                d.putSubItem(Item(v["r"], item.iname, "0", "r"))
-                d.putSubItem(Item(v["g"], item.iname, "1", "g"))
-                d.putSubItem(Item(v["b"], item.iname, "2", "b"))
-                d.putSubItem(Item(v["a"], item.iname, "3", "a"))
+                d.putFields(value)
 
-    def qdump__Color_(d, item):
-        v = item.value
+    def qdump__Color_(d, value):
+        v = value
         d.putValue("(%s, %s, %s; %s)" % (v["r"], v["g"], v["b"], v["a"]))
-        if d.isExpanded(item):
+        if d.isExpanded():
             with Children(d):
-                with SubItem(d):
-                    d.putField("iname", item.iname + ".0")
-                    d.putItem(Item(v["r"], item.iname, "0", "r"))
-                with SubItem(d):
-                    d.putField("iname", item.iname + ".1")
-                    d.putItem(Item(v["g"], item.iname, "1", "g"))
-                with SubItem(d):
-                    d.putField("iname", item.iname + ".2")
-                    d.putItem(Item(v["b"], item.iname, "2", "b"))
-                with SubItem(d):
-                    d.putField("iname", item.iname + ".3")
-                    d.putItem(Item(v["a"], item.iname, "3", "a"))
-
-
-    def qdump__Function(d, item):
-        min = item.value["min"]
-        max = item.value["max"]
-        var = extractByteArray(item.value["var"])
-        f = extractByteArray(item.value["f"])
+                with SubItem(d, "0"):
+                    d.putItem(v["r"])
+                with SubItem(d, "1"):
+                    d.putItem(v["g"])
+                with SubItem(d, "2"):
+                    d.putItem(v["b"])
+                with SubItem(d, "3"):
+                    d.putItem(v["a"])
+
+
+    def qdump__Function(d, value):
+        min = value["min"]
+        max = value["max"]
+        var = extractByteArray(value["var"])
+        f = extractByteArray(value["f"])
         d.putValue("%s, %s=%f..%f" % (f, var, min, max))
         d.putNumChild(0)
         d.putField("typeformats", "Normal,Displayed");
-        format = d.itemFormat(item)
+        format = d.currentItemFormat()
         if format == 0:
             d.putDisplay(StopDisplay)
         elif format == 1:
@@ -2431,48 +2336,37 @@ if False:
 
 if False:
 
-    def qdump__tree_entry(d, item):
-        value = item.value
+    def qdump__tree_entry(d, value):
         d.putValue("len: %s, offset: %s, type: %s" %
             (value["blocklength"], value["offset"], value["type"]))
         d.putNumChild(0)
 
-    def qdump__tree(d, item):
-        value = item.value
+    def qdump__tree(d, value):
         count = value["count"]
         entries = value["entries"]
         base = value["base"].cast(lookupType("char").pointer())
         d.putItemCount(count)
         d.putNumChild(count)
-        if d.isExpanded(item):
+        if d.isExpanded():
           with Children(d):
-            with SubItem(d):
-              iname = item.iname + ".tree"
-              d.putField("iname", iname)
-              d.putName("tree")
+            with SubItem(d, "tree"):
               d.putValue(" ")
               d.putNoType()
               d.putNumChild(1)
-              if d.isExpandedIName(iname):
+              if d.isExpanded():
                 with Children(d):
                   for i in xrange(count):
                       d.putSubItem(Item(entries[i], iname))
-            with SubItem(d):
-              iname = item.iname + ".data"
-              d.putField("iname", iname)
-              d.putName("data")
+            with SubItem(d, "data"):
               d.putValue(" ")
               d.putNoType()
               d.putNumChild(1)
-              if d.isExpandedIName(iname):
+              if d.isExpanded():
                  with Children(d):
                     for i in xrange(count):
-                      with SubItem(d):
-                        iiname = iname + "." + str(i)
+                      with SubItem(d, i):
                         entry = entries[i]
                         mpitype = str(entry["type"])
-                        d.putField("iname", iiname)
-                        d.putName("%s" % i)
                         d.putType(mpitype)
                         length = int(entry["blocklength"])
                         offset = int(entry["offset"])
@@ -2486,13 +2380,12 @@ if False:
                         else:
                           length = 0
                         d.putNumChild(length)
-                        if d.isExpandedIName(iiname):
+                        if d.isExpanded():
                            with Children(d):
                               t = lookupType(innerType).pointer()
                               p = (base + offset).cast(t)
                               for j in range(length):
-                                d.putSubItem(Item(p.dereference(), iiname))
-                                p = p + 1
+                                d.putSubItem(j, p.dereference())
 
     #struct KRBase
     #{
@@ -2510,23 +2403,23 @@ if False:
     #    ptr2 = new KRB;
     #}
 
-    def qdump__KRBase(d, item):
-        if getattr(item, "__nested__", None) is None:
-            base = ["KRA", "KRB"][int(item.value["type"])]
-            nest = Item(item.value.cast(lookupType(base)), item.iname)
+    def qdump__KRBase(d, value):
+        if getattr(value, "__nested__", None) is None:
+            base = ["KRA", "KRB"][int(value["type"])]
+            nest = value.cast(lookupType(base))
             nest.__nested__ = True
             warn("NEST %s " % dir(nest))
             d.putItem(nest)
         else:
             d.putName("type")
-            d.putValue(item.value["type"])
+            d.putValue(value["type"])
             d.putNoType()
 
 
 
 if False:
-    def qdump__bug5106__A5106(d, item):
+    def qdump__bug5106__A5106(d, value):
         d.putName("a")
-        d.putValue("This is the value: %s" % item.value["m_a"])
+        d.putValue("This is the value: %s" % value["m_a"])
         d.putNoType()
         d.putNumChild(0)