forked from qt-creator/qt-creator
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:
@@ -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();
|
||||
|
||||
@@ -69,7 +69,6 @@ public:
|
||||
|
||||
void setError(const QString &);
|
||||
void setValue(const QString &);
|
||||
void setType(const QString &, bool guessChildrenFromType = true);
|
||||
|
||||
QString toString() const;
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user