Merge remote-tracking branch 'origin/4.15' into 5.0

Change-Id: I5e57cb456e3f501d5182c8db3688c2729e9fadb2
This commit is contained in:
Eike Ziller
2021-07-09 14:09:12 +02:00
5 changed files with 162 additions and 41 deletions

55
dist/changes-4.15.2.md vendored Normal file
View File

@@ -0,0 +1,55 @@
Qt Creator 4.15.2
=================
Qt Creator version 4.15.2 contains bug fixes.
The most important changes are listed in this document. For a complete
list of changes, see the Git log for the Qt Creator sources that
you can check out from the public Git repository. For example:
git clone git://code.qt.io/qt-creator/qt-creator.git
git log --cherry-pick --pretty=oneline origin/v4.15.1..v4.15.2
Projects
--------
### CMake
* Improved performance after project load and reparse
* Fixed crash on session switch (QTCREATORBUG-25837)
### qmake
* Fixed issues with executing system calls (QTCREATORBUG-25970)
Test Integration
----------------
### CTest
* Fixed test detection if `ctest` takes long to run (QTCREATORBUG-25851)
Platforms
---------
### WASM
* Fixed Python version that is on Windows (QTCREATORBUG-25897)
Credits for these changes go to:
--------------------------------
Ahmad Samir
Alessandro Portale
Christian Stenger
Cristian Adam
Eike Ziller
Ivan Komissarov
Kai Köhne
Knud Dollereder
Michael Winkelmann
Mitch Curtis
Robert Löhning
Thomas Hartmann
Tim Blechmann
Tim Jenssen
Tuomo Pelkonen

View File

@@ -284,8 +284,11 @@ QmakeBuildSystem::~QmakeBuildSystem()
delete m_qmakeVfs; delete m_qmakeVfs;
m_qmakeVfs = nullptr; m_qmakeVfs = nullptr;
m_asyncUpdateFutureInterface.reportCanceled(); if (m_asyncUpdateFutureInterface) {
m_asyncUpdateFutureInterface.reportFinished(); m_asyncUpdateFutureInterface->reportCanceled();
m_asyncUpdateFutureInterface->reportFinished();
m_asyncUpdateFutureInterface.reset();
}
} }
void QmakeBuildSystem::updateCodeModels() void QmakeBuildSystem::updateCodeModels()
@@ -591,8 +594,9 @@ void QmakeBuildSystem::incrementPendingEvaluateFutures()
} }
++m_pendingEvaluateFuturesCount; ++m_pendingEvaluateFuturesCount;
TRACE("pending inc to: " << m_pendingEvaluateFuturesCount); TRACE("pending inc to: " << m_pendingEvaluateFuturesCount);
m_asyncUpdateFutureInterface.setProgressRange(m_asyncUpdateFutureInterface.progressMinimum(), m_asyncUpdateFutureInterface->setProgressRange(m_asyncUpdateFutureInterface->progressMinimum(),
m_asyncUpdateFutureInterface.progressMaximum() + 1); m_asyncUpdateFutureInterface->progressMaximum()
+ 1);
} }
void QmakeBuildSystem::decrementPendingEvaluateFutures() void QmakeBuildSystem::decrementPendingEvaluateFutures()
@@ -605,15 +609,17 @@ void QmakeBuildSystem::decrementPendingEvaluateFutures()
return; // We are closing the project! return; // We are closing the project!
} }
m_asyncUpdateFutureInterface.setProgressValue(m_asyncUpdateFutureInterface.progressValue() + 1); m_asyncUpdateFutureInterface->setProgressValue(m_asyncUpdateFutureInterface->progressValue()
+ 1);
if (m_pendingEvaluateFuturesCount == 0) { if (m_pendingEvaluateFuturesCount == 0) {
// We are done! // We are done!
setRootProjectNode(QmakeNodeTreeBuilder::buildTree(this)); setRootProjectNode(QmakeNodeTreeBuilder::buildTree(this));
if (!m_rootProFile->validParse()) if (!m_rootProFile->validParse())
m_asyncUpdateFutureInterface.reportCanceled(); m_asyncUpdateFutureInterface->reportCanceled();
m_asyncUpdateFutureInterface.reportFinished(); m_asyncUpdateFutureInterface->reportFinished();
m_asyncUpdateFutureInterface.reset();
m_cancelEvaluate = false; m_cancelEvaluate = false;
// TODO clear the profile cache ? // TODO clear the profile cache ?
@@ -659,12 +665,13 @@ void QmakeBuildSystem::asyncUpdate()
m_qmakeVfs->invalidateCache(); m_qmakeVfs->invalidateCache();
} }
m_asyncUpdateFutureInterface.setProgressRange(0, 0); m_asyncUpdateFutureInterface.reset(new QFutureInterface<void>);
Core::ProgressManager::addTask(m_asyncUpdateFutureInterface.future(), m_asyncUpdateFutureInterface->setProgressRange(0, 0);
Core::ProgressManager::addTask(m_asyncUpdateFutureInterface->future(),
tr("Reading Project \"%1\"").arg(project()->displayName()), tr("Reading Project \"%1\"").arg(project()->displayName()),
Constants::PROFILE_EVALUATE); Constants::PROFILE_EVALUATE);
m_asyncUpdateFutureInterface.reportStarted(); m_asyncUpdateFutureInterface->reportStarted();
const auto watcher = new QFutureWatcher<void>(this); const auto watcher = new QFutureWatcher<void>(this);
connect(watcher, &QFutureWatcher<void>::canceled, this, [this, watcher] { connect(watcher, &QFutureWatcher<void>::canceled, this, [this, watcher] {
if (!m_qmakeGlobals) if (!m_qmakeGlobals)
@@ -676,7 +683,7 @@ void QmakeBuildSystem::asyncUpdate()
watcher->disconnect(); watcher->disconnect();
watcher->deleteLater(); watcher->deleteLater();
}); });
watcher->setFuture(m_asyncUpdateFutureInterface.future()); watcher->setFuture(m_asyncUpdateFutureInterface->future());
const Kit *const k = kit(); const Kit *const k = kit();
QtSupport::BaseQtVersion *const qtVersion = QtSupport::QtKitAspect::qtVersion(k); QtSupport::BaseQtVersion *const qtVersion = QtSupport::QtKitAspect::qtVersion(k);
@@ -687,8 +694,9 @@ void QmakeBuildSystem::asyncUpdate()
.arg(project()->displayName(), k->displayName()) .arg(project()->displayName(), k->displayName())
: tr("Cannot parse project \"%1\": No kit selected.").arg(project()->displayName()); : tr("Cannot parse project \"%1\": No kit selected.").arg(project()->displayName());
proFileParseError(errorMessage, project()->projectFilePath()); proFileParseError(errorMessage, project()->projectFilePath());
m_asyncUpdateFutureInterface.reportCanceled(); m_asyncUpdateFutureInterface->reportCanceled();
m_asyncUpdateFutureInterface.reportFinished(); m_asyncUpdateFutureInterface->reportFinished();
m_asyncUpdateFutureInterface.reset();
return; return;
} }

View File

@@ -200,7 +200,7 @@ private:
QString m_qmakeSysroot; QString m_qmakeSysroot;
QFutureInterface<void> m_asyncUpdateFutureInterface; std::unique_ptr<QFutureInterface<void>> m_asyncUpdateFutureInterface;
int m_pendingEvaluateFuturesCount = 0; int m_pendingEvaluateFuturesCount = 0;
AsyncUpdateState m_asyncUpdateState = Base; AsyncUpdateState m_asyncUpdateState = Base;
bool m_cancelEvaluate = false; bool m_cancelEvaluate = false;

View File

@@ -25,6 +25,7 @@
#include "proitems.h" #include "proitems.h"
#include <qdebug.h>
#include <qfileinfo.h> #include <qfileinfo.h>
#include <qset.h> #include <qset.h>
#include <qstringlist.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) : 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) 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) : 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(); updatedHash();
} }
ProString::ProString(const char *str) : 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 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) ProString &ProString::prepend(const ProString &other)
@@ -493,4 +500,9 @@ ProKey ProFile::getHashStr(const ushort *&tPtr)
return ret; return ret;
} }
QDebug operator<<(QDebug debug, const ProString &str)
{
return debug << str.toQString();
}
QT_END_NAMESPACE QT_END_NAMESPACE

View File

@@ -64,6 +64,8 @@ class ProFile;
class ProString { class ProString {
public: public:
ProString(); ProString();
ProString(const ProString &other);
ProString &operator=(const ProString &) = default;
template<typename A, typename B> template<typename A, typename B>
ProString &operator=(const QStringBuilder<A, B> &str) ProString &operator=(const QStringBuilder<A, B> &str)
{ return *this = QString(str); } { return *this = QString(str); }
@@ -74,7 +76,6 @@ public:
ProString(const QStringBuilder<A, B> &str) ProString(const QStringBuilder<A, B> &str)
: ProString(QString(str)) : ProString(QString(str))
{} {}
ProString(const QString &str, int offset, int length); ProString(const QString &str, int offset, int length);
void setValue(const QString &str); void setValue(const QString &str);
void clear() { m_string.clear(); m_length = 0; } void clear() { m_string.clear(); m_length = 0; }
@@ -83,14 +84,14 @@ public:
int sourceFile() const { return m_file; } int sourceFile() const { return m_file; }
ProString &prepend(const ProString &other); 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)); } ProString &append(const QString &other) { return append(ProString(other)); }
template<typename A, typename B> template<typename A, typename B>
ProString &append(const QStringBuilder<A, B> &other) { return append(QString(other)); } ProString &append(const QStringBuilder<A, B> &other) { return append(QString(other)); }
ProString &append(const QLatin1String other); ProString &append(const QLatin1String other);
ProString &append(const char *other) { return append(QLatin1String(other)); } ProString &append(const char *other) { return append(QLatin1String(other)); }
ProString &append(QChar 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 ProString &other) { return append(other); }
ProString &operator+=(const QString &other) { return append(other); } ProString &operator+=(const QString &other) { return append(other); }
template<typename A, typename B> 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 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(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; } 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); } qlonglong toLongLong(bool *ok = nullptr, int base = 10) const { return toStringView().toLongLong(ok, base); }
int toInt(bool *ok = 0, int base = 10) const { return toStringView().toInt(ok, base); } int toInt(bool *ok = nullptr, int base = 10) const { return toStringView().toInt(ok, base); }
short toShort(bool *ok = 0, int base = 10) const { return toStringView().toShort(ok, base); } short toShort(bool *ok = nullptr, int base = 10) const { return toStringView().toShort(ok, base); }
uint hash() const { return m_hash; } uint hash() const { return m_hash; }
static uint hash(const QChar *p, int n); static uint hash(const QChar *p, int n);
@@ -185,7 +186,8 @@ private:
friend QString operator+(const ProString &one, const ProString &two); friend QString operator+(const ProString &one, const ProString &two);
friend class ProKey; friend class ProKey;
}; };
Q_DECLARE_TYPEINFO(ProString, Q_MOVABLE_TYPE); Q_DECLARE_TYPEINFO(ProString, Q_RELOCATABLE_TYPE);
class ProKey : public ProString { class ProKey : public ProString {
public: public:
@@ -195,7 +197,6 @@ public:
ProKey(const QStringBuilder<A, B> &str) ProKey(const QStringBuilder<A, B> &str)
: ProString(str) : ProString(str)
{} {}
PROITEM_EXPLICIT ProKey(const char *str); PROITEM_EXPLICIT ProKey(const char *str);
ProKey(const QString &str, int off, int len); ProKey(const QString &str, int off, int len);
ProKey(const QString &str, int off, int len, uint hash); ProKey(const QString &str, int off, int len, uint hash);
@@ -217,7 +218,7 @@ public:
private: private:
ProKey(const ProString &other); ProKey(const ProString &other);
}; };
Q_DECLARE_TYPEINFO(ProKey, Q_MOVABLE_TYPE); Q_DECLARE_TYPEINFO(ProKey, Q_RELOCATABLE_TYPE);
template <> struct QConcatenable<ProString> : private QAbstractConcatenable 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) static inline void appendTo(const ProString &a, QChar *&out)
{ {
const auto n = a.size(); const auto n = a.size();
if (!n)
return;
memcpy(out, a.toStringView().data(), sizeof(QChar) * n); memcpy(out, a.toStringView().data(), sizeof(QChar) * n);
out += n; out += n;
} }
@@ -242,6 +245,8 @@ template <> struct QConcatenable<ProKey> : private QAbstractConcatenable
static inline void appendTo(const ProKey &a, QChar *&out) static inline void appendTo(const ProKey &a, QChar *&out)
{ {
const auto n = a.size(); const auto n = a.size();
if (!n)
return;
memcpy(out, a.toStringView().data(), sizeof(QChar) * n); memcpy(out, a.toStringView().data(), sizeof(QChar) * n);
out += n; out += n;
} }
@@ -257,6 +262,54 @@ QTextStream &operator<<(QTextStream &t, const ProString &str);
template<typename A, typename B> template<typename A, typename B>
QTextStream &operator<<(QTextStream &t, const QStringBuilder<A, B> &str) { return t << QString(str); } 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> { class ProStringList : public QVector<ProString> {
public: public:
ProStringList() {} ProStringList() {}
@@ -290,21 +343,12 @@ public:
{ return contains(ProString(str), cs); } { return contains(ProString(str), cs); }
bool contains(const char *str, Qt::CaseSensitivity cs = Qt::CaseSensitive) const; 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) inline ProStringList operator+(const ProStringList &one, const ProStringList &two)
{ ProStringList ret = one; ret += two; return ret; } { ProStringList ret = one; ret += two; return ret; }
typedef QHash<ProKey, ProStringList> ProValueMap; typedef QMap<ProKey, ProStringList> ProValueMap;
// For std::list (sic!)
#ifdef Q_CC_MSVC
inline bool operator<(const ProValueMap &, const ProValueMap &)
{
Q_ASSERT(false);
return false;
}
#endif
// These token definitions affect both ProFileEvaluator and ProWriter // These token definitions affect both ProFileEvaluator and ProWriter
enum ProToken { enum ProToken {
@@ -419,7 +463,7 @@ class ProFunctionDef {
public: public:
ProFunctionDef(ProFile *pro, int offset) : m_pro(pro), m_offset(offset) { m_pro->ref(); } 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(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; } : m_pro(other.m_pro), m_offset(other.m_offset) { other.m_pro = nullptr; }
~ProFunctionDef() { if (m_pro) m_pro->deref(); } ~ProFunctionDef() { if (m_pro) m_pro->deref(); }
ProFunctionDef &operator=(const ProFunctionDef &o) ProFunctionDef &operator=(const ProFunctionDef &o)
@@ -433,13 +477,13 @@ public:
} }
return *this; return *this;
} }
ProFunctionDef &operator=(ProFunctionDef &&other) Q_DECL_NOTHROW ProFunctionDef &operator=(ProFunctionDef &&other) noexcept
{ {
ProFunctionDef moved(std::move(other)); ProFunctionDef moved(std::move(other));
swap(moved); swap(moved);
return *this; return *this;
} }
void swap(ProFunctionDef &other) Q_DECL_NOTHROW void swap(ProFunctionDef &other) noexcept
{ {
qSwap(m_pro, other.m_pro); qSwap(m_pro, other.m_pro);
qSwap(m_offset, other.m_offset); qSwap(m_offset, other.m_offset);
@@ -452,11 +496,13 @@ private:
int m_offset; int m_offset;
}; };
Q_DECLARE_TYPEINFO(ProFunctionDef, Q_MOVABLE_TYPE); Q_DECLARE_TYPEINFO(ProFunctionDef, Q_RELOCATABLE_TYPE);
struct ProFunctionDefs { struct ProFunctionDefs {
QHash<ProKey, ProFunctionDef> testFunctions; QHash<ProKey, ProFunctionDef> testFunctions;
QHash<ProKey, ProFunctionDef> replaceFunctions; QHash<ProKey, ProFunctionDef> replaceFunctions;
}; };
QDebug operator<<(QDebug debug, const ProString &str);
QT_END_NAMESPACE QT_END_NAMESPACE