forked from qt-creator/qt-creator
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:
@@ -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 ''
|
||||
|
@@ -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):
|
||||
|
@@ -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):
|
||||
|
@@ -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.
|
||||
|
@@ -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)
|
||||
|
||||
|
||||
|
@@ -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",
|
||||
|
Reference in New Issue
Block a user