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()