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");
}
bool isCharPointerType(const QString &type)
{
return type == "char *" || type == "const char *" || type == "char const *";
}
bool isIntType(const QString &type)
{
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.
// Second case: Python dumper only.
return type.startsWith("__fptr()")
|| (type.isEmpty() && name == QLatin1String("[vptr]"));
return type.startsWith("__fptr()") || (type.isEmpty() && name == "[vptr]");
}
void WatchItem::setError(const QString &msg)
@@ -147,87 +141,6 @@ void WatchItem::setValue(const QString &value0)
value.clear();
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
@@ -397,7 +310,7 @@ void WatchItem::parseHelper(const GdbMi &input, bool maySort)
{
GdbMi mi = input["type"];
if (mi.isValid())
setType(mi.data());
type = mi.data();
editvalue = input["editvalue"].data();
editformat = input["editformat"].data();
@@ -428,7 +341,7 @@ void WatchItem::parseHelper(const GdbMi &input, bool maySort)
// *(class X*)0xdeadbeef for gdb.
exp = name;
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);
WatchItem *child = new WatchItem;
if (childType.isValid())
child->setType(childType.data());
child->type = childType.data();
if (childNumChild.isValid())
child->setHasChildren(childNumChild.toInt() > 0);
GdbMi name = subinput["name"];
@@ -516,7 +429,7 @@ void WatchItem::parseHelper(const GdbMi &input, bool maySort)
child->iname = this->iname + '.' + nn;
if (addressStep) {
child->address = addressBase + i * addressStep;
child->exp = "*(" + gdbQuoteTypes(child->type) + "*)0x"
child->exp = "*(" + child->type + "*)0x"
+ QString::number(child->address, 16);
}
QString key = subinput["key"].data();

View File

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

View File

@@ -220,22 +220,6 @@ bool isKeyWord(const QString &exp)
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.
QString formatToolTipAddress(quint64 a)
{
@@ -256,61 +240,5 @@ QString formatToolTipAddress(quint64 a)
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 Debugger

View File

@@ -40,10 +40,6 @@ bool hasLetterOrNumber(const QString &exp);
bool hasSideEffects(const QString &exp);
bool isKeyWord(const QString &exp);
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 isIntOrFloatType(const QString &type);
bool isIntType(const QString &type);