forked from qt-creator/qt-creator
Debugger: Save a few cycles in watch data
Change-Id: I1fada2767bedb5c9a90bd8f4f2db6b2c881f111e Reviewed-by: David Schulz <david.schulz@qt.io>
This commit is contained in:
@@ -15,106 +15,88 @@
|
|||||||
|
|
||||||
namespace Debugger::Internal {
|
namespace Debugger::Internal {
|
||||||
|
|
||||||
bool isPointerType(const QString &type)
|
bool isPointerType(const QStringView type)
|
||||||
{
|
{
|
||||||
return type.endsWith('*') || type.endsWith("* const");
|
return type.endsWith('*') || type.endsWith(u"* const");
|
||||||
}
|
}
|
||||||
|
|
||||||
bool isIntType(const QString &type)
|
bool isIntType(const QStringView type)
|
||||||
{
|
{
|
||||||
if (type.isEmpty())
|
if (type.isEmpty())
|
||||||
return false;
|
return false;
|
||||||
switch (type.at(0).unicode()) {
|
switch (type.at(0).unicode()) {
|
||||||
case 'b':
|
case 'b':
|
||||||
return type == "bool";
|
return type == u"bool";
|
||||||
case 'c':
|
case 'c':
|
||||||
return type.startsWith("char") &&
|
return type.startsWith(u"char") &&
|
||||||
( type == "char"
|
( type == u"char"
|
||||||
|| type == "char8_t"
|
|| type == u"char8_t"
|
||||||
|| type == "char16_t"
|
|| type == u"char16_t"
|
||||||
|| type == "char32_t" );
|
|| type == u"char32_t" );
|
||||||
case 'i':
|
case 'i':
|
||||||
return type.startsWith("int") &&
|
return type.startsWith(u"int") &&
|
||||||
( type == "int"
|
( type == u"int"
|
||||||
|| type == "int8_t"
|
|| type == u"int8_t"
|
||||||
|| type == "int16_t"
|
|| type == u"int16_t"
|
||||||
|| type == "int32_t"
|
|| type == u"int32_t"
|
||||||
|| type == "int64_t");
|
|| type == u"int64_t");
|
||||||
case 'l':
|
case 'l':
|
||||||
return type == "long"
|
return type == u"long"
|
||||||
|| type == "long int"
|
|| type == u"long int"
|
||||||
|| type == "long unsigned int";
|
|| type == u"long unsigned int";
|
||||||
case 'p':
|
case 'p':
|
||||||
return type == "ptrdiff_t";
|
return type == u"ptrdiff_t";
|
||||||
case 'q':
|
case 'q':
|
||||||
return type == "qint8" || type == "quint8"
|
return type == u"qint8" || type == u"quint8"
|
||||||
|| type == "qint16" || type == "quint16"
|
|| type == u"qint16" || type == u"quint16"
|
||||||
|| type == "qint32" || type == "quint32"
|
|| type == u"qint32" || type == u"quint32"
|
||||||
|| type == "qint64" || type == "quint64"
|
|| type == u"qint64" || type == u"quint64"
|
||||||
|| type == "qlonglong" || type == "qulonglong";
|
|| type == u"qlonglong" || type == u"qulonglong";
|
||||||
case 's':
|
case 's':
|
||||||
return type == "short"
|
return type == u"short"
|
||||||
|| type == "signed"
|
|| type == u"signed"
|
||||||
|| type == "size_t"
|
|| type == u"size_t"
|
||||||
|| type == "std::size_t"
|
|| type == u"std::size_t"
|
||||||
|| type == "std::ptrdiff_t"
|
|| type == u"std::ptrdiff_t"
|
||||||
|| (type.startsWith("signed") &&
|
|| (type.startsWith(u"signed") &&
|
||||||
( type == "signed char"
|
( type == u"signed char"
|
||||||
|| type == "signed short"
|
|| type == u"signed short"
|
||||||
|| type == "signed short int"
|
|| type == u"signed short int"
|
||||||
|| type == "signed long"
|
|| type == u"signed long"
|
||||||
|| type == "signed long int"
|
|| type == u"signed long int"
|
||||||
|| type == "signed long long"
|
|| type == u"signed long long"
|
||||||
|| type == "signed long long int"));
|
|| type == u"signed long long int"));
|
||||||
case 'u':
|
case 'u':
|
||||||
return type == "unsigned"
|
return type == u"unsigned"
|
||||||
|| (type.startsWith("unsigned") &&
|
|| (type.startsWith(u"unsigned") &&
|
||||||
( type == "unsigned char"
|
( type == u"unsigned char"
|
||||||
|| type == "unsigned short"
|
|| type == u"unsigned short"
|
||||||
|| type == "unsigned short int"
|
|| type == u"unsigned short int"
|
||||||
|| type == "unsigned int"
|
|| type == u"unsigned int"
|
||||||
|| type == "unsigned long"
|
|| type == u"unsigned long"
|
||||||
|| type == "unsigned long int"
|
|| type == u"unsigned long int"
|
||||||
|| type == "unsigned long long"
|
|| type == u"unsigned long long"
|
||||||
|| type == "unsigned long long int"))
|
|| type == u"unsigned long long int"))
|
||||||
|| (type.startsWith("uint") &&
|
|| (type.startsWith(u"uint") &&
|
||||||
( type == "uint8_t"
|
( type == u"uint8_t"
|
||||||
|| type == "uint16_t"
|
|| type == u"uint16_t"
|
||||||
|| type == "uint32_t"
|
|| type == u"uint32_t"
|
||||||
|| type == "uint64_t"));
|
|| type == u"uint64_t"));
|
||||||
default:
|
default:
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool isFloatType(const QString &type)
|
bool isFloatType(const QStringView type)
|
||||||
{
|
{
|
||||||
return type == "float" || type == "double" || type == "qreal" || type == "number";
|
return type == u"float" || type == u"double" || type == u"qreal" || type == u"number";
|
||||||
}
|
}
|
||||||
|
|
||||||
bool isIntOrFloatType(const QString &type)
|
bool isIntOrFloatType(const QStringView type)
|
||||||
{
|
{
|
||||||
return isIntType(type) || isFloatType(type);
|
return isIntType(type) || isFloatType(type);
|
||||||
}
|
}
|
||||||
|
|
||||||
WatchItem::WatchItem() :
|
|
||||||
id(WatchItem::InvalidId),
|
|
||||||
address(0),
|
|
||||||
origaddr(0),
|
|
||||||
size(0),
|
|
||||||
bitpos(0),
|
|
||||||
bitsize(0),
|
|
||||||
elided(0),
|
|
||||||
arrayIndex(-1),
|
|
||||||
sortGroup(0),
|
|
||||||
wantsChildren(false),
|
|
||||||
valueEnabled(true),
|
|
||||||
valueEditable(true),
|
|
||||||
autoDerefCount(0),
|
|
||||||
outdated(false)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
bool WatchItem::isVTablePointer() const
|
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.
|
||||||
|
@@ -18,7 +18,7 @@ class GdbMi;
|
|||||||
class WatchItem : public Utils::TypedTreeItem<WatchItem, WatchItem>
|
class WatchItem : public Utils::TypedTreeItem<WatchItem, WatchItem>
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
WatchItem();
|
WatchItem() {}
|
||||||
|
|
||||||
void parse(const GdbMi &input, bool maySort);
|
void parse(const GdbMi &input, bool maySort);
|
||||||
|
|
||||||
@@ -54,7 +54,7 @@ public:
|
|||||||
QString key() const { return address ? hexAddress() : iname; }
|
QString key() const { return address ? hexAddress() : iname; }
|
||||||
|
|
||||||
public:
|
public:
|
||||||
qint64 id; // Token for the engine for internal mapping
|
qint64 id = InvalidId; // Token for the engine for internal mapping
|
||||||
QString iname; // Internal name sth like 'local.baz.public.a'
|
QString iname; // Internal name sth like 'local.baz.public.a'
|
||||||
QString exp; // The expression
|
QString exp; // The expression
|
||||||
QString name; // Displayed name
|
QString name; // Displayed name
|
||||||
@@ -66,16 +66,16 @@ public:
|
|||||||
quint64 address; // Displayed address of the actual object
|
quint64 address; // Displayed address of the actual object
|
||||||
quint64 origaddr; // Address of the pointer referencing this item (gdb auto-deref)
|
quint64 origaddr; // Address of the pointer referencing this item (gdb auto-deref)
|
||||||
uint size; // Size
|
uint size; // Size
|
||||||
uint bitpos; // Position within bit fields
|
uint bitpos = 0; // Position within bit fields
|
||||||
uint bitsize; // Size in case of bit fields
|
uint bitsize = 0; // Size in case of bit fields
|
||||||
int elided; // Full size if value was cut off, -1 if cut on unknown size, 0 otherwise
|
uint autoDerefCount = 0; // number of levels of automatic dereferencing that has taken place (for pointer types)
|
||||||
int arrayIndex; // -1 if not an array member
|
int elided = 0; // Full size if value was cut off, -1 if cut on unknown size, 0 otherwise
|
||||||
uchar sortGroup; // 0 - ordinary member, 1 - vptr, 2 - base class
|
int arrayIndex = -1; // -1 if not an array member
|
||||||
bool wantsChildren;
|
uchar sortGroup = 0; // 0 - ordinary member, 1 - vptr, 2 - base class
|
||||||
bool valueEnabled; // Value will be enabled or not
|
bool wantsChildren = false;
|
||||||
bool valueEditable; // Value will be editable
|
bool valueEnabled = true; // Value will be enabled or not
|
||||||
uint autoDerefCount; // number of levels of automatic dereferencing that has taken place (for pointer types)
|
bool valueEditable = true; // Value will be editable
|
||||||
bool outdated; // \internal item is to be removed.
|
bool outdated = false; // \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
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
@@ -14,8 +14,7 @@
|
|||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
|
|
||||||
namespace Debugger {
|
namespace Debugger::Internal{
|
||||||
namespace Internal {
|
|
||||||
|
|
||||||
QString removeObviousSideEffects(const QString &expIn)
|
QString removeObviousSideEffects(const QString &expIn)
|
||||||
{
|
{
|
||||||
@@ -143,7 +142,7 @@ bool isLetterOrNumber(int c)
|
|||||||
|| (c >= '0' && c <= '9');
|
|| (c >= '0' && c <= '9');
|
||||||
}
|
}
|
||||||
|
|
||||||
bool hasLetterOrNumber(const QString &exp)
|
bool hasLetterOrNumber(const QStringView exp)
|
||||||
{
|
{
|
||||||
const QChar underscore = '_';
|
const QChar underscore = '_';
|
||||||
for (int i = exp.size(); --i >= 0; )
|
for (int i = exp.size(); --i >= 0; )
|
||||||
@@ -152,66 +151,66 @@ bool hasLetterOrNumber(const QString &exp)
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool hasSideEffects(const QString &exp)
|
bool hasSideEffects(const QStringView exp)
|
||||||
{
|
{
|
||||||
// FIXME: complete?
|
// FIXME: complete?
|
||||||
return exp.contains("-=")
|
return exp.contains(u"-=")
|
||||||
|| exp.contains("+=")
|
|| exp.contains(u"+=")
|
||||||
|| exp.contains("/=")
|
|| exp.contains(u"/=")
|
||||||
|| exp.contains("%=")
|
|| exp.contains(u"%=")
|
||||||
|| exp.contains("*=")
|
|| exp.contains(u"*=")
|
||||||
|| exp.contains("&=")
|
|| exp.contains(u"&=")
|
||||||
|| exp.contains("|=")
|
|| exp.contains(u"|=")
|
||||||
|| exp.contains("^=")
|
|| exp.contains(u"^=")
|
||||||
|| exp.contains("--")
|
|| exp.contains(u"--")
|
||||||
|| exp.contains("++");
|
|| exp.contains(u"++");
|
||||||
}
|
}
|
||||||
|
|
||||||
bool isKeyWord(const QString &exp)
|
bool isKeyWord(const QStringView exp)
|
||||||
{
|
{
|
||||||
// FIXME: incomplete.
|
// FIXME: incomplete.
|
||||||
if (!exp.isEmpty())
|
if (!exp.isEmpty())
|
||||||
return false;
|
return false;
|
||||||
switch (exp.at(0).toLatin1()) {
|
switch (exp.at(0).toLatin1()) {
|
||||||
case 'a':
|
case 'a':
|
||||||
return exp == "auto";
|
return exp == u"auto";
|
||||||
case 'b':
|
case 'b':
|
||||||
return exp == "break";
|
return exp == u"break";
|
||||||
case 'c':
|
case 'c':
|
||||||
return exp == "case" || exp == "class" || exp == "const" || exp == "constexpr"
|
return exp == u"case" || exp == u"class" || exp == u"const" || exp == u"constexpr"
|
||||||
|| exp == "catch" || exp == "continue" || exp == "const_cast";
|
|| exp == u"catch" || exp == u"continue" || exp == u"const_cast";
|
||||||
case 'd':
|
case 'd':
|
||||||
return exp == "do" || exp == "default" || exp == "delete" || exp == "decltype"
|
return exp == u"do" || exp == u"default" || exp == u"delete" || exp == u"decltype"
|
||||||
|| exp == "dynamic_cast";
|
|| exp == u"dynamic_cast";
|
||||||
case 'e':
|
case 'e':
|
||||||
return exp == "else" || exp == "extern" || exp == "enum" || exp == "explicit";
|
return exp == u"else" || exp == u"extern" || exp == u"enum" || exp == u"explicit";
|
||||||
case 'f':
|
case 'f':
|
||||||
return exp == "for" || exp == "friend" || exp == "final";
|
return exp == u"for" || exp == u"friend" || exp == u"final";
|
||||||
case 'g':
|
case 'g':
|
||||||
return exp == "goto";
|
return exp == u"goto";
|
||||||
case 'i':
|
case 'i':
|
||||||
return exp == "if" || exp == "inline";
|
return exp == u"if" || exp == u"inline";
|
||||||
case 'n':
|
case 'n':
|
||||||
return exp == "new" || exp == "namespace" || exp == "noexcept";
|
return exp == u"new" || exp == u"namespace" || exp == u"noexcept";
|
||||||
case 'm':
|
case 'm':
|
||||||
return exp == "mutable";
|
return exp == u"mutable";
|
||||||
case 'o':
|
case 'o':
|
||||||
return exp == "operator" || exp == "override";
|
return exp == u"operator" || exp == u"override";
|
||||||
case 'p':
|
case 'p':
|
||||||
return exp == "public" || exp == "protected" || exp == "private";
|
return exp == u"public" || exp == u"protected" || exp == u"private";
|
||||||
case 'r':
|
case 'r':
|
||||||
return exp == "return" || exp == "register" || exp == "reinterpret_cast";
|
return exp == u"return" || exp == u"register" || exp == u"reinterpret_cast";
|
||||||
case 's':
|
case 's':
|
||||||
return exp == "struct" || exp == "switch" || exp == "static_cast";
|
return exp == u"struct" || exp == u"switch" || exp == u"static_cast";
|
||||||
case 't':
|
case 't':
|
||||||
return exp == "template" || exp == "typename" || exp == "try"
|
return exp == u"template" || exp == u"typename" || exp == u"try"
|
||||||
|| exp == "throw" || exp == "typedef";
|
|| exp == u"throw" || exp == u"typedef";
|
||||||
case 'u':
|
case 'u':
|
||||||
return exp == "union" || exp == "using";
|
return exp == u"union" || exp == u"using";
|
||||||
case 'v':
|
case 'v':
|
||||||
return exp == "void" || exp == "volatile" || exp == "virtual";
|
return exp == u"void" || exp == u"volatile" || exp == u"virtual";
|
||||||
case 'w':
|
case 'w':
|
||||||
return exp == "while";
|
return exp == u"while";
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -277,5 +276,4 @@ QString escapeUnprintable(const QString &str, int unprintableBase)
|
|||||||
return encoded;
|
return encoded;
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace Internal
|
} // Debugger::Internal
|
||||||
} // namespace Debugger
|
|
||||||
|
@@ -8,24 +8,22 @@
|
|||||||
|
|
||||||
#include <QString>
|
#include <QString>
|
||||||
|
|
||||||
namespace Debugger {
|
namespace Debugger::Internal {
|
||||||
namespace Internal {
|
|
||||||
|
|
||||||
bool isSkippableFunction(const QStringView funcName, const QStringView fileName);
|
bool isSkippableFunction(const QStringView funcName, const QStringView fileName);
|
||||||
bool isLeavableFunction(const QStringView funcName, const QStringView fileName);
|
bool isLeavableFunction(const QStringView funcName, const QStringView fileName);
|
||||||
|
|
||||||
bool hasLetterOrNumber(const QString &exp);
|
bool hasLetterOrNumber(const QStringView exp);
|
||||||
bool hasSideEffects(const QString &exp);
|
bool hasSideEffects(const QStringView exp);
|
||||||
bool isKeyWord(const QString &exp);
|
bool isKeyWord(const QStringView exp);
|
||||||
bool isPointerType(const QString &type);
|
bool isPointerType(const QStringView type);
|
||||||
bool isFloatType(const QString &type);
|
bool isFloatType(const QStringView type);
|
||||||
bool isIntOrFloatType(const QString &type);
|
bool isIntOrFloatType(const QStringView type);
|
||||||
bool isIntType(const QString &type);
|
bool isIntType(const QStringView type);
|
||||||
|
|
||||||
QString formatToolTipAddress(quint64 a);
|
QString formatToolTipAddress(quint64 a);
|
||||||
QString removeObviousSideEffects(const QString &exp);
|
QString removeObviousSideEffects(const QString &exp);
|
||||||
|
|
||||||
QString escapeUnprintable(const QString &str, int unprintableBase = -1);
|
QString escapeUnprintable(const QString &str, int unprintableBase = -1);
|
||||||
|
|
||||||
} // namespace Internal
|
} // Debugger::Internal
|
||||||
} // namespace Debugger
|
|
||||||
|
Reference in New Issue
Block a user