Commit af43f684 authored by hjk's avatar hjk

Debugger: Consolidate metaObject recognition

Same code can be used for LLDB and GDB...

Change-Id: I07aae10fec28f01425cc13285504f57aef3afd25
Reviewed-by: default avatarhjk <hjk121@nokiamail.com>
parent 376f7795
......@@ -922,6 +922,46 @@ class DumperBase:
pass
def extractStaticMetaObjectHelper(self, typeName):
"""
Checks whether type has a Q_OBJECT macro.
Returns the staticMetaObject, or 0.
"""
# No templates for now.
if typeName.find('<') >= 0:
return 0
staticMetaObjectName = typeName + "::staticMetaObject"
result = self.findSymbol(staticMetaObjectName)
# We need to distinguish Q_OBJECT from Q_GADGET:
# a Q_OBJECT SMO has a non-null superdata (unless it's QObject itself),
# a Q_GADGET SMO has a null superdata (hopefully)
if result and typeName != self.qtNamespace() + "QObject":
if not self.extractPointer(result):
# This looks like a Q_GADGET
result = 0
return result
def extractStaticMetaObject(self, typeobj):
"""
Checks recursively whether a type derives from QObject.
"""
typeName = str(typeobj)
result = self.knownStaticMetaObjects.get(typeName, None)
if result is not None: # Is 0 or the static metaobject.
return result
result = self.extractStaticMetaObjectHelper(typeName)
if not result:
base = self.directBaseClass(typeobj, 0)
if base:
result = self.extractStaticMetaObject(base)
self.knownStaticMetaObjects[typeName] = result
return result
def staticQObjectPropertyNames(self, metaobject):
properties = []
dd = metaobject["d"]
......
......@@ -657,8 +657,12 @@ class Dumper(DumperBase):
return str(value)
def directBaseClass(self, typeobj, index = 0):
# FIXME: Check it's really a base.
return typeobj.fields()[index]
for f in typeobj.fields():
if f.is_base_class:
if index == 0:
return f.type
index -= 1;
return None
def checkPointer(self, p, align = 1):
if not self.isNull(p):
......@@ -861,47 +865,6 @@ class Dumper(DumperBase):
except:
return 0
def extractStaticMetaObjectHelper(self, typeName):
"""
Checks whether type has a Q_OBJECT macro.
Returns the staticMetaObject, or 0.
"""
# No templates for now.
if typeName.find('<') >= 0:
return 0
staticMetaObjectName = typeName + "::staticMetaObject"
result = self.findSymbol(staticMetaObjectName)
# We need to distinguish Q_OBJECT from Q_GADGET:
# a Q_OBJECT SMO has a non-null superdata (unless it's QObject itself),
# a Q_GADGET SMO has a null superdata (hopefully)
if result and typeName != self.qtNamespace() + "QObject":
if not self.extractPointer(result):
# This looks like a Q_GADGET
result = 0
return result
def extractStaticMetaObject(self, typeobj):
"""
Checks recursively whether a type derives from QObject.
"""
typeName = str(typeobj)
result = self.knownStaticMetaObjects.get(typeName, None)
if result is not None: # Is 0 or the static metaobject.
return result
result = self.extractStaticMetaObjectHelper(typeName)
if not result:
fields = typeobj.fields()
if len(fields) and fields[0].is_base_class:
result = self.extractStaticMetaObject(fields[0].type)
self.knownStaticMetaObjects[typeName] = result
return result
def put(self, value):
self.output.append(value)
......
......@@ -408,7 +408,8 @@ class Dumper(DumperBase):
return p.GetValueAsUnsigned() == 0
def directBaseClass(self, typeobj, index = 0):
return typeobj.GetDirectBaseClassAtIndex(index)
result = typeobj.GetDirectBaseClassAtIndex(index)
return result if result.IsValid() else None
def templateArgument(self, typeobj, index):
type = typeobj.GetTemplateArgumentType(index)
......@@ -883,31 +884,8 @@ class Dumper(DumperBase):
buf[i] = data.GetUnsignedInt8(error, i)
return Blob(bytes(buf))
def extractStaticMetaObjectHelper(self, typeobj):
if typeobj.GetTypeClass() in (lldb.eTypeClassStruct, lldb.eTypeClassClass):
needle = typeobj.GetUnqualifiedType().GetName() + "::staticMetaObject"
options = lldb.SBExpressionOptions()
result = self.target.EvaluateExpression(needle, options)
# Surprising results include:
# (lldb) script print lldb.target.FindFirstGlobalVariable(
# '::QSharedDataPointer<QDirPrivate>::staticMetaObject')
# (const QMetaObject) QAbstractAnimation::staticMetaObject = { d = { ... } }
#if result.GetName() != needle:
if result is None or not result.IsValid():
result = 0
else:
result = 0
self.knownStaticMetaObjects[typeobj.GetName()] = result
return result
def extractStaticMetaObject(self, typeobj):
if not self.isGoodLldb:
return 0
result = self.extractStaticMetaObjectHelper(typeobj)
if result:
return result
base = typeobj.GetDirectBaseClassAtIndex(0).GetType()
return self.extractStaticMetaObjectHelper(base)
def findSymbol(self, symbolName):
return self.target.FindFirstGlobalVariable(symbolName)
def stripNamespaceFromType(self, typeName):
#type = stripClassTag(typeName)
......
......@@ -1776,7 +1776,7 @@ def qdump__QStringRef(d, value):
def qdump__QStringList(d, value):
listType = d.directBaseClass(value.type).type
listType = d.directBaseClass(value.type)
qdump__QList(d, value.cast(listType))
d.putBetterType(value.type)
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment