Debugger: Fix enum dumper

Make the hex display work with LLDB, fix GDB and LLDB test.

Change-Id: I529b5cdc908dbcba7270bc4574fa59a012fcacad
Reviewed-by: David Schulz <david.schulz@qt.io>
This commit is contained in:
hjk
2018-03-21 17:10:24 +01:00
parent f88dc5fd58
commit a8a23110bf
6 changed files with 30 additions and 42 deletions

View File

@@ -181,8 +181,8 @@ class Dumper(DumperBase):
tdata.lalignment = lambda : \
self.nativeStructAlignment(nativeType)
if code == TypeCodeEnum:
tdata.enumDisplay = lambda intval, addr : \
self.nativeTypeEnumDisplay(nativeType, addr)
tdata.enumDisplay = lambda intval, addr, form : \
self.nativeTypeEnumDisplay(nativeType, addr, form)
tdata.templateArguments = self.listTemplateParameters(nativeType.name())
self.registerType(typeId, tdata) # Fix up fields and template args
return self.Type(self, typeId)
@@ -208,7 +208,7 @@ class Dumper(DumperBase):
align = handleItem(f.type(), align)
return align
def nativeTypeEnumDisplay(self, nativeType, addr):
def nativeTypeEnumDisplay(self, nativeType, addr, form):
value = cdbext.createValue(addr, nativeType)
if value is None:
return ''

View File

@@ -2742,13 +2742,8 @@ class DumperBase:
if typeobj.code == TypeCodeBitfield:
#warn('BITFIELD VALUE: %s %d %s' % (value.name, value.lvalue, typeName))
self.putNumChild(0)
if typeobj.ltarget and typeobj.ltarget.code == TypeCodeEnum:
if hasattr(typeobj.ltarget.typeData(), 'enumHexDisplay'):
self.putValue(typeobj.ltarget.typeData().enumHexDisplay(value.lvalue, value.laddress))
else:
self.putValue(typeobj.ltarget.typeData().enumDisplay(value.lvalue, value.laddress))
else:
self.putValue(value.lvalue)
dd = typeobj.ltarget.typeData().enumDisplay
self.putValue(str(value.lvalue) if dd is None else dd(value.lvalue, value.laddress, '%d'))
self.putType(typeName)
return
@@ -2911,12 +2906,14 @@ class DumperBase:
% (self.name, self.type.name, self.lbitsize, self.lbitpos,
self.dumper.hexencode(self.ldata), addr)
def display(self, useHex = 1):
if self.type.code == TypeCodeEnum:
intval = self.integer()
if useHex and hasattr(self.type.typeData(), 'enumHexDisplay'):
return self.type.typeData().enumHexDisplay(intval, self.laddress)
return self.type.typeData().enumDisplay(intval, self.laddress)
def displayEnum(self, form='%d'):
intval = self.integer()
dd = self.type.typeData().enumDisplay
if dd is None:
return str(intval)
return dd(intval, self.laddress, form)
def display(self):
simple = self.value()
if simple is not None:
return str(simple)
@@ -3375,7 +3372,7 @@ class DumperBase:
self.code = None
self.name = None
self.typeId = None
self.enumDisplay = str
self.enumDisplay = None
self.moduleName = None
def copy(self):

View File

@@ -354,10 +354,8 @@ class Dumper(DumperBase):
gdb.TYPE_CODE_STRING : TypeCodeFortranString,
}[code]
if tdata.code == TypeCodeEnum:
tdata.enumDisplay = lambda intval, addr : \
self.nativeTypeEnumDisplay(nativeType, intval, 0)
tdata.enumHexDisplay = lambda intval, addr : \
self.nativeTypeEnumDisplay(nativeType, intval, 1)
tdata.enumDisplay = lambda intval, addr, form : \
self.nativeTypeEnumDisplay(nativeType, intval, form)
if tdata.code == TypeCodeStruct:
tdata.lalignment = lambda : \
self.nativeStructAlignment(nativeType)
@@ -388,17 +386,13 @@ class Dumper(DumperBase):
targs2 = self.listTemplateParametersManually(str(nativeType))
return targs if len(targs) >= len(targs2) else targs2
def nativeTypeEnumDisplay(self, nativeType, intval, useHex):
if useHex:
format = lambda text, intval: '%s (0x%04x)' % (text, intval)
else:
format = lambda text, intval: '%s (%d)' % (text, intval)
def nativeTypeEnumDisplay(self, nativeType, intval, form):
try:
enumerators = []
for field in nativeType.fields():
# If we found an exact match, return it immediately
if field.enumval == intval:
return format(field.name, intval)
return field.name + ' (' + (form % intval) + ')'
enumerators.append((field.name, field.enumval))
# No match was found, try to return as flags
@@ -414,12 +408,10 @@ class Dumper(DumperBase):
if not found or v != 0:
# Leftover value
flags.append('unknown:%d' % v)
return format(" | ".join(flags), intval)
return " | ".join(flags) + ' (' + (form % intval) + ')'
except:
pass
if useHex:
return '0x%04x' % intval;
return '%d' % intval
return form % intval
def nativeTypeId(self, nativeType):
if nativeType and (nativeType.code == gdb.TYPE_CODE_TYPEDEF):

View File

@@ -445,8 +445,8 @@ class Dumper(DumperBase):
warn('UNKNOWN TYPE KEY: %s: %s' % (typeName, code))
elif code == lldb.eTypeClassEnumeration:
tdata.code = TypeCodeEnum
tdata.enumDisplay = lambda intval, addr : \
self.nativeTypeEnumDisplay(nativeType, intval)
tdata.enumDisplay = lambda intval, addr, form : \
self.nativeTypeEnumDisplay(nativeType, intval, form)
elif code in (lldb.eTypeClassComplexInteger, lldb.eTypeClassComplexFloat):
tdata.code = TypeCodeComplex
elif code in (lldb.eTypeClassClass, lldb.eTypeClassStruct, lldb.eTypeClassUnion):
@@ -534,7 +534,7 @@ class Dumper(DumperBase):
#warn('NATIVE TYPE ID FOR %s IS %s' % (name, typeId))
return typeId
def nativeTypeEnumDisplay(self, nativeType, intval):
def nativeTypeEnumDisplay(self, nativeType, intval, form):
if hasattr(nativeType, 'get_enum_members_array'):
for enumMember in nativeType.get_enum_members_array():
# Even when asking for signed we get unsigned with LLDB 3.8.
@@ -543,8 +543,8 @@ class Dumper(DumperBase):
if diff & mask == 0:
path = nativeType.GetName().split('::')
path[-1] = enumMember.GetName()
return '%s (%d)' % ('::'.join(path), intval)
return '%d' % intval
return '::'.join(path) + ' (' + (form % intval) + ')'
return form % intval
def nativeDynamicTypeName(self, address, baseType):
return None # FIXME: Seems sufficient, no idea why.

View File

@@ -644,10 +644,8 @@ def qdump__QFiniteStack(d, value):
def qdump__QFlags(d, value):
i = value.split('{int}')[0]
enumType = value.type[0]
if d.isGdb:
d.putValue(i.cast('enum ' + enumType.name).display(useHex = 1))
else:
d.putValue(i.cast(enumType.name).display())
v = i.cast(enumType.name)
d.putValue(v.displayEnum('0x%04x'))
d.putNumChild(0)

View File

@@ -1944,8 +1944,9 @@ void tst_Dumpers::dumper_data()
"FooFlags f1(a);\n"
"FooFlags f2(a | b);\n")
+ CoreProfile()
+ Check("f1", "a (1)", TypeDef("QFlags<enum Foo>", "FooFlags"))
+ Check("f2", "(a | b) (3)", "FooFlags") % GdbEngine;
+ Check("f1", "a (1)", TypeDef("QFlags<enum Foo>", "FooFlags")) % CdbEngine
+ Check("f1", "a (0x0001)", "FooFlags") % NoCdbEngine
+ Check("f2", "a | b (0x0003)", "FooFlags") % GdbEngine;
QTest::newRow("QDateTime")
<< Data("#include <QDateTime>\n",