forked from qt-creator/qt-creator
Debugger: Reduce number of function calls in QLocale display
Change-Id: Ib186dafbee148b9c4aaf69124a3642404e16c002 Reviewed-by: Christian Stenger <christian.stenger@qt.io>
This commit is contained in:
@@ -2518,7 +2518,7 @@ class DumperBase:
|
|||||||
return
|
return
|
||||||
|
|
||||||
if typeobj.isEnumType():
|
if typeobj.isEnumType():
|
||||||
#warn("ENUM VALUE: %s" % value)
|
#warn("ENUM VALUE: %s" % value.stringify())
|
||||||
self.putType(typeobj.name)
|
self.putType(typeobj.name)
|
||||||
self.putValue(value.display())
|
self.putValue(value.display())
|
||||||
self.putNumChild(0)
|
self.putNumChild(0)
|
||||||
@@ -2651,24 +2651,22 @@ class DumperBase:
|
|||||||
error("INCONSISTENT TYPE: %s" % type(self.type))
|
error("INCONSISTENT TYPE: %s" % type(self.type))
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
|
#error("Not implemented")
|
||||||
|
return self.stringify()
|
||||||
|
|
||||||
|
def stringify(self):
|
||||||
self.check()
|
self.check()
|
||||||
addr = "None" if self.laddress is None else ("0x%x" % self.laddress)
|
addr = "None" if self.laddress is None else ("0x%x" % self.laddress)
|
||||||
#return self.display()
|
|
||||||
return "Value(name='%s',type=%s,data=%s,address=%s,nativeValue=%s)" \
|
return "Value(name='%s',type=%s,data=%s,address=%s,nativeValue=%s)" \
|
||||||
% (self.name, self.type, self.dumper.hexencode(self.ldata),
|
% (self.name, self.type, self.dumper.hexencode(self.ldata),
|
||||||
addr, self.nativeValue)
|
addr, self.nativeValue)
|
||||||
|
|
||||||
def display(self):
|
def display(self):
|
||||||
|
if self.type.lEnumType:
|
||||||
|
return self.type.enumDisplay(self.extractInteger(self.type.size() * 8, False))
|
||||||
simple = self.value()
|
simple = self.value()
|
||||||
if simple is not None:
|
if simple is not None:
|
||||||
return str(simple)
|
return str(simple)
|
||||||
if self.type.lEnumType:
|
|
||||||
if self.nativeValue is not None:
|
|
||||||
if self.dumper.isLldb:
|
|
||||||
return "%s (%d)" % (self.nativeValue.GetValue(), self.nativeValue.GetValueAsSigned())
|
|
||||||
else:
|
|
||||||
return "%s (%d)" % (self.nativeValue, self.nativeValue)
|
|
||||||
return self.integer()
|
|
||||||
if self.type.lComplexType:
|
if self.type.lComplexType:
|
||||||
if self.nativeValue is not None:
|
if self.nativeValue is not None:
|
||||||
if self.dumper.isLldb:
|
if self.dumper.isLldb:
|
||||||
@@ -2854,6 +2852,19 @@ class DumperBase:
|
|||||||
return val
|
return val
|
||||||
error("BAD DATA TO DEREFERENCE: %s %s" % (self.type, type(self)))
|
error("BAD DATA TO DEREFERENCE: %s %s" % (self.type, type(self)))
|
||||||
|
|
||||||
|
def extend(self, size):
|
||||||
|
if self.type.size() < size:
|
||||||
|
val = self.dumper.Value(self.dumper)
|
||||||
|
val.laddress = None
|
||||||
|
if sys.version_info[0] == 3:
|
||||||
|
val.ldata = self.ldata + bytes('\0' * (size - self.type.size()), encoding='latin1')
|
||||||
|
else:
|
||||||
|
val.ldata = self.ldata + bytes('\0' * (size - self.type.size()))
|
||||||
|
return val
|
||||||
|
if self.type.size() == size:
|
||||||
|
return self
|
||||||
|
error("NOT IMPLEMENTED")
|
||||||
|
|
||||||
def cast(self, typish):
|
def cast(self, typish):
|
||||||
self.check()
|
self.check()
|
||||||
typeobj = self.dumper.createType(typish)
|
typeobj = self.dumper.createType(typish)
|
||||||
@@ -2886,7 +2897,14 @@ class DumperBase:
|
|||||||
self.check()
|
self.check()
|
||||||
if self.ldata is not None:
|
if self.ldata is not None:
|
||||||
if len(self.ldata) > 0:
|
if len(self.ldata) > 0:
|
||||||
return self.ldata
|
if size is None:
|
||||||
|
return self.ldata
|
||||||
|
if size == len(self.ldata):
|
||||||
|
return self.ldata
|
||||||
|
if size < len(self.ldata):
|
||||||
|
return self.ldata[:size]
|
||||||
|
error("DATA PRESENT, BUT NOT BIG ENOUGH: %s WANT: %s"
|
||||||
|
% (self.stringify(), size))
|
||||||
if self.laddress is not None:
|
if self.laddress is not None:
|
||||||
if size is None:
|
if size is None:
|
||||||
size = self.type.size()
|
size = self.type.size()
|
||||||
@@ -2918,7 +2936,12 @@ class DumperBase:
|
|||||||
if code is None:
|
if code is None:
|
||||||
return None
|
return None
|
||||||
rawBytes = self.data(size)
|
rawBytes = self.data(size)
|
||||||
return struct.unpack_from(code, rawBytes, 0)[0]
|
try:
|
||||||
|
return struct.unpack_from(code, rawBytes, 0)[0]
|
||||||
|
except:
|
||||||
|
pass
|
||||||
|
error("Cannot extract: Code: %s Bytes: %s Bitsize: %s Size: %s"
|
||||||
|
% (code, self.dumper.hexencode(rawBytes), bitsize, size))
|
||||||
|
|
||||||
def extractSomething(self, code, bitsize):
|
def extractSomething(self, code, bitsize):
|
||||||
self.check()
|
self.check()
|
||||||
@@ -2984,6 +3007,11 @@ class DumperBase:
|
|||||||
def __str__(self):
|
def __str__(self):
|
||||||
self.check()
|
self.check()
|
||||||
return self.name
|
return self.name
|
||||||
|
#error("Not implemented")
|
||||||
|
|
||||||
|
def stringify(self):
|
||||||
|
return "Type(name='%s',bsize=%s,bpos=%s,enum=%s,native=%s)" \
|
||||||
|
% (self.name, self.lbitsize, self.lbitpos, self.lEnumType, self.nativeType is not None)
|
||||||
|
|
||||||
def __getitem__(self, index):
|
def __getitem__(self, index):
|
||||||
if self.dumper.isInt(index):
|
if self.dumper.isInt(index):
|
||||||
@@ -3202,6 +3230,11 @@ class DumperBase:
|
|||||||
return True
|
return True
|
||||||
return strippedName == "QStringList" and self.dumper.qtVersion() >= 0x050000
|
return strippedName == "QStringList" and self.dumper.qtVersion() >= 0x050000
|
||||||
|
|
||||||
|
def enumDisplay(self, intval):
|
||||||
|
if self.nativeType is not None:
|
||||||
|
return self.dumper.nativeTypeEnumDisplay(self.nativeType, intval)
|
||||||
|
return "%d" % intval
|
||||||
|
|
||||||
class Field:
|
class Field:
|
||||||
def __init__(self, dumper):
|
def __init__(self, dumper):
|
||||||
self.dumper = dumper
|
self.dumper = dumper
|
||||||
@@ -3271,6 +3304,11 @@ class DumperBase:
|
|||||||
typish.check()
|
typish.check()
|
||||||
return typish
|
return typish
|
||||||
if isinstance(typish, str):
|
if isinstance(typish, str):
|
||||||
|
if typish.startswith("enum "):
|
||||||
|
typish = typish[5:]
|
||||||
|
isEnum = True
|
||||||
|
else:
|
||||||
|
isEnum = False
|
||||||
if typish[0] == 'Q':
|
if typish[0] == 'Q':
|
||||||
if typish in ("QByteArray", "QString", "QList", "QStringList"):
|
if typish in ("QByteArray", "QString", "QList", "QStringList"):
|
||||||
typish = self.qtNamespace() + typish
|
typish = self.qtNamespace() + typish
|
||||||
@@ -3287,14 +3325,12 @@ class DumperBase:
|
|||||||
elif typish == "QChar":
|
elif typish == "QChar":
|
||||||
typish = self.qtNamespace() + typish
|
typish = self.qtNamespace() + typish
|
||||||
size = 2
|
size = 2
|
||||||
#res.lEnumType = False
|
|
||||||
elif typish in ("quint32", "qint32"):
|
elif typish in ("quint32", "qint32"):
|
||||||
typish = self.qtNamespace() + typish
|
typish = self.qtNamespace() + typish
|
||||||
size = 4
|
size = 4
|
||||||
|
|
||||||
#typeobj = self.Type(self)
|
#typeobj = self.Type(self)
|
||||||
#typeobj.name = typish
|
#typeobj.name = typish
|
||||||
#warn("CREATE TYPE: %s" % typish)
|
|
||||||
nativeType = self.lookupNativeType(typish) # FIXME: Remove?
|
nativeType = self.lookupNativeType(typish) # FIXME: Remove?
|
||||||
#warn("FOUND NAT TYPE: %s" % dir(nativeType))
|
#warn("FOUND NAT TYPE: %s" % dir(nativeType))
|
||||||
if nativeType is not None:
|
if nativeType is not None:
|
||||||
@@ -3306,6 +3342,8 @@ class DumperBase:
|
|||||||
typeobj.name = typish
|
typeobj.name = typish
|
||||||
if size is not None:
|
if size is not None:
|
||||||
typeobj.lbitsize = 8 * size
|
typeobj.lbitsize = 8 * size
|
||||||
|
#warn("CREATE TYPE: %s" % typeobj)
|
||||||
|
typeobj.lEnumType = isEnum
|
||||||
typeobj.check()
|
typeobj.check()
|
||||||
return typeobj
|
return typeobj
|
||||||
error("NEED TYPE, NOT %s" % type(typish))
|
error("NEED TYPE, NOT %s" % type(typish))
|
||||||
|
@@ -379,6 +379,13 @@ class Dumper(DumperBase):
|
|||||||
if len(nativeFields) and nativeFields[0].is_base_class:
|
if len(nativeFields) and nativeFields[0].is_base_class:
|
||||||
return self.fromNativeType(nativeFields[0].type)
|
return self.fromNativeType(nativeFields[0].type)
|
||||||
|
|
||||||
|
def nativeTypeEnumDisplay(self, nativeType, intval):
|
||||||
|
try:
|
||||||
|
val = gdb.parse_and_eval("(%s)%d" % (nativeType.name, intval))
|
||||||
|
return "%s (%d)" % (val, intval)
|
||||||
|
except:
|
||||||
|
return "%d" % intval
|
||||||
|
|
||||||
def nativeTypeFields(self, nativeType):
|
def nativeTypeFields(self, nativeType):
|
||||||
#warn("TYPE: %s" % nativeType)
|
#warn("TYPE: %s" % nativeType)
|
||||||
fields = []
|
fields = []
|
||||||
|
@@ -351,6 +351,18 @@ class Dumper(DumperBase):
|
|||||||
#warn(" GOT BASE FROM: %s" % t)
|
#warn(" GOT BASE FROM: %s" % t)
|
||||||
return self.fromNativeType(nativeType.GetDirectBaseClassAtIndex(0).GetType())
|
return self.fromNativeType(nativeType.GetDirectBaseClassAtIndex(0).GetType())
|
||||||
|
|
||||||
|
def nativeTypeEnumDisplay(self, nativeType, intval):
|
||||||
|
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.
|
||||||
|
diff = enumMember.GetValueAsSigned() - intval
|
||||||
|
mask = (1 << nativeType.GetByteSize() * 8) - 1
|
||||||
|
if diff & mask == 0:
|
||||||
|
path = nativeType.GetName().split('::')
|
||||||
|
path[-1] = enumMember.GetName()
|
||||||
|
return "%s (%d)" % ('::'.join(path), intval)
|
||||||
|
return "%d" % intval
|
||||||
|
|
||||||
def stateName(self, s):
|
def stateName(self, s):
|
||||||
try:
|
try:
|
||||||
# See db.StateType
|
# See db.StateType
|
||||||
|
@@ -620,12 +620,9 @@ def qdump__QFiniteStack(d, value):
|
|||||||
|
|
||||||
|
|
||||||
def qdump__QFlags(d, value):
|
def qdump__QFlags(d, value):
|
||||||
i = value["i"]
|
i = value.split('{int}')[0]
|
||||||
try:
|
enumType = value.type[0]
|
||||||
enumType = value.type.unqualified()[0]
|
d.putValue(i.cast('enum ' + enumType.name).display())
|
||||||
d.putValue("%s (%s)" % (i.cast(enumType), i))
|
|
||||||
except:
|
|
||||||
d.putValue("%s" % i)
|
|
||||||
d.putNumChild(0)
|
d.putNumChild(0)
|
||||||
|
|
||||||
|
|
||||||
@@ -923,25 +920,36 @@ def qdump__QLocale(d, value):
|
|||||||
# index = int(value["d"]["d"]["m_data"]...)
|
# index = int(value["d"]["d"]["m_data"]...)
|
||||||
#d.check(index >= 0)
|
#d.check(index >= 0)
|
||||||
#d.check(index <= qqLocalesCount)
|
#d.check(index <= qqLocalesCount)
|
||||||
|
dd = value.extractPointer()
|
||||||
|
ns = d.qtNamespace()
|
||||||
|
prefix = "enum " + ns + "QLocale::"
|
||||||
|
(data, ref, numberOptions) = d.split("pi{int}", dd)
|
||||||
|
(languageId, scriptId, countryId,
|
||||||
|
decimal, group, listt, percent, zero,
|
||||||
|
minus, plus, exponential) \
|
||||||
|
= d.split('{short}{short}{QChar}'
|
||||||
|
+ '{QChar}{QChar}{short}{QChar}{QChar}'
|
||||||
|
+ '{QChar}{QChar}{QChar}', data)
|
||||||
d.putStringValue(d.call("const char *", value, "name"))
|
d.putStringValue(d.call("const char *", value, "name"))
|
||||||
d.putNumChild(1)
|
d.putNumChild(1)
|
||||||
if d.isExpanded():
|
if d.isExpanded():
|
||||||
ns = d.qtNamespace()
|
with Children(d):
|
||||||
with Children(d, childType=d.lookupType(ns + "QChar"), childNumChild=0):
|
d.putSubItem("country", countryId.extend(4).cast(prefix + "Country"))
|
||||||
d.putCallItem("country", value, "country")
|
d.putSubItem("language", languageId.extend(4).cast(prefix + "Language"))
|
||||||
d.putCallItem("language", value, "language")
|
d.putSubItem("numberOptions", numberOptions.cast(prefix + "NumberOptions"))
|
||||||
d.putCallItem("measurementSystem", value, "measurementSystem")
|
d.putSubItem("decimalPoint", decimal)
|
||||||
d.putCallItem("numberOptions", value, "numberOptions")
|
d.putSubItem("exponential", exponential)
|
||||||
d.putCallItem("timeFormat_(short)", value,
|
d.putSubItem("percent", percent)
|
||||||
"timeFormat", ns + "QLocale::ShortFormat")
|
d.putSubItem("zeroDigit", zero)
|
||||||
d.putCallItem("timeFormat_(long)", value,
|
d.putSubItem("groupSeparator", group)
|
||||||
"timeFormat", ns + "QLocale::LongFormat")
|
d.putSubItem("negativeSign", minus)
|
||||||
d.putCallItem("decimalPoint", value, "decimalPoint")
|
d.putSubItem("positiveSign", plus)
|
||||||
d.putCallItem("exponential", value, "exponential")
|
d.putCallItem("measurementSystem", ns + "QLocale::MeasurementSystem",
|
||||||
d.putCallItem("percent", value, "percent")
|
value, "measurementSystem")
|
||||||
d.putCallItem("zeroDigit", value, "zeroDigit")
|
d.putCallItem("timeFormat_(short)", ns + "QString",
|
||||||
d.putCallItem("groupSeparator", value, "groupSeparator")
|
value, "timeFormat", ns + "QLocale::ShortFormat")
|
||||||
d.putCallItem("negativeSign", value, "negativeSign")
|
d.putCallItem("timeFormat_(long)", ns + "QString",
|
||||||
|
value, "timeFormat", ns + "QLocale::LongFormat")
|
||||||
d.putFields(value)
|
d.putFields(value)
|
||||||
|
|
||||||
|
|
||||||
|
@@ -2216,10 +2216,19 @@ void tst_Dumpers::dumper_data()
|
|||||||
"QLocale::MeasurementSystem m1 = loc1.measurementSystem();\n"
|
"QLocale::MeasurementSystem m1 = loc1.measurementSystem();\n"
|
||||||
"unused(&loc0, &loc, &m, &loc1, &m1);\n")
|
"unused(&loc0, &loc, &m, &loc1, &m1);\n")
|
||||||
+ CoreProfile()
|
+ CoreProfile()
|
||||||
// + Check("loc0", "\"en_US\"", "@QLocale") FIXME
|
|
||||||
+ CheckType("loc", "@QLocale")
|
+ CheckType("loc", "@QLocale")
|
||||||
+ CheckType("m", "@QLocale::MeasurementSystem")
|
+ CheckType("m", "@QLocale::MeasurementSystem")
|
||||||
+ Check("loc1", "\"en_US\"", "@QLocale")
|
+ Check("loc1", "\"en_US\"", "@QLocale")
|
||||||
|
+ Check("loc1.country", "@QLocale::UnitedStates (225)", "@QLocale::Country")
|
||||||
|
+ Check("loc1.language", "@QLocale::English (31)", "@QLocale::Language")
|
||||||
|
+ Check("loc1.numberOptions", "@QLocale::DefaultNumberOptions (0)", "@QLocale::NumberOptions")
|
||||||
|
+ Check("loc1.decimalPoint", "46", "@QChar") // .
|
||||||
|
+ Check("loc1.exponential", "101", "@QChar") // e
|
||||||
|
+ Check("loc1.percent", "37", "@QChar") // %
|
||||||
|
+ Check("loc1.zeroDigit", "48", "@QChar") // 0
|
||||||
|
+ Check("loc1.groupSeparator", "44", "@QChar") // ,
|
||||||
|
+ Check("loc1.negativeSign", "45", "@QChar") // -
|
||||||
|
+ Check("loc1.positiveSign", "43", "@QChar") // +
|
||||||
+ Check("m1", ValuePattern(".*Imperial.*System (1)"), Pattern(".*MeasurementSystem"));
|
+ Check("m1", ValuePattern(".*Imperial.*System (1)"), Pattern(".*MeasurementSystem"));
|
||||||
|
|
||||||
|
|
||||||
@@ -4855,6 +4864,19 @@ void tst_Dumpers::dumper_data()
|
|||||||
+ Check("s32s", "-2147483648", "@qint32");
|
+ Check("s32s", "-2147483648", "@qint32");
|
||||||
|
|
||||||
|
|
||||||
|
QTest::newRow("Enum")
|
||||||
|
<< Data("\n"
|
||||||
|
"enum Foo { a = -1000, b, c = 1, d };\n",
|
||||||
|
"Foo fa = a; unused(&fa);\n"
|
||||||
|
"Foo fb = b; unused(&fb);\n"
|
||||||
|
"Foo fc = c; unused(&fc);\n"
|
||||||
|
"Foo fd = d; unused(&fd);\n")
|
||||||
|
+ Check("fa", "a (-1000)", "Foo")
|
||||||
|
+ Check("fb", "b (-999)", "Foo")
|
||||||
|
+ Check("fc", "c (1)", "Foo")
|
||||||
|
+ Check("fd", "d (2)", "Foo");
|
||||||
|
|
||||||
|
|
||||||
QTest::newRow("Array")
|
QTest::newRow("Array")
|
||||||
<< Data("double a1[3][3];\n"
|
<< Data("double a1[3][3];\n"
|
||||||
"for (int i = 0; i != 3; ++i)\n"
|
"for (int i = 0; i != 3; ++i)\n"
|
||||||
|
Reference in New Issue
Block a user