summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorhjk <hjk@theqtcompany.com>2016-07-14 13:13:16 +0200
committerhjk <hjk@qt.io>2016-07-15 10:44:03 +0000
commit26fa769bab11cd94d2f17a4bbdfaa731b5cfe009 (patch)
tree8d1db6a7b1ccee3951fd186607272ab268b2a5da
parentac1c04b6b38a75bc958298d3755a8ed873fba2a5 (diff)
downloadqt-creator-26fa769bab11cd94d2f17a4bbdfaa731b5cfe009.tar.gz
Debugger: Add dumper for QMeta{Enum,Method,Property}
Task-number: QTCREATORBUG-16593 Change-Id: Iaa710660d8ef69459596f93831cf8467913f0468 Reviewed-by: Alexandru Croitor <alexandru.croitor@qt.io>
-rw-r--r--share/qtcreator/debugger/dumper.py403
-rw-r--r--share/qtcreator/debugger/gdbbridge.py19
-rw-r--r--share/qtcreator/debugger/lldbbridge.py24
-rw-r--r--share/qtcreator/debugger/qttypes.py390
-rw-r--r--tests/manual/debugger/simple/simple_test_app.cpp27
5 files changed, 277 insertions, 586 deletions
diff --git a/share/qtcreator/debugger/dumper.py b/share/qtcreator/debugger/dumper.py
index bda932b80b..99db06848c 100644
--- a/share/qtcreator/debugger/dumper.py
+++ b/share/qtcreator/debugger/dumper.py
@@ -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 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, extraData, dd, smo):
+ 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"')
+ def superData(mo):
+ return mo['d']['superdata']
+
+ isQMetaObject = origType == "QMetaObject"
+ isQObject = origType == "QObject"
+
+ 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()
+
+ 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():
+ 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)
-
- 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)
-
- if extraData:
- with SubItem(self, "[extraData]"):
- self.putValue("0x%x" % toInteger(extraData))
- self.putType("void *")
- self.putNumChild(0)
-
+ 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]"):
- propertyCount = 0
- usesVector = self.qtVersion() >= 0x50700
+ self.put('sortgroup="5"')
+ self.putItemCount(propertyCount)
if self.isExpanded():
- propertyNames = self.staticQObjectPropertyNames(smo)
- propertyCount = len(propertyNames) # Doesn't include dynamic properties.
+ 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])
-
-
- 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)
+ 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]"):
+ # 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]"):
diff --git a/share/qtcreator/debugger/gdbbridge.py b/share/qtcreator/debugger/gdbbridge.py
index f9cf2d9f36..24abf794d0 100644
--- a/share/qtcreator/debugger/gdbbridge.py
+++ b/share/qtcreator/debugger/gdbbridge.py
@@ -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)
diff --git a/share/qtcreator/debugger/lldbbridge.py b/share/qtcreator/debugger/lldbbridge.py
index 89a4a38fb2..5402db229f 100644
--- a/share/qtcreator/debugger/lldbbridge.py
+++ b/share/qtcreator/debugger/lldbbridge.py
@@ -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:
diff --git a/share/qtcreator/debugger/qttypes.py b/share/qtcreator/debugger/qttypes.py
index 93eb91ae85..095f30a8ff 100644
--- a/share/qtcreator/debugger/qttypes.py
+++ b/share/qtcreator/debugger/qttypes.py
@@ -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))
-
-def _qdump__QObject(d, value):
- d.putQObjectNameValue(value)
- ns = d.qtNamespace()
+ d.putQObjectGutsHelper(0, 0, -1, value, "QMetaObject")
+ d.putMembersItem(value)
- 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()
diff --git a/tests/manual/debugger/simple/simple_test_app.cpp b/tests/manual/debugger/simple/simple_test_app.cpp
index 20f74e347c..bf68715fef 100644
--- a/tests/manual/debugger/simple/simple_test_app.cpp
+++ b/tests/manual/debugger/simple/simple_test_app.cpp
@@ -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()