Debugger: Reduce reliance on implicit conversions

Easier maintenance if code is typesafe. Whatever that means in Python.

Change-Id: I450e5d42bcfdb30d607dd878353d037ba18fe6d9
Reviewed-by: hjk <hjk@qt.io>
This commit is contained in:
hjk
2016-09-15 17:55:56 +02:00
committed by hjk
parent 950b665741
commit f1a85e1441
6 changed files with 74 additions and 84 deletions
+1 -1
View File
@@ -36,7 +36,7 @@ def qdump__boost__bimaps__bimap(d, value):
def qdump__boost__optional(d, value):
innerType = value.type[0]
(initialized, pad, payload) = d.split('b@{%s}' % innerType, value)
(initialized, pad, payload) = d.split('b@{%s}' % innerType.name, value)
if initialized:
d.putItem(payload)
d.putBetterType(value.type)
+61 -37
View File
@@ -147,18 +147,10 @@ class Children:
if childType is None:
self.childType = None
else:
self.childType = d.stripClassTag(str(childType))
self.childType = d.stripClassTag(childType.name)
if not self.d.isCli:
self.d.put('childtype="%s",' % self.childType)
if childNumChild is None:
pass
#if childType.isSimpleType():
# self.d.put('childnumchild="0",')
# self.childNumChild = 0
#elif childType.code == PointerCode:
# self.d.put('childnumchild="1",')
# self.childNumChild = 1
else:
if childNumChild is not None:
self.d.put('childnumchild="%s",' % childNumChild)
self.childNumChild = childNumChild
if addrBase is not None and addrStep is not None:
@@ -202,7 +194,7 @@ class PairedChildrenData:
self.isCompact = d.isMapCompact(self.keyType, self.valueType)
self.childType = valueType if self.isCompact else pairType
ns = d.qtNamespace()
keyTypeName = d.stripClassTag(str(self.keyType))
keyTypeName = d.stripClassTag(self.keyType.name)
self.keyIsQString = keyTypeName == ns + "QString"
self.keyIsQByteArray = keyTypeName == ns + "QByteArray"
self.keyIsStdString = keyTypeName == "std::string" \
@@ -440,6 +432,8 @@ class DumperBase:
return True
def stripClassTag(self, typeName):
if not isinstance(typeName, str):
error("Expected string in stripClassTag(), got %s" % type(typeName))
if typeName.startswith("class "):
return typeName[6:]
if typeName.startswith("struct "):
@@ -451,6 +445,8 @@ class DumperBase:
return typeName
def stripForFormat(self, typeName):
if not isinstance(typeName, str):
error("Expected string in stripForFormat(), got %s" % type(typeName))
if typeName in self.cachedFormats:
return self.cachedFormats[typeName]
stripped = ""
@@ -977,10 +973,13 @@ class DumperBase:
def putField(self, name, value):
self.put('%s="%s",' % (name, value))
def putType(self, type, priority = 0):
def putType(self, typish, priority = 0):
# Higher priority values override lower ones.
if priority >= self.currentType.priority:
self.currentType.value = str(type)
if isinstance(typish, str):
self.currentType.value = typish
else:
self.currentType.value = typish.name
self.currentType.priority = priority
def putValue(self, value, encoding = None, priority = 0, elided = None):
@@ -1007,11 +1006,13 @@ class DumperBase:
def putName(self, name):
self.put('name="%s",' % name)
def putBetterType(self, type):
if isinstance(type, ReportItem):
self.currentType.value = str(type.value)
def putBetterType(self, typish):
if isinstance(typish, ReportItem):
self.currentType.value = typish.value
elif isinstance(typish, str):
self.currentType.value = typish
else:
self.currentType.value = str(type)
self.currentType.value = typish.name
self.currentType.priority += 1
def putNoType(self):
@@ -1044,7 +1045,7 @@ class DumperBase:
innerType = self.fromNativeType(value.nativeValue[0].type)
else:
innerType = value.type.target()
innerTypeName = str(innerType.unqualified())
innerTypeName = innerType.unqualified().name
address = value.address()
if address:
self.putValue("@0x%x" % address, priority = -1)
@@ -1235,7 +1236,7 @@ class DumperBase:
self.putNumChild(0)
return
displayFormat = self.currentItemFormat(value.type)
displayFormat = self.currentItemFormat(value.type.name)
innerType = value.type.target().unqualified()
innerTypeName = innerType.name
@@ -1456,7 +1457,7 @@ class DumperBase:
if someTypeObj.isSimpleType():
return 0
typeName = str(someTypeObj)
typeName = someTypeObj.name
isQObjectProper = typeName == self.qtNamespace() + "QObject"
if not isQObjectProper:
@@ -1483,7 +1484,7 @@ class DumperBase:
def extractStaticMetaObjectPtrFromType(someTypeObj):
if someTypeObj is None:
return 0
someTypeName = str(someTypeObj)
someTypeName = someTypeObj.name
self.bump('metaObjectFromType')
known = self.knownStaticMetaObjects.get(someTypeName, None)
if known is not None: # Is 0 or the static metaobject.
@@ -1511,7 +1512,7 @@ class DumperBase:
ptrSize = self.ptrSize()
typeName = str(typeobj)
typeName = typeobj.name
result = self.knownStaticMetaObjects.get(typeName, None)
if result is not None: # Is 0 or the static metaobject.
self.bump("typecached")
@@ -1974,12 +1975,12 @@ class DumperBase:
if pp > 1000:
break
def currentItemFormat(self, type = None):
def currentItemFormat(self, typeName = None):
displayFormat = self.formats.get(self.currentIName, AutomaticFormat)
if displayFormat == AutomaticFormat:
if type is None:
type = self.currentType.value
needle = self.stripForFormat(str(type))
if typeName is None:
typeName = self.currentType.value
needle = None if typeName is None else self.stripForFormat(typeName)
displayFormat = self.typeformats.get(needle, AutomaticFormat)
return displayFormat
@@ -1997,9 +1998,9 @@ class DumperBase:
addrBase = base
innerSize = innerType.size()
#warn("ADDRESS: %s INNERSIZE: %s INNERTYPE: %s" % (addrBase, innerSize, innerType))
enc = self.simpleEncoding(innerType)
enc = innerType.simpleEncoding()
if enc:
self.put('childtype="%s",' % innerType)
self.put('childtype="%s",' % innerType.name)
self.put('addrbase="0x%x",' % addrBase)
self.put('addrstep="0x%x",' % innerSize)
self.put('arrayencoding="%s",' % enc)
@@ -2029,7 +2030,7 @@ class DumperBase:
self.put('plotelided="%s",' % n) # FIXME: Act on that in frontend
n = maxNumChild
if self.currentItemFormat() == ArrayPlotFormat and innerType.isSimpleType():
enc = self.simpleEncoding(innerType)
enc = innerType.simpleEncoding()
if enc:
self.putField("editencoding", enc)
self.putDisplay("plotdata:separate",
@@ -2457,7 +2458,7 @@ class DumperBase:
if value.type.isPointerType():
value = value.dereference()
data = value["data"]
return data.cast(self.lookupType(str(value.type).replace("QV4::", "QV4::Heap::")))
return data.cast(self.lookupType(value.type.name.replace("QV4::", "QV4::Heap::")))
def extractInterpreterStack(self):
return self.sendInterpreterRequest('backtrace', {'limit': 10 })
@@ -2987,7 +2988,6 @@ class DumperBase:
def __init__(self, dumper):
self.dumper = dumper
self.name = None
self.code = None # Backward compatibility
self.nativeType = None
self.lfields = None
self.lbitsize = None
@@ -3006,6 +3006,7 @@ class DumperBase:
def __str__(self):
self.check()
error("Not implemented")
return self.name
#error("Not implemented")
@@ -3013,6 +3014,10 @@ class DumperBase:
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 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):
if self.dumper.isInt(index):
return self.templateArgument(index)
@@ -3057,6 +3062,23 @@ class DumperBase:
'char', 'signed char', 'unsigned char',
'bool')
def simpleEncoding(self):
res = {
'bool' : 'int:1',
'char' : 'int:1',
'signed char' : 'int:1',
'unsigned char' : 'uint:1',
'short' : 'int:2',
'unsigned short' : 'uint:2',
'int' : 'int:4',
'unsigned int' : 'uint:4',
'long long' : 'int:8',
'unsigned long long' : 'uint:8',
'float': 'float:4',
'double': 'float:8'
}.get(self.name, None)
return res
def isFloatingPointType(self):
return self.name in ('float', 'double')
@@ -3366,20 +3388,22 @@ class DumperBase:
return val
error("EXPECTING ADDRESS OR BYTES, GOT %s" % type(datish))
def createListItem(self, data, typeName):
def createListItem(self, data, innerTypish):
innerType = self.createType(innerTypish)
typeobj = self.Type(self)
typeobj.name = self.qtNamespace() + "QList<%s>" % typeName
typeobj.templateArguments = [self.createType(typeName)]
typeobj.name = self.qtNamespace() + "QList<%s>" % innerType.name
typeobj.templateArguments = [innerType]
typeobj.lbitsize = 8 * self.ptrSize()
val = self.Value(self)
val.ldata = data
val.type = typeobj
return val
def createVectorItem(self, data, typeName):
def createVectorItem(self, data, innerTypish):
innerType = self.createType(innerTypish)
typeobj = self.Type(self)
typeobj.name = self.qtNamespace() + "QVector<%s>" % typeName
typeobj.templateArguments = [self.createType(typeName)]
typeobj.name = self.qtNamespace() + "QVector<%s>" % innerType.name
typeobj.templateArguments = [innerType]
typeobj.lbitsize = 8 * self.ptrSize()
val = self.Value(self)
val.ldata = data
-13
View File
@@ -903,19 +903,6 @@ class Dumper(DumperBase):
self.isQt3Support = lambda: self.cachedIsQt3Suport
return self.cachedIsQt3Suport
def simpleEncoding(self, typeobj):
code = typeobj.code
if code == BoolCode or code == CharCode:
return "int:1"
if code == IntCode:
if str(typeobj).find("unsigned") >= 0:
return "uint:%d" % typeobj.size()
else:
return "int:%d" % typeobj.size()
if code == FloatCode:
return "float:%d" % typeobj.size()
return None
def readCString(self, base):
inferior = self.selectedInferior()
mem = ""
-21
View File
@@ -604,27 +604,6 @@ class Dumper(DumperBase):
def put(self, stuff):
self.output += stuff
def simpleEncoding(self, typeobj):
#warn("TYPE OBJ: %s" % typeobj)
code = typeobj.code
size = typeobj.size()
if code == lldb.eTypeClassBuiltin:
name = str(typeobj)
if name == 'float':
return 'float:4'
if name == 'double':
return 'float:8'
if name.find('unsigned') >= 0:
return 'uint:%d' % size
else:
return 'int:%d' % size
return None
#def createValue(self, address, referencedType):
# addr = int(address) & 0xFFFFFFFFFFFFFFFF
# sbaddr = lldb.SBAddress(addr, self.target)
# return self.target.CreateValueFromAddress('@', sbaddr, referencedType)
def childRange(self):
if self.currentMaxNumChild is None:
return xrange(0, self.currentNumChild)
+8 -8
View File
@@ -655,10 +655,10 @@ def qdumpHelper_QHash(d, value, keyType, valueType):
node = hashDataFirstNode()
for i in d.childRange():
if isShort:
typeCode = 'P{%s}@{%s}' % (keyType, valueType)
typeCode = 'P{%s}@{%s}' % (keyType.name, valueType.name)
(pnext, key, padding2, val) = d.split(typeCode, node)
else:
typeCode = 'Pi@{%s}@{%s}' % (keyType, valueType)
typeCode = 'Pi@{%s}@{%s}' % (keyType.name, valueType.name)
(pnext, hashval, padding1, key, padding2, val) = d.split(typeCode, node)
d.putPairItem(i, (key, val))
node = hashDataNextNode(node)
@@ -684,7 +684,7 @@ def qdump__QHashNode(d, value):
def qHashIteratorHelper(d, value):
typeName = str(value.type)
typeName = value.type.name
hashTypeName = typeName[0:typeName.rfind("::")]
hashType = d.lookupType(hashTypeName)
keyType = hashType[0]
@@ -696,10 +696,10 @@ def qHashIteratorHelper(d, value):
node = d.extractPointer(value)
isShort = d.qtVersion() < 0x050000 and keyType.name == 'int'
if isShort:
typeCode = 'P{%s}@{%s}' % (keyType, valueType)
typeCode = 'P{%s}@{%s}' % (keyType.name, valueType.name)
(pnext, key, padding2, val) = d.split(typeCode, node)
else:
typeCode = 'Pi@{%s}@{%s}' % (keyType, valueType)
typeCode = 'Pi@{%s}@{%s}' % (keyType.name, valueType.name)
(pnext, hashval, padding1, key, padding2, val) = d.split(typeCode, node)
d.putSubItem("key", key)
d.putSubItem("value", val)
@@ -988,7 +988,7 @@ def qdumpHelper_Qt5_QMap(d, value, keyType, valueType):
if n > 10000:
n = 10000
typeCode = 'ppp@{%s}@{%s}' % (keyType, valueType)
typeCode = 'ppp@{%s}@{%s}' % (keyType.name, valueType.name)
def helper(node):
(p, left, right, padding1, key, padding2, value) = d.split(typeCode, node)
@@ -1196,10 +1196,10 @@ def qdump__QSet(d, value):
node = hashDataFirstNode()
for i in d.childRange():
if isShort:
typeCode = 'P{%s}' % keyType
typeCode = 'P{%s}' % keyType.name
(pnext, key) = d.split(typeCode, node)
else:
typeCode = 'Pi@{%s}' % keyType
typeCode = 'Pi@{%s}' % keyType.name
(pnext, hashval, padding1, key) = d.split(typeCode, node)
with SubItem(d, i):
d.putItem(key, i)
+4 -4
View File
@@ -227,7 +227,7 @@ def qdump__std__map(d, value):
pairPointer = pairType.pointer()
with PairedChildren(d, size, pairType=pairType, maxNumChild=1000):
node = impl["_M_header"]["_M_left"]
typeCode = "p@{%s}@{%s}" % (pairType[0], pairType[1])
typeCode = "p@{%s}@{%s}" % (pairType[0].name, pairType[1].name)
for i in d.childRange():
pair = (node + 1).cast(pairPointer).dereference()
d.putPairItem(i, pair)
@@ -337,11 +337,11 @@ def qdumpHelper__std__tree__iterator(d, value, isSet=False):
if d.isExpanded():
with Children(d):
if isSet:
typecode = 'pppp@{%s}' % keyType
typecode = 'pppp@{%s}' % keyType.name
(color, parent, left, right, pad1, key) = d.split(typecode, node)
d.putSubItem("value", key)
else:
typecode = 'pppp@{%s}@{%s}' % (keyType, valueType)
typecode = 'pppp@{%s}@{%s}' % (keyType.name, valueType.name)
(color, parent, left, right, pad1, key, pad2, value) = d.split(typecode, node)
d.putSubItem("first", key)
d.putSubItem("second", value)
@@ -937,7 +937,7 @@ def qdump____gnu_cxx__hash_set(d, value):
d.check(0 <= size and size <= 1000 * 1000 * 1000)
d.putItemCount(size)
innerType = value.type[0]
d.putType("__gnu__cxx::hash_set<%s>" % innerType)
d.putType("__gnu__cxx::hash_set<%s>" % innerType.name)
if d.isExpanded():
with Children(d, size, maxNumChild=1000, childType=innerType):
buckets = ht["_M_buckets"]["_M_impl"]