aboutsummaryrefslogtreecommitdiffstats
path: root/share/qtcreator/debugger-with-python2/libcpp_stdtypes.py
diff options
context:
space:
mode:
Diffstat (limited to 'share/qtcreator/debugger-with-python2/libcpp_stdtypes.py')
-rw-r--r--share/qtcreator/debugger-with-python2/libcpp_stdtypes.py527
1 files changed, 527 insertions, 0 deletions
diff --git a/share/qtcreator/debugger-with-python2/libcpp_stdtypes.py b/share/qtcreator/debugger-with-python2/libcpp_stdtypes.py
new file mode 100644
index 0000000000..44b3a235ff
--- /dev/null
+++ b/share/qtcreator/debugger-with-python2/libcpp_stdtypes.py
@@ -0,0 +1,527 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+from stdtypes import qdump__std__array, qdump__std__complex, qdump__std__once_flag, qdump__std__unique_ptr, qdumpHelper__std__deque__libcxx, qdumpHelper__std__vector__libcxx
+from utils import DisplayFormat
+from dumper import Children, DumperBase
+
+
+def qform__std____1__array():
+ return [DisplayFormat.ArrayPlot]
+
+
+def qdump__std____1__array(d, value):
+ qdump__std__array(d, value)
+
+
+def qdump__std____1__complex(d, value):
+ qdump__std__complex(d, value)
+
+
+def qdump__std____1__deque(d, value):
+ qdumpHelper__std__deque__libcxx(d, value)
+
+
+def qdump__std____1__list(d, value):
+ if value.type.size() == 3 * d.ptrSize():
+ # C++11 only.
+ (dummy1, dummy2, size) = value.split("ppp")
+ d.putItemCount(size)
+ else:
+ # Need to count manually.
+ p = d.extractPointer(value)
+ head = value.address()
+ size = 0
+ while head != p and size < 1001:
+ size += 1
+ p = d.extractPointer(p)
+ d.putItemCount(size, 1000)
+
+ if d.isExpanded():
+ (prev, p) = value.split("pp")
+ innerType = value.type[0]
+ typeCode = "pp{%s}" % innerType.name
+ with Children(d, size, maxNumChild=1000, childType=innerType):
+ for i in d.childRange():
+ (prev, p, val) = d.split(typeCode, p)
+ d.putSubItem(i, val)
+
+
+def qdump__std____1__set(d, value):
+ (proxy, head, size) = value.split("ppp")
+
+ d.check(0 <= size and size <= 100 * 1000 * 1000)
+ d.putItemCount(size)
+
+ if d.isExpanded():
+ valueType = value.type[0]
+
+ def in_order_traversal(node):
+ (left, right, parent, color, pad, data) = d.split("pppB@{%s}" % (valueType.name), node)
+
+ if left:
+ for res in in_order_traversal(left):
+ yield res
+
+ yield data
+
+ if right:
+ for res in in_order_traversal(right):
+ yield res
+
+ with Children(d, size, maxNumChild=1000):
+ for (i, data) in zip(d.childRange(), in_order_traversal(head)):
+ d.putSubItem(i, data)
+
+
+def qdump__std____1__multiset(d, value):
+ qdump__std____1__set(d, value)
+
+
+def qform__std____1__map():
+ return [DisplayFormat.CompactMap]
+
+
+def qdump__std____1__map(d, value):
+ try:
+ (proxy, head, size) = value.split("ppp")
+ d.check(0 <= size and size <= 100 * 1000 * 1000)
+
+ # Sometimes there is extra data at the front. Don't know why at the moment.
+ except RuntimeError:
+ (junk, proxy, head, size) = value.split("pppp")
+ d.check(0 <= size and size <= 100 * 1000 * 1000)
+
+ d.putItemCount(size)
+
+ if d.isExpanded():
+ keyType = value.type[0]
+ valueType = value.type[1]
+ pairType = value.type[3][0]
+
+ def in_order_traversal(node):
+ (left, right, parent, color, pad, pair) = d.split("pppB@{%s}" % (pairType.name), node)
+
+ if left:
+ for res in in_order_traversal(left):
+ yield res
+
+ yield pair.split("{%s}@{%s}" % (keyType.name, valueType.name))[::2]
+
+ if right:
+ for res in in_order_traversal(right):
+ yield res
+
+ with Children(d, size, maxNumChild=1000):
+ for (i, pair) in zip(d.childRange(), in_order_traversal(head)):
+ d.putPairItem(i, pair)
+
+
+def qform__std____1__multimap():
+ return [DisplayFormat.CompactMap]
+
+
+def qdump__std____1__multimap(d, value):
+ qdump__std____1__map(d, value)
+
+
+def qdump__std____1__map__iterator(d, value):
+ d.putEmptyValue()
+ if d.isExpanded():
+ with Children(d):
+ node = value['__i_']['__ptr_'].dereference()['__value_']['__cc']
+ d.putSubItem('first', node['first'])
+ d.putSubItem('second', node['second'])
+
+
+def qdump__std____1__map__const_iterator(d, value):
+ qdump__std____1__map__iterator(d, value)
+
+
+def qdump__std____1__set__iterator(d, value):
+ d.putEmptyValue()
+ d.putExpandable()
+ if value.type.name.endswith("::iterator"):
+ treeTypeName = value.type.name[:-len("::iterator")]
+ elif value.type.name.endswith("::const_iterator"):
+ treeTypeName = value.type.name[:-len("::const_iterator")]
+ treeType = d.lookupType(treeTypeName)
+ keyType = treeType[0]
+ if d.isExpanded():
+ with Children(d):
+ node = value['__ptr_'].dereference()['__value_']
+ node = node.cast(keyType)
+ d.putSubItem('value', node)
+
+
+def qdump__std____1__set_const_iterator(d, value):
+ qdump__std____1__set__iterator(d, value)
+
+
+def qdump__std____1__stack(d, value):
+ d.putItem(value["c"])
+ d.putBetterType(value.type)
+
+
+def GetChildMemberWithName(value, name):
+ members = value.members(True)
+
+ for member in members:
+ if member.name == name:
+ return member
+ return None
+
+
+def GetIndexOfChildWithName(value, name):
+ members = value.members(True)
+
+ for i, member in enumerate(members):
+ if member.name == name:
+ return i
+ return None
+
+
+class StringLayout:
+ CSD = 0
+ DSC = 1
+
+
+def std_1_string_dumper_v2(d, value):
+ charType = value['__l']['__data_'].dereference().type
+
+ R = GetChildMemberWithName(value, "__r_")
+ if not R:
+ raise Exception("Could not find __r_")
+
+ # __r_ is a compressed_pair of the actual data and the allocator. The data we
+ # want is in the first base class.
+ R_Base_SP = R[0]
+
+ if not R_Base_SP:
+ raise Exception("Could not find R_Base_SP")
+
+ Rep_Sp = GetChildMemberWithName(R_Base_SP, "__value_")
+
+ if not Rep_Sp:
+ raise Exception("Could not find __value_")
+
+ # Our layout seems a little different
+ Rep_Sp = Rep_Sp[0]
+
+ if not Rep_Sp:
+ raise Exception("Could not find Rep_Sp")
+
+ L = GetChildMemberWithName(Rep_Sp, "__l")
+
+ if not L:
+ raise Exception("Could not find __l")
+
+ layout = StringLayout.CSD
+ if GetIndexOfChildWithName(L, "__data_") == 0:
+ layout = StringLayout.DSC
+
+ short_mode = False
+ using_bitmasks = True
+ size = 0
+ size_mode_value = 0
+
+ Short_Sp = GetChildMemberWithName(Rep_Sp, "__s")
+ if not Short_Sp:
+ raise Exception("Could not find __s")
+
+ Is_Long = GetChildMemberWithName(Short_Sp, "__is_long_")
+ Size_Sp = GetChildMemberWithName(Short_Sp, "__size_")
+ if not Size_Sp:
+ raise Exception("Could not find __size_")
+
+ if Is_Long:
+ using_bitmasks = False
+ short_mode = Is_Long.integer() == 0
+ size = Size_Sp.integer()
+ else:
+ size_mode_value = Size_Sp.integer()
+ mode_mask = 1
+ if layout == StringLayout.DSC:
+ mode_mask = 0x80
+ short_mode = (size_mode_value & mode_mask) == 0
+
+ if short_mode:
+ Location_Sp = GetChildMemberWithName(Short_Sp, "__data_")
+
+ if using_bitmasks:
+ size = ((size_mode_value >> 1) % 256)
+ if layout == StringLayout.DSC:
+ size = size_mode_value
+
+ # The string is most likely not initialized yet
+ if size > 100 or not Location_Sp:
+ raise Exception("Probably not initialized yet")
+
+ d.putCharArrayHelper(d.extractPointer(Location_Sp), size,
+ charType, d.currentItemFormat())
+ return
+
+ Location_Sp = GetChildMemberWithName(L, "__data_")
+ Size_Vo = GetChildMemberWithName(L, "__size_")
+ Capacity_Vo = GetChildMemberWithName(L, "__cap_")
+
+ if not Location_Sp or not Size_Vo or not Capacity_Vo:
+ raise Exception("Could not find Location_Sp, Size_Vo or Capacity_Vo")
+
+ size = Size_Vo.integer()
+ capacity = Capacity_Vo.integer()
+ if not using_bitmasks and layout == StringLayout.CSD:
+ capacity *= 2
+ if capacity < size:
+ raise Exception("Capacity is less than size")
+
+ d.putCharArrayHelper(d.extractPointer(Location_Sp), size,
+ charType, d.currentItemFormat())
+
+
+def std_1_string_dumper_v1(d, value):
+ charType = value['__l']['__data_'].dereference().type
+ D = None
+
+ if d.isLldb:
+ D = value[0][0][0][0]
+ elif d.isGdb:
+ D = value["__r_"].members(True)[0][0][0]
+ else:
+ raise Exception("Unknown debugger (neither gdb nor lldb)")
+
+ layoutDecider = D[0][0]
+ if not layoutDecider:
+ raise Exception("Could not find layoutDecider")
+
+ size = 0
+ size_mode_value = 0
+ short_mode = False
+ libcxx_version = 14
+
+ layoutModeIsDSC = layoutDecider.name == '__data_'
+ if (layoutModeIsDSC):
+ size_mode = D[1][1][0]
+ if not size_mode:
+ raise Exception("Could not find size_mode")
+ if not size_mode.name == '__size_':
+ size_mode = D[1][1][1]
+ if not size_mode:
+ raise Exception("Could not find size_mode")
+
+ size_mode_value = size_mode.integer()
+ short_mode = ((size_mode_value & 0x80) == 0)
+ else:
+ size_mode = D[1][0][0]
+ if not size_mode:
+ raise Exception("Could not find size_mode")
+
+ if size_mode.name == '__is_long_':
+ libcxx_version = 15
+ short_mode = (size_mode.integer() == 0)
+
+ size_mode = D[1][0][1]
+ size_mode_value = size_mode.integer()
+ else:
+ size_mode_value = size_mode.integer()
+ short_mode = ((size_mode_value & 1) == 0)
+
+ if short_mode:
+ s = D[1]
+
+ if not s:
+ raise Exception("Could not find s")
+
+ if libcxx_version == 14:
+ location_sp = s[0] if layoutModeIsDSC else s[1]
+ size = size_mode_value if layoutModeIsDSC else ((size_mode_value >> 1) % 256)
+ elif libcxx_version == 15:
+ location_sp = s[0] if layoutModeIsDSC else s[2]
+ size = size_mode_value
+
+ else:
+ l = D[0]
+ if not l:
+ raise Exception("Could not find l")
+
+ # we can use the layout_decider object as the data pointer
+ location_sp = layoutDecider if layoutModeIsDSC else l[2]
+ size_vo = l[1]
+ if not size_vo or not location_sp:
+ raise Exception("Could not find size_vo or location_sp")
+ size = size_vo.integer()
+
+ if short_mode and location_sp:
+ d.putCharArrayHelper(d.extractPointer(location_sp), size,
+ charType, d.currentItemFormat())
+ else:
+ d.putCharArrayHelper(location_sp.integer(),
+ size, charType, d.currentItemFormat())
+
+ return
+
+def qdump__std____1__string(d, value):
+ try:
+ std_1_string_dumper_v2(d, value)
+ except Exception as eV2:
+ try:
+ std_1_string_dumper_v1(d, value)
+ except Exception as eV1:
+ d.putValue("Could not parse: %s, %s" % (eV1, eV2))
+
+
+def qdump__std____1__wstring(d, value):
+ try:
+ std_1_string_dumper_v2(d, value)
+ except Exception as eV2:
+ try:
+ std_1_string_dumper_v1(d, value)
+ except Exception as eV1:
+ d.putValue("Could not parse: %s, %s" % (eV1, eV2))
+
+
+def qdump__std____1__basic_string(d, value):
+ innerType = value.type[0].name
+ if innerType in ("char", "char8_t", "char16_t"):
+ qdump__std____1__string(d, value)
+ elif innerType in ("wchar_t", "char32_t"):
+ qdump__std____1__wstring(d, value)
+ else:
+ d.warn("UNKNOWN INNER TYPE %s" % innerType)
+
+
+def qdump__std____1__shared_ptr(d, value):
+ i = value["__ptr_"]
+ if i.pointer() == 0:
+ d.putValue("(null)")
+ else:
+ d.putItem(i.dereference())
+ d.putBetterType(value.type)
+
+
+def qdump__std____1__weak_ptr(d, value):
+ return qdump__std____1__shared_ptr(d, value)
+
+
+def qdump__std____1__unique_ptr(d, value):
+ if value.type.size() == d.ptrSize():
+ p = d.extractPointer(value)
+ else:
+ _, p = value.split("pp"); # For custom deleters.
+ if p == 0:
+ d.putValue("(null)")
+ else:
+ try:
+ d.putItem(value["__value_"])
+ d.putValue(d.currentValue.value, d.currentValue.encoding)
+ except:
+ d.putItem(d.createValue(p, value.type[0]))
+ d.putBetterType(value.type)
+
+
+def qform__std____1__unordered_map():
+ return [DisplayFormat.CompactMap]
+
+
+def qdump__std____1__unordered_map(d, value):
+ (size, _) = value["__table_"]["__p2_"].split("pp")
+ d.putItemCount(size)
+
+ keyType = value.type[0]
+ valueType = value.type[1]
+ pairType = value.type[4][0]
+
+ if d.isExpanded():
+ curr = value["__table_"]["__p1_"].split("pp")[0]
+
+ def traverse_list(node):
+ while node:
+ (next_, _, pad, pair) = d.split("pp@{%s}" % (pairType.name), node)
+ yield pair.split("{%s}@{%s}" % (keyType.name, valueType.name))[::2]
+ node = next_
+
+ with Children(d, size, childType=value.type[0], maxNumChild=1000):
+ for (i, value) in zip(d.childRange(), traverse_list(curr)):
+ d.putPairItem(i, value, 'key', 'value')
+
+
+def qdump__std____1__unordered_set(d, value):
+ (size, _) = value["__table_"]["__p2_"].split("pp")
+ d.putItemCount(size)
+
+ valueType = value.type[0]
+
+ if d.isExpanded():
+ curr = value["__table_"]["__p1_"].split("pp")[0]
+
+ def traverse_list(node):
+ while node:
+ (next_, _, pad, val) = d.split("pp@{%s}" % (valueType.name), node)
+ yield val
+ node = next_
+
+ with Children(d, size, childType=value.type[0], maxNumChild=1000):
+ for (i, value) in zip(d.childRange(), traverse_list(curr)):
+ d.putSubItem(i, value)
+
+
+def qdump__std____1__unordered_multiset(d, value):
+ qdump__std____1__unordered_set(d, value)
+
+
+def qform__std____1__valarray():
+ return [DisplayFormat.ArrayPlot]
+
+
+def qdump__std____1__valarray(d, value):
+ innerType = value.type[0]
+ (begin, end) = value.split('pp')
+ size = int((end - begin) / innerType.size())
+ d.putItemCount(size)
+ d.putPlotData(begin, size, innerType)
+
+
+def qform__std____1__vector():
+ return [DisplayFormat.ArrayPlot]
+
+
+def qdump__std____1__vector(d, value):
+ qdumpHelper__std__vector__libcxx(d, value)
+
+
+def qdump__std____1__once_flag(d, value):
+ qdump__std__once_flag(d, value)
+
+
+def qdump__std____1__variant(d, value):
+ index = value['__impl']['__index']
+ index_num = int(index)
+ value_type = d.templateArgument(value.type, index_num)
+ d.putValue("<%s:%s>" % (index_num, value_type.name))
+
+ d.putNumChild(2)
+ if d.isExpanded():
+ with Children(d):
+ d.putSubItem("index", index)
+ d.putSubItem("value", value.cast(value_type))
+
+
+def qdump__std____1__optional(d, value):
+ if value['__engaged_'].integer() == 0:
+ d.putSpecialValue("empty")
+ else:
+ d.putItem(value['#1']['__val_'])
+
+
+def qdump__std____1__tuple(d, value):
+ values = []
+ for member in value['__base_'].members(False):
+ values.append(member['__value_'])
+ d.putItemCount(len(values))
+ d.putNumChild(len(values))
+ if d.isExpanded():
+ with Children(d):
+ count = 0
+ for internal_value in values:
+ d.putSubItem("[%i]" % count, internal_value)
+ count += 1