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