Valgrind: Use QMetaEnum for parsing enum values

Change-Id: I43685e3fde662a57b6966d5f5f29d4138158b4d8
Reviewed-by: hjk <hjk@qt.io>
This commit is contained in:
Jarek Kobus
2023-07-25 16:29:36 +02:00
parent e87a131c37
commit 545dbc5743
4 changed files with 26 additions and 78 deletions

View File

@@ -28,7 +28,7 @@ QT_BEGIN_NAMESPACE
namespace QTest { namespace QTest {
template<> template<>
inline bool qCompare(int const &t1, MemcheckErrorKind const &t2, inline bool qCompare(int const &t1, MemcheckError const &t2,
char const *actual, char const *expected, char const *file, int line) char const *actual, char const *expected, char const *file, int line)
{ {
return qCompare(t1, int(t2), actual, expected, file, line); return qCompare(t1, int(t2), actual, expected, file, line);

View File

@@ -22,6 +22,7 @@
#include <QDebug> #include <QDebug>
#include <QListView> #include <QListView>
#include <QMetaEnum>
#include <QPushButton> #include <QPushButton>
#include <QSettings> #include <QSettings>
#include <QStandardItemModel> #include <QStandardItemModel>
@@ -325,8 +326,9 @@ ValgrindSettings::ValgrindSettings(bool global)
visibleErrorKinds.setSettingsKey(base + "VisibleErrorKinds"); visibleErrorKinds.setSettingsKey(base + "VisibleErrorKinds");
QList<int> defaultErrorKinds; QList<int> defaultErrorKinds;
for (int i = 0; i < Valgrind::XmlProtocol::MemcheckErrorKindCount; ++i) const QMetaEnum memcheckErrorEnum = QMetaEnum::fromType<XmlProtocol::MemcheckError>();
defaultErrorKinds << i; for (int i = 0; i < memcheckErrorEnum.keyCount(); ++i)
defaultErrorKinds << memcheckErrorEnum.value(i);
visibleErrorKinds.setDefaultValue(defaultErrorKinds); visibleErrorKinds.setDefaultValue(defaultErrorKinds);
detectCycles.setSettingsKey(base + "Callgrind.CycleDetection"); detectCycles.setSettingsKey(base + "Callgrind.CycleDetection");

View File

@@ -14,13 +14,15 @@ QT_END_NAMESPACE
namespace Valgrind { namespace Valgrind {
namespace XmlProtocol { namespace XmlProtocol {
Q_NAMESPACE
class Stack; class Stack;
class Suppression; class Suppression;
/** /**
* Error kinds, specific to memcheck * Error kinds, specific to memcheck
*/ */
enum MemcheckErrorKind enum MemcheckError
{ {
InvalidFree, InvalidFree,
MismatchedFree, MismatchedFree,
@@ -36,19 +38,20 @@ enum MemcheckErrorKind
Leak_DefinitelyLost, Leak_DefinitelyLost,
Leak_PossiblyLost, Leak_PossiblyLost,
Leak_StillReachable, Leak_StillReachable,
Leak_IndirectlyLost, Leak_IndirectlyLost
MemcheckErrorKindCount
}; };
Q_ENUM_NS(MemcheckError);
enum PtrcheckErrorKind enum PtrcheckError
{ {
SorG, SorG,
Heap, Heap,
Arith, Arith,
SysParam SysParam
}; };
Q_ENUM_NS(PtrcheckError);
enum HelgrindErrorKind enum HelgrindError
{ {
Race, Race,
UnlockUnlocked, UnlockUnlocked,
@@ -58,6 +61,7 @@ enum HelgrindErrorKind
LockOrder, LockOrder,
Misc Misc
}; };
Q_ENUM_NS(HelgrindError);
class Error class Error
{ {

View File

@@ -15,7 +15,7 @@
#include <QAbstractSocket> #include <QAbstractSocket>
#include <QHash> #include <QHash>
#include <QIODevice> #include <QIODevice>
#include <QPair> #include <QMetaEnum>
#include <QXmlStreamReader> #include <QXmlStreamReader>
namespace { namespace {
@@ -88,9 +88,6 @@ private:
void checkTool(const QString &tool); void checkTool(const QString &tool);
XWhat parseXWhat(); XWhat parseXWhat();
XauxWhat parseXauxWhat(); XauxWhat parseXauxWhat();
MemcheckErrorKind parseMemcheckErrorKind(const QString &kind);
HelgrindErrorKind parseHelgrindErrorKind(const QString &kind);
PtrcheckErrorKind parsePtrcheckErrorKind(const QString &kind);
int parseErrorKind(const QString &kind); int parseErrorKind(const QString &kind);
void reportInternalError(const QString &errorString); void reportInternalError(const QString &errorString);
@@ -100,19 +97,12 @@ private:
Tool tool = Tool::Unknown; Tool tool = Tool::Unknown;
QXmlStreamReader reader; QXmlStreamReader reader;
QHash<QString, MemcheckErrorKind> errorKindsByName_memcheck;
QHash<QString, HelgrindErrorKind> errorKindsByName_helgrind;
QHash<QString, PtrcheckErrorKind> errorKindsByName_ptrcheck;
QHash<QString, Tool> toolsByName; QHash<QString, Tool> toolsByName;
private: private:
Parser *const q; Parser *const q;
}; };
#undef ADD_ENUM
#define ADD_ENUM(tool,enumV) { errorKindsByName_##tool.insert(#enumV, enumV); }
Parser::Private::Private(Parser *qq) Parser::Private::Private(Parser *qq)
: q(qq) : q(qq)
{ {
@@ -120,38 +110,8 @@ Parser::Private::Private(Parser *qq)
toolsByName.insert("ptrcheck", Tool::Ptrcheck); toolsByName.insert("ptrcheck", Tool::Ptrcheck);
toolsByName.insert("exp-ptrcheck", Tool::Ptrcheck); toolsByName.insert("exp-ptrcheck", Tool::Ptrcheck);
toolsByName.insert("helgrind", Tool::Helgrind); toolsByName.insert("helgrind", Tool::Helgrind);
ADD_ENUM(memcheck, ClientCheck)
ADD_ENUM(memcheck, InvalidFree)
ADD_ENUM(memcheck, InvalidJump)
ADD_ENUM(memcheck, InvalidRead)
ADD_ENUM(memcheck, InvalidWrite)
ADD_ENUM(memcheck, Leak_DefinitelyLost)
ADD_ENUM(memcheck, Leak_PossiblyLost)
ADD_ENUM(memcheck, Leak_StillReachable)
ADD_ENUM(memcheck, Leak_IndirectlyLost)
ADD_ENUM(memcheck, MismatchedFree)
ADD_ENUM(memcheck, Overlap)
ADD_ENUM(memcheck, SyscallParam)
ADD_ENUM(memcheck, UninitCondition)
ADD_ENUM(memcheck, UninitValue)
ADD_ENUM(helgrind, Race)
ADD_ENUM(helgrind, UnlockUnlocked)
ADD_ENUM(helgrind, UnlockForeign)
ADD_ENUM(helgrind, UnlockBogus)
ADD_ENUM(helgrind, PthAPIerror)
ADD_ENUM(helgrind, LockOrder)
ADD_ENUM(helgrind, Misc)
ADD_ENUM(ptrcheck, SorG)
ADD_ENUM(ptrcheck, Heap)
ADD_ENUM(ptrcheck, Arith)
ADD_ENUM(ptrcheck, SysParam)
} }
#undef ADD_ENUM
static quint64 parseHex(const QString &str, const QString &context) static quint64 parseHex(const QString &str, const QString &context)
{ {
bool ok; bool ok;
@@ -316,44 +276,26 @@ XauxWhat Parser::Private::parseXauxWhat()
return what; return what;
} }
template <typename Enum>
int parseErrorEnum(const QString &kind)
MemcheckErrorKind Parser::Private::parseMemcheckErrorKind(const QString &kind)
{ {
const auto it = errorKindsByName_memcheck.constFind(kind); const QMetaEnum metaEnum = QMetaEnum::fromType<Enum>();
if (it != errorKindsByName_memcheck.constEnd()) const int value = metaEnum.keyToValue(kind.toUtf8());
return *it; if (value >= 0)
else return value;
throw ParserException(Tr::tr("Unknown memcheck error kind \"%1\"").arg(kind)); throw ParserException(Tr::tr("Unknown %1 kind \"%2\"")
} .arg(QString::fromUtf8(metaEnum.enumName()), kind));
HelgrindErrorKind Parser::Private::parseHelgrindErrorKind(const QString &kind)
{
const auto it = errorKindsByName_helgrind.constFind(kind);
if (it != errorKindsByName_helgrind.constEnd())
return *it;
else
throw ParserException(Tr::tr("Unknown helgrind error kind \"%1\"").arg(kind));
}
PtrcheckErrorKind Parser::Private::parsePtrcheckErrorKind(const QString &kind)
{
const auto it = errorKindsByName_ptrcheck.constFind(kind);
if (it != errorKindsByName_ptrcheck.constEnd())
return *it;
else
throw ParserException(Tr::tr("Unknown ptrcheck error kind \"%1\"").arg(kind));
} }
int Parser::Private::parseErrorKind(const QString &kind) int Parser::Private::parseErrorKind(const QString &kind)
{ {
switch (tool) { switch (tool) {
case Tool::Memcheck: case Tool::Memcheck:
return parseMemcheckErrorKind(kind); return parseErrorEnum<MemcheckError>(kind);
case Tool::Ptrcheck: case Tool::Ptrcheck:
return parsePtrcheckErrorKind(kind); return parseErrorEnum<PtrcheckError>(kind);
case Tool::Helgrind: case Tool::Helgrind:
return parseHelgrindErrorKind(kind); return parseErrorEnum<HelgrindError>(kind);
case Tool::Unknown: case Tool::Unknown:
default: default:
break; break;