QDebug: improve support for printing 64-bit QFlags
Like the 32-bit version, we add an explicitly-exported non-template overload. And we can call the 64-bit implementation from the 32-bit one to save in code generation inside QtCore. Task-number: QTBUG-111926 Change-Id: I8a96935cf6c742259c9dfffd17e9928218333c04 Reviewed-by: Ahmad Samir <a.samirh78@gmail.com> Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
This commit is contained in:
parent
2971dbfe06
commit
094f7cab54
@ -1329,9 +1329,19 @@ QDebugStateSaver::~QDebugStateSaver()
|
||||
*/
|
||||
void qt_QMetaEnum_flagDebugOperator(QDebug &debug, size_t sizeofT, uint value)
|
||||
{
|
||||
qt_QMetaEnum_flagDebugOperator<uint>(debug, sizeofT, value);
|
||||
qt_QMetaEnum_flagDebugOperator(debug, sizeofT, quint64(value));
|
||||
}
|
||||
|
||||
/*!
|
||||
\internal
|
||||
Ditto, for 64-bit.
|
||||
*/
|
||||
void qt_QMetaEnum_flagDebugOperator(QDebug &debug, size_t sizeofT, quint64 value)
|
||||
{
|
||||
qt_QMetaEnum_flagDebugOperator<quint64>(debug, sizeofT, value);
|
||||
}
|
||||
|
||||
|
||||
#ifndef QT_NO_QOBJECT
|
||||
/*!
|
||||
\internal
|
||||
@ -1449,7 +1459,7 @@ QDebug qt_QMetaEnum_flagDebugOperator(QDebug &debug, quint64 value, const QMetaO
|
||||
debug << '(';
|
||||
}
|
||||
|
||||
debug << me.valueToKeys(static_cast<int>(value));
|
||||
debug << me.valueToKeys(value);
|
||||
|
||||
if (enumScope)
|
||||
debug << ')';
|
||||
|
@ -526,6 +526,7 @@ inline QDebug operator<<(QDebug debug, const QTaggedPointer<T, Tag> &ptr)
|
||||
Q_CORE_EXPORT QDebug qt_QMetaEnum_debugOperator(QDebug&, qint64 value, const QMetaObject *meta, const char *name);
|
||||
Q_CORE_EXPORT QDebug qt_QMetaEnum_flagDebugOperator(QDebug &dbg, quint64 value, const QMetaObject *meta, const char *name);
|
||||
Q_CORE_EXPORT void qt_QMetaEnum_flagDebugOperator(QDebug &debug, size_t sizeofT, uint value);
|
||||
Q_CORE_EXPORT void qt_QMetaEnum_flagDebugOperator(QDebug &debug, size_t sizeofT, quint64 value);
|
||||
|
||||
template <typename Int>
|
||||
void qt_QMetaEnum_flagDebugOperator(QDebug &debug, size_t sizeofT, Int value)
|
||||
@ -556,9 +557,13 @@ inline QDebug operator<<(QDebug debug, Flags flags)
|
||||
using UInt = typename QIntegerForSizeof<T>::Unsigned;
|
||||
#if !defined(QT_NO_QOBJECT)
|
||||
if constexpr (QtPrivate::IsQEnumHelper<T>::Value || QtPrivate::IsQEnumHelper<Flags>::Value) {
|
||||
// if QFlags<T> is a Q_FLAG, we always zero-extend; if not, we need to
|
||||
// allow it to sign-extend if it is signed (see QMetaEnum::valueToKeys)
|
||||
using Int = std::conditional_t<QtPrivate::IsQEnumHelper<Flags>::Value, UInt,
|
||||
std::underlying_type_t<T>>;
|
||||
const QMetaObject *obj = qt_getEnumMetaObject(T());
|
||||
const char *name = qt_getEnumName(T());
|
||||
return qt_QMetaEnum_flagDebugOperator(debug, UInt(flags.toInt()), obj, name);
|
||||
return qt_QMetaEnum_flagDebugOperator(debug, Int(flags.toInt()), obj, name);
|
||||
} else
|
||||
#endif
|
||||
{
|
||||
|
@ -54,9 +54,14 @@ class tst_QDebug: public QObject
|
||||
public:
|
||||
enum EnumType { EnumValue1 = 1, EnumValue2 = INT_MIN };
|
||||
enum FlagType { EnumFlag1 = 1, EnumFlag2 = INT_MIN };
|
||||
enum Enum64Type { Enum64Value1 = 1, Enum64Value2 = Q_UINT64_C(0x1'0000'0002) };
|
||||
enum Flag64Type : qlonglong { Enum64Flag1 = 1, Enum64Flag2 = Q_UINT64_C(0x1'0000'0002) };
|
||||
Q_ENUM(EnumType)
|
||||
Q_ENUM(Enum64Type)
|
||||
Q_DECLARE_FLAGS(Flags, FlagType)
|
||||
Q_FLAG(Flags)
|
||||
Q_DECLARE_FLAGS(Flags64, Flag64Type)
|
||||
Q_FLAG(Flags64)
|
||||
|
||||
private slots:
|
||||
void assignment() const;
|
||||
@ -88,6 +93,7 @@ private slots:
|
||||
void qDebugQByteArray() const;
|
||||
void qDebugQByteArrayView() const;
|
||||
void qDebugQFlags() const;
|
||||
void qDebugQFlags64() const;
|
||||
void qDebugStdChrono_data() const;
|
||||
void qDebugStdChrono() const;
|
||||
void qDebugStdOptional() const;
|
||||
@ -106,6 +112,8 @@ private slots:
|
||||
void objcInObjcMode() const;
|
||||
#endif
|
||||
};
|
||||
Q_DECLARE_OPERATORS_FOR_FLAGS(tst_QDebug::Flags)
|
||||
Q_DECLARE_OPERATORS_FOR_FLAGS(tst_QDebug::Flags64)
|
||||
|
||||
void tst_QDebug::assignment() const
|
||||
{
|
||||
@ -1096,8 +1104,9 @@ void tst_QDebug::qDebugQFlags() const
|
||||
QString file, function;
|
||||
int line = 0;
|
||||
QFlags<TestEnum> flags(Flag1 | Flag2 | SignFlag);
|
||||
|
||||
MessageHandlerSetter mhs(myMessageHandler);
|
||||
|
||||
// first, test QFlags on an enum where neither are Q_FLAG or Q_ENUM
|
||||
{ qDebug() << flags; }
|
||||
#ifndef QT_NO_MESSAGELOGCONTEXT
|
||||
file = __FILE__; line = __LINE__ - 2; function = Q_FUNC_INFO;
|
||||
@ -1108,17 +1117,54 @@ void tst_QDebug::qDebugQFlags() const
|
||||
QCOMPARE(s_line, line);
|
||||
QCOMPARE(QString::fromLatin1(s_function), function);
|
||||
|
||||
// Test the output of QFlags with an enum not declared with Q_DECLARE_FLAGS and Q_FLAGS
|
||||
// QFlags where the backing enum is a Q_ENUM but the QFlags isn't a QFLAG
|
||||
QFlags<EnumType> flags2(EnumValue2);
|
||||
qDebug() << flags2;
|
||||
QCOMPARE(s_msg, QString::fromLatin1("QFlags<tst_QDebug::EnumType>(EnumValue2)"));
|
||||
|
||||
// A now for one that was fully declared
|
||||
// And now for one that was fully declared
|
||||
tst_QDebug::Flags flags3(EnumFlag1);
|
||||
qDebug() << flags3;
|
||||
QCOMPARE(s_msg, QString::fromLatin1("QFlags<tst_QDebug::FlagType>(EnumFlag1)"));
|
||||
}
|
||||
|
||||
enum class TestEnum64 : qulonglong {
|
||||
Flag1 = 0x1,
|
||||
Flag2 = Q_UINT64_C(0x8000'0000'0000'0000)
|
||||
};
|
||||
|
||||
Q_DECLARE_FLAGS(TestFlags64, TestEnum64)
|
||||
Q_DECLARE_OPERATORS_FOR_FLAGS(TestFlags64)
|
||||
|
||||
void tst_QDebug::qDebugQFlags64() const
|
||||
{
|
||||
QString file, function;
|
||||
int line = 0;
|
||||
QFlags<TestEnum64> flags(TestEnum64::Flag1 | TestEnum64::Flag2);
|
||||
MessageHandlerSetter mhs(myMessageHandler);
|
||||
|
||||
// first, test QFlags on an enum where neither are Q_FLAG or Q_ENUM
|
||||
qDebug() << flags;
|
||||
#ifndef QT_NO_MESSAGELOGCONTEXT
|
||||
file = __FILE__; line = __LINE__ - 2; function = Q_FUNC_INFO;
|
||||
#endif
|
||||
QCOMPARE(s_msgType, QtDebugMsg);
|
||||
QCOMPARE(s_msg, "QFlags(0x1|0x8000000000000000)");
|
||||
QCOMPARE(QString::fromLatin1(s_file), file);
|
||||
QCOMPARE(s_line, line);
|
||||
QCOMPARE(QString::fromLatin1(s_function), function);
|
||||
|
||||
// QFlags where the backing enum is a Q_ENUM but the QFlags isn't a QFLAG
|
||||
QFlags<Enum64Type> flags2(Enum64Value2);
|
||||
qDebug() << flags2;
|
||||
QCOMPARE(s_msg, QString::fromLatin1("QFlags<tst_QDebug::Enum64Type>(Enum64Value2)"));
|
||||
|
||||
// And now for one that was fully declared
|
||||
tst_QDebug::Flags64 flags3(Enum64Flag1|Enum64Flag2);
|
||||
qDebug() << flags3;
|
||||
QCOMPARE(s_msg, QString::fromLatin1("QFlags<tst_QDebug::Flag64Type>(Enum64Flag1|Enum64Flag2)"));
|
||||
}
|
||||
|
||||
using ToStringFunction = std::function<QString()>;
|
||||
void tst_QDebug::qDebugStdChrono_data() const
|
||||
{
|
||||
|
Loading…
x
Reference in New Issue
Block a user