forked from qt-creator/qt-creator
Dumper: Fix displaying enums with LLDB
Prioritize displaying as enum if a type is known to be an enum. Otherwise this would just end up get displayed as string representation of its value. Enable respective dumper tests. Change-Id: I3e5406e14a68f02741b6144bb54528b72cc8192d Reviewed-by: Orgad Shaneh <orgads@gmail.com> Reviewed-by: hjk <hjk@qt.io>
This commit is contained in:
@@ -2944,8 +2944,6 @@ class DumperBase:
|
|||||||
return str(simple)
|
return str(simple)
|
||||||
if self.ldisplay is not None:
|
if self.ldisplay is not None:
|
||||||
return self.ldisplay
|
return self.ldisplay
|
||||||
if self.type.code == TypeCodeEnum:
|
|
||||||
return self.displayEnum()
|
|
||||||
#if self.ldata is not None:
|
#if self.ldata is not None:
|
||||||
# if sys.version_info[0] == 2 and isinstance(self.ldata, buffer):
|
# if sys.version_info[0] == 2 and isinstance(self.ldata, buffer):
|
||||||
# return bytes(self.ldata).encode('hex')
|
# return bytes(self.ldata).encode('hex')
|
||||||
@@ -3020,6 +3018,8 @@ class DumperBase:
|
|||||||
|
|
||||||
def value(self):
|
def value(self):
|
||||||
if self.type is not None:
|
if self.type is not None:
|
||||||
|
if self.type.code == TypeCodeEnum:
|
||||||
|
return self.displayEnum()
|
||||||
if self.type.code == TypeCodeTypedef:
|
if self.type.code == TypeCodeTypedef:
|
||||||
return self.detypedef().value()
|
return self.detypedef().value()
|
||||||
if self.type.code == TypeCodeIntegral:
|
if self.type.code == TypeCodeIntegral:
|
||||||
|
@@ -409,7 +409,7 @@ class Dumper(DumperBase):
|
|||||||
if not found or v != 0:
|
if not found or v != 0:
|
||||||
# Leftover value
|
# Leftover value
|
||||||
flags.append('unknown: %d' % v)
|
flags.append('unknown: %d' % v)
|
||||||
return " | ".join(flags) + ' (' + (form % intval) + ')'
|
return '(' + " | ".join(flags) + ') (' + (form % intval) + ')'
|
||||||
except:
|
except:
|
||||||
pass
|
pass
|
||||||
return form % intval
|
return form % intval
|
||||||
|
@@ -531,14 +531,29 @@ class Dumper(DumperBase):
|
|||||||
|
|
||||||
def nativeTypeEnumDisplay(self, nativeType, intval, form):
|
def nativeTypeEnumDisplay(self, nativeType, intval, form):
|
||||||
if hasattr(nativeType, 'get_enum_members_array'):
|
if hasattr(nativeType, 'get_enum_members_array'):
|
||||||
|
enumerators = []
|
||||||
|
flags = []
|
||||||
|
found = False
|
||||||
for enumMember in 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.
|
# Even when asking for signed we get unsigned with LLDB 3.8.
|
||||||
diff = enumMember.GetValueAsSigned() - intval
|
value = enumMember.GetValueAsSigned()
|
||||||
mask = (1 << nativeType.GetByteSize() * 8) - 1
|
name = nativeType.GetName().split('::')
|
||||||
if diff & mask == 0:
|
name[-1] = enumMember.GetName()
|
||||||
path = nativeType.GetName().split('::')
|
if value == intval:
|
||||||
path[-1] = enumMember.GetName()
|
return '::'.join(name) + ' (' + (form % intval) + ')'
|
||||||
return '::'.join(path) + ' (' + (form % intval) + ')'
|
enumerators.append(('::'.join(name), value))
|
||||||
|
|
||||||
|
given = intval
|
||||||
|
for (name, value) in enumerators:
|
||||||
|
if value & given != 0:
|
||||||
|
flags.append(name)
|
||||||
|
given = given & ~value
|
||||||
|
found = True
|
||||||
|
|
||||||
|
if not found or given != 0:
|
||||||
|
flags.append('unknown: %d' % given)
|
||||||
|
|
||||||
|
return '(' + ' | '.join(flags) + ') (' + (form % intval) + ')'
|
||||||
return form % intval
|
return form % intval
|
||||||
|
|
||||||
def nativeDynamicTypeName(self, address, baseType):
|
def nativeDynamicTypeName(self, address, baseType):
|
||||||
|
@@ -5416,7 +5416,7 @@ void tst_Dumpers::dumper_data()
|
|||||||
"Flags fthree = (Flags)(one|two); unused(&fthree);\n"
|
"Flags fthree = (Flags)(one|two); unused(&fthree);\n"
|
||||||
"Flags fmixed = (Flags)(two|8); unused(&fmixed);\n"
|
"Flags fmixed = (Flags)(two|8); unused(&fmixed);\n"
|
||||||
"Flags fbad = (Flags)(24); unused(&fbad);\n")
|
"Flags fbad = (Flags)(24); unused(&fbad);\n")
|
||||||
+ GdbEngine
|
+ NoCdbEngine
|
||||||
+ Check("fone", "one (1)", "Flags")
|
+ Check("fone", "one (1)", "Flags")
|
||||||
+ Check("fthree", "(one | two) (3)", "Flags")
|
+ Check("fthree", "(one | two) (3)", "Flags")
|
||||||
+ Check("fmixed", "(two | unknown: 8) (10)", "Flags")
|
+ Check("fmixed", "(two | unknown: 8) (10)", "Flags")
|
||||||
@@ -5433,7 +5433,7 @@ void tst_Dumpers::dumper_data()
|
|||||||
" Enum3 e3 = Enum3(c3 | b3);\n"
|
" Enum3 e3 = Enum3(c3 | b3);\n"
|
||||||
"};\n",
|
"};\n",
|
||||||
"E e;\n")
|
"E e;\n")
|
||||||
+ GdbEngine
|
+ NoCdbEngine
|
||||||
+ Check("e.e1", "(E::b1 | E::c1) (3)", "E::Enum1")
|
+ Check("e.e1", "(E::b1 | E::c1) (3)", "E::Enum1")
|
||||||
+ Check("e.e2", "(E::b2 | E::c2) (3)", "E::Enum2")
|
+ Check("e.e2", "(E::b2 | E::c2) (3)", "E::Enum2")
|
||||||
+ Check("e.e3", "(E::b3 | E::c3) (3)", "E::Enum3");
|
+ Check("e.e3", "(E::b3 | E::c3) (3)", "E::Enum3");
|
||||||
|
Reference in New Issue
Block a user