diff --git a/share/qtcreator/gdbmacros/dumper.py b/share/qtcreator/gdbmacros/dumper.py
index e2ca7777cee7b30db697a5b5c6dd5ca85703b98a..ac8b2e69d6b8d1dc2734cb4bd4c621146e864738 100644
--- a/share/qtcreator/gdbmacros/dumper.py
+++ b/share/qtcreator/gdbmacros/dumper.py
@@ -162,15 +162,43 @@ def cleanAddress(addr):
     # that might trigger Unicode encoding errors.
     return addr.cast(lookupType("void").pointer())
 
-def templateArgument(type, position)
+def extractTemplateArgument(type, position):
+    level = 0
+    skipSpace = False
+    inner = ""
+    type = str(type)
+    for c in type[type.find('<') + 1 : -1]:
+        if c == '<':
+            inner += c
+            level += 1
+        elif c == '>':
+            level -= 1
+            inner += c
+        elif c == ',':
+            if level == 0:
+                if position == 0:
+                    return inner
+                position -= 1
+                inner = ""
+            else:
+                inner += c
+                skipSpace = True
+        else:
+            if skipSpace and c == ' ':
+                pass
+            else:
+                inner += c
+                skipSpace = False
+    return inner
+
+def templateArgument(type, position):
     try:
         # This fails on stock 7.2 with
         # "RuntimeError: No type named myns::QObject.\n"
         return type.template_argument(position)
     except:
         # That's something like "myns::QList<...>"
-        innerString = str(type.strip_typedefs())
-        return lookupType(innerString[innerString.find('<') + 1 : -1])
+        return lookupType(extractTemplateArgument(type.strip_typedefs(), position))
 
 # Workaround for gdb < 7.1
 def numericTemplateArgument(type, position):
diff --git a/share/qtcreator/gdbmacros/gdbmacros.py b/share/qtcreator/gdbmacros/gdbmacros.py
index 04eb757bedbac156488ecff99872c73055ee73f1..379e3d0483fd33aaadcd7479063183aec2c8ff04 100644
--- a/share/qtcreator/gdbmacros/gdbmacros.py
+++ b/share/qtcreator/gdbmacros/gdbmacros.py
@@ -354,8 +354,8 @@ def qdump__QHash(d, item):
             bucket += 1
         return node
 
-    keyType = item.value.type.template_argument(0)
-    valueType = item.value.type.template_argument(1)
+    keyType = templateArgument(item.value.type, 0)
+    valueType = templateArgument(item.value.type, 1)
 
     d_ptr = item.value["d"]
     e_ptr = item.value["e"]
@@ -392,8 +392,8 @@ def qdump__QHash(d, item):
 
 
 def qdump__QHashNode(d, item):
-    keyType = item.value.type.template_argument(0)
-    valueType = item.value.type.template_argument(1)
+    keyType = templateArgument(item.value.type, 0)
+    valueType = templateArgument(item.value.type, 1)
     key = item.value["key"]
     value = item.value["value"]
 
@@ -592,8 +592,8 @@ def qdump__QMap(d, item):
         if n > 1000:
             n = 1000
 
-        keyType = item.value.type.template_argument(0)
-        valueType = item.value.type.template_argument(1)
+        keyType = templateArgument(item.value.type, 0)
+        valueType = templateArgument(item.value.type, 1)
 
         isSimpleKey = isSimpleType(keyType)
         isSimpleValue = isSimpleType(valueType)
@@ -826,7 +826,7 @@ def qdump__QObject(d, item):
             if d.isExpandedIName(item.iname + ".connections"):
                 with Children(d):
                     vectorType = connections.type.target().fields()[0].type
-                    innerType = vectorType.template_argument(0)
+                    innerType = templateArgument(vectorType, 0)
                     # Should check:  innerType == ns::QObjectPrivate::ConnectionList
                     p = gdb.Value(connections["p"]["array"]).cast(innerType.pointer())
                     pp = 0
@@ -1541,7 +1541,7 @@ def qdump__QSet(d, item):
             bucket += 1
         return node
 
-    keyType = item.value.type.template_argument(0)
+    keyType = templateArgument(item.value.type, 0)
 
     d_ptr = item.value["q_hash"]["d"]
     e_ptr = item.value["q_hash"]["e"]
@@ -1975,7 +1975,7 @@ def qdump__std__deque(d, item):
     d.putItemCount(size)
     d.putNumChild(size)
     if d.isExpanded(item):
-        innerType = item.value.type.template_argument(0)
+        innerType = templateArgument(item.value.type, 0)
         innerSize = innerType.sizeof
         bufsize = select(innerSize < 512, 512 / innerSize, 1)
         with Children(d, [size, 2000], innerType):
@@ -2009,7 +2009,7 @@ def qdump__std__list(d, item):
 
     if d.isExpanded(item):
         p = node["_M_next"]
-        innerType = item.value.type.template_argument(0)
+        innerType = templateArgument(item.value.type, 0)
         with Children(d, [size, 1000], innerType):
             for i in d.childRange():
                 innerPointer = innerType.pointer()
@@ -2026,9 +2026,9 @@ def qdump__std__map(d, item):
     d.putNumChild(size)
 
     if d.isExpanded(item):
-        keyType = item.value.type.template_argument(0)
-        valueType = item.value.type.template_argument(1)
-        pairType = item.value.type.template_argument(3).template_argument(0)
+        keyType = templateArgument(item.value.type, 0)
+        valueType = templateArgument(item.value.type, 1)
+        pairType = templateArgument(templateArgument(item.value.type, 3), 0)
         isSimpleKey = isSimpleType(keyType)
         isSimpleValue = isSimpleType(valueType)
         innerType = select(isSimpleKey and isSimpleValue, valueType, pairType)
@@ -2073,7 +2073,7 @@ def qdump__std__set(d, item):
     d.putItemCount(size)
     d.putNumChild(size)
     if d.isExpanded(item):
-        valueType = item.value.type.template_argument(0)
+        valueType = templateArgument(item.value.type, 0)
         node = impl["_M_header"]["_M_left"]
         with Children(d, [size, 1000], valueType):
             for i in d.childRange():
@@ -2110,7 +2110,7 @@ def qdump__std__string(d, item):
     elif str(baseType) == 'std::wstring':
         charType = lookupType("wchar_t")
     else:
-        charType = baseType.template_argument(0)
+        charType = templateArgument(baseType, 0)
     repType = lookupType("%s::_Rep" % baseType).pointer()
     rep = (data.cast(repType) - 1).dereference()
     size = rep['_M_length']
@@ -2156,7 +2156,7 @@ def qdump__std__string(d, item):
 
 def qdump__std__vector(d, item):
     impl = item.value["_M_impl"]
-    type = item.value.type.template_argument(0)
+    type = templateArgument(item.value.type, 0)
     alloc = impl["_M_end_of_storage"]
     isBool = str(type) == 'bool'
     if isBool:
@@ -2214,7 +2214,7 @@ def qdump____gnu_cxx__hash_set(d, item):
     check(0 <= size and size <= 1000 * 1000 * 1000)
     d.putItemCount(size)
     d.putNumChild(size)
-    type = item.value.type.template_argument(0)
+    type = templateArgument(item.value.type, 0)
     d.putType("__gnu__cxx::hash_set<%s>" % type)
     if d.isExpanded(item):
         with Children(d, [size, 1000], type):
@@ -2246,7 +2246,7 @@ def qdump__boost__optional(d, item):
         d.putNumChild(0)
     else:
         d.putType(item.value.type, d.currentTypePriority + 1)
-        type = item.value.type.template_argument(0)
+        type = templateArgument(item.value.type, 0)
         storage = item.value["m_storage"]
         if type.code == gdb.TYPE_CODE_REF:
             value = storage.cast(type.target().pointer()).dereference()