forked from qt-creator/qt-creator
Debugger: Use direct memory instead of member access
This introduces a dumper types abstraction layer with classes
Dumper.{Value,Type,Field} wrapping either gdb.{Value,Type,Field}
or lldb.{SBValue,SBType,SBField} and uses it to move
to more direct memory accesses in the dumper implementation.
This way we can use duck typing for artificial intermediate
objects eliminating the need for {gdb.Value,lldb.SBValue}.cast()
in some case which are flaky in general and typically not
available in release builds.
As consequence QRegion and QVariant dumper work without debug
info now.
Change-Id: Iea2411175ef67f2bf651ee7eaade9879ed5ceba1
Reviewed-by: Christian Stenger <christian.stenger@qt.io>
This commit is contained in:
@@ -26,63 +26,55 @@
|
||||
from dumper import *
|
||||
|
||||
def qdump__boost__bimaps__bimap(d, value):
|
||||
#leftType = d.templateArgument(value.type, 0)
|
||||
#rightType = d.templateArgument(value.type, 1)
|
||||
size = int(value["core"]["node_count"])
|
||||
#leftType = value.type[0]
|
||||
#rightType = value.type[1]
|
||||
size = value["core"]["node_count"].integer()
|
||||
d.putItemCount(size)
|
||||
if d.isExpanded():
|
||||
d.putPlainChildren(value)
|
||||
|
||||
|
||||
def qdump__boost__optional(d, value):
|
||||
if int(value["m_initialized"]) == 0:
|
||||
innerType = value.type[0]
|
||||
(initialized, pad, payload) = d.split('b@{%s}' % innerType, value)
|
||||
if initialized:
|
||||
d.putItem(payload)
|
||||
d.putBetterType(value.type)
|
||||
else:
|
||||
d.putSpecialValue("uninitialized")
|
||||
d.putNumChild(0)
|
||||
else:
|
||||
type = d.templateArgument(value.type, 0)
|
||||
storage = value["m_storage"]
|
||||
if d.isReferenceType(type):
|
||||
d.putItem(storage.cast(type.target().pointer()).dereference())
|
||||
else:
|
||||
d.putItem(storage.cast(type))
|
||||
d.putBetterType(value.type)
|
||||
|
||||
|
||||
def qdump__boost__shared_ptr(d, value):
|
||||
# s boost::shared_ptr<int>
|
||||
# px 0x0 int *
|
||||
# pn boost::detail::shared_count
|
||||
# pi_ 0x0 boost::detail::sp_counted_base *
|
||||
# px 0x0 int *
|
||||
if d.isNull(value["pn"]["pi_"]):
|
||||
(px, pi) = value.split("pp")
|
||||
if pi == 0:
|
||||
d.putValue("(null)")
|
||||
d.putNumChild(0)
|
||||
return
|
||||
|
||||
if d.isNull(value["px"]):
|
||||
if px == 0:
|
||||
d.putValue("(null)")
|
||||
d.putNumChild(0)
|
||||
return
|
||||
|
||||
countedbase = value["pn"]["pi_"].dereference()
|
||||
weakcount = int(countedbase["weak_count_"])
|
||||
usecount = int(countedbase["use_count_"])
|
||||
(vptr, usecount, weakcount) = d.split('pii', pi)
|
||||
d.check(weakcount >= 0)
|
||||
d.check(weakcount <= usecount)
|
||||
d.check(usecount <= 10*1000*1000)
|
||||
|
||||
val = value["px"].dereference()
|
||||
type = val.type
|
||||
# handle boost::shared_ptr<int>::element_type as int
|
||||
if str(type).endswith(">::element_type"):
|
||||
type = type.strip_typedefs()
|
||||
|
||||
if d.isSimpleType(type):
|
||||
innerType = value.type[0]
|
||||
val = d.createValue(px, innerType)
|
||||
if innerType.isSimpleType():
|
||||
d.putNumChild(3)
|
||||
d.putItem(val)
|
||||
d.putBetterType(value.type)
|
||||
else:
|
||||
d.putEmptyValue()
|
||||
|
||||
d.putNumChild(3)
|
||||
if d.isExpanded():
|
||||
with Children(d, 3):
|
||||
d.putSubItem("data", val)
|
||||
@@ -92,10 +84,10 @@ def qdump__boost__shared_ptr(d, value):
|
||||
|
||||
def qdump__boost__container__list(d, value):
|
||||
r = value["members_"]["m_icont"]["data_"]["root_plus_size_"]
|
||||
n = toInteger(r["size_"])
|
||||
n = r["size_"].integer()
|
||||
d.putItemCount(n)
|
||||
if d.isExpanded():
|
||||
innerType = d.templateArgument(value.type, 0)
|
||||
innerType = value.type[0]
|
||||
offset = 2 * d.ptrSize()
|
||||
with Children(d, n):
|
||||
try:
|
||||
@@ -103,42 +95,42 @@ def qdump__boost__container__list(d, value):
|
||||
except:
|
||||
root = r["m_header"]
|
||||
p = root["next_"]
|
||||
for i in xrange(n):
|
||||
d.putSubItem("%s" % i, d.createValue(d.pointerValue(p) + offset, innerType))
|
||||
for i in d.childRange():
|
||||
d.putSubItem(i, d.createValue(p.integer() + offset, innerType))
|
||||
p = p["next_"]
|
||||
|
||||
|
||||
def qdump__boost__gregorian__date(d, value):
|
||||
d.putValue(int(value["days_"]), "juliandate")
|
||||
d.putValue(value.integer(), "juliandate")
|
||||
d.putNumChild(0)
|
||||
|
||||
|
||||
def qdump__boost__posix_time__ptime(d, value):
|
||||
ms = int(int(value["time_"]["time_count_"]["value_"]) / 1000)
|
||||
ms = int(value.integer() / 1000)
|
||||
d.putValue("%s/%s" % divmod(ms, 86400000), "juliandateandmillisecondssincemidnight")
|
||||
d.putNumChild(0)
|
||||
|
||||
|
||||
def qdump__boost__posix_time__time_duration(d, value):
|
||||
d.putValue(int(int(value["ticks_"]["value_"]) / 1000), "millisecondssincemidnight")
|
||||
d.putValue(int(value.integer() / 1000), "millisecondssincemidnight")
|
||||
d.putNumChild(0)
|
||||
|
||||
|
||||
def qdump__boost__unordered__unordered_set(d, value):
|
||||
base = d.addressOf(value)
|
||||
base = value.address()
|
||||
ptrSize = d.ptrSize()
|
||||
size = d.extractInt(base + 2 * ptrSize)
|
||||
d.putItemCount(size)
|
||||
|
||||
if d.isExpanded():
|
||||
innerType = d.templateArgument(value.type, 0)
|
||||
innerType = value.type[0]
|
||||
bucketCount = d.extractInt(base + ptrSize)
|
||||
#warn("A BUCKET COUNT: %s" % bucketCount)
|
||||
#warn("X BUCKET COUNT: %s" % d.parseAndEvaluate("s1.table_.bucket_count_"))
|
||||
try:
|
||||
# boost 1.58
|
||||
table = value["table_"]
|
||||
bucketsAddr = toInteger(table["buckets_"])
|
||||
bucketsAddr = table["buckets_"].integer()
|
||||
#warn("A BUCKETS: 0x%x" % bucketsAddr)
|
||||
#warn("X BUCKETS: %s" % d.parseAndEvaluate("s1.table_.buckets_"))
|
||||
lastBucketAddr = bucketsAddr + bucketCount * ptrSize
|
||||
@@ -159,7 +151,7 @@ def qdump__boost__unordered__unordered_set(d, value):
|
||||
item = d.extractPointer(item)
|
||||
except:
|
||||
# boost 1.48
|
||||
offset = int((innerType.sizeof + ptrSize - 1) / ptrSize) * ptrSize
|
||||
offset = int((innerType.size() + ptrSize - 1) / ptrSize) * ptrSize
|
||||
with Children(d, size, maxNumChild=10000):
|
||||
afterBuckets = d.extractPointer(base + 5 * ptrSize)
|
||||
afterBuckets += bucketCount * ptrSize
|
||||
|
||||
+1557
-457
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -35,69 +35,71 @@ def qdump____m128(d, value):
|
||||
d.putEmptyValue()
|
||||
d.putNumChild(1)
|
||||
if d.isExpanded():
|
||||
d.putArrayData(value.address, 4, d.lookupType("float"))
|
||||
d.putArrayData(value.address(), 4, d.lookupType("float"))
|
||||
|
||||
def qdump____m256(d, value):
|
||||
d.putEmptyValue()
|
||||
d.putNumChild(1)
|
||||
if d.isExpanded():
|
||||
d.putArrayData(value.address, 8, d.lookupType("float"))
|
||||
d.putArrayData(value.address(), 8, d.lookupType("float"))
|
||||
|
||||
def qdump____m512(d, value):
|
||||
d.putEmptyValue()
|
||||
d.putNumChild(1)
|
||||
if d.isExpanded():
|
||||
d.putArrayData(value.address, 16, d.lookupType("float"))
|
||||
d.putArrayData(value.address(), 16, d.lookupType("float"))
|
||||
|
||||
def qdump____m128d(d, value):
|
||||
d.putEmptyValue()
|
||||
d.putNumChild(1)
|
||||
if d.isExpanded():
|
||||
d.putArrayData(value.address, 2, d.lookupType("double"))
|
||||
d.putArrayData(value.address(), 2, d.lookupType("double"))
|
||||
|
||||
def qdump____m256d(d, value):
|
||||
d.putEmptyValue()
|
||||
d.putNumChild(1)
|
||||
if d.isExpanded():
|
||||
d.putArrayData(value.address, 4, d.lookupType("double"))
|
||||
d.putArrayData(value.address(), 4, d.lookupType("double"))
|
||||
|
||||
def qdump____m512d(d, value):
|
||||
d.putEmptyValue()
|
||||
d.putNumChild(1)
|
||||
if d.isExpanded():
|
||||
d.putArrayData(value.address, 8, d.lookupType("double"))
|
||||
d.putArrayData(value.address(), 8, d.lookupType("double"))
|
||||
|
||||
def qdump____m128i(d, value):
|
||||
data = d.readMemory(value.address, 16)
|
||||
data = d.hexencode(value.data())
|
||||
d.putValue(':'.join("%04x" % int(data[i:i+4], 16) for i in xrange(0, 32, 4)))
|
||||
d.putNumChild(4)
|
||||
if d.isExpanded():
|
||||
with Children(d):
|
||||
d.putArrayItem("uint8x16", value.address, 16, "unsigned char")
|
||||
d.putArrayItem("uint16x8", value.address, 8, "unsigned short")
|
||||
d.putArrayItem("uint32x4", value.address, 4, "unsigned int")
|
||||
d.putArrayItem("uint64x2", value.address, 2, "unsigned long long")
|
||||
addr = value.address()
|
||||
d.putArrayItem("uint8x16", addr, 16, "unsigned char")
|
||||
d.putArrayItem("uint16x8", addr, 8, "unsigned short")
|
||||
d.putArrayItem("uint32x4", addr, 4, "unsigned int")
|
||||
d.putArrayItem("uint64x2", addr, 2, "unsigned long long")
|
||||
|
||||
def qdump____m256i(d, value):
|
||||
data = d.readMemory(value.address, 32)
|
||||
data = d.hexencode(value.data())
|
||||
d.putValue(':'.join("%04x" % int(data[i:i+4], 16) for i in xrange(0, 64, 4)))
|
||||
d.putNumChild(4)
|
||||
if d.isExpanded():
|
||||
with Children(d):
|
||||
d.putArrayItem("uint8x32", value.address, 32, "unsigned char")
|
||||
d.putArrayItem("uint16x16", value.address, 16, "unsigned short")
|
||||
d.putArrayItem("uint32x8", value.address, 8, "unsigned int")
|
||||
d.putArrayItem("uint64x4", value.address, 4, "unsigned long long")
|
||||
addr = value.address()
|
||||
d.putArrayItem("uint8x32", addr, 32, "unsigned char")
|
||||
d.putArrayItem("uint16x16", addr, 16, "unsigned short")
|
||||
d.putArrayItem("uint32x8", addr, 8, "unsigned int")
|
||||
d.putArrayItem("uint64x4", addr, 4, "unsigned long long")
|
||||
|
||||
def qdump____m512i(d, value):
|
||||
data = d.readMemory(value.address, 64)
|
||||
data = d.hexencode(value.data())
|
||||
d.putValue(':'.join("%04x" % int(data[i:i+4], 16) for i in xrange(0, 64, 4))
|
||||
+ ', ' + ':'.join("%04x" % int(data[i:i+4], 16) for i in xrange(64, 128, 4)))
|
||||
d.putNumChild(2)
|
||||
if d.isExpanded():
|
||||
with Children(d):
|
||||
d.putArrayItem("uint32x16", value.address, 16, "unsigned int")
|
||||
d.putArrayItem("uint64x8", value.address, 8, "unsigned long long")
|
||||
d.putArrayItem("uint32x16", value.address(), 16, "unsigned int")
|
||||
d.putArrayItem("uint64x8", value.address(), 8, "unsigned long long")
|
||||
|
||||
#######################################################################
|
||||
#
|
||||
@@ -109,11 +111,11 @@ def qdump____m512i(d, value):
|
||||
# return "Transposed"
|
||||
|
||||
def qdump__Eigen__Matrix(d, value):
|
||||
innerType = d.templateArgument(value.type, 0)
|
||||
options = d.numericTemplateArgument(value.type, 3)
|
||||
innerType = value.type.templateArgument(0, False)
|
||||
argRow = value.type.templateArgument(1, True)
|
||||
argCol = value.type.templateArgument(2, True)
|
||||
options = value.type.templateArgument(3, True)
|
||||
rowMajor = (int(options) & 0x1)
|
||||
argRow = d.numericTemplateArgument(value.type, 1)
|
||||
argCol = d.numericTemplateArgument(value.type, 2)
|
||||
# The magic dimension value is -1 in Eigen3, but 10000 in Eigen2.
|
||||
# 10000 x 10000 matrices are rare, vectors of dim 10000 less so.
|
||||
# So "fix" only the matrix case:
|
||||
@@ -123,12 +125,13 @@ def qdump__Eigen__Matrix(d, value):
|
||||
if argCol != -1 and argRow != -1:
|
||||
nrows = argRow
|
||||
ncols = argCol
|
||||
p = d.createPointerValue(d.addressOf(value), innerType)
|
||||
p = value.address()
|
||||
else:
|
||||
storage = value["m_storage"]
|
||||
nrows = toInteger(storage["m_rows"]) if argRow == -1 else argRow
|
||||
ncols = toInteger(storage["m_cols"]) if argCol == -1 else argCol
|
||||
p = d.createValue(d.addressOf(value), innerType.pointer())
|
||||
nrows = storage["m_rows"].integer() if argRow == -1 else argRow
|
||||
ncols = storage["m_cols"].integer() if argCol == -1 else argCol
|
||||
p = storage["m_data"].integer()
|
||||
innerSize = innerType.size()
|
||||
d.putValue("(%s x %s), %s" % (nrows, ncols, ["ColumnMajor", "RowMajor"][rowMajor]))
|
||||
d.putField("keeporder", "1")
|
||||
d.putNumChild(nrows * ncols)
|
||||
@@ -141,19 +144,19 @@ def qdump__Eigen__Matrix(d, value):
|
||||
with Children(d, nrows * ncols, childType=innerType):
|
||||
if ncols == 1 or nrows == 1:
|
||||
for i in range(0, min(nrows * ncols, 10000)):
|
||||
d.putSubItem(i, (p + i).dereference())
|
||||
d.putSubItem(i, d.createValue(p + i * innerSize, innerType))
|
||||
elif rowMajor == 1:
|
||||
s = 0
|
||||
for i in range(0, nnrows):
|
||||
for j in range(0, nncols):
|
||||
v = (p + i * ncols + j).dereference()
|
||||
v = d.createValue(p + (i * ncols + j) * innerSize, innerType)
|
||||
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):
|
||||
v = (p + i + j * nrows).dereference()
|
||||
v = d.createValue(p + (i + j * nrows) * innerSize, innerType)
|
||||
d.putNamedSubItem(s, v, "[%d,%d]" % (i, j))
|
||||
s = s + 1
|
||||
|
||||
@@ -362,7 +365,7 @@ def qdump__WTF__String(d, value):
|
||||
d.check(0 <= stringLength and stringLength <= 100000000)
|
||||
|
||||
# WTF::StringImpl* -> WTF::StringImpl -> sizeof(WTF::StringImpl)
|
||||
offsetToData = data.type.target().sizeof
|
||||
offsetToData = data.type.target().size()
|
||||
bufferPtr = data.cast(d.charPtrType()) + offsetToData
|
||||
|
||||
is8Bit = data['m_is8Bit']
|
||||
|
||||
+699
-767
File diff suppressed because it is too large
Load Diff
@@ -29,10 +29,10 @@ def qform__std__array():
|
||||
return arrayForms()
|
||||
|
||||
def qdump__std__array(d, value):
|
||||
size = d.numericTemplateArgument(value.type, 1)
|
||||
size = value.type.templateArgument(1, numeric=True)
|
||||
d.putItemCount(size)
|
||||
if d.isExpanded():
|
||||
d.putPlotData(d.addressOf(value), size, d.templateArgument(value.type, 0))
|
||||
d.putPlotData(value.address(), size, value.type[0])
|
||||
|
||||
|
||||
def qform__std____1__array():
|
||||
@@ -43,56 +43,69 @@ def qdump__std____1__array(d, value):
|
||||
|
||||
|
||||
def qdump__std__complex(d, value):
|
||||
innerType = d.templateArgument(value.type, 0)
|
||||
real = value.cast(innerType)
|
||||
imag = d.createValue(d.addressOf(value) + innerType.sizeof, innerType)
|
||||
d.putValue("(%f, %f)" % (real, imag));
|
||||
d.putNumChild(2)
|
||||
innerType = value.type[0]
|
||||
(real, imag) = value.split('{%s}{%s}' % (innerType.name, innerType.name))
|
||||
d.putValue("(%s, %s)" % (real.display(), imag.display()))
|
||||
if d.isExpanded():
|
||||
with Children(d, 2, childType=innerType):
|
||||
d.putSubItem("real", real)
|
||||
d.putSubItem("imag", imag)
|
||||
|
||||
def qdump__std____1__complex(d, value):
|
||||
qdump__std__complex(d, value)
|
||||
|
||||
|
||||
def qdump__std__deque(d, value):
|
||||
if d.isQnxTarget():
|
||||
qdump__std__deque__QNX(d, value)
|
||||
return
|
||||
|
||||
innerType = d.templateArgument(value.type, 0)
|
||||
innerSize = innerType.sizeof
|
||||
innerType = value.type[0]
|
||||
innerSize = innerType.size()
|
||||
bufsize = 1
|
||||
if innerSize < 512:
|
||||
bufsize = int(512 / innerSize)
|
||||
|
||||
#(mapptr, mapsize, startCur, startFirst, startLast, startNode,
|
||||
# finishCur, finishFirst, finishLast, finishNode) = d.split("pppppppppp", value)
|
||||
#
|
||||
# numInBuf = bufsize * (int((finishNode - startNode) / innerSize) - 1)
|
||||
# numFirstItems = int((startLast - startCur) / innerSize)
|
||||
# numLastItems = int((finishCur - finishFirst) / innerSize)
|
||||
|
||||
impl = value["_M_impl"]
|
||||
start = impl["_M_start"]
|
||||
finish = impl["_M_finish"]
|
||||
size = bufsize * toInteger(finish["_M_node"] - start["_M_node"] - 1)
|
||||
size += toInteger(finish["_M_cur"] - finish["_M_first"])
|
||||
size += toInteger(start["_M_last"] - start["_M_cur"])
|
||||
size = bufsize * int((finish["_M_node"].integer() - start["_M_node"].integer()) / d.ptrSize() - 1)
|
||||
size += int((finish["_M_cur"].integer() - finish["_M_first"].integer()) / innerSize)
|
||||
size += int((start["_M_last"].integer() - start["_M_cur"].integer()) / innerSize)
|
||||
|
||||
d.check(0 <= size and size <= 1000 * 1000 * 1000)
|
||||
d.putItemCount(size)
|
||||
if d.isExpanded():
|
||||
with Children(d, size, maxNumChild=2000, childType=innerType):
|
||||
pcur = start["_M_cur"]
|
||||
pcur = start["_M_cur"].integer()
|
||||
pfirst = start["_M_first"]
|
||||
plast = start["_M_last"]
|
||||
plast = start["_M_last"].integer()
|
||||
pnode = start["_M_node"]
|
||||
for i in d.childRange():
|
||||
d.putSubItem(i, pcur.dereference())
|
||||
pcur += 1
|
||||
if toInteger(pcur) == toInteger(plast):
|
||||
newnode = pnode + 1
|
||||
d.putSubItem(i, d.createValue(pcur, innerType))
|
||||
pcur += innerSize
|
||||
if pcur == plast:
|
||||
# FIXME: Remove pointer operation.
|
||||
newnode = pnode + 1 # Type is std::_Deque_iterator<Foo, Foo&, Foo*>::_Map_pointer\"} a.k.a 'Foo **'
|
||||
#warn("TYPE: %s" % pnode.type)
|
||||
#warn("PNODE: 0x%x %s" % (pnode.pointer(), pnode))
|
||||
#warn("NEWNODE: 0x%x %s" % (newnode.pointer(), newnode))
|
||||
pnode = newnode
|
||||
pfirst = newnode.dereference()
|
||||
plast = pfirst + bufsize
|
||||
#warn("PNODE 2: 0x%x %s" % (pnode.pointer(), pnode))
|
||||
pfirst = newnode.dereference().integer()
|
||||
plast = pfirst + bufsize * d.ptrSize()
|
||||
pcur = pfirst
|
||||
|
||||
def qdump__std__deque__QNX(d, value):
|
||||
innerType = d.templateArgument(value.type, 0)
|
||||
innerSize = innerType.sizeof
|
||||
innerType = value.type[0]
|
||||
innerSize = innerType.size()
|
||||
if innerSize <= 1:
|
||||
bufsize = 16
|
||||
elif innerSize <= 2:
|
||||
@@ -130,25 +143,27 @@ def qdump__std__list(d, value):
|
||||
qdump__std__list__QNX(d, value)
|
||||
return
|
||||
|
||||
impl = value["_M_impl"]
|
||||
node = impl["_M_node"]
|
||||
head = d.addressOf(node)
|
||||
size = 0
|
||||
pp = d.extractPointer(head)
|
||||
while head != pp and size <= 1001:
|
||||
size += 1
|
||||
pp = d.extractPointer(pp)
|
||||
|
||||
d.putItemCount(size, 1000)
|
||||
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():
|
||||
p = node["_M_next"]
|
||||
innerType = d.templateArgument(value.type, 0)
|
||||
p = d.extractPointer(value)
|
||||
innerType = value.type[0]
|
||||
with Children(d, size, maxNumChild=1000, childType=innerType):
|
||||
for i in d.childRange():
|
||||
innerPointer = innerType.pointer()
|
||||
d.putSubItem(i, (p + 1).cast(innerPointer).dereference())
|
||||
p = p["_M_next"]
|
||||
d.putSubItem(i, d.createValue(p + 2 * d.ptrSize(), innerType))
|
||||
p = d.extractPointer(p)
|
||||
|
||||
def qdump__std__list__QNX(d, value):
|
||||
node = value["_Myhead"]
|
||||
@@ -158,8 +173,7 @@ def qdump__std__list__QNX(d, value):
|
||||
|
||||
if d.isExpanded():
|
||||
p = node["_Next"]
|
||||
innerType = d.templateArgument(value.type, 0)
|
||||
with Children(d, size, maxNumChild=1000, childType=innerType):
|
||||
with Children(d, size, maxNumChild=1000, childType=value.type[0]):
|
||||
for i in d.childRange():
|
||||
d.putSubItem(i, p['_Myval'])
|
||||
p = p["_Next"]
|
||||
@@ -170,6 +184,30 @@ def qdump__std____debug__list(d, value):
|
||||
def qdump__std____cxx11__list(d, value):
|
||||
qdump__std__list(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 qform__std__map():
|
||||
return mapForms()
|
||||
|
||||
@@ -178,30 +216,37 @@ def qdump__std__map(d, value):
|
||||
qdump__std__map__QNX(d, value)
|
||||
return
|
||||
|
||||
# stuff is actually (color, pad) with 'I@', but we can save cycles/
|
||||
(compare, stuff, parent, left, right, size) = value.split('pppppp')
|
||||
impl = value["_M_t"]["_M_impl"]
|
||||
size = int(impl["_M_node_count"])
|
||||
d.check(0 <= size and size <= 100*1000*1000)
|
||||
d.putItemCount(size)
|
||||
|
||||
if d.isExpanded():
|
||||
pairType = d.templateArgument(d.templateArgument(value.type, 3), 0)
|
||||
pairType = value.type[3][0]
|
||||
pairPointer = pairType.pointer()
|
||||
with PairedChildren(d, size, pairType=pairType, maxNumChild=1000):
|
||||
node = impl["_M_header"]["_M_left"]
|
||||
typeCode = "p@{%s}@{%s}" % (pairType[0], pairType[1])
|
||||
for i in d.childRange():
|
||||
with SubItem(d, i):
|
||||
pair = (node + 1).cast(pairPointer).dereference()
|
||||
d.putPair(pair, i)
|
||||
if d.isNull(node["_M_right"]):
|
||||
pair = (node + 1).cast(pairPointer).dereference()
|
||||
d.putPairItem(i, pair)
|
||||
#(pp, pad1, key, pad2, value) = d.split(typeCode, node.integer())
|
||||
#d.putPairItem(i, (key, value))
|
||||
if node["_M_right"].integer() == 0:
|
||||
parent = node["_M_parent"]
|
||||
while node == parent["_M_right"]:
|
||||
while True:
|
||||
if node.integer() != parent["_M_right"].integer():
|
||||
break
|
||||
node = parent
|
||||
parent = parent["_M_parent"]
|
||||
if node["_M_right"] != parent:
|
||||
node = parent
|
||||
else:
|
||||
node = node["_M_right"]
|
||||
while not d.isNull(node["_M_left"]):
|
||||
while True:
|
||||
if node["_M_left"].integer() == 0:
|
||||
break
|
||||
node = node["_M_left"]
|
||||
|
||||
def qdump__std__map__QNX(d, value):
|
||||
@@ -210,16 +255,16 @@ def qdump__std__map__QNX(d, value):
|
||||
d.putItemCount(size)
|
||||
|
||||
if d.isExpanded():
|
||||
keyType = d.templateArgument(value.type, 0)
|
||||
valueType = d.templateArgument(value.type, 1)
|
||||
keyType = value.type[0]
|
||||
valueType = value.type[1]
|
||||
try:
|
||||
# Does not work on gcc 4.4, the allocator type (fourth template
|
||||
# argument) seems not to be available.
|
||||
pairType = d.templateArgument(d.templateArgument(value.type, 3), 0)
|
||||
# Does not work on gcc 4.4, the allocator type
|
||||
# (fourth template argument) is not available.
|
||||
pairType = value.type[3][0]
|
||||
pairPointer = pairType.pointer()
|
||||
except:
|
||||
# So use this as workaround:
|
||||
pairType = d.templateArgument(impl.type, 1)
|
||||
pairType = impl.type[1]
|
||||
pairPointer = pairType.pointer()
|
||||
isCompact = d.isMapCompact(keyType, valueType)
|
||||
innerType = pairType
|
||||
@@ -278,59 +323,60 @@ def qform__std__multimap():
|
||||
def qdump__std__multimap(d, value):
|
||||
return qdump__std__map(d, value)
|
||||
|
||||
def stdTreeIteratorHelper(d, value):
|
||||
node = value["_M_node"]
|
||||
def qdumpHelper__std__tree__iterator(d, value, isSet=False):
|
||||
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]
|
||||
valueType = treeType[1]
|
||||
node = value["_M_node"].dereference() # std::_Rb_tree_node_base
|
||||
d.putNumChild(1)
|
||||
d.putEmptyValue()
|
||||
if d.isExpanded():
|
||||
with Children(d):
|
||||
nodeTypeName = str(value.type).replace("_Rb_tree_iterator", "_Rb_tree_node", 1)
|
||||
nodeTypeName = nodeTypeName.replace("_Rb_tree_const_iterator", "_Rb_tree_node", 1)
|
||||
nodeType = d.lookupType(nodeTypeName + '*')
|
||||
nnode = node.cast(nodeType).dereference()
|
||||
try:
|
||||
data = nnode["_M_value_field"]
|
||||
except: # GCC 5.x, C++11.
|
||||
data = nnode["_M_storage"] # __gnu_cxx::__aligned_membuf<T>
|
||||
data = data.cast(d.templateArgument(data.type, 0))
|
||||
first = d.childWithName(data, "first")
|
||||
if first:
|
||||
d.putSubItem("first", first)
|
||||
d.putSubItem("second", data["second"])
|
||||
if isSet:
|
||||
typecode = 'pppp@{%s}' % keyType
|
||||
(color, parent, left, right, pad1, key) = d.split(typecode, node)
|
||||
d.putSubItem("value", key)
|
||||
else:
|
||||
d.putSubItem("value", data)
|
||||
with SubItem(d, "node"):
|
||||
typecode = 'pppp@{%s}@{%s}' % (keyType, valueType)
|
||||
(color, parent, left, right, pad1, key, pad2, value) = d.split(typecode, node)
|
||||
d.putSubItem("first", key)
|
||||
d.putSubItem("second", value)
|
||||
with SubItem(d, "[node]"):
|
||||
d.putNumChild(1)
|
||||
d.putEmptyValue()
|
||||
d.putType(" ")
|
||||
if d.isExpanded():
|
||||
with Children(d):
|
||||
d.putSubItem("color", node["_M_color"])
|
||||
d.putSubItem("left", node["_M_left"])
|
||||
d.putSubItem("right", node["_M_right"])
|
||||
d.putSubItem("parent", node["_M_parent"])
|
||||
|
||||
#d.putSubItem("color", color)
|
||||
nodeType = node.type.pointer()
|
||||
d.putSubItem("left", d.createValue(left, nodeType))
|
||||
d.putSubItem("right", d.createValue(right, nodeType))
|
||||
d.putSubItem("parent", d.createValue(parent, nodeType))
|
||||
|
||||
def qdump__std___Rb_tree_iterator(d, value):
|
||||
stdTreeIteratorHelper(d, value)
|
||||
qdumpHelper__std__tree__iterator(d, value)
|
||||
|
||||
def qdump__std___Rb_tree_const_iterator(d, value):
|
||||
stdTreeIteratorHelper(d, value)
|
||||
qdumpHelper__std__tree__iterator(d, value)
|
||||
|
||||
def qdump__std__map__iterator(d, value):
|
||||
stdTreeIteratorHelper(d, value)
|
||||
qdumpHelper__std__tree__iterator(d, value)
|
||||
|
||||
def qdump____gnu_debug___Safe_iterator(d, value):
|
||||
d.putItem(value["_M_current"])
|
||||
|
||||
def qdump__std__map__const_iterator(d, value):
|
||||
stdTreeIteratorHelper(d, value)
|
||||
qdumpHelper__std__tree__iterator(d, value)
|
||||
|
||||
def qdump__std__set__iterator(d, value):
|
||||
stdTreeIteratorHelper(d, value)
|
||||
qdumpHelper__std__tree__iterator(d, value, True)
|
||||
|
||||
def qdump__std__set__const_iterator(d, value):
|
||||
stdTreeIteratorHelper(d, value)
|
||||
qdumpHelper__std__tree__iterator(d, value, True)
|
||||
|
||||
def qdump__std____cxx1998__set(d, value):
|
||||
qdump__std__set(d, value)
|
||||
@@ -341,16 +387,16 @@ def qdump__std__set(d, value):
|
||||
return
|
||||
|
||||
impl = value["_M_t"]["_M_impl"]
|
||||
size = int(impl["_M_node_count"])
|
||||
size = impl["_M_node_count"].integer()
|
||||
d.check(0 <= size and size <= 100*1000*1000)
|
||||
d.putItemCount(size)
|
||||
if d.isExpanded():
|
||||
valueType = d.templateArgument(value.type, 0)
|
||||
valueType = value.type[0]
|
||||
node = impl["_M_header"]["_M_left"]
|
||||
with Children(d, size, maxNumChild=1000, childType=valueType):
|
||||
for i in d.childRange():
|
||||
d.putSubItem(i, (node + 1).cast(valueType.pointer()).dereference())
|
||||
if d.isNull(node["_M_right"]):
|
||||
if node["_M_right"].integer() == 0:
|
||||
parent = node["_M_parent"]
|
||||
while node == parent["_M_right"]:
|
||||
node = parent
|
||||
@@ -359,7 +405,7 @@ def qdump__std__set(d, value):
|
||||
node = parent
|
||||
else:
|
||||
node = node["_M_right"]
|
||||
while not d.isNull(node["_M_left"]):
|
||||
while node["_M_left"].integer() != 0:
|
||||
node = node["_M_left"]
|
||||
|
||||
def qdump__std__set__QNX(d, value):
|
||||
@@ -367,11 +413,10 @@ def qdump__std__set__QNX(d, value):
|
||||
d.check(0 <= size and size <= 100*1000*1000)
|
||||
d.putItemCount(size)
|
||||
if d.isExpanded():
|
||||
valueType = d.templateArgument(value.type, 0)
|
||||
head = value['_Myhead']
|
||||
node = head['_Left']
|
||||
nodeType = head.type
|
||||
with Children(d, size, maxNumChild=1000, childType=valueType):
|
||||
with Children(d, size, maxNumChild=1000, childType=value.type[0]):
|
||||
for i in d.childRange():
|
||||
d.putSubItem(i, node.cast(nodeType).dereference()['_Myval'])
|
||||
if not node['_Right']['_Isnil']:
|
||||
@@ -393,7 +438,7 @@ def std1TreeMin(d, node):
|
||||
# return __x;
|
||||
#
|
||||
left = node['__left_']
|
||||
if not d.isNull(left):
|
||||
if left.integer():
|
||||
node = left
|
||||
return node
|
||||
|
||||
@@ -402,7 +447,7 @@ def std1TreeIsLeftChild(d, node):
|
||||
# return __x == __x->__parent_->__left_;
|
||||
#
|
||||
other = node['__parent_']['__left_']
|
||||
return toInteger(node) == toInteger(other)
|
||||
return node.integer() == other.integer()
|
||||
|
||||
|
||||
def std1TreeNext(d, node):
|
||||
@@ -414,7 +459,7 @@ def std1TreeNext(d, node):
|
||||
# return __x->__parent_;
|
||||
#
|
||||
right = node['__right_']
|
||||
if not d.isNull(right):
|
||||
if right.integer():
|
||||
return std1TreeMin(d, right)
|
||||
while not std1TreeIsLeftChild(d, node):
|
||||
node = node['__parent_']
|
||||
@@ -422,13 +467,13 @@ def std1TreeNext(d, node):
|
||||
|
||||
def qdump__std____1__set(d, value):
|
||||
tree = value["__tree_"]
|
||||
base3 = d.addressOf(tree["__pair3_"])
|
||||
base3 = tree["__pair3_"].address()
|
||||
size = d.extractUInt(base3)
|
||||
d.check(size <= 100*1000*1000)
|
||||
d.putItemCount(size)
|
||||
if d.isExpanded():
|
||||
# type of node is std::__1::__tree_node<Foo, void *>::value_type
|
||||
valueType = d.templateArgument(value.type, 0)
|
||||
valueType = value.type[0]
|
||||
d.putFields(tree)
|
||||
node = tree["__begin_node_"]
|
||||
nodeType = node.type
|
||||
@@ -444,25 +489,24 @@ def qform__std____1__map():
|
||||
|
||||
def qdump__std____1__map(d, value):
|
||||
tree = value["__tree_"]
|
||||
base3 = d.addressOf(tree["__pair3_"])
|
||||
base3 = tree["__pair3_"].address()
|
||||
size = d.extractUInt(base3)
|
||||
d.check(size <= 100*1000*1000)
|
||||
d.putItemCount(size)
|
||||
if d.isExpanded():
|
||||
# type of node is std::__1::__tree_node<Foo, Bar>::value_type
|
||||
valueType = d.templateArgument(value.type, 0)
|
||||
valueType = value.type[0]
|
||||
node = tree["__begin_node_"]
|
||||
nodeType = node.type
|
||||
pairType = d.templateArgument(d.templateArgument(value.type, 3), 0)
|
||||
pairType = value.type[3][0]
|
||||
with PairedChildren(d, size, pairType=pairType, maxNumChild=1000):
|
||||
node = tree["__begin_node_"]
|
||||
nodeType = node.type
|
||||
for i in d.childRange():
|
||||
with SubItem(d, i):
|
||||
# There's possibly also:
|
||||
#pair = node['__value_']['__nc']
|
||||
pair = node['__value_']['__cc']
|
||||
d.putPair(pair, i)
|
||||
# There's possibly also:
|
||||
#pair = node['__value_']['__nc']
|
||||
pair = node['__value_']['__cc']
|
||||
d.putPairItem(i, pair)
|
||||
node = std1TreeNext(d, node).cast(nodeType)
|
||||
|
||||
def qform__std____1__multimap():
|
||||
@@ -473,7 +517,7 @@ def qdump__std____1__multimap(d, value):
|
||||
|
||||
def qdump__std__stack(d, value):
|
||||
d.putItem(value["c"])
|
||||
d.putType(str(value.type))
|
||||
d.putBetterType(value.type)
|
||||
|
||||
def qdump__std____debug__stack(d, value):
|
||||
qdump__std__stack(d, value)
|
||||
@@ -483,29 +527,27 @@ def qform__std__string():
|
||||
Utf8StringFormat, SeparateUtf8StringFormat ]
|
||||
|
||||
def qdump__std__string(d, value):
|
||||
qdump__std__stringHelper1(d, value, 1, d.currentItemFormat())
|
||||
qdumpHelper_std__string(d, value, d.createType("char"), d.currentItemFormat())
|
||||
|
||||
def qdump__std__stringHelper1(d, value, charSize, format):
|
||||
def qdumpHelper_std__string(d, value, charType, format):
|
||||
if d.isQnxTarget():
|
||||
qdump__std__stringHelper1__QNX(d, value, charSize, format)
|
||||
qdumpHelper__std__string__QNX(d, value, charType, format)
|
||||
return
|
||||
|
||||
data = value["_M_dataplus"]["_M_p"]
|
||||
data = value.extractPointer()
|
||||
# We can't lookup the std::string::_Rep type without crashing LLDB,
|
||||
# so hard-code assumption on member position
|
||||
# struct { size_type _M_length, size_type _M_capacity, int _M_refcount; }
|
||||
sizePtr = data.cast(d.sizetType().pointer())
|
||||
size = int(sizePtr[-3])
|
||||
alloc = int(sizePtr[-2])
|
||||
refcount = int(sizePtr[-1]) & 0xffffffff
|
||||
d.check(refcount >= -1) # Can be -1 accoring to docs.
|
||||
(size, alloc, refcount) = d.split("ppp", data - 3 * d.ptrSize())
|
||||
refcount = refcount & 0xffffffff
|
||||
d.check(refcount >= -1) # Can be -1 according to docs.
|
||||
d.check(0 <= size and size <= alloc and alloc <= 100*1000*1000)
|
||||
d.putCharArrayHelper(sizePtr, size, charSize, format)
|
||||
d.putCharArrayHelper(data, size, charType, format)
|
||||
|
||||
def qdump__std__stringHelper1__QNX(d, value, charSize, format):
|
||||
def qdumpHelper__std__string__QNX(d, value, charType, format):
|
||||
size = value['_Mysize']
|
||||
alloc = value['_Myres']
|
||||
_BUF_SIZE = 16 / charSize
|
||||
_BUF_SIZE = int(16 / charType.size())
|
||||
if _BUF_SIZE <= alloc: #(_BUF_SIZE <= _Myres ? _Bx._Ptr : _Bx._Buf);
|
||||
data = value['_Bx']['_Ptr']
|
||||
else:
|
||||
@@ -514,51 +556,42 @@ def qdump__std__stringHelper1__QNX(d, value, charSize, format):
|
||||
refcount = int(sizePtr[-1])
|
||||
d.check(refcount >= -1) # Can be -1 accoring to docs.
|
||||
d.check(0 <= size and size <= alloc and alloc <= 100*1000*1000)
|
||||
d.putCharArrayHelper(sizePtr, size, charSize, format)
|
||||
d.putCharArrayHelper(sizePtr, size, charType, format)
|
||||
|
||||
|
||||
def qdump__std____1__string(d, value):
|
||||
base = d.addressOf(value)
|
||||
firstByte = d.extractByte(base)
|
||||
if firstByte & 1:
|
||||
# Long/external.
|
||||
data = d.extractPointer(base + 2 * d.ptrSize())
|
||||
size = d.extractUInt(base + d.ptrSize())
|
||||
else:
|
||||
firstByte = value.split('b')[0]
|
||||
if int(firstByte & 1) == 0:
|
||||
# Short/internal.
|
||||
size = firstByte / 2
|
||||
data = base + 1
|
||||
d.putCharArrayHelper(data, size, 1, d.currentItemFormat())
|
||||
size = int(firstByte / 2)
|
||||
data = value.address() + 1
|
||||
else:
|
||||
# Long/external.
|
||||
(dummy, size, data) = value.split('ppp')
|
||||
d.putCharArrayHelper(data, size, d.charType(), d.currentItemFormat())
|
||||
d.putType("std::string")
|
||||
|
||||
|
||||
def qdump__std____1__wstring(d, value):
|
||||
base = d.addressOf(value)
|
||||
firstByte = d.extractByte(base)
|
||||
if firstByte & 1:
|
||||
# Long/external.
|
||||
data = d.extractPointer(base + 2 * d.ptrSize())
|
||||
size = d.extractUInt(base + d.ptrSize())
|
||||
else:
|
||||
firstByte = value.split('b')[0]
|
||||
if int(firstByte & 1) == 0:
|
||||
# Short/internal.
|
||||
size = firstByte / 2
|
||||
data = base + 4
|
||||
d.putCharArrayHelper(data, size, 4)
|
||||
size = int(firstByte / 2)
|
||||
data = value.address() + 4
|
||||
else:
|
||||
# Long/external.
|
||||
(dummy, size, data) = value.split('ppp')
|
||||
d.putCharArrayHelper(data, size, d.createType('wchar_t'))
|
||||
d.putType("std::wstring")
|
||||
|
||||
|
||||
def qdump__std__shared_ptr(d, value):
|
||||
i = value["_M_ptr"]
|
||||
if d.isNull(i):
|
||||
if i.integer() == 0:
|
||||
d.putValue("(null)")
|
||||
d.putNumChild(0)
|
||||
return
|
||||
|
||||
if d.isSimpleType(d.templateArgument(value.type, 0)):
|
||||
d.putValue("%s @0x%x" % (d.simpleValue(i.dereference()), d.pointerValue(i)))
|
||||
else:
|
||||
d.putValue("@0x%x" % d.pointerValue(i))
|
||||
|
||||
d.putValue(i.dereference().simpleDisplay())
|
||||
d.putNumChild(3)
|
||||
with Children(d, 3):
|
||||
d.putSubItem("data", i)
|
||||
@@ -568,16 +601,11 @@ def qdump__std__shared_ptr(d, value):
|
||||
|
||||
def qdump__std____1__shared_ptr(d, value):
|
||||
i = value["__ptr_"]
|
||||
if d.isNull(i):
|
||||
if i.integer() == 0:
|
||||
d.putValue("(null)")
|
||||
d.putNumChild(0)
|
||||
return
|
||||
|
||||
if d.isSimpleType(d.templateArgument(value.type, 0)):
|
||||
d.putValue("%s @0x%x" % (d.simpleValue(i.dereference()), d.pointerValue(i)))
|
||||
else:
|
||||
d.putValue("@0x%x" % d.pointerValue(i))
|
||||
|
||||
d.putValue(i.dereference().simpleDisplay())
|
||||
d.putNumChild(3)
|
||||
with Children(d, 3):
|
||||
d.putSubItem("data", i.dereference())
|
||||
@@ -586,37 +614,19 @@ def qdump__std____1__shared_ptr(d, value):
|
||||
#d.putIntItem("weakcount", refcount["_M_weak_count"])
|
||||
|
||||
def qdump__std__unique_ptr(d, value):
|
||||
i = value["_M_t"]["_M_head_impl"]
|
||||
if d.isNull(i):
|
||||
p = d.extractPointer(value)
|
||||
if p == 0:
|
||||
d.putValue("(null)")
|
||||
d.putNumChild(0)
|
||||
return
|
||||
|
||||
if d.isSimpleType(d.templateArgument(value.type, 0)):
|
||||
d.putValue("%s @0x%x" % (d.simpleValue(i.dereference()), d.pointerValue(i)))
|
||||
else:
|
||||
d.putValue("@0x%x" % d.pointerValue(i))
|
||||
|
||||
val = d.createValue(p, value.type[0])
|
||||
d.putValue(val.simpleDisplay())
|
||||
d.putNumChild(1)
|
||||
with Children(d, 1):
|
||||
d.putSubItem("data", i)
|
||||
d.putSubItem("data", val)
|
||||
|
||||
def qdump__std____1__unique_ptr(d, value):
|
||||
#i = d.childAt(d.childAt(value["__ptr_"], 0), 0)
|
||||
i = d.childAt(value["__ptr_"], 0)["__first_"]
|
||||
if d.isNull(i):
|
||||
d.putValue("(null)")
|
||||
d.putNumChild(0)
|
||||
return
|
||||
|
||||
if d.isSimpleType(d.templateArgument(value.type, 0)):
|
||||
d.putValue("%s @0x%x" % (d.simpleValue(i.dereference()), d.pointerValue(i)))
|
||||
else:
|
||||
d.putValue("@0x%x" % d.pointerValue(i))
|
||||
|
||||
d.putNumChild(1)
|
||||
with Children(d, 1):
|
||||
d.putSubItem("data", i.dereference())
|
||||
qdump__std__unique_ptr(d, value)
|
||||
|
||||
|
||||
def qform__std__unordered_map():
|
||||
@@ -626,34 +636,34 @@ def qform__std____debug__unordered_map():
|
||||
return mapForms()
|
||||
|
||||
def qdump__std__unordered_map(d, value):
|
||||
keyType = d.templateArgument(value.type, 0)
|
||||
valueType = d.templateArgument(value.type, 1)
|
||||
allocatorType = d.templateArgument(value.type, 4)
|
||||
pairType = d.templateArgument(allocatorType, 0)
|
||||
keyType = value.type[0]
|
||||
valueType = value.type[1]
|
||||
allocatorType = value.type[4]
|
||||
pairType = allocatorType[0]
|
||||
ptrSize = d.ptrSize()
|
||||
try:
|
||||
# gcc ~= 4.7
|
||||
size = int(value["_M_element_count"])
|
||||
size = value["_M_element_count"].integer()
|
||||
start = value["_M_before_begin"]["_M_nxt"]
|
||||
offset = 0
|
||||
except:
|
||||
try:
|
||||
# libc++ (Mac)
|
||||
size = int(value["_M_h"]["_M_element_count"])
|
||||
size = value["_M_h"]["_M_element_count"].integer()
|
||||
start = value["_M_h"]["_M_bbegin"]["_M_node"]["_M_nxt"]
|
||||
offset = 0
|
||||
except:
|
||||
try:
|
||||
# gcc 4.9.1
|
||||
size = int(value["_M_h"]["_M_element_count"])
|
||||
size = value["_M_h"]["_M_element_count"].integer()
|
||||
start = value["_M_h"]["_M_before_begin"]["_M_nxt"]
|
||||
offset = 0
|
||||
except:
|
||||
# gcc 4.6.2
|
||||
size = int(value["_M_element_count"])
|
||||
size = value["_M_element_count"].integer()
|
||||
start = value["_M_buckets"].dereference()
|
||||
# FIXME: Pointer-aligned?
|
||||
offset = pairType.sizeof
|
||||
offset = pairType.size()
|
||||
d.putItemCount(size)
|
||||
# We don't know where the data is
|
||||
d.putNumChild(0)
|
||||
@@ -661,13 +671,12 @@ def qdump__std__unordered_map(d, value):
|
||||
|
||||
d.putItemCount(size)
|
||||
if d.isExpanded():
|
||||
p = d.pointerValue(start)
|
||||
p = start.integer()
|
||||
if d.isMapCompact(keyType, valueType):
|
||||
with PairedChildren(d, size, pairType=pairType):
|
||||
for i in d.childRange():
|
||||
pair = d.createValue(p + ptrSize, pairType)
|
||||
with SubItem(d, i):
|
||||
d.putPair(pair, i)
|
||||
d.putPairItem(i, pair)
|
||||
p = d.extractPointer(p)
|
||||
else:
|
||||
with Children(d, size, childType=pairType):
|
||||
@@ -681,31 +690,31 @@ def qdump__std____debug__unordered_map(d, value):
|
||||
def qdump__std__unordered_set(d, value):
|
||||
try:
|
||||
# gcc ~= 4.7
|
||||
size = int(value["_M_element_count"])
|
||||
size = value["_M_element_count"].integer()
|
||||
start = value["_M_before_begin"]["_M_nxt"]
|
||||
offset = 0
|
||||
except:
|
||||
try:
|
||||
# libc++ (Mac)
|
||||
size = int(value["_M_h"]["_M_element_count"])
|
||||
size = value["_M_h"]["_M_element_count"].integer()
|
||||
start = value["_M_h"]["_M_bbegin"]["_M_node"]["_M_nxt"]
|
||||
offset = 0
|
||||
except:
|
||||
try:
|
||||
# gcc 4.6.2
|
||||
size = int(value["_M_element_count"])
|
||||
size = value["_M_element_count"].integer()
|
||||
start = value["_M_buckets"].dereference()
|
||||
offset = d.ptrSize()
|
||||
except:
|
||||
# gcc 4.9.1
|
||||
size = int(value["_M_h"]["_M_element_count"])
|
||||
size = value["_M_h"]["_M_element_count"].integer()
|
||||
start = value["_M_h"]["_M_before_begin"]["_M_nxt"]
|
||||
offset = 0
|
||||
|
||||
d.putItemCount(size)
|
||||
if d.isExpanded():
|
||||
p = d.pointerValue(start)
|
||||
valueType = d.templateArgument(value.type, 0)
|
||||
p = start.integer()
|
||||
valueType = value.type[0]
|
||||
with Children(d, size, childType=valueType):
|
||||
ptrSize = d.ptrSize()
|
||||
for i in d.childRange():
|
||||
@@ -716,7 +725,7 @@ def qform__std____1__unordered_map():
|
||||
return mapForms()
|
||||
|
||||
def qdump__std____1__unordered_map(d, value):
|
||||
size = int(value["__table_"]["__p2_"]["__first_"])
|
||||
size = value["__table_"]["__p2_"]["__first_"].integer()
|
||||
d.putItemCount(size)
|
||||
if d.isExpanded():
|
||||
# There seem to be several versions of the implementation.
|
||||
@@ -729,8 +738,7 @@ def qdump__std____1__unordered_map(d, value):
|
||||
node = value["__table_"]["__p1_"]["__first_"]["__next_"]
|
||||
with PairedChildren(d, size, pairType=valueCCorNot(node["__value_"]).type):
|
||||
for i in d.childRange():
|
||||
with SubItem(d, i):
|
||||
d.putPair(valueCCorNot(node["__value_"]), i)
|
||||
d.putPairItem(i, valueCCorNot(node["__value_"]))
|
||||
node = node["__next_"]
|
||||
|
||||
|
||||
@@ -739,8 +747,7 @@ def qdump__std____1__unordered_set(d, value):
|
||||
d.putItemCount(size)
|
||||
if d.isExpanded():
|
||||
node = value["__table_"]["__p1_"]["__first_"]["__next_"]
|
||||
valueType = d.templateArgument(value.type, 0)
|
||||
with Children(d, size, childType=valueType, maxNumChild=1000):
|
||||
with Children(d, size, childType=value.type[0], maxNumChild=1000):
|
||||
for i in d.childRange():
|
||||
d.putSubItem(i, node["__value_"])
|
||||
node = node["__next_"]
|
||||
@@ -754,9 +761,20 @@ def qform__std__valarray():
|
||||
return arrayForms()
|
||||
|
||||
def qdump__std__valarray(d, value):
|
||||
size = int(value["_M_size"])
|
||||
(size, data) = value.split('pp')
|
||||
d.putItemCount(size)
|
||||
d.putPlotData(value["_M_data"], size, d.templateArgument(value.type, 0))
|
||||
d.putPlotData(data, size, value.type[0])
|
||||
|
||||
|
||||
def qform__std____1__valarray():
|
||||
return arrayForms()
|
||||
|
||||
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__vector():
|
||||
@@ -766,7 +784,7 @@ def qedit__std__vector(d, value, data):
|
||||
import gdb
|
||||
values = data.split(',')
|
||||
n = len(values)
|
||||
innerType = d.templateArgument(value.type, 0)
|
||||
innerType = value.type[0]
|
||||
cmd = "set $d = (%s*)calloc(sizeof(%s)*%s,1)" % (innerType, innerType, n)
|
||||
gdb.execute(cmd)
|
||||
cmd = "set {void*[3]}%s = {$d, $d+%s, $d+%s}" % (value.address, n, n)
|
||||
@@ -776,64 +794,60 @@ def qedit__std__vector(d, value, data):
|
||||
|
||||
def qdump__std__vector(d, value):
|
||||
if d.isQnxTarget():
|
||||
qdump__std__vector__QNX(d, value)
|
||||
return
|
||||
|
||||
impl = value["_M_impl"]
|
||||
type = d.templateArgument(value.type, 0)
|
||||
alloc = impl["_M_end_of_storage"]
|
||||
# The allocator case below is bogus, but that's what Apple
|
||||
# LLVM version 5.0 (clang-500.2.79) (based on LLVM 3.3svn)
|
||||
# produces.
|
||||
isBool = str(type) == 'bool' or str(type) == 'std::allocator<bool>'
|
||||
if isBool:
|
||||
start = impl["_M_start"]["_M_p"]
|
||||
finish = impl["_M_finish"]["_M_p"]
|
||||
# FIXME: 8 is CHAR_BIT
|
||||
size = (d.pointerValue(finish) - d.pointerValue(start)) * 8
|
||||
size += int(impl["_M_finish"]["_M_offset"])
|
||||
size -= int(impl["_M_start"]["_M_offset"])
|
||||
qdumpHelper__std__vector__QNX(d, value)
|
||||
else:
|
||||
start = impl["_M_start"]
|
||||
finish = impl["_M_finish"]
|
||||
size = finish - start
|
||||
qdumpHelper__std__vector(d, value, False)
|
||||
|
||||
def qdumpHelper__std__vector(d, value, isLibCpp):
|
||||
innerType = value.type[0]
|
||||
isBool = innerType.name == 'bool'
|
||||
if isBool:
|
||||
if isLibCpp:
|
||||
(start, size) = value.split("pp") # start is 'unsigned long *'
|
||||
alloc = size
|
||||
else:
|
||||
(start, soffset, pad, finish, foffset, pad, alloc) = value.split("pI@pI@p")
|
||||
size = (finish - start) * 8 + foffset - soffset # 8 is CHAR_BIT.
|
||||
else:
|
||||
(start, finish, alloc) = value.split("ppp")
|
||||
size = int((finish - start) / innerType.size())
|
||||
d.check(finish <= alloc)
|
||||
if size > 0:
|
||||
d.checkPointer(start)
|
||||
d.checkPointer(finish)
|
||||
d.checkPointer(alloc)
|
||||
|
||||
d.check(0 <= size and size <= 1000 * 1000 * 1000)
|
||||
d.check(int(finish) <= int(alloc))
|
||||
d.checkPointer(start)
|
||||
d.checkPointer(finish)
|
||||
d.checkPointer(alloc)
|
||||
|
||||
d.putItemCount(size)
|
||||
if isBool:
|
||||
if d.isExpanded():
|
||||
with Children(d, size, maxNumChild=10000, childType=type):
|
||||
base = d.pointerValue(start)
|
||||
with Children(d, size, maxNumChild=10000, childType=innerType):
|
||||
for i in d.childRange():
|
||||
q = base + int(i / 8)
|
||||
q = start + int(i / 8)
|
||||
with SubItem(d, i):
|
||||
d.putValue((int(d.extractPointer(q)) >> (i % 8)) & 1)
|
||||
d.putType("bool")
|
||||
d.putNumChild(0)
|
||||
else:
|
||||
d.putPlotData(start, size, type)
|
||||
d.putPlotData(start, size, innerType)
|
||||
|
||||
def qdump__std__vector__QNX(d, value):
|
||||
innerType = d.templateArgument(value.type, 0)
|
||||
isBool = str(type) == 'bool'
|
||||
def qdumpHelper__std__vector__QNX(d, value):
|
||||
innerType = value.type[0]
|
||||
isBool = str(innerType) == 'bool'
|
||||
if isBool:
|
||||
impl = value['_Myvec']
|
||||
start = impl['_Myfirst']
|
||||
last = impl['_Mylast']
|
||||
end = impl['_Myend']
|
||||
size = value['_Mysize']
|
||||
storagesize = start.dereference().type.sizeof * 8
|
||||
storagesize = start.dereference().type.size() * 8
|
||||
else:
|
||||
start = value['_Myfirst']
|
||||
last = value['_Mylast']
|
||||
end = value['_Myend']
|
||||
size = int (last - start)
|
||||
alloc = int (end - start)
|
||||
size = (last.integer() - start.integer()) / innerType.size()
|
||||
alloc = (end.integer() - start.integer()) / innerType.size()
|
||||
|
||||
d.check(0 <= size and size <= 1000 * 1000 * 1000)
|
||||
d.check(last <= end)
|
||||
@@ -855,21 +869,7 @@ def qdump__std__vector__QNX(d, value):
|
||||
d.putArrayData(start, size, innerType)
|
||||
|
||||
def qdump__std____1__vector(d, value):
|
||||
innerType = d.templateArgument(value.type, 0)
|
||||
if d.isLldb and d.childAt(value, 0).type == innerType:
|
||||
# That's old lldb automatically formatting
|
||||
begin = d.extractPointer(value)
|
||||
size = value.GetNumChildren()
|
||||
else:
|
||||
# Normal case
|
||||
begin = d.pointerValue(value['__begin_'])
|
||||
end = d.pointerValue(value['__end_'])
|
||||
size = (end - begin) / innerType.sizeof
|
||||
|
||||
d.putItemCount(size)
|
||||
if d.isExpanded():
|
||||
d.putPlotData(begin, size, innerType)
|
||||
|
||||
qdumpHelper__std__vector(d, value, True)
|
||||
|
||||
def qform__std____debug__vector():
|
||||
return arrayForms()
|
||||
@@ -891,22 +891,25 @@ def qform__std__wstring():
|
||||
return [SimpleFormat, SeparateFormat]
|
||||
|
||||
def qdump__std__wstring(d, value):
|
||||
charSize = d.lookupType('wchar_t').sizeof
|
||||
qdump__std__stringHelper1(d, value, charSize, d.currentItemFormat())
|
||||
qdumpHelper_std__string(d, value, d.createType('wchar_t'), d.currentItemFormat())
|
||||
|
||||
def qdump__std__basic_string(d, value):
|
||||
innerType = d.templateArgument(value.type, 0)
|
||||
qdump__std__stringHelper1(d, value, innerType.sizeof, d.currentItemFormat())
|
||||
innerType = value.type[0]
|
||||
qdumpHelper_std__string(d, value, innerType, d.currentItemFormat())
|
||||
|
||||
def qdump__std____cxx11__basic_string(d, value):
|
||||
innerType = d.templateArgument(value.type, 0)
|
||||
data = value["_M_dataplus"]["_M_p"]
|
||||
size = int(value["_M_string_length"])
|
||||
innerType = value.type[0]
|
||||
(data, size) = value.split("pI")
|
||||
d.check(0 <= size) #and size <= alloc and alloc <= 100*1000*1000)
|
||||
d.putCharArrayHelper(data, size, innerType.sizeof, d.currentItemFormat())
|
||||
d.putCharArrayHelper(data, size, innerType, d.currentItemFormat())
|
||||
|
||||
def qform__std____cxx11__string(d, value):
|
||||
qdump__std____cxx11__basic_string(d, value)
|
||||
qform__std__string(d, value)
|
||||
|
||||
def qdump__std____cxx11__string(d, value):
|
||||
(data, size) = value.split("pI")
|
||||
d.check(0 <= size) #and size <= alloc and alloc <= 100*1000*1000)
|
||||
d.putCharArrayHelper(data, size, d.charType(), d.currentItemFormat())
|
||||
|
||||
# Needed only to trigger the form report above.
|
||||
def qform__std____cxx11__string():
|
||||
@@ -916,7 +919,7 @@ def qform__std____cxx11__wstring():
|
||||
return qform__std__wstring()
|
||||
|
||||
def qdump__std____1__basic_string(d, value):
|
||||
innerType = str(d.templateArgument(value.type, 0))
|
||||
innerType = value.type[0].name
|
||||
if innerType == "char":
|
||||
qdump__std____1__string(d, value)
|
||||
elif innerType == "wchar_t":
|
||||
@@ -930,34 +933,33 @@ def qdump__wstring(d, value):
|
||||
|
||||
def qdump____gnu_cxx__hash_set(d, value):
|
||||
ht = value["_M_ht"]
|
||||
size = int(ht["_M_num_elements"])
|
||||
size = ht["_M_num_elements"].integer()
|
||||
d.check(0 <= size and size <= 1000 * 1000 * 1000)
|
||||
d.putItemCount(size)
|
||||
type = d.templateArgument(value.type, 0)
|
||||
d.putType("__gnu__cxx::hash_set<%s>" % type)
|
||||
innerType = value.type[0]
|
||||
d.putType("__gnu__cxx::hash_set<%s>" % innerType)
|
||||
if d.isExpanded():
|
||||
with Children(d, size, maxNumChild=1000, childType=type):
|
||||
with Children(d, size, maxNumChild=1000, childType=innerType):
|
||||
buckets = ht["_M_buckets"]["_M_impl"]
|
||||
bucketStart = buckets["_M_start"]
|
||||
bucketFinish = buckets["_M_finish"]
|
||||
p = bucketStart
|
||||
itemCount = 0
|
||||
for i in xrange(toInteger(bucketFinish - bucketStart)):
|
||||
if not d.isNull(p.dereference()):
|
||||
for i in xrange(int((bucketFinish.integer() - bucketStart.integer()) / d.ptrSize())):
|
||||
if p.dereference().integer():
|
||||
cur = p.dereference()
|
||||
while not d.isNull(cur):
|
||||
with SubItem(d, itemCount):
|
||||
d.putValue(cur["_M_val"])
|
||||
cur = cur["_M_next"]
|
||||
itemCount += 1
|
||||
while cur.integer():
|
||||
d.putSubItem(itemCount, cur["_M_val"])
|
||||
cur = cur["_M_next"]
|
||||
itemCount += 1
|
||||
p = p + 1
|
||||
|
||||
|
||||
def qdump__uint8_t(d, value):
|
||||
d.putNumChild(0)
|
||||
d.putValue(int(value))
|
||||
d.putValue(value.integer())
|
||||
|
||||
def qdump__int8_t(d, value):
|
||||
d.putNumChild(0)
|
||||
d.putValue(int(value))
|
||||
d.putValue(value.integer())
|
||||
|
||||
|
||||
@@ -2,6 +2,10 @@ QT = core network
|
||||
|
||||
QTC_LIB_DEPENDS += utils
|
||||
|
||||
!win32 {
|
||||
CONFIG -= release
|
||||
CONFIG += debug
|
||||
}
|
||||
include(../qttest.pri)
|
||||
|
||||
msvc {
|
||||
|
||||
+338
-319
File diff suppressed because it is too large
Load Diff
@@ -1837,10 +1837,10 @@ namespace qobject {
|
||||
Q_SLOT void setMyProp2(const QString&mt) { m_myProp2 = mt; }
|
||||
|
||||
Q_PROPERTY(long myProp3 READ myProp3)
|
||||
long myProp3() const { return 54; }
|
||||
long myProp3() const { return -54; }
|
||||
|
||||
Q_PROPERTY(long myProp4 READ myProp4)
|
||||
long myProp4() const { return 44; }
|
||||
Q_PROPERTY(int myProp4 READ myProp4)
|
||||
int myProp4() const { return -44; }
|
||||
|
||||
Q_SIGNAL void sigFoo();
|
||||
Q_SIGNAL void sigBar(int);
|
||||
@@ -1887,6 +1887,8 @@ namespace qobject {
|
||||
v[i] = mo->method(i);
|
||||
|
||||
|
||||
test.setProperty("USER DEFINED 1", 44);
|
||||
test.setProperty("USER DEFINED 2", QStringList() << "FOO" << "BAR");
|
||||
BREAK_HERE;
|
||||
// Check s "HELLOWORLD" QString.
|
||||
// Check test qobject::Names::Bar::TestObject.
|
||||
@@ -2275,7 +2277,11 @@ namespace qregion {
|
||||
BREAK_HERE;
|
||||
// Check region <4 items> QRegion.
|
||||
// Continue.
|
||||
dummyStatement(®ion);
|
||||
QVector<int> vv = { 1, 2, 3 };
|
||||
dummyStatement(®ion, &vv);
|
||||
QRect x(12, 34, 66, 77);
|
||||
QVector<QRect> rr = { {1, 2, 3, 4}, {5, 6, 7, 8} };
|
||||
dummyStatement(®ion, &vv, &rr, &x);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user