From 84576d30986fc896a8171001f2d11905db2ac32d Mon Sep 17 00:00:00 2001 From: Christian Stenger Date: Thu, 15 Nov 2018 09:04:39 +0100 Subject: [PATCH] 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 Reviewed-by: hjk --- share/qtcreator/debugger/dumper.py | 4 ++-- share/qtcreator/debugger/gdbbridge.py | 2 +- share/qtcreator/debugger/lldbbridge.py | 27 ++++++++++++++++++++------ tests/auto/debugger/tst_dumpers.cpp | 4 ++-- 4 files changed, 26 insertions(+), 11 deletions(-) diff --git a/share/qtcreator/debugger/dumper.py b/share/qtcreator/debugger/dumper.py index 6446131608a..80eaa318bdc 100644 --- a/share/qtcreator/debugger/dumper.py +++ b/share/qtcreator/debugger/dumper.py @@ -2944,8 +2944,6 @@ class DumperBase: return str(simple) if self.ldisplay is not None: return self.ldisplay - if self.type.code == TypeCodeEnum: - return self.displayEnum() #if self.ldata is not None: # if sys.version_info[0] == 2 and isinstance(self.ldata, buffer): # return bytes(self.ldata).encode('hex') @@ -3020,6 +3018,8 @@ class DumperBase: def value(self): if self.type is not None: + if self.type.code == TypeCodeEnum: + return self.displayEnum() if self.type.code == TypeCodeTypedef: return self.detypedef().value() if self.type.code == TypeCodeIntegral: diff --git a/share/qtcreator/debugger/gdbbridge.py b/share/qtcreator/debugger/gdbbridge.py index 75cb512c68e..cdde71b3ff3 100644 --- a/share/qtcreator/debugger/gdbbridge.py +++ b/share/qtcreator/debugger/gdbbridge.py @@ -409,7 +409,7 @@ class Dumper(DumperBase): if not found or v != 0: # Leftover value flags.append('unknown: %d' % v) - return " | ".join(flags) + ' (' + (form % intval) + ')' + return '(' + " | ".join(flags) + ') (' + (form % intval) + ')' except: pass return form % intval diff --git a/share/qtcreator/debugger/lldbbridge.py b/share/qtcreator/debugger/lldbbridge.py index e50efacfe78..a3b46a413e6 100644 --- a/share/qtcreator/debugger/lldbbridge.py +++ b/share/qtcreator/debugger/lldbbridge.py @@ -531,14 +531,29 @@ class Dumper(DumperBase): def nativeTypeEnumDisplay(self, nativeType, intval, form): if hasattr(nativeType, 'get_enum_members_array'): + enumerators = [] + flags = [] + found = False for enumMember in nativeType.get_enum_members_array(): # Even when asking for signed we get unsigned with LLDB 3.8. - diff = enumMember.GetValueAsSigned() - intval - mask = (1 << nativeType.GetByteSize() * 8) - 1 - if diff & mask == 0: - path = nativeType.GetName().split('::') - path[-1] = enumMember.GetName() - return '::'.join(path) + ' (' + (form % intval) + ')' + value = enumMember.GetValueAsSigned() + name = nativeType.GetName().split('::') + name[-1] = enumMember.GetName() + if value == intval: + return '::'.join(name) + ' (' + (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 def nativeDynamicTypeName(self, address, baseType): diff --git a/tests/auto/debugger/tst_dumpers.cpp b/tests/auto/debugger/tst_dumpers.cpp index 9d439f05c2d..89d54ab1bba 100644 --- a/tests/auto/debugger/tst_dumpers.cpp +++ b/tests/auto/debugger/tst_dumpers.cpp @@ -5416,7 +5416,7 @@ void tst_Dumpers::dumper_data() "Flags fthree = (Flags)(one|two); unused(&fthree);\n" "Flags fmixed = (Flags)(two|8); unused(&fmixed);\n" "Flags fbad = (Flags)(24); unused(&fbad);\n") - + GdbEngine + + NoCdbEngine + Check("fone", "one (1)", "Flags") + Check("fthree", "(one | two) (3)", "Flags") + Check("fmixed", "(two | unknown: 8) (10)", "Flags") @@ -5433,7 +5433,7 @@ void tst_Dumpers::dumper_data() " Enum3 e3 = Enum3(c3 | b3);\n" "};\n", "E e;\n") - + GdbEngine + + NoCdbEngine + Check("e.e1", "(E::b1 | E::c1) (3)", "E::Enum1") + Check("e.e2", "(E::b2 | E::c2) (3)", "E::Enum2") + Check("e.e3", "(E::b3 | E::c3) (3)", "E::Enum3");