forked from qt-creator/qt-creator
Debugger: Add dumper for QMeta{Enum,Method,Property}
Task-number: QTCREATORBUG-16593 Change-Id: Iaa710660d8ef69459596f93831cf8467913f0468 Reviewed-by: Alexandru Croitor <alexandru.croitor@qt.io>
This commit is contained in:
@@ -737,12 +737,16 @@ class DumperBase:
|
||||
with Children(self):
|
||||
self.putFields(value, dumpBase)
|
||||
|
||||
def putMembersItem(self, value, sortorder = 10):
|
||||
with SubItem(self, "[members]"):
|
||||
self.put('sortgroup="%s"' % sortorder)
|
||||
self.putPlainChildren(value)
|
||||
|
||||
def isMapCompact(self, keyType, valueType):
|
||||
if self.currentItemFormat() == CompactMapFormat:
|
||||
return True
|
||||
return self.isSimpleType(keyType) and self.isSimpleType(valueType)
|
||||
|
||||
|
||||
def check(self, exp):
|
||||
if not exp:
|
||||
raise RuntimeError("Check failed")
|
||||
@@ -923,13 +927,6 @@ class DumperBase:
|
||||
# self.expandedINames, self.currentIName in self.expandedINames))
|
||||
return self.currentIName in self.expandedINames
|
||||
|
||||
def putPlainChildren(self, value):
|
||||
self.putEmptyValue(-99)
|
||||
self.putNumChild(1)
|
||||
if self.currentIName in self.expandedINames:
|
||||
with Children(self):
|
||||
self.putFields(value)
|
||||
|
||||
def putCStyleArray(self, value):
|
||||
arrayType = value.type.unqualified()
|
||||
innerType = value[0].type
|
||||
@@ -1325,50 +1322,6 @@ class DumperBase:
|
||||
self.knownStaticMetaObjects[typeName] = result
|
||||
return result
|
||||
|
||||
def staticQObjectMetaData(self, metaobject, offset1, offset2, step):
|
||||
items = []
|
||||
dd = metaobject["d"]
|
||||
data = self.extractPointer(dd["data"])
|
||||
sd = self.extractPointer(dd["stringdata"])
|
||||
|
||||
metaObjectVersion = self.extractInt(data)
|
||||
itemCount = self.extractInt(data + offset1)
|
||||
itemData = -offset2 if offset2 < 0 else self.extractInt(data + offset2)
|
||||
|
||||
if metaObjectVersion >= 7: # Qt 5.
|
||||
byteArrayDataType = self.lookupType(self.qtNamespace() + "QByteArrayData")
|
||||
byteArrayDataSize = byteArrayDataType.sizeof
|
||||
for i in range(itemCount):
|
||||
x = data + (itemData + step * i) * 4
|
||||
literal = sd + self.extractInt(x) * byteArrayDataSize
|
||||
ldata, lsize, lalloc = self.byteArrayDataHelper(literal)
|
||||
items.append(self.extractBlob(ldata, lsize).toString())
|
||||
else: # Qt 4.
|
||||
for i in range(itemCount):
|
||||
x = data + (itemData + step * i) * 4
|
||||
ldata = sd + self.extractInt(x)
|
||||
items.append(self.extractCString(ldata).decode("utf8"))
|
||||
|
||||
return items
|
||||
|
||||
def staticQObjectPropertyCount(self, metaobject):
|
||||
return self.extractInt(self.extractPointer(metaobject["d"]["data"]) + 24)
|
||||
|
||||
def staticQObjectPropertyNames(self, metaobject):
|
||||
return self.staticQObjectMetaData(metaobject, 24, 28, 3)
|
||||
|
||||
def staticQObjectMethodCount(self, metaobject):
|
||||
return self.extractInt(self.extractPointer(metaobject["d"]["data"]) + 16)
|
||||
|
||||
def staticQObjectMethodNames(self, metaobject):
|
||||
return self.staticQObjectMetaData(metaobject, 16, 20, 5)
|
||||
|
||||
def staticQObjectSignalCount(self, metaobject):
|
||||
return self.extractInt(self.extractPointer(metaobject["d"]["data"]) + 52)
|
||||
|
||||
def staticQObjectSignalNames(self, metaobject):
|
||||
return self.staticQObjectMetaData(metaobject, 52, -14, 5)
|
||||
|
||||
def extractCString(self, addr):
|
||||
result = bytearray()
|
||||
while True:
|
||||
@@ -1406,6 +1359,21 @@ class DumperBase:
|
||||
for i in range(size):
|
||||
yield self.createValue(data + i * innerSize, innerType)
|
||||
|
||||
def putStructGuts(self, value):
|
||||
self.putEmptyValue()
|
||||
if self.showQObjectNames:
|
||||
staticMetaObject = self.extractStaticMetaObject(value.type)
|
||||
if staticMetaObject:
|
||||
self.context = value
|
||||
self.putQObjectNameValue(value)
|
||||
if self.isExpanded():
|
||||
self.put('sortable="1"')
|
||||
with Children(self, 1, childType=None):
|
||||
self.putFields(value)
|
||||
if not self.showQObjectNames:
|
||||
staticMetaObject = self.extractStaticMetaObject(value.type)
|
||||
if staticMetaObject:
|
||||
self.putQObjectGuts(value, staticMetaObject)
|
||||
|
||||
# This is called is when a QObject derived class is expanded
|
||||
def putQObjectGuts(self, qobject, smo):
|
||||
@@ -1414,9 +1382,14 @@ class DumperBase:
|
||||
|
||||
# Parent and children.
|
||||
try:
|
||||
d_ptr = qobject["d_ptr"]["d"]
|
||||
self.putSubItem("[parent]", d_ptr["parent"])
|
||||
self.putSubItem("[children]", d_ptr["children"])
|
||||
if qobject:
|
||||
d_ptr = qobject["d_ptr"]["d"]
|
||||
with SubItem(self, "[parent]"):
|
||||
self.putItem(d_ptr["parent"])
|
||||
self.put('sortgroup="9"')
|
||||
with SubItem(self, "[children]"):
|
||||
self.putItem(d_ptr["children"])
|
||||
self.put('sortgroup="1"')
|
||||
except:
|
||||
pass
|
||||
|
||||
@@ -1424,29 +1397,46 @@ class DumperBase:
|
||||
isQt5 = self.qtVersion() >= 0x50000
|
||||
extraDataOffset = 5 * ptrSize + 8 if isQt5 else 6 * ptrSize + 8
|
||||
extraData = self.extractPointer(dd + extraDataOffset)
|
||||
self.putQObjectGutsHelper(extraData, dd, smo)
|
||||
self.putQObjectGutsHelper(qobject, extraData, -1, smo, "QObject")
|
||||
|
||||
|
||||
def putQObjectGutsHelper(self, extraData, dd, smo):
|
||||
def metaString(self, metaObject, index, revision = 7):
|
||||
sd = self.extractPointer(metaObject["d"]["stringdata"])
|
||||
if revision >= 7: # Qt 5.
|
||||
byteArrayDataType = self.lookupQtType("QByteArrayData")
|
||||
byteArrayDataSize = byteArrayDataType.sizeof
|
||||
literal = toInteger(sd) + toInteger(index) * byteArrayDataSize
|
||||
ldata, lsize, lalloc = self.byteArrayDataHelper(literal)
|
||||
try:
|
||||
return self.extractBlob(ldata, lsize).toString()
|
||||
except:
|
||||
return "<unavailable>"
|
||||
else: # Qt 4.
|
||||
ldata = sd + index
|
||||
return self.extractCString(ldata).decode("utf8")
|
||||
|
||||
def putQMetaStuff(self, value, origType):
|
||||
metaObject = value["mobj"]
|
||||
if not metaObject:
|
||||
self.putEmptyValue()
|
||||
if self.isExpanded():
|
||||
with Children(self):
|
||||
self.putFields(value)
|
||||
else:
|
||||
handle = toInteger(value["handle"])
|
||||
index = toInteger(metaObject["d"]["data"][handle])
|
||||
name = self.metaString(metaObject.dereference(), index)
|
||||
self.putValue(name)
|
||||
self.putNumChild(1)
|
||||
if self.isExpanded():
|
||||
with Children(self):
|
||||
self.putFields(value)
|
||||
self.putQObjectGutsHelper(0, 0, handle, metaObject, origType)
|
||||
|
||||
def putQObjectGutsHelper(self, qobject, extraData, handle, metaObject, origType):
|
||||
intSize = self.intSize()
|
||||
ptrSize = self.ptrSize()
|
||||
data = smo["d"]["data"]
|
||||
#warn("DATA: %s" % data)
|
||||
|
||||
def metaString(offset):
|
||||
ddata = self.extractPointer(data)
|
||||
sd = self.extractPointer(smo["d"]["stringdata"])
|
||||
|
||||
metaObjectVersion = self.extractInt(ddata)
|
||||
if metaObjectVersion >= 7: # Qt 5.
|
||||
byteArrayDataType = self.lookupType(self.qtNamespace() + "QByteArrayData")
|
||||
byteArrayDataSize = byteArrayDataType.sizeof
|
||||
literal = sd + offset * byteArrayDataSize
|
||||
ldata, lsize, lalloc = self.byteArrayDataHelper(literal)
|
||||
return self.extractBlob(ldata, lsize).toString()
|
||||
else: # Qt 4.
|
||||
ldata = sd + offset
|
||||
return self.extractCString(ldata).decode("utf8")
|
||||
data = metaObject["d"]["data"]
|
||||
|
||||
def walker(base):
|
||||
ptr = toInteger(base)
|
||||
@@ -1454,63 +1444,105 @@ class DumperBase:
|
||||
yield self.extractInt(ptr)
|
||||
ptr += intSize
|
||||
|
||||
def put1(name, p):
|
||||
x = p.next()
|
||||
with SubItem(self, name):
|
||||
self.putValue(x)
|
||||
self.putType("uint")
|
||||
self.putNumChild(0)
|
||||
return x
|
||||
|
||||
def put2(name, p):
|
||||
xy = (p.next(), p.next())
|
||||
with SubItem(self, name):
|
||||
self.putValue("%s %s" % xy)
|
||||
self.putType("uint")
|
||||
self.putNumChild(0)
|
||||
return xy[0]
|
||||
|
||||
def putt(name, value):
|
||||
def putt(name, value, typeName = ' '):
|
||||
with SubItem(self, name):
|
||||
self.putValue(value)
|
||||
self.putType(" ")
|
||||
self.putType(typeName)
|
||||
self.putNumChild(0)
|
||||
|
||||
with SubItem(self, "[raw]"):
|
||||
self.putEmptyValue()
|
||||
self.putNumChild(1)
|
||||
if self.isExpanded():
|
||||
self.put('sortable="0"')
|
||||
p = walker(data)
|
||||
def superData(mo):
|
||||
return mo['d']['superdata']
|
||||
|
||||
with Children(self):
|
||||
put1("revision", p)
|
||||
put1("classname", p)
|
||||
put2("classinfo", p)
|
||||
methodCount = put2("methods", p)
|
||||
put2("properties", p)
|
||||
put2("enums/sets", p)
|
||||
put2("constructors", p)
|
||||
put1("flags", p)
|
||||
signalCount = put1("signalCount", p)
|
||||
isQMetaObject = origType == "QMetaObject"
|
||||
isQObject = origType == "QObject"
|
||||
|
||||
if extraData:
|
||||
with SubItem(self, "[extraData]"):
|
||||
self.putValue("0x%x" % toInteger(extraData))
|
||||
self.putType("void *")
|
||||
self.putNumChild(0)
|
||||
p = walker(data)
|
||||
revision = p.next()
|
||||
classname = p.next()
|
||||
classinfo = p.next()
|
||||
classinfo2 = p.next()
|
||||
methodCount = p.next()
|
||||
methods = p.next()
|
||||
propertyCount = p.next()
|
||||
properties = p.next()
|
||||
enumCount = p.next()
|
||||
enums = p.next()
|
||||
constructorCount = p.next()
|
||||
constructors = p.next()
|
||||
flags = p.next()
|
||||
signalCount = p.next()
|
||||
|
||||
with SubItem(self, "[properties]"):
|
||||
propertyCount = 0
|
||||
usesVector = self.qtVersion() >= 0x50700
|
||||
globalOffset = 0
|
||||
superdata = superData(metaObject)
|
||||
while toInteger(superdata):
|
||||
sdata = superdata["d"]["data"]
|
||||
p = walker(sdata)
|
||||
revision = p.next()
|
||||
classname = p.next()
|
||||
classinfo = p.next()
|
||||
classinfo2 = p.next()
|
||||
methodCount = p.next()
|
||||
globalOffset += methodCount
|
||||
superdata = superData(superdata)
|
||||
|
||||
largestStringIndex = -1
|
||||
for i in range(methodCount):
|
||||
t = (p.next(), p.next(), p.next(), p.next(), p.next())
|
||||
if largestStringIndex < t[0]:
|
||||
largestStringIndex = t[0]
|
||||
|
||||
if isQMetaObject:
|
||||
with SubItem(self, "[strings]"):
|
||||
self.put('sortgroup="2"')
|
||||
self.putSpecialValue("minimumitemcount", largestStringIndex + 1)
|
||||
self.putNumChild(1)
|
||||
if self.isExpanded():
|
||||
propertyNames = self.staticQObjectPropertyNames(smo)
|
||||
propertyCount = len(propertyNames) # Doesn't include dynamic properties.
|
||||
with Children(self, largestStringIndex + 1):
|
||||
for i in self.childRange():
|
||||
with SubItem(self, i):
|
||||
self.putValue(self.hexencode(self.metaString(metaObject, i)), "latin1")
|
||||
self.putNumChild(0)
|
||||
|
||||
if isQMetaObject:
|
||||
with SubItem(self, "[raw]"):
|
||||
self.put('sortgroup="1"')
|
||||
p = walker(data)
|
||||
self.putEmptyValue()
|
||||
self.putNumChild(1)
|
||||
if self.isExpanded():
|
||||
with Children(self):
|
||||
putt("revision", revision)
|
||||
putt("classname", classname)
|
||||
putt("classinfo", classinfo)
|
||||
putt("methods", "%d %d" % (methodCount, methods))
|
||||
putt("properties", "%d %d" % (propertyCount, properties))
|
||||
putt("enums/sets", "%d %d" % (enumCount, enums))
|
||||
putt("constructors", "%d %d" % (constructorCount, constructors))
|
||||
putt("flags", flags)
|
||||
putt("signalCount", signalCount)
|
||||
p = walker(toInteger(data) + 14 * 4)
|
||||
for i in range(methodCount):
|
||||
t = (p.next(), p.next(), p.next(), p.next(), p.next())
|
||||
putt("method %d" % i, "%s %s %s %s %s" % t)
|
||||
|
||||
putt("[extraData]", "0x%x" % toInteger(extraData), "void *")
|
||||
|
||||
if isQMetaObject or isQObject:
|
||||
with SubItem(self, "[properties]"):
|
||||
self.put('sortgroup="5"')
|
||||
self.putItemCount(propertyCount)
|
||||
if self.isExpanded():
|
||||
usesVector = self.qtVersion() >= 0x50700
|
||||
with Children(self):
|
||||
# Static properties.
|
||||
p = walker(toInteger(data) + properties * 4)
|
||||
for i in range(propertyCount):
|
||||
name = propertyNames[i]
|
||||
self.putCallItem(str(name), qobject, "property", '"' + name + '"')
|
||||
t = (p.next(), p.next(), p.next())
|
||||
name = self.metaString(metaObject, t[0])
|
||||
if qobject:
|
||||
self.putCallItem(name, qobject, "property", '"' + name + '"')
|
||||
else:
|
||||
putt(name, ' ')
|
||||
|
||||
# Dynamic properties.
|
||||
if extraData:
|
||||
@@ -1527,68 +1559,93 @@ class DumperBase:
|
||||
self.put('keyencoded="latin1",')
|
||||
self.putItem(v)
|
||||
propertyCount += 1
|
||||
self.putItemCount(propertyCount)
|
||||
else:
|
||||
# We need a handle to [x] for the user to expand the item
|
||||
# before we know whether there are actual children. Counting
|
||||
# them is too expensive.
|
||||
self.putNumChild(1)
|
||||
self.putSpecialValue("minimumitemcount", 0)
|
||||
self.putSpecialValue("minimumitemcount", propertyCount)
|
||||
|
||||
#with SubItem(self, "[methods]"):
|
||||
# methodCount = self.staticQObjectMethodCount(smo)
|
||||
# self.putItemCount(methodCount)
|
||||
# if self.isExpanded():
|
||||
# methodNames = self.staticQObjectMethodNames(smo)
|
||||
# with Children(self):
|
||||
# for i in range(methodCount):
|
||||
# k = methodNames[i]
|
||||
# with SubItem(self, k):
|
||||
# self.putEmptyValue()
|
||||
#
|
||||
|
||||
with SubItem(self, "[methods]"):
|
||||
methodCount = self.staticQObjectMethodCount(smo)
|
||||
self.putItemCount(methodCount)
|
||||
if self.isExpanded():
|
||||
with Children(self):
|
||||
p = walker(toInteger(data) + 14 * 4)
|
||||
for i in range(methodCount):
|
||||
t = (p.next(), p.next(), p.next(), p.next(), p.next())
|
||||
name = metaString(t[0])
|
||||
with SubItem(self, "[%s]" % i):
|
||||
self.putValue(name)
|
||||
self.putType(" ")
|
||||
self.putNumChild(1)
|
||||
with Children(self):
|
||||
putt("name", name)
|
||||
putt("nameindex", t[0])
|
||||
if isQMetaObject or isQObject:
|
||||
with SubItem(self, "[methods]"):
|
||||
self.put('sortgroup="3"')
|
||||
self.putItemCount(methodCount)
|
||||
if self.isExpanded():
|
||||
with Children(self):
|
||||
p = walker(toInteger(data) + 14 * 4)
|
||||
for i in range(methodCount):
|
||||
t = (p.next(), p.next(), p.next(), p.next(), p.next())
|
||||
name = self.metaString(metaObject, t[0])
|
||||
with SubItem(self, i):
|
||||
self.putValue(name)
|
||||
self.putType(" ")
|
||||
self.putNumChild(1)
|
||||
isSignal = False
|
||||
flags = t[4]
|
||||
if flags == 0x06:
|
||||
putt("type", "signal")
|
||||
typ = "signal"
|
||||
isSignal = True
|
||||
elif flags == 0x0a:
|
||||
putt("type", "slot")
|
||||
typ = "slot"
|
||||
elif flags == 0x0a:
|
||||
putt("type", "invokable")
|
||||
putt("argc", t[1])
|
||||
putt("parameter", t[2])
|
||||
putt("tag", t[3])
|
||||
putt("flags", t[4])
|
||||
typ = "invokable"
|
||||
else:
|
||||
typ = "<unknown>"
|
||||
with Children(self):
|
||||
putt("[nameindex]", t[0])
|
||||
putt("[type]", typ)
|
||||
putt("[argc]", t[1])
|
||||
putt("[parameter]", t[2])
|
||||
putt("[tag]", t[3])
|
||||
putt("[flags]", t[4])
|
||||
putt("[localindex]", str(i))
|
||||
putt("[globalindex]", str(globalOffset + i))
|
||||
|
||||
if isQObject:
|
||||
self.putSubItem("[metaObject]", metaObject)
|
||||
|
||||
if isQObject:
|
||||
with SubItem(self, "d"):
|
||||
self.put('sortgroup="15"')
|
||||
self.putItem(qobject["d_ptr"]["d"])
|
||||
|
||||
if isQMetaObject:
|
||||
with SubItem(self, "[superdata]"):
|
||||
self.put('sortgroup="12"')
|
||||
superdata = superData(metaObject)
|
||||
self.putValue("0x%x" % superdata)
|
||||
if toInteger(superdata):
|
||||
self.putNumChild(1)
|
||||
if self.isExpanded():
|
||||
with Children(self):
|
||||
self.putSubItem('*', superdata)
|
||||
else:
|
||||
self.putNumChild(0)
|
||||
self.putType(superdata.type)
|
||||
|
||||
if handle >= 0:
|
||||
localIndex = (handle - methods) / 5
|
||||
with SubItem(self, "[localindex]"):
|
||||
self.put('sortgroup="12"')
|
||||
self.putValue(localIndex)
|
||||
with SubItem(self, "[globalindex]"):
|
||||
self.put('sortgroup="11"')
|
||||
self.putValue(globalOffset + localIndex)
|
||||
|
||||
|
||||
with SubItem(self, "[signals]"):
|
||||
signalCount = self.staticQObjectSignalCount(smo)
|
||||
self.putItemCount(signalCount)
|
||||
if self.isExpanded():
|
||||
signalNames = self.staticQObjectSignalNames(smo)
|
||||
signalCount = len(signalNames)
|
||||
with Children(self):
|
||||
for i in range(signalCount):
|
||||
k = signalNames[i]
|
||||
with SubItem(self, k):
|
||||
self.putEmptyValue()
|
||||
if dd:
|
||||
self.putQObjectConnections(dd)
|
||||
#with SubItem(self, "[signals]"):
|
||||
# self.putItemCount(signalCount)
|
||||
# signalNames = metaData(52, -14, 5)
|
||||
# warn("NAMES: %s" % signalNames)
|
||||
# if self.isExpanded():
|
||||
# with Children(self):
|
||||
# putt("A", "b")
|
||||
# for i in range(signalCount):
|
||||
# k = signalNames[i]
|
||||
# with SubItem(self, k):
|
||||
# self.putEmptyValue()
|
||||
# if dd:
|
||||
# self.putQObjectConnections(dd)
|
||||
|
||||
def putQObjectConnections(self, dd):
|
||||
with SubItem(self, "[connections]"):
|
||||
|
@@ -1136,23 +1136,10 @@ class Dumper(DumperBase):
|
||||
#warn("INAME: %s " % self.currentIName)
|
||||
#warn("INAMES: %s " % self.expandedINames)
|
||||
#warn("EXPANDED: %s " % (self.currentIName in self.expandedINames))
|
||||
if self.showQObjectNames:
|
||||
staticMetaObject = self.extractStaticMetaObject(value.type)
|
||||
if staticMetaObject:
|
||||
self.putQObjectNameValue(value)
|
||||
self.putType(typeName)
|
||||
self.putEmptyValue()
|
||||
self.putNumChild(len(typeobj.fields()))
|
||||
self.putStructGuts(value)
|
||||
|
||||
if self.currentIName in self.expandedINames:
|
||||
innerType = None
|
||||
self.put('sortable="1"')
|
||||
with Children(self, 1, childType=innerType):
|
||||
self.putFields(value)
|
||||
if not self.showQObjectNames:
|
||||
staticMetaObject = self.extractStaticMetaObject(value.type)
|
||||
if staticMetaObject:
|
||||
self.putQObjectGuts(value, staticMetaObject)
|
||||
|
||||
def toBlob(self, value):
|
||||
size = toInteger(value.type.sizeof)
|
||||
@@ -1251,7 +1238,7 @@ class Dumper(DumperBase):
|
||||
# int (**)(void)
|
||||
n = 100
|
||||
self.putType(" ")
|
||||
self.put('sortgroup="1"')
|
||||
self.put('sortgroup="20"')
|
||||
self.putValue(value[field.name])
|
||||
self.putNumChild(n)
|
||||
if self.isExpanded():
|
||||
@@ -1275,7 +1262,7 @@ class Dumper(DumperBase):
|
||||
baseNumber += 1
|
||||
with UnnamedSubItem(self, "@%d" % baseNumber):
|
||||
baseValue = value.cast(field.type)
|
||||
self.put('sortgroup="2"')
|
||||
self.put('sortgroup="30"')
|
||||
self.putBaseClassName(field.name)
|
||||
self.putAddress(baseValue.address)
|
||||
self.putItem(baseValue, False)
|
||||
|
@@ -1084,27 +1084,14 @@ class Dumper(DumperBase):
|
||||
self.putValue(v)
|
||||
|
||||
self.putType(typeName)
|
||||
self.putEmptyValue()
|
||||
self.putNumChild(numchild)
|
||||
if self.showQObjectNames:
|
||||
staticMetaObject = self.extractStaticMetaObject(value.GetType())
|
||||
if staticMetaObject:
|
||||
self.context = value
|
||||
self.putQObjectNameValue(value)
|
||||
self.putStructGuts(value)
|
||||
|
||||
if self.currentIName in self.expandedINames:
|
||||
self.put('sortable="1"')
|
||||
with Children(self):
|
||||
self.putFields(value)
|
||||
if not self.showQObjectNames:
|
||||
staticMetaObject = self.extractStaticMetaObject(value.GetType())
|
||||
if staticMetaObject:
|
||||
self.putQObjectGuts(value, staticMetaObject)
|
||||
|
||||
def warn(self, msg):
|
||||
self.put('{name="%s",value="",type="",numchild="0"},' % msg)
|
||||
|
||||
def putFields(self, value):
|
||||
def putFields(self, value, dumpBase = True):
|
||||
# Suppress printing of 'name' field for arrays.
|
||||
if value.GetType().GetTypeClass() == lldb.eTypeClassArray:
|
||||
for i in xrange(value.GetNumChildren()):
|
||||
@@ -1139,9 +1126,10 @@ class Dumper(DumperBase):
|
||||
for i in xrange(len(baseObjects)):
|
||||
baseObject = baseObjects[i]
|
||||
with UnnamedSubItem(self, "@%d" % (i + 1)):
|
||||
self.put('iname="%s",' % self.currentIName)
|
||||
self.put('name="[%s]",' % baseObject.name)
|
||||
self.putItem(baseObject.value)
|
||||
self.put('iname="%s",' % self.currentIName)
|
||||
self.put('name="[%s]",' % baseObject.name)
|
||||
self.put('sortgroup="30"')
|
||||
self.putItem(baseObject.value)
|
||||
|
||||
memberCount = value.GetNumChildren()
|
||||
if memberCount > 10000:
|
||||
|
@@ -268,28 +268,7 @@ def qdump__QDateTime(d, value):
|
||||
# {sharedref(4), ...
|
||||
base = d.extractPointer(value)
|
||||
is32bit = d.is32bit()
|
||||
if qtVersion >= 0x050800:
|
||||
# FIXME: Don't give up.
|
||||
d.putPlainChildren(value)
|
||||
return
|
||||
msecsOffset = 0
|
||||
statusOffset = 8
|
||||
offsetFromUtcOffset = 12
|
||||
timeZoneOffset = 24
|
||||
status = d.extractInt(base + statusOffset)
|
||||
if int(status & 0x0c == 0x0c): # ValidDate and ValidTime
|
||||
isValid = True
|
||||
msecs = d.extractInt64(base + msecsOffset)
|
||||
offset = d.extractInt(base + offsetFromUtcOffset)
|
||||
tzp = d.extractPointer(base + timeZoneOffset)
|
||||
if tzp == 0:
|
||||
tz = ""
|
||||
else:
|
||||
idBase = tzp + 2 * d.ptrSize() # [QSharedData] + [vptr]
|
||||
elided, tz = d.encodeByteArrayHelper(d.extractPointer(idBase), limit=100)
|
||||
d.putValue("%s/%s/%s/%s/%s" % (msecs, -1, offset, tz, status),
|
||||
"datetimeinternal")
|
||||
elif qtVersion >= 0x050200:
|
||||
if qtVersion >= 0x050200:
|
||||
if d.isWindowsTarget():
|
||||
msecsOffset = 8
|
||||
specOffset = 16
|
||||
@@ -1110,371 +1089,26 @@ def qdump__QVariantMap(d, value):
|
||||
qdump__QMap(d, value)
|
||||
|
||||
|
||||
def qdump__QMetaObjectPrivate(d, value):
|
||||
d.putEmptyValue()
|
||||
d.putNumChild(1)
|
||||
if d.isExpanded():
|
||||
with Children(d):
|
||||
# int revision;
|
||||
# int className;
|
||||
# int classInfoCount, classInfoData;
|
||||
# int methodCount, methodData;
|
||||
# int propertyCount, propertyData;
|
||||
# int enumeratorCount, enumeratorData;
|
||||
# int constructorCount, constructorData; //since revision 2
|
||||
# int flags; //since revision 3
|
||||
# int signalCount; //since revision 4
|
||||
d.putIntItem("revision", value["revision"])
|
||||
d.putIntItem("methodCount", value["methodCount"])
|
||||
d.putIntItem("propertyCount", value["propertyCount"])
|
||||
d.putIntItem("enumeratorCount", value["enumeratorCount"])
|
||||
d.putIntItem("constructorCount", value["constructorCount"])
|
||||
d.putIntItem("flags", value["flags"])
|
||||
d.putIntItem("signalCount", value["signalCount"])
|
||||
def qdump__QMetaMethod(d, value):
|
||||
d.putQMetaStuff(value, "QMetaMethod")
|
||||
|
||||
def qdump__QMetaEnum(d, value):
|
||||
d.putQMetaStuff(value, "QMetaEnum")
|
||||
|
||||
def qdump__QMetaProperty(d, value):
|
||||
d.putQMetaStuff(value, "QMetaProperty")
|
||||
|
||||
def qdump__QMetaClassInfo(d, value):
|
||||
d.putQMetaStuff(value, "QMetaClassInfo")
|
||||
|
||||
def qdump__QMetaObject(d, value):
|
||||
d.putEmptyValue()
|
||||
d.putNumChild(1)
|
||||
if d.isExpanded():
|
||||
with Children(d):
|
||||
dd = value["d"]
|
||||
d.putSubItem("d", dd)
|
||||
data = d.extractPointer(dd["data"])
|
||||
d.putQObjectGutsHelper(0, 0, value)
|
||||
d.putSubItem("stringData", dd["stringdata"])
|
||||
#d.putIntItem("revision", d.extractInt(data))
|
||||
#d.putIntItem("className", d.extractInt(data + 4))
|
||||
#d.putIntItem("classInfoCount", d.extractInt(data + 8))
|
||||
#d.putIntItem("className", d.extractInt(data + 12))
|
||||
#d.putIntItem("methodCount", d.extractInt(data + 16))
|
||||
#d.putIntItem("methodData", d.extractInt(data + 20))
|
||||
#d.putIntItem("propertyCount", d.extractInt(data + 24))
|
||||
#d.putIntItem("propertyData", d.extractInt(data + 28))
|
||||
#d.putIntItem("enumeratorCount", d.extractInt(data + 32))
|
||||
#d.putIntItem("enumeratorData", d.extractInt(data + 36))
|
||||
#d.putIntItem("constructorCount", d.extractInt(data + 40))
|
||||
#d.putIntItem("constructorData", d.extractInt(data + 44))
|
||||
#d.putIntItem("flags", d.extractInt(data + 48))
|
||||
#d.putIntItem("signalCount", d.extractInt(data + 52))
|
||||
d.putQObjectGutsHelper(0, 0, -1, value, "QMetaObject")
|
||||
d.putMembersItem(value)
|
||||
|
||||
def _qdump__QObject(d, value):
|
||||
d.putQObjectNameValue(value)
|
||||
ns = d.qtNamespace()
|
||||
|
||||
try:
|
||||
privateTypeName = ns + "QObjectPrivate"
|
||||
privateType = d.lookupType(privateTypeName)
|
||||
staticMetaObject = value["staticMetaObject"]
|
||||
except:
|
||||
d.putPlainChildren(value)
|
||||
return
|
||||
#warn("SMO: %s " % staticMetaObject)
|
||||
#warn("SMO DATA: %s " % staticMetaObject["d"]["stringdata"])
|
||||
superData = staticMetaObject["d"]["superdata"]
|
||||
#warn("SUPERDATA: %s" % superData)
|
||||
#while not d.isNull(superData):
|
||||
# superData = superData.dereference()["d"]["superdata"]
|
||||
# warn("SUPERDATA: %s" % superData)
|
||||
|
||||
if privateType is None:
|
||||
#d.putValue(d.cleanAddress(d.pointerValue(value))
|
||||
d.putPlainChildren(value)
|
||||
return
|
||||
|
||||
#warn("OBJECTNAME: %s " % objectName)
|
||||
dd = value["d_ptr"]["d"]
|
||||
d_ptr = dd.cast(privateType.pointer()).dereference()
|
||||
#warn("D_PTR: %s " % d_ptr)
|
||||
mo = d_ptr["metaObject"]
|
||||
if d.isNull(mo):
|
||||
mo = staticMetaObject
|
||||
#warn("MO: %s " % mo)
|
||||
#warn("MO.D: %s " % mo["d"])
|
||||
metaData = mo["d"]["data"]
|
||||
metaStringData = mo["d"]["stringdata"]
|
||||
# This is char * in Qt 4 and ByteArrayData * in Qt 5.
|
||||
# Force it to the char * data in the Qt 5 case.
|
||||
try:
|
||||
offset = metaStringData["offset"]
|
||||
metaStringData = metaStringData.cast(d.charPtrType()) + int(offset)
|
||||
except:
|
||||
pass
|
||||
|
||||
#extradata = mo["d"]["extradata"] # Capitalization!
|
||||
#warn("METADATA: %s " % metaData)
|
||||
#warn("STRINGDATA: %s " % metaStringData)
|
||||
#warn("TYPE: %s " % value.type)
|
||||
#warn("INAME: %s " % d.currentIName)
|
||||
d.putEmptyValue()
|
||||
#QSignalMapper::staticMetaObject
|
||||
#d.checkRef(d_ptr["ref"])
|
||||
d.putNumChild(4)
|
||||
if d.isExpanded():
|
||||
with Children(d):
|
||||
d.putQObjectGuts(value)
|
||||
|
||||
# Local data.
|
||||
if privateTypeName != ns + "QObjectPrivate":
|
||||
if not privateType is None:
|
||||
with SubItem(d, "data"):
|
||||
d.putEmptyValue()
|
||||
d.putNoType()
|
||||
d.putPlainChildren(d_ptr, False)
|
||||
|
||||
d.putFields(value)
|
||||
# Parent and children.
|
||||
if d.stripClassTag(str(value.type)) == ns + "QObject":
|
||||
d.putSubItem("parent", d_ptr["parent"])
|
||||
d.putSubItem("children", d_ptr["children"])
|
||||
|
||||
# Metaobject.
|
||||
d.putSubItem("metaobject", mo)
|
||||
|
||||
# Dynamic Properties.
|
||||
with SubItem(d, "dynamics"):
|
||||
# Prolog
|
||||
extraData = d_ptr["extraData"] # Capitalization!
|
||||
if d.isNull(extraData):
|
||||
dynamicPropertyCount = 0
|
||||
else:
|
||||
extraDataType = d.lookupType(
|
||||
ns + "QObjectPrivate::ExtraData").pointer()
|
||||
extraData = extraData.cast(extraDataType)
|
||||
ed = extraData.dereference()
|
||||
names = ed["propertyNames"]
|
||||
values = ed["propertyValues"]
|
||||
#userData = ed["userData"]
|
||||
namesBegin = names["d"]["begin"]
|
||||
namesEnd = names["d"]["end"]
|
||||
namesArray = names["d"]["array"]
|
||||
dynamicPropertyCount = namesEnd - namesBegin
|
||||
|
||||
d.putNoType()
|
||||
d.putItemCount(dynamicPropertyCount)
|
||||
|
||||
if d.isExpanded() and d.isGdb:
|
||||
import gdb
|
||||
# FIXME: Make this global. Don't leak.
|
||||
variant = "'%sQVariant'" % ns
|
||||
# Avoid malloc symbol clash with QVector
|
||||
gdb.execute("set $d = (%s*)calloc(sizeof(%s), 1)"
|
||||
% (variant, variant))
|
||||
gdb.execute("set $d.d.is_shared = 0")
|
||||
|
||||
with Children(d):
|
||||
dummyType = d.voidPtrType().pointer()
|
||||
namesType = d.lookupType(ns + "QByteArray")
|
||||
valuesBegin = values["d"]["begin"]
|
||||
valuesEnd = values["d"]["end"]
|
||||
valuesArray = values["d"]["array"]
|
||||
valuesType = d.lookupType(ns + "QVariant")
|
||||
p = namesArray.cast(dummyType) + namesBegin
|
||||
q = valuesArray.cast(dummyType) + valuesBegin
|
||||
for i in xrange(dynamicPropertyCount):
|
||||
with SubItem(d, i):
|
||||
pp = p.cast(namesType.pointer()).dereference();
|
||||
d.putField("key", d.encodeByteArray(pp))
|
||||
d.putField("keyencoded", "latin1")
|
||||
qq = q.cast(valuesType.pointer().pointer())
|
||||
qq = qq.dereference();
|
||||
d.putField("address", d.cleanAddress(qq))
|
||||
d.putField("exp", "*(%s*)%s"
|
||||
% (variant, d.cleanAddress(qq)))
|
||||
t = qdump__QVariant(d, qq)
|
||||
# Override the "QVariant (foo)" output.
|
||||
d.putBetterType(t)
|
||||
p += 1
|
||||
q += 1
|
||||
|
||||
|
||||
# Connections.
|
||||
with SubItem(d, "connections"):
|
||||
d.putNoType()
|
||||
connections = d_ptr["connectionLists"]
|
||||
connectionListCount = 0
|
||||
if not d.isNull(connections):
|
||||
connectionListCount = connections["d"]["size"]
|
||||
d.putItemCount(connectionListCount, 0)
|
||||
if d.isExpanded():
|
||||
pp = 0
|
||||
with Children(d):
|
||||
vectorType = d.fieldAt(connections.type.target(), 0).type
|
||||
innerType = d.templateArgument(vectorType, 0)
|
||||
# Should check: innerType == ns::QObjectPrivate::ConnectionList
|
||||
p = gdb.Value(connections["p"]["array"]).cast(innerType.pointer())
|
||||
for i in xrange(connectionListCount):
|
||||
first = p.dereference()["first"]
|
||||
while not d.isNull(first):
|
||||
with SubItem(d, pp):
|
||||
connection = first.dereference()
|
||||
d.putItem(connection)
|
||||
d.putValue(connection["callFunction"])
|
||||
first = first["nextConnectionList"]
|
||||
# We need to enforce some upper limit.
|
||||
pp += 1
|
||||
if pp > 1000:
|
||||
break
|
||||
p += 1
|
||||
if pp < 1000:
|
||||
d.putItemCount(pp)
|
||||
|
||||
|
||||
# Active connection.
|
||||
with SubItem(d, "currentSender"):
|
||||
d.putNoType()
|
||||
sender = d_ptr["currentSender"]
|
||||
d.putPointerValue(sender)
|
||||
if d.isNull(sender):
|
||||
d.putNumChild(0)
|
||||
else:
|
||||
d.putNumChild(1)
|
||||
if d.isExpanded():
|
||||
with Children(d):
|
||||
# Sending object
|
||||
d.putSubItem("object", sender["sender"])
|
||||
# Signal in sending object
|
||||
with SubItem(d, "signal"):
|
||||
d.putValue(sender["signal"])
|
||||
d.putNoType()
|
||||
d.putNumChild(0)
|
||||
|
||||
# QObject
|
||||
|
||||
# static const uint qt_meta_data_QObject[] = {
|
||||
|
||||
# int revision;
|
||||
# int className;
|
||||
# int classInfoCount, classInfoData;
|
||||
# int methodCount, methodData;
|
||||
# int propertyCount, propertyData;
|
||||
# int enumeratorCount, enumeratorData;
|
||||
# int constructorCount, constructorData; //since revision 2
|
||||
# int flags; //since revision 3
|
||||
# int signalCount; //since revision 4
|
||||
|
||||
# // content:
|
||||
# 4, // revision
|
||||
# 0, // classname
|
||||
# 0, 0, // classinfo
|
||||
# 4, 14, // methods
|
||||
# 1, 34, // properties
|
||||
# 0, 0, // enums/sets
|
||||
# 2, 37, // constructors
|
||||
# 0, // flags
|
||||
# 2, // signalCount
|
||||
|
||||
# /* 14 */
|
||||
|
||||
# // signals: signature, parameters, type, tag, flags
|
||||
# 9, 8, 8, 8, 0x05,
|
||||
# 29, 8, 8, 8, 0x25,
|
||||
|
||||
# /* 24 */
|
||||
# // slots: signature, parameters, type, tag, flags
|
||||
# 41, 8, 8, 8, 0x0a,
|
||||
# 55, 8, 8, 8, 0x08,
|
||||
|
||||
# /* 34 */
|
||||
# // properties: name, type, flags
|
||||
# 90, 82, 0x0a095103,
|
||||
|
||||
# /* 37 */
|
||||
# // constructors: signature, parameters, type, tag, flags
|
||||
# 108, 101, 8, 8, 0x0e,
|
||||
# 126, 8, 8, 8, 0x2e,
|
||||
|
||||
# 0 // eod
|
||||
# };
|
||||
|
||||
# static const char qt_meta_stringdata_QObject[] = {
|
||||
# "QObject\0\0destroyed(QObject*)\0destroyed()\0"
|
||||
# "deleteLater()\0_q_reregisterTimers(void*)\0"
|
||||
# "QString\0objectName\0parent\0QObject(QObject*)\0"
|
||||
# "QObject()\0"
|
||||
# };
|
||||
|
||||
|
||||
# QSignalMapper
|
||||
|
||||
# static const uint qt_meta_data_QSignalMapper[] = {
|
||||
|
||||
# // content:
|
||||
# 4, // revision
|
||||
# 0, // classname
|
||||
# 0, 0, // classinfo
|
||||
# 7, 14, // methods
|
||||
# 0, 0, // properties
|
||||
# 0, 0, // enums/sets
|
||||
# 0, 0, // constructors
|
||||
# 0, // flags
|
||||
# 4, // signalCount
|
||||
|
||||
# // signals: signature, parameters, type, tag, flags
|
||||
# 15, 14, 14, 14, 0x05,
|
||||
# 27, 14, 14, 14, 0x05,
|
||||
# 43, 14, 14, 14, 0x05,
|
||||
# 60, 14, 14, 14, 0x05,
|
||||
|
||||
# // slots: signature, parameters, type, tag, flags
|
||||
# 77, 14, 14, 14, 0x0a,
|
||||
# 90, 83, 14, 14, 0x0a,
|
||||
# 104, 14, 14, 14, 0x08,
|
||||
|
||||
# 0 // eod
|
||||
# };
|
||||
|
||||
# static const char qt_meta_stringdata_QSignalMapper[] = {
|
||||
# "QSignalMapper\0\0mapped(int)\0mapped(QString)\0"
|
||||
# "mapped(QWidget*)\0mapped(QObject*)\0"
|
||||
# "map()\0sender\0map(QObject*)\0"
|
||||
# "_q_senderDestroyed()\0"
|
||||
# };
|
||||
|
||||
# const QMetaObject QSignalMapper::staticMetaObject = {
|
||||
# { &QObject::staticMetaObject, qt_meta_stringdata_QSignalMapper,
|
||||
# qt_meta_data_QSignalMapper, 0 }
|
||||
# };
|
||||
|
||||
|
||||
|
||||
# // Meta enumeration helpers
|
||||
# static inline void dumpMetaEnumType(QDumper &d, const QMetaEnum &me)
|
||||
# {
|
||||
# QByteArray type = me.scope()
|
||||
# if !type.isEmpty())
|
||||
# type += "::"
|
||||
# type += me.name()
|
||||
# d.putField("type", type.constData())
|
||||
# }
|
||||
#
|
||||
# static inline void dumpMetaEnumValue(QDumper &d, const QMetaProperty &mop,
|
||||
# int value)
|
||||
# {
|
||||
#
|
||||
# const QMetaEnum me = mop.enumerator()
|
||||
# dumpMetaEnumType(d, me)
|
||||
# if const char *enumValue = me.valueToKey(value)) {
|
||||
# d.putValue(enumValue)
|
||||
# } else {
|
||||
# d.putValue(value)
|
||||
# }
|
||||
# d.putField("numchild", 0)
|
||||
# }
|
||||
#
|
||||
# static inline void dumpMetaFlagValue(QDumper &d, const QMetaProperty &mop,
|
||||
# int value)
|
||||
# {
|
||||
# const QMetaEnum me = mop.enumerator()
|
||||
# dumpMetaEnumType(d, me)
|
||||
# const QByteArray flagsValue = me.valueToKeys(value)
|
||||
# if flagsValue.isEmpty():
|
||||
# d.putValue(value)
|
||||
# else:
|
||||
# d.putValue(flagsValue.constData())
|
||||
# d.putNumChild(0)
|
||||
# }
|
||||
|
||||
def qdump__QPixmap(d, value):
|
||||
offset = (3 if d.qtVersion() >= 0x050000 else 2) * d.ptrSize()
|
||||
|
@@ -217,6 +217,7 @@ void dummyStatement(...) {}
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include <QMetaMethod>
|
||||
#include <stdarg.h>
|
||||
#include <stdint.h>
|
||||
|
||||
@@ -1842,6 +1843,9 @@ namespace qobject {
|
||||
Q_SIGNAL void sigFoo();
|
||||
Q_SIGNAL void sigBar(int);
|
||||
|
||||
enum Side { LeftSide, RightSide };
|
||||
Q_ENUMS(Side)
|
||||
|
||||
public:
|
||||
Ui *m_ui;
|
||||
QString m_myProp1;
|
||||
@@ -1860,11 +1864,32 @@ namespace qobject {
|
||||
test.setObjectName("An object");
|
||||
QString s = test.myProp1();
|
||||
s += test.myProp2();
|
||||
const QMetaObject *mo = test.metaObject();
|
||||
QMetaMethod mm0;
|
||||
const QMetaObject smo = test.staticMetaObject;
|
||||
QMetaMethod mm = mo->method(0);
|
||||
QByteArray mmname = mm.name();
|
||||
|
||||
QMetaEnum me0;
|
||||
QMetaEnum me = mo->enumerator(0);
|
||||
|
||||
QMetaProperty mp0;
|
||||
QMetaProperty mp = mo->property(0);
|
||||
|
||||
QMetaClassInfo mci0;
|
||||
QMetaClassInfo mci = mo->classInfo(0);
|
||||
|
||||
int n = mo->methodCount();
|
||||
QVector<QMetaMethod> v(n);
|
||||
for (int i = 0; i < n; ++i)
|
||||
v[i] = mo->method(i);
|
||||
|
||||
|
||||
BREAK_HERE;
|
||||
// Check s "HELLOWORLD" QString.
|
||||
// Check test qobject::Names::Bar::TestObject.
|
||||
// Continue.
|
||||
dummyStatement(&s);
|
||||
dummyStatement(&s, &mm, &smo, &mo, &mmname, &mm0, &me, &me0, &mp, &mp0, &mci, &mci0);
|
||||
}
|
||||
|
||||
void testQObject3()
|
||||
|
Reference in New Issue
Block a user