forked from qt-creator/qt-creator
Debugger: Fix display of multidimensional C arrays
Fixes: QTCREATORBUG-19356 Fixes: QTCREATORBUG-20639 Fixes: QTCREATORBUG-21677 Change-Id: Ie28b51c6caf526e125234959cbf11503d0683dc7 Reviewed-by: Christian Stenger <christian.stenger@qt.io>
This commit is contained in:
@@ -3379,6 +3379,19 @@ class DumperBase:
|
|||||||
def type(self, typeId):
|
def type(self, typeId):
|
||||||
return self.typeData.get(typeId)
|
return self.typeData.get(typeId)
|
||||||
|
|
||||||
|
def splitArrayType(self, type_name):
|
||||||
|
# "foo[2][3][4]" -> ("foo", "[3][4]", 2)
|
||||||
|
pos1 = len(type_name)
|
||||||
|
# In case there are more dimensions we need the inner one.
|
||||||
|
while True:
|
||||||
|
pos1 = type_name.rfind('[', 0, pos1 - 1)
|
||||||
|
pos2 = type_name.find(']', pos1)
|
||||||
|
if type_name[pos1 - 1] != ']':
|
||||||
|
break
|
||||||
|
|
||||||
|
item_count = type_name[pos1+1:pos2]
|
||||||
|
return (type_name[0:pos1].strip(), type_name[pos2+1:].strip(), int(item_count))
|
||||||
|
|
||||||
def registerType(self, typeId, tdata):
|
def registerType(self, typeId, tdata):
|
||||||
#warn('REGISTER TYPE: %s' % typeId)
|
#warn('REGISTER TYPE: %s' % typeId)
|
||||||
self.typeData[typeId] = tdata
|
self.typeData[typeId] = tdata
|
||||||
@@ -3585,16 +3598,6 @@ class DumperBase:
|
|||||||
def pointer(self):
|
def pointer(self):
|
||||||
return self.dumper.createPointerType(self)
|
return self.dumper.createPointerType(self)
|
||||||
|
|
||||||
def splitArrayType(self):
|
|
||||||
# -> (inner type, count)
|
|
||||||
if not self.code == TypeCodeArray:
|
|
||||||
error('Not an array')
|
|
||||||
s = self.name
|
|
||||||
pos1 = s.rfind('[')
|
|
||||||
pos2 = s.find(']', pos1)
|
|
||||||
itemCount = s[pos1+1:pos2]
|
|
||||||
return (self.dumper.createType(s[0:pos1].strip()), int(s[pos1+1:pos2]))
|
|
||||||
|
|
||||||
def target(self):
|
def target(self):
|
||||||
return self.typeData().ltarget
|
return self.typeData().ltarget
|
||||||
|
|
||||||
@@ -3613,9 +3616,6 @@ class DumperBase:
|
|||||||
def bitsize(self):
|
def bitsize(self):
|
||||||
if self.lbitsize is not None:
|
if self.lbitsize is not None:
|
||||||
return self.lbitsize
|
return self.lbitsize
|
||||||
if self.code == TypeCodeArray:
|
|
||||||
(innerType, itemCount) = self.splitArrayType()
|
|
||||||
return itemCount * innerType.bitsize()
|
|
||||||
error('DONT KNOW SIZE: %s' % self)
|
error('DONT KNOW SIZE: %s' % self)
|
||||||
|
|
||||||
def isMovableType(self):
|
def isMovableType(self):
|
||||||
@@ -3748,14 +3748,23 @@ class DumperBase:
|
|||||||
error('Expected type in createArrayType(), got %s'
|
error('Expected type in createArrayType(), got %s'
|
||||||
% type(targetType))
|
% type(targetType))
|
||||||
targetTypeId = targetType.typeId
|
targetTypeId = targetType.typeId
|
||||||
typeId = '%s[%d]' % (targetTypeId, count)
|
|
||||||
|
if targetTypeId.endswith(']'):
|
||||||
|
(prefix, suffix, inner_count) = self.splitArrayType(targetTypeId)
|
||||||
|
type_id = '%s[%d][%d]%s' % (prefix, count, inner_count, suffix)
|
||||||
|
type_name = type_id
|
||||||
|
else:
|
||||||
|
type_id = '%s[%d]' % (targetTypeId, count)
|
||||||
|
type_name = '%s[%d]' % (targetType.name, count)
|
||||||
|
|
||||||
tdata = self.TypeData(self)
|
tdata = self.TypeData(self)
|
||||||
tdata.name = '%s[%d]' % (targetType.name, count)
|
tdata.name = type_name
|
||||||
tdata.typeId = typeId
|
tdata.typeId = type_id
|
||||||
tdata.code = TypeCodeArray
|
tdata.code = TypeCodeArray
|
||||||
tdata.ltarget = targetType
|
tdata.ltarget = targetType
|
||||||
self.registerType(typeId, tdata)
|
tdata.lbitsize = targetType.lbitsize * count
|
||||||
return self.Type(self, typeId)
|
self.registerType(type_id, tdata)
|
||||||
|
return self.Type(self, type_id)
|
||||||
|
|
||||||
def createBitfieldType(self, targetType, bitsize):
|
def createBitfieldType(self, targetType, bitsize):
|
||||||
if not isinstance(targetType, self.Type):
|
if not isinstance(targetType, self.Type):
|
||||||
@@ -3796,13 +3805,6 @@ class DumperBase:
|
|||||||
#typish.check()
|
#typish.check()
|
||||||
return typish
|
return typish
|
||||||
if isinstance(typish, str):
|
if isinstance(typish, str):
|
||||||
if typish.endswith(']') and not typish.endswith('[]'):
|
|
||||||
# Array fallback.
|
|
||||||
pos1 = typish.rfind('[')
|
|
||||||
itemType = self.createType(typish[0:pos1].strip())
|
|
||||||
itemCount = int(typish[pos1+1:-1])
|
|
||||||
return self.createArrayType(itemType, itemCount)
|
|
||||||
|
|
||||||
def knownSize(tn):
|
def knownSize(tn):
|
||||||
if tn[0] == 'Q':
|
if tn[0] == 'Q':
|
||||||
if tn in ('QByteArray', 'QString', 'QList', 'QStringList',
|
if tn in ('QByteArray', 'QString', 'QList', 'QStringList',
|
||||||
|
@@ -5441,10 +5441,10 @@ void tst_Dumpers::dumper_data()
|
|||||||
|
|
||||||
QTest::newRow("Array")
|
QTest::newRow("Array")
|
||||||
<< Data("",
|
<< Data("",
|
||||||
"double a1[3][3];\n"
|
"double a1[3][4];\n"
|
||||||
"for (int i = 0; i != 3; ++i)\n"
|
"for (int i = 0; i != 3; ++i)\n"
|
||||||
" for (int j = 0; j != 3; ++j)\n"
|
" for (int j = 0; j != 3; ++j)\n"
|
||||||
" a1[i][j] = i + j;\n"
|
" a1[i][j] = i + 10 * j;\n"
|
||||||
"unused(&a1);\n\n"
|
"unused(&a1);\n\n"
|
||||||
|
|
||||||
"char a2[20] = { 0 };\n"
|
"char a2[20] = { 0 };\n"
|
||||||
@@ -5455,11 +5455,11 @@ void tst_Dumpers::dumper_data()
|
|||||||
"a2[4] = 0;\n"
|
"a2[4] = 0;\n"
|
||||||
"unused(&a2);\n")
|
"unused(&a2);\n")
|
||||||
|
|
||||||
+ Check("a1", Pointer(), "double [3][3]")
|
+ Check("a1", Pointer(), "double[3][4]")
|
||||||
+ Check("a1.0", "[0]", Pointer(), "double [3]")
|
+ Check("a1.0", "[0]", Pointer(), "double[4]")
|
||||||
+ Check("a1.0.0", "[0]", FloatValue("0"), "double")
|
+ Check("a1.0.0", "[0]", FloatValue("0"), "double")
|
||||||
+ Check("a1.0.2", "[2]", FloatValue("2"), "double")
|
+ Check("a1.0.2", "[2]", FloatValue("20"), "double")
|
||||||
+ Check("a1.2", "[2]", Pointer(), "double [3]")
|
+ Check("a1.2", "[2]", Pointer(), "double[4]")
|
||||||
|
|
||||||
+ Check("a2", Value("\"abcd" + QString(16, 0) + '"'), "char [20]")
|
+ Check("a2", Value("\"abcd" + QString(16, 0) + '"'), "char [20]")
|
||||||
+ Check("a2.0", "[0]", "97", "char")
|
+ Check("a2.0", "[0]", "97", "char")
|
||||||
|
Reference in New Issue
Block a user