diff options
author | Eike Ziller <eike.ziller@qt.io> | 2021-07-09 11:22:22 +0200 |
---|---|---|
committer | Eike Ziller <eike.ziller@qt.io> | 2021-07-09 12:05:20 +0000 |
commit | c3e413a8643857111ea80747605ba2cf5c2e328b (patch) | |
tree | 2926147acd8969f7a211f7a64593a48ad031130d | |
parent | 0568be071d5523478775019c9dd28d5a081efa74 (diff) |
proparser: Update ProItems to state in Qt 6.2
Except for our Qt 5 workarounds with toStringView, qHash return value,
and ProStringList which must be an explicit QVector for Qt 5.
Most importantly that pulls in a change to
ProString::toQString(QString &tmp) const
from 76004502baa118016c8e0f32895af7a822f1ba37 in qtbase, which replaces
a setRawData call which otherwise leads to severe issues when built with
Qt 6.
Fixes: QTCREATORBUG-25574
Change-Id: I488b4e0b63becc59a4ea34aace5c249921fa1a60
Reviewed-by: Joerg Bornemann <joerg.bornemann@qt.io>
Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org>
Reviewed-by: Christian Kandeler <christian.kandeler@qt.io>
-rw-r--r-- | src/shared/proparser/proitems.cpp | 18 | ||||
-rw-r--r-- | src/shared/proparser/proitems.h | 94 |
2 files changed, 85 insertions, 27 deletions
diff --git a/src/shared/proparser/proitems.cpp b/src/shared/proparser/proitems.cpp index f689c41923..1f4a436115 100644 --- a/src/shared/proparser/proitems.cpp +++ b/src/shared/proparser/proitems.cpp @@ -25,6 +25,7 @@ #include "proitems.h" +#include <qdebug.h> #include <qfileinfo.h> #include <qset.h> #include <qstringlist.h> @@ -50,6 +51,11 @@ ProString::ProString() : { } +ProString::ProString(const ProString &other) : + m_string(other.m_string), m_offset(other.m_offset), m_length(other.m_length), m_file(other.m_file), m_hash(other.m_hash) +{ +} + ProString::ProString(const ProString &other, OmitPreHashing) : m_string(other.m_string), m_offset(other.m_offset), m_length(other.m_length), m_file(other.m_file), m_hash(0x80000000) { @@ -72,13 +78,13 @@ ProString::ProString(Utils::StringView str) : } ProString::ProString(const char *str, DoPreHashing) : - m_string(QString::fromLatin1(str)), m_offset(0), m_length(qstrlen(str)), m_file(0) + m_string(QString::fromLatin1(str)), m_offset(0), m_length(int(qstrlen(str))), m_file(0) { updatedHash(); } ProString::ProString(const char *str) : - m_string(QString::fromLatin1(str)), m_offset(0), m_length(qstrlen(str)), m_file(0), m_hash(0x80000000) + m_string(QString::fromLatin1(str)), m_offset(0), m_length(int(qstrlen(str))), m_file(0), m_hash(0x80000000) { } @@ -148,7 +154,8 @@ QString ProString::toQString() const QString &ProString::toQString(QString &tmp) const { - return tmp.setRawData(m_string.constData() + m_offset, m_length); + tmp = m_string.mid(m_offset, m_length); + return tmp; } ProString &ProString::prepend(const ProString &other) @@ -493,4 +500,9 @@ ProKey ProFile::getHashStr(const ushort *&tPtr) return ret; } +QDebug operator<<(QDebug debug, const ProString &str) +{ + return debug << str.toQString(); +} + QT_END_NAMESPACE diff --git a/src/shared/proparser/proitems.h b/src/shared/proparser/proitems.h index 3e0686fe13..9d851a9d57 100644 --- a/src/shared/proparser/proitems.h +++ b/src/shared/proparser/proitems.h @@ -64,6 +64,8 @@ class ProFile; class ProString { public: ProString(); + ProString(const ProString &other); + ProString &operator=(const ProString &) = default; template<typename A, typename B> ProString &operator=(const QStringBuilder<A, B> &str) { return *this = QString(str); } @@ -74,7 +76,6 @@ public: ProString(const QStringBuilder<A, B> &str) : ProString(QString(str)) {} - ProString(const QString &str, int offset, int length); void setValue(const QString &str); void clear() { m_string.clear(); m_length = 0; } @@ -83,14 +84,14 @@ public: int sourceFile() const { return m_file; } ProString &prepend(const ProString &other); - ProString &append(const ProString &other, bool *pending = 0); + ProString &append(const ProString &other, bool *pending = nullptr); ProString &append(const QString &other) { return append(ProString(other)); } template<typename A, typename B> ProString &append(const QStringBuilder<A, B> &other) { return append(QString(other)); } ProString &append(const QLatin1String other); ProString &append(const char *other) { return append(QLatin1String(other)); } ProString &append(QChar other); - ProString &append(const ProStringList &other, bool *pending = 0, bool skipEmpty1st = false); + ProString &append(const ProStringList &other, bool *pending = nullptr, bool skipEmpty1st = false); ProString &operator+=(const ProString &other) { return append(other); } ProString &operator+=(const QString &other) { return append(other); } template<typename A, typename B> @@ -146,9 +147,9 @@ public: bool contains(const QString &s, Qt::CaseSensitivity cs = Qt::CaseSensitive) const { return indexOf(s, 0, cs) >= 0; } bool contains(const char *s, Qt::CaseSensitivity cs = Qt::CaseSensitive) const { return indexOf(QLatin1String(s), 0, cs) >= 0; } bool contains(QChar c, Qt::CaseSensitivity cs = Qt::CaseSensitive) const { return indexOf(c, 0, cs) >= 0; } - int toLongLong(bool *ok = 0, int base = 10) const { return toStringView().toLongLong(ok, base); } - int toInt(bool *ok = 0, int base = 10) const { return toStringView().toInt(ok, base); } - short toShort(bool *ok = 0, int base = 10) const { return toStringView().toShort(ok, base); } + qlonglong toLongLong(bool *ok = nullptr, int base = 10) const { return toStringView().toLongLong(ok, base); } + int toInt(bool *ok = nullptr, int base = 10) const { return toStringView().toInt(ok, base); } + short toShort(bool *ok = nullptr, int base = 10) const { return toStringView().toShort(ok, base); } uint hash() const { return m_hash; } static uint hash(const QChar *p, int n); @@ -185,7 +186,8 @@ private: friend QString operator+(const ProString &one, const ProString &two); friend class ProKey; }; -Q_DECLARE_TYPEINFO(ProString, Q_MOVABLE_TYPE); +Q_DECLARE_TYPEINFO(ProString, Q_RELOCATABLE_TYPE); + class ProKey : public ProString { public: @@ -195,7 +197,6 @@ public: ProKey(const QStringBuilder<A, B> &str) : ProString(str) {} - PROITEM_EXPLICIT ProKey(const char *str); ProKey(const QString &str, int off, int len); ProKey(const QString &str, int off, int len, uint hash); @@ -217,7 +218,7 @@ public: private: ProKey(const ProString &other); }; -Q_DECLARE_TYPEINFO(ProKey, Q_MOVABLE_TYPE); +Q_DECLARE_TYPEINFO(ProKey, Q_RELOCATABLE_TYPE); template <> struct QConcatenable<ProString> : private QAbstractConcatenable { @@ -228,6 +229,8 @@ template <> struct QConcatenable<ProString> : private QAbstractConcatenable static inline void appendTo(const ProString &a, QChar *&out) { const auto n = a.size(); + if (!n) + return; memcpy(out, a.toStringView().data(), sizeof(QChar) * n); out += n; } @@ -242,6 +245,8 @@ template <> struct QConcatenable<ProKey> : private QAbstractConcatenable static inline void appendTo(const ProKey &a, QChar *&out) { const auto n = a.size(); + if (!n) + return; memcpy(out, a.toStringView().data(), sizeof(QChar) * n); out += n; } @@ -257,6 +262,54 @@ QTextStream &operator<<(QTextStream &t, const ProString &str); template<typename A, typename B> QTextStream &operator<<(QTextStream &t, const QStringBuilder<A, B> &str) { return t << QString(str); } +// This class manages read-only access to a ProString via a raw data QString +// temporary, ensuring that the latter is accessed exclusively. +class ProStringRoUser +{ +public: + ProStringRoUser(QString &rs) + { + m_rs = &rs; + } + ProStringRoUser(const ProString &ps, QString &rs) + : ProStringRoUser(rs) + { + ps.toQString(rs); + } + // No destructor, as a RAII pattern cannot be used: references to the + // temporary string can legitimately outlive instances of this class + // (if they are held by Qt, e.g. in QRegExp). + QString &set(const ProString &ps) { return ps.toQString(*m_rs); } + QString &str() { return *m_rs; } + +protected: + QString *m_rs; +}; + +// This class manages read-write access to a ProString via a raw data QString +// temporary, ensuring that the latter is accessed exclusively, and that raw +// data does not leak outside its source's refcounting. +class ProStringRwUser : public ProStringRoUser +{ +public: + ProStringRwUser(QString &rs) + : ProStringRoUser(rs), m_ps(nullptr) {} + ProStringRwUser(const ProString &ps, QString &rs) + : ProStringRoUser(ps, rs), m_ps(&ps) {} + QString &set(const ProString &ps) { m_ps = &ps; return ProStringRoUser::set(ps); } + ProString extract(const QString &s) const + { return s.isSharedWith(*m_rs) ? *m_ps : ProString(s).setSource(*m_ps); } + ProString extract(const QString &s, const ProStringRwUser &other) const + { + if (other.m_ps && s.isSharedWith(*other.m_rs)) + return *other.m_ps; + return extract(s); + } + +private: + const ProString *m_ps; +}; + class ProStringList : public QVector<ProString> { public: ProStringList() {} @@ -290,21 +343,12 @@ public: { return contains(ProString(str), cs); } bool contains(const char *str, Qt::CaseSensitivity cs = Qt::CaseSensitive) const; }; -Q_DECLARE_TYPEINFO(ProStringList, Q_MOVABLE_TYPE); +Q_DECLARE_TYPEINFO(ProStringList, Q_RELOCATABLE_TYPE); inline ProStringList operator+(const ProStringList &one, const ProStringList &two) { ProStringList ret = one; ret += two; return ret; } -typedef QHash<ProKey, ProStringList> ProValueMap; - -// For std::list (sic!) -#ifdef Q_CC_MSVC -inline bool operator<(const ProValueMap &, const ProValueMap &) -{ - Q_ASSERT(false); - return false; -} -#endif +typedef QMap<ProKey, ProStringList> ProValueMap; // These token definitions affect both ProFileEvaluator and ProWriter enum ProToken { @@ -419,7 +463,7 @@ class ProFunctionDef { public: ProFunctionDef(ProFile *pro, int offset) : m_pro(pro), m_offset(offset) { m_pro->ref(); } ProFunctionDef(const ProFunctionDef &o) : m_pro(o.m_pro), m_offset(o.m_offset) { m_pro->ref(); } - ProFunctionDef(ProFunctionDef &&other) Q_DECL_NOTHROW + ProFunctionDef(ProFunctionDef &&other) noexcept : m_pro(other.m_pro), m_offset(other.m_offset) { other.m_pro = nullptr; } ~ProFunctionDef() { if (m_pro) m_pro->deref(); } ProFunctionDef &operator=(const ProFunctionDef &o) @@ -433,13 +477,13 @@ public: } return *this; } - ProFunctionDef &operator=(ProFunctionDef &&other) Q_DECL_NOTHROW + ProFunctionDef &operator=(ProFunctionDef &&other) noexcept { ProFunctionDef moved(std::move(other)); swap(moved); return *this; } - void swap(ProFunctionDef &other) Q_DECL_NOTHROW + void swap(ProFunctionDef &other) noexcept { qSwap(m_pro, other.m_pro); qSwap(m_offset, other.m_offset); @@ -452,11 +496,13 @@ private: int m_offset; }; -Q_DECLARE_TYPEINFO(ProFunctionDef, Q_MOVABLE_TYPE); +Q_DECLARE_TYPEINFO(ProFunctionDef, Q_RELOCATABLE_TYPE); struct ProFunctionDefs { QHash<ProKey, ProFunctionDef> testFunctions; QHash<ProKey, ProFunctionDef> replaceFunctions; }; +QDebug operator<<(QDebug debug, const ProString &str); + QT_END_NAMESPACE |