Debugger: Save a few cycles in watch data

Change-Id: I1fada2767bedb5c9a90bd8f4f2db6b2c881f111e
Reviewed-by: David Schulz <david.schulz@qt.io>
This commit is contained in:
hjk
2023-01-03 14:09:44 +01:00
parent b00442e946
commit e1ae96647d
4 changed files with 124 additions and 146 deletions

View File

@@ -15,106 +15,88 @@
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())
return false;
switch (type.at(0).unicode()) {
case 'b':
return type == "bool";
return type == u"bool";
case 'c':
return type.startsWith("char") &&
( type == "char"
|| type == "char8_t"
|| type == "char16_t"
|| type == "char32_t" );
return type.startsWith(u"char") &&
( type == u"char"
|| type == u"char8_t"
|| type == u"char16_t"
|| type == u"char32_t" );
case 'i':
return type.startsWith("int") &&
( type == "int"
|| type == "int8_t"
|| type == "int16_t"
|| type == "int32_t"
|| type == "int64_t");
return type.startsWith(u"int") &&
( type == u"int"
|| type == u"int8_t"
|| type == u"int16_t"
|| type == u"int32_t"
|| type == u"int64_t");
case 'l':
return type == "long"
|| type == "long int"
|| type == "long unsigned int";
return type == u"long"
|| type == u"long int"
|| type == u"long unsigned int";
case 'p':
return type == "ptrdiff_t";
return type == u"ptrdiff_t";
case 'q':
return type == "qint8" || type == "quint8"
|| type == "qint16" || type == "quint16"
|| type == "qint32" || type == "quint32"
|| type == "qint64" || type == "quint64"
|| type == "qlonglong" || type == "qulonglong";
return type == u"qint8" || type == u"quint8"
|| type == u"qint16" || type == u"quint16"
|| type == u"qint32" || type == u"quint32"
|| type == u"qint64" || type == u"quint64"
|| type == u"qlonglong" || type == u"qulonglong";
case 's':
return type == "short"
|| type == "signed"
|| type == "size_t"
|| type == "std::size_t"
|| type == "std::ptrdiff_t"
|| (type.startsWith("signed") &&
( type == "signed char"
|| type == "signed short"
|| type == "signed short int"
|| type == "signed long"
|| type == "signed long int"
|| type == "signed long long"
|| type == "signed long long int"));
return type == u"short"
|| type == u"signed"
|| type == u"size_t"
|| type == u"std::size_t"
|| type == u"std::ptrdiff_t"
|| (type.startsWith(u"signed") &&
( type == u"signed char"
|| type == u"signed short"
|| type == u"signed short int"
|| type == u"signed long"
|| type == u"signed long int"
|| type == u"signed long long"
|| type == u"signed long long int"));
case 'u':
return type == "unsigned"
|| (type.startsWith("unsigned") &&
( type == "unsigned char"
|| type == "unsigned short"
|| type == "unsigned short int"
|| type == "unsigned int"
|| type == "unsigned long"
|| type == "unsigned long int"
|| type == "unsigned long long"
|| type == "unsigned long long int"))
|| (type.startsWith("uint") &&
( type == "uint8_t"
|| type == "uint16_t"
|| type == "uint32_t"
|| type == "uint64_t"));
return type == u"unsigned"
|| (type.startsWith(u"unsigned") &&
( type == u"unsigned char"
|| type == u"unsigned short"
|| type == u"unsigned short int"
|| type == u"unsigned int"
|| type == u"unsigned long"
|| type == u"unsigned long int"
|| type == u"unsigned long long"
|| type == u"unsigned long long int"))
|| (type.startsWith(u"uint") &&
( type == u"uint8_t"
|| type == u"uint16_t"
|| type == u"uint32_t"
|| type == u"uint64_t"));
default:
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);
}
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
{
// First case: Cdb only. No user type can be named like this, this is safe.

View File

@@ -18,7 +18,7 @@ class GdbMi;
class WatchItem : public Utils::TypedTreeItem<WatchItem, WatchItem>
{
public:
WatchItem();
WatchItem() {}
void parse(const GdbMi &input, bool maySort);
@@ -54,7 +54,7 @@ public:
QString key() const { return address ? hexAddress() : iname; }
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 exp; // The expression
QString name; // Displayed name
@@ -66,16 +66,16 @@ public:
quint64 address; // Displayed address of the actual object
quint64 origaddr; // Address of the pointer referencing this item (gdb auto-deref)
uint size; // Size
uint bitpos; // Position within bit fields
uint bitsize; // Size in case of bit fields
int elided; // Full size if value was cut off, -1 if cut on unknown size, 0 otherwise
int arrayIndex; // -1 if not an array member
uchar sortGroup; // 0 - ordinary member, 1 - vptr, 2 - base class
bool wantsChildren;
bool valueEnabled; // Value will be enabled or not
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.
uint bitpos = 0; // Position within bit fields
uint bitsize = 0; // Size in case of bit fields
uint autoDerefCount = 0; // number of levels of automatic dereferencing that has taken place (for pointer types)
int elided = 0; // Full size if value was cut off, -1 if cut on unknown size, 0 otherwise
int arrayIndex = -1; // -1 if not an array member
uchar sortGroup = 0; // 0 - ordinary member, 1 - vptr, 2 - base class
bool wantsChildren = false;
bool valueEnabled = true; // Value will be enabled or not
bool valueEditable = true; // Value will be editable
bool outdated = false; // \internal item is to be removed.
double time = 0; // Time used on the dumper side to produce this item
private:

View File

@@ -14,8 +14,7 @@
#include <string.h>
#include <ctype.h>
namespace Debugger {
namespace Internal {
namespace Debugger::Internal{
QString removeObviousSideEffects(const QString &expIn)
{
@@ -143,7 +142,7 @@ bool isLetterOrNumber(int c)
|| (c >= '0' && c <= '9');
}
bool hasLetterOrNumber(const QString &exp)
bool hasLetterOrNumber(const QStringView exp)
{
const QChar underscore = '_';
for (int i = exp.size(); --i >= 0; )
@@ -152,66 +151,66 @@ bool hasLetterOrNumber(const QString &exp)
return false;
}
bool hasSideEffects(const QString &exp)
bool hasSideEffects(const QStringView exp)
{
// FIXME: complete?
return exp.contains("-=")
|| exp.contains("+=")
|| exp.contains("/=")
|| exp.contains("%=")
|| exp.contains("*=")
|| exp.contains("&=")
|| exp.contains("|=")
|| exp.contains("^=")
|| exp.contains("--")
|| exp.contains("++");
return exp.contains(u"-=")
|| exp.contains(u"+=")
|| exp.contains(u"/=")
|| exp.contains(u"%=")
|| exp.contains(u"*=")
|| exp.contains(u"&=")
|| exp.contains(u"|=")
|| exp.contains(u"^=")
|| exp.contains(u"--")
|| exp.contains(u"++");
}
bool isKeyWord(const QString &exp)
bool isKeyWord(const QStringView exp)
{
// FIXME: incomplete.
if (!exp.isEmpty())
return false;
switch (exp.at(0).toLatin1()) {
case 'a':
return exp == "auto";
return exp == u"auto";
case 'b':
return exp == "break";
return exp == u"break";
case 'c':
return exp == "case" || exp == "class" || exp == "const" || exp == "constexpr"
|| exp == "catch" || exp == "continue" || exp == "const_cast";
return exp == u"case" || exp == u"class" || exp == u"const" || exp == u"constexpr"
|| exp == u"catch" || exp == u"continue" || exp == u"const_cast";
case 'd':
return exp == "do" || exp == "default" || exp == "delete" || exp == "decltype"
|| exp == "dynamic_cast";
return exp == u"do" || exp == u"default" || exp == u"delete" || exp == u"decltype"
|| exp == u"dynamic_cast";
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':
return exp == "for" || exp == "friend" || exp == "final";
return exp == u"for" || exp == u"friend" || exp == u"final";
case 'g':
return exp == "goto";
return exp == u"goto";
case 'i':
return exp == "if" || exp == "inline";
return exp == u"if" || exp == u"inline";
case 'n':
return exp == "new" || exp == "namespace" || exp == "noexcept";
return exp == u"new" || exp == u"namespace" || exp == u"noexcept";
case 'm':
return exp == "mutable";
return exp == u"mutable";
case 'o':
return exp == "operator" || exp == "override";
return exp == u"operator" || exp == u"override";
case 'p':
return exp == "public" || exp == "protected" || exp == "private";
return exp == u"public" || exp == u"protected" || exp == u"private";
case 'r':
return exp == "return" || exp == "register" || exp == "reinterpret_cast";
return exp == u"return" || exp == u"register" || exp == u"reinterpret_cast";
case 's':
return exp == "struct" || exp == "switch" || exp == "static_cast";
return exp == u"struct" || exp == u"switch" || exp == u"static_cast";
case 't':
return exp == "template" || exp == "typename" || exp == "try"
|| exp == "throw" || exp == "typedef";
return exp == u"template" || exp == u"typename" || exp == u"try"
|| exp == u"throw" || exp == u"typedef";
case 'u':
return exp == "union" || exp == "using";
return exp == u"union" || exp == u"using";
case 'v':
return exp == "void" || exp == "volatile" || exp == "virtual";
return exp == u"void" || exp == u"volatile" || exp == u"virtual";
case 'w':
return exp == "while";
return exp == u"while";
}
return false;
}
@@ -277,5 +276,4 @@ QString escapeUnprintable(const QString &str, int unprintableBase)
return encoded;
}
} // namespace Internal
} // namespace Debugger
} // Debugger::Internal

View File

@@ -8,24 +8,22 @@
#include <QString>
namespace Debugger {
namespace Internal {
namespace Debugger::Internal {
bool isSkippableFunction(const QStringView funcName, const QStringView fileName);
bool isLeavableFunction(const QStringView funcName, const QStringView fileName);
bool hasLetterOrNumber(const QString &exp);
bool hasSideEffects(const QString &exp);
bool isKeyWord(const QString &exp);
bool isPointerType(const QString &type);
bool isFloatType(const QString &type);
bool isIntOrFloatType(const QString &type);
bool isIntType(const QString &type);
bool hasLetterOrNumber(const QStringView exp);
bool hasSideEffects(const QStringView exp);
bool isKeyWord(const QStringView exp);
bool isPointerType(const QStringView type);
bool isFloatType(const QStringView type);
bool isIntOrFloatType(const QStringView type);
bool isIntType(const QStringView type);
QString formatToolTipAddress(quint64 a);
QString removeObviousSideEffects(const QString &exp);
QString escapeUnprintable(const QString &str, int unprintableBase = -1);
} // namespace Internal
} // namespace Debugger
} // Debugger::Internal