forked from qt-creator/qt-creator
Debugger: Prepend '*'s for autodereferenced pointers
If automatic dereferencing of pointers is enabled, the "Value" and "Type" columns for pointers hold the values for the dereferenced pointers. In order to have a consistent behavior for the "Name" column as well, prepend '*'s to indicate that the variable/expression has actually been dereferenced. Add parantheses around the original expression if it doesn't match a simple regex for variable names, to avoid that the leading '*' changes the meaning of the expression (so e.g. a dereferenced 'somepointer + 1' is displayed as '*(somepointer + 1)' rather than '*somepointer + 1'). This introduces a new 'autoderefcount' field to propagate the information how many levels of dereferencing have taken place from the Python to the C++ side, which is then used to add the leading '*'s for the display name. Fixes: QTCREATORBUG-20907 Change-Id: Ia9a41cb42e25ba72a6d980a765dbe2b454deb8c8 Reviewed-by: hjk <hjk@qt.io>
This commit is contained in:
@@ -1312,6 +1312,11 @@ class DumperBase():
|
|||||||
savedCurrentChildType = self.currentChildType
|
savedCurrentChildType = self.currentChildType
|
||||||
self.currentChildType = innerType.name
|
self.currentChildType = innerType.name
|
||||||
derefValue.name = '*'
|
derefValue.name = '*'
|
||||||
|
derefValue.autoDerefCount = value.autoDerefCount + 1
|
||||||
|
|
||||||
|
if derefValue.type.code != TypeCode.Pointer:
|
||||||
|
self.putField('autoderefcount', '{}'.format(derefValue.autoDerefCount))
|
||||||
|
|
||||||
self.putItem(derefValue)
|
self.putItem(derefValue)
|
||||||
self.currentChildType = savedCurrentChildType
|
self.currentChildType = savedCurrentChildType
|
||||||
|
|
||||||
@@ -2920,6 +2925,7 @@ class DumperBase():
|
|||||||
self.targetValue = None # For references.
|
self.targetValue = None # For references.
|
||||||
self.isBaseClass = None
|
self.isBaseClass = None
|
||||||
self.nativeValue = None
|
self.nativeValue = None
|
||||||
|
self.autoDerefCount = 0
|
||||||
|
|
||||||
def copy(self):
|
def copy(self):
|
||||||
val = self.dumper.Value(self.dumper)
|
val = self.dumper.Value(self.dumper)
|
||||||
|
@@ -115,6 +115,7 @@ WatchItem::WatchItem() :
|
|||||||
wantsChildren(false),
|
wantsChildren(false),
|
||||||
valueEnabled(true),
|
valueEnabled(true),
|
||||||
valueEditable(true),
|
valueEditable(true),
|
||||||
|
autoDerefCount(0),
|
||||||
outdated(false)
|
outdated(false)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
@@ -388,6 +389,14 @@ void WatchItem::parseHelper(const GdbMi &input, bool maySort)
|
|||||||
else if (mi.data() == "false")
|
else if (mi.data() == "false")
|
||||||
valueEditable = false;
|
valueEditable = false;
|
||||||
|
|
||||||
|
mi = input["autoderefcount"];
|
||||||
|
if (mi.isValid()) {
|
||||||
|
bool ok = false;
|
||||||
|
uint derefCount = mi.data().toUInt(&ok);
|
||||||
|
if (ok)
|
||||||
|
autoDerefCount = derefCount;
|
||||||
|
}
|
||||||
|
|
||||||
mi = input["numchild"]; // GDB/MI
|
mi = input["numchild"]; // GDB/MI
|
||||||
if (mi.isValid())
|
if (mi.isValid())
|
||||||
setHasChildren(mi.toInt() > 0);
|
setHasChildren(mi.toInt() > 0);
|
||||||
|
@@ -99,6 +99,7 @@ public:
|
|||||||
bool wantsChildren;
|
bool wantsChildren;
|
||||||
bool valueEnabled; // Value will be enabled or not
|
bool valueEnabled; // Value will be enabled or not
|
||||||
bool valueEditable; // Value will be editable
|
bool valueEditable; // Value will be editable
|
||||||
|
uint autoDerefCount; // number of levels of automatic dereferencing that has taken place (for pointer types)
|
||||||
bool outdated; // \internal item is to be removed.
|
bool outdated; // \internal item is to be removed.
|
||||||
double time = 0; // Time used on the dumper side to produce this item
|
double time = 0; // Time used on the dumper side to produce this item
|
||||||
|
|
||||||
|
@@ -869,6 +869,19 @@ static QString displayName(const WatchItem *item)
|
|||||||
else
|
else
|
||||||
result = watchModel(item)->removeNamespaces(item->name);
|
result = watchModel(item)->removeNamespaces(item->name);
|
||||||
|
|
||||||
|
// prepend '*'s to indicate where autodereferencing has taken place
|
||||||
|
if (item->autoDerefCount > 0) {
|
||||||
|
// add parentheses for everything except simple variable names (e.g. pointer arithmetics,...)
|
||||||
|
QRegularExpression variableNameRegex("^[a-zA-Z0-9_]+$");
|
||||||
|
bool addParanthesis = !variableNameRegex.match(result).hasMatch();
|
||||||
|
if (addParanthesis)
|
||||||
|
result = "(" + result;
|
||||||
|
for (uint i = 0; i < item->autoDerefCount; i++)
|
||||||
|
result = "*" + result;
|
||||||
|
if (addParanthesis)
|
||||||
|
result += ")";
|
||||||
|
}
|
||||||
|
|
||||||
// Simplify names that refer to base classes.
|
// Simplify names that refer to base classes.
|
||||||
if (result.startsWith('[')) {
|
if (result.startsWith('[')) {
|
||||||
result = simplifyType(result);
|
result = simplifyType(result);
|
||||||
|
Reference in New Issue
Block a user