Debugger: Remove old formatting hacks

These go back to the time where we faced raw GDB output. Nowadays
we get polished data from the dumpers already.

Change-Id: Ifeb2c0609d482bbd6d7783242f13c74ecc320233
Reviewed-by: Christian Stenger <christian.stenger@qt.io>
This commit is contained in:
hjk
2016-10-07 13:26:14 +02:00
parent 816d0010c2
commit 656ceff510
4 changed files with 5 additions and 169 deletions

View File

@@ -40,11 +40,6 @@ bool isPointerType(const QString &type)
return type.endsWith('*') || type.endsWith("* const"); return type.endsWith('*') || type.endsWith("* const");
} }
bool isCharPointerType(const QString &type)
{
return type == "char *" || type == "const char *" || type == "char const *";
}
bool isIntType(const QString &type) bool isIntType(const QString &type)
{ {
if (type.isEmpty()) if (type.isEmpty())
@@ -128,8 +123,7 @@ bool WatchItem::isVTablePointer() const
{ {
// First case: Cdb only. No user type can be named like this, this is safe. // First case: Cdb only. No user type can be named like this, this is safe.
// Second case: Python dumper only. // Second case: Python dumper only.
return type.startsWith("__fptr()") return type.startsWith("__fptr()") || (type.isEmpty() && name == "[vptr]");
|| (type.isEmpty() && name == QLatin1String("[vptr]"));
} }
void WatchItem::setError(const QString &msg) void WatchItem::setError(const QString &msg)
@@ -147,87 +141,6 @@ void WatchItem::setValue(const QString &value0)
value.clear(); value.clear();
wantsChildren = true; // at least one... wantsChildren = true; // at least one...
} }
// strip off quoted characters for chars.
if (value.endsWith(QLatin1Char('\'')) && type.endsWith("char")) {
const int blankPos = value.indexOf(QLatin1Char(' '));
if (blankPos != -1)
value.truncate(blankPos);
}
// avoid duplicated information
if (value.startsWith(QLatin1Char('(')) && value.contains(QLatin1String(") 0x")))
value.remove(0, value.lastIndexOf(QLatin1String(") 0x")) + 2);
// doubles are sometimes displayed as "@0x6141378: 1.2".
// I don't want that.
if (/*isIntOrFloatType(type) && */ value.startsWith(QLatin1String("@0x"))
&& value.contains(QLatin1Char(':'))) {
value.remove(0, value.indexOf(QLatin1Char(':')) + 2);
setHasChildren(false);
}
// "numchild" is sometimes lying
//MODEL_DEBUG("\n\n\nPOINTER: " << type << value);
if (isPointerType(type))
setHasChildren(value != QLatin1String("0x0") && value != QLatin1String("<null>")
&& !isCharPointerType(type));
// pointer type information is available in the 'type'
// column. No need to duplicate it here.
if (value.startsWith('(' + type + ") 0x"))
value = value.section(QLatin1Char(' '), -1, -1);
}
enum GuessChildrenResult { HasChildren, HasNoChildren, HasPossiblyChildren };
static GuessChildrenResult guessChildren(const QString &type)
{
if (isIntOrFloatType(type))
return HasNoChildren;
if (isCharPointerType(type))
return HasNoChildren;
if (isPointerType(type))
return HasChildren;
if (type.endsWith("QString"))
return HasNoChildren;
return HasPossiblyChildren;
}
void WatchItem::setType(const QString &str, bool guessChildrenFromType)
{
type = str.trimmed();
bool changed = true;
while (changed) {
if (type.endsWith("const"))
type.chop(5);
else if (type.endsWith(' '))
type.chop(1);
else if (type.startsWith("const "))
type = type.mid(6);
else if (type.startsWith("volatile "))
type = type.mid(9);
else if (type.startsWith("class "))
type = type.mid(6);
else if (type.startsWith("struct "))
type = type.mid(7);
else if (type.startsWith(' '))
type = type.mid(1);
else
changed = false;
}
if (guessChildrenFromType) {
switch (guessChildren(type)) {
case HasChildren:
setHasChildren(true);
break;
case HasNoChildren:
setHasChildren(false);
break;
case HasPossiblyChildren:
setHasChildren(true); // FIXME: bold assumption
break;
}
}
} }
QString WatchItem::toString() const QString WatchItem::toString() const
@@ -397,7 +310,7 @@ void WatchItem::parseHelper(const GdbMi &input, bool maySort)
{ {
GdbMi mi = input["type"]; GdbMi mi = input["type"];
if (mi.isValid()) if (mi.isValid())
setType(mi.data()); type = mi.data();
editvalue = input["editvalue"].data(); editvalue = input["editvalue"].data();
editformat = input["editformat"].data(); editformat = input["editformat"].data();
@@ -428,7 +341,7 @@ void WatchItem::parseHelper(const GdbMi &input, bool maySort)
// *(class X*)0xdeadbeef for gdb. // *(class X*)0xdeadbeef for gdb.
exp = name; exp = name;
else else
exp = "*(" + gdbQuoteTypes(type) + "*)" + hexAddress(); exp = "*(" + type + "*)" + hexAddress();
} }
} }
@@ -497,7 +410,7 @@ void WatchItem::parseHelper(const GdbMi &input, bool maySort)
const GdbMi &subinput = children.children().at(i); const GdbMi &subinput = children.children().at(i);
WatchItem *child = new WatchItem; WatchItem *child = new WatchItem;
if (childType.isValid()) if (childType.isValid())
child->setType(childType.data()); child->type = childType.data();
if (childNumChild.isValid()) if (childNumChild.isValid())
child->setHasChildren(childNumChild.toInt() > 0); child->setHasChildren(childNumChild.toInt() > 0);
GdbMi name = subinput["name"]; GdbMi name = subinput["name"];
@@ -516,7 +429,7 @@ void WatchItem::parseHelper(const GdbMi &input, bool maySort)
child->iname = this->iname + '.' + nn; child->iname = this->iname + '.' + nn;
if (addressStep) { if (addressStep) {
child->address = addressBase + i * addressStep; child->address = addressBase + i * addressStep;
child->exp = "*(" + gdbQuoteTypes(child->type) + "*)0x" child->exp = "*(" + child->type + "*)0x"
+ QString::number(child->address, 16); + QString::number(child->address, 16);
} }
QString key = subinput["key"].data(); QString key = subinput["key"].data();

View File

@@ -69,7 +69,6 @@ public:
void setError(const QString &); void setError(const QString &);
void setValue(const QString &); void setValue(const QString &);
void setType(const QString &, bool guessChildrenFromType = true);
QString toString() const; QString toString() const;

View File

@@ -220,22 +220,6 @@ bool isKeyWord(const QString &exp)
return false; return false;
} }
bool startsWithDigit(const QString &str)
{
return !str.isEmpty() && str.at(0).isDigit();
}
QString stripPointerType(QString type)
{
if (type.endsWith('*'))
type.chop(1);
if (type.endsWith("* const"))
type.chop(7);
if (type.endsWith(' '))
type.chop(1);
return type;
}
// Format a hex address with colons as in the memory editor. // Format a hex address with colons as in the memory editor.
QString formatToolTipAddress(quint64 a) QString formatToolTipAddress(quint64 a)
{ {
@@ -256,61 +240,5 @@ QString formatToolTipAddress(quint64 a)
return "0x" + rc; return "0x" + rc;
} }
QString gdbQuoteTypes(const QString &type)
{
// gdb does not understand sizeof(Core::IDocument*).
// "sizeof('Core::IDocument*')" is also not acceptable,
// it needs to be "sizeof('Core::IDocument'*)"
//
// We never will have a perfect solution here (even if we had a full blown
// C++ parser as we do not have information on what is a type and what is
// a variable name. So "a<b>::c" could either be two comparisons of values
// 'a', 'b' and '::c', or a nested type 'c' in a template 'a<b>'. We
// assume here it is the latter.
//return type;
// (*('myns::QPointer<myns::QObject>*'*)0x684060)" is not acceptable
// (*('myns::QPointer<myns::QObject>'**)0x684060)" is acceptable
if (isPointerType(type))
return gdbQuoteTypes(stripPointerType(type)) + '*';
QString accu;
QString result;
int templateLevel = 0;
const char colon = ':';
const char singleQuote = '\'';
const char lessThan = '<';
const char greaterThan = '>';
for (int i = 0; i != type.size(); ++i) {
const QChar c = type.at(i);
if (isLetterOrNumber(c.unicode()) || c == '_' || c == colon || c == ' ') {
accu += c;
} else if (c == lessThan) {
++templateLevel;
accu += c;
} else if (c == greaterThan) {
--templateLevel;
accu += c;
} else if (templateLevel > 0) {
accu += c;
} else {
if (accu.contains(colon) || accu.contains(lessThan))
result += singleQuote + accu + singleQuote;
else
result += accu;
accu.clear();
result += c;
}
}
if (accu.contains(colon) || accu.contains(lessThan))
result += singleQuote + accu + singleQuote;
else
result += accu;
//qDebug() << "GDB_QUOTING" << type << " TO " << result;
return result;
}
} // namespace Internal } // namespace Internal
} // namespace Debugger } // namespace Debugger

View File

@@ -40,10 +40,6 @@ bool hasLetterOrNumber(const QString &exp);
bool hasSideEffects(const QString &exp); bool hasSideEffects(const QString &exp);
bool isKeyWord(const QString &exp); bool isKeyWord(const QString &exp);
bool isPointerType(const QString &type); bool isPointerType(const QString &type);
bool isCharPointerType(const QString &type);
bool startsWithDigit(const QString &str);
QString stripPointerType(QString type);
QString gdbQuoteTypes(const QString &type);
bool isFloatType(const QString &type); bool isFloatType(const QString &type);
bool isIntOrFloatType(const QString &type); bool isIntOrFloatType(const QString &type);
bool isIntType(const QString &type); bool isIntType(const QString &type);