summaryrefslogtreecommitdiffstats
path: root/src/corelib/kernel
diff options
context:
space:
mode:
authorLeander Beernaert <leander.beernaert@qt.io>2020-01-22 13:47:08 +0100
committerLeander Beernaert <leander.beernaert@qt.io>2020-01-24 13:17:33 +0100
commit502d3d6744913899da87acfda5ebdab42c40329e (patch)
tree16658a328503bfd5a62b4fd5d69ffb66e9854b18 /src/corelib/kernel
parentd1be8b9ceb2c7b20bbe53a07154c79699540ea3d (diff)
parent06bb315beb6c2c398223cfe52cbc7f66e14a8557 (diff)
Merge remote-tracking branch 'origin/dev' into merge-dev
Diffstat (limited to 'src/corelib/kernel')
-rw-r--r--src/corelib/kernel/qbasictimer.cpp10
-rw-r--r--src/corelib/kernel/qcoreapplication.cpp157
-rw-r--r--src/corelib/kernel/qcoreapplication_p.h10
-rw-r--r--src/corelib/kernel/qcoreapplication_win.cpp2
-rw-r--r--src/corelib/kernel/qcoreevent.cpp2
-rw-r--r--src/corelib/kernel/qdeadlinetimer.h4
-rw-r--r--src/corelib/kernel/qeventdispatcher_glib.cpp40
-rw-r--r--src/corelib/kernel/qeventdispatcher_unix.cpp6
-rw-r--r--src/corelib/kernel/qeventdispatcher_unix_p.h2
-rw-r--r--src/corelib/kernel/qeventdispatcher_win.cpp38
-rw-r--r--src/corelib/kernel/qeventloop.cpp43
-rw-r--r--src/corelib/kernel/qmetaobject.cpp116
-rw-r--r--src/corelib/kernel/qmetaobjectbuilder.cpp54
-rw-r--r--src/corelib/kernel/qmetatype.cpp54
-rw-r--r--src/corelib/kernel/qmetatype.h26
-rw-r--r--src/corelib/kernel/qmimedata.cpp2
-rw-r--r--src/corelib/kernel/qobject.cpp253
-rw-r--r--src/corelib/kernel/qobject.h10
-rw-r--r--src/corelib/kernel/qobject_p.h8
-rw-r--r--src/corelib/kernel/qobjectcleanuphandler.cpp2
-rw-r--r--src/corelib/kernel/qobjectdefs.h188
-rw-r--r--src/corelib/kernel/qsharedmemory.cpp2
-rw-r--r--src/corelib/kernel/qsharedmemory_systemv.cpp6
-rw-r--r--src/corelib/kernel/qsharedmemory_unix.cpp2
-rw-r--r--src/corelib/kernel/qsocketnotifier.cpp15
-rw-r--r--src/corelib/kernel/qtestsupport_core.cpp2
-rw-r--r--src/corelib/kernel/qtimer.cpp14
-rw-r--r--src/corelib/kernel/qtimer.h6
-rw-r--r--src/corelib/kernel/qtimerinfo_unix.cpp20
-rw-r--r--src/corelib/kernel/qtmetamacros.h234
-rw-r--r--src/corelib/kernel/qtranslator.cpp38
-rw-r--r--src/corelib/kernel/qvariant.cpp166
-rw-r--r--src/corelib/kernel/qvariant.h38
-rw-r--r--src/corelib/kernel/qvariant_p.h5
-rw-r--r--src/corelib/kernel/qwineventnotifier.cpp6
35 files changed, 791 insertions, 790 deletions
diff --git a/src/corelib/kernel/qbasictimer.cpp b/src/corelib/kernel/qbasictimer.cpp
index ea8f8e2c77..623ecb9b8b 100644
--- a/src/corelib/kernel/qbasictimer.cpp
+++ b/src/corelib/kernel/qbasictimer.cpp
@@ -216,13 +216,11 @@ void QBasicTimer::stop()
{
if (id) {
QAbstractEventDispatcher *eventDispatcher = QAbstractEventDispatcher::instance();
- if (eventDispatcher) {
- if (Q_UNLIKELY(!eventDispatcher->unregisterTimer(id))) {
- qWarning("QBasicTimer::stop: Failed. Possibly trying to stop from a different thread");
- return;
- }
- QAbstractEventDispatcherPrivate::releaseTimerId(id);
+ if (eventDispatcher && !eventDispatcher->unregisterTimer(id)) {
+ qWarning("QBasicTimer::stop: Failed. Possibly trying to stop from a different thread");
+ return;
}
+ QAbstractEventDispatcherPrivate::releaseTimerId(id);
}
id = 0;
}
diff --git a/src/corelib/kernel/qcoreapplication.cpp b/src/corelib/kernel/qcoreapplication.cpp
index 6531cd8e0c..dc46695f80 100644
--- a/src/corelib/kernel/qcoreapplication.cpp
+++ b/src/corelib/kernel/qcoreapplication.cpp
@@ -121,7 +121,6 @@
#endif
#ifdef Q_OS_WASM
-#include <emscripten.h>
#include <emscripten/val.h>
#endif
@@ -135,23 +134,6 @@
QT_BEGIN_NAMESPACE
-#ifndef QT_NO_QOBJECT
-class QMutexUnlocker
-{
-public:
- inline explicit QMutexUnlocker(QMutex *m)
- : mtx(m)
- { }
- inline ~QMutexUnlocker() { unlock(); }
- inline void unlock() { if (mtx) mtx->unlock(); mtx = 0; }
-
-private:
- Q_DISABLE_COPY(QMutexUnlocker)
-
- QMutex *mtx;
-};
-#endif
-
#if defined(Q_OS_WIN) || defined(Q_OS_MAC)
extern QString qAppFileName();
#endif
@@ -497,13 +479,6 @@ QCoreApplicationPrivate::QCoreApplicationPrivate(int &aargc, char **aargv, uint
QCoreApplicationPrivate::~QCoreApplicationPrivate()
{
-#ifdef Q_OS_WASM
- EM_ASM(
- // unmount persistent directory as IDBFS
- // see also QTBUG-70002
- FS.unmount('/home/web_user');
- );
-#endif
#ifndef QT_NO_QOBJECT
cleanupThreadData();
#endif
@@ -517,25 +492,27 @@ QCoreApplicationPrivate::~QCoreApplicationPrivate()
void QCoreApplicationPrivate::cleanupThreadData()
{
- if (threadData && !threadData_clean) {
+ auto thisThreadData = threadData.loadRelaxed();
+
+ if (thisThreadData && !threadData_clean) {
#if QT_CONFIG(thread)
- void *data = &threadData->tls;
+ void *data = &thisThreadData->tls;
QThreadStorageData::finish((void **)data);
#endif
// need to clear the state of the mainData, just in case a new QCoreApplication comes along.
- const auto locker = qt_scoped_lock(threadData->postEventList.mutex);
- for (int i = 0; i < threadData->postEventList.size(); ++i) {
- const QPostEvent &pe = threadData->postEventList.at(i);
+ const auto locker = qt_scoped_lock(thisThreadData->postEventList.mutex);
+ for (int i = 0; i < thisThreadData->postEventList.size(); ++i) {
+ const QPostEvent &pe = thisThreadData->postEventList.at(i);
if (pe.event) {
--pe.receiver->d_func()->postedEvents;
pe.event->posted = false;
delete pe.event;
}
}
- threadData->postEventList.clear();
- threadData->postEventList.recursion = 0;
- threadData->quitNow = false;
+ thisThreadData->postEventList.clear();
+ thisThreadData->postEventList.recursion = 0;
+ thisThreadData->quitNow = false;
threadData_clean = true;
}
}
@@ -553,10 +530,10 @@ void QCoreApplicationPrivate::eventDispatcherReady()
{
}
-QBasicAtomicPointer<QThread> QCoreApplicationPrivate::theMainThread = Q_BASIC_ATOMIC_INITIALIZER(0);
+QBasicAtomicPointer<QThread> QCoreApplicationPrivate::theMainThread = Q_BASIC_ATOMIC_INITIALIZER(nullptr);
QThread *QCoreApplicationPrivate::mainThread()
{
- Q_ASSERT(theMainThread.loadRelaxed() != 0);
+ Q_ASSERT(theMainThread.loadRelaxed() != nullptr);
return theMainThread.loadRelaxed();
}
@@ -713,7 +690,7 @@ QCoreApplication::QCoreApplication(QCoreApplicationPrivate &p)
#ifdef QT_NO_QOBJECT
: d_ptr(&p)
#else
- : QObject(p, 0)
+ : QObject(p, nullptr)
#endif
{
d_func()->q_ptr = this;
@@ -795,17 +772,8 @@ void QCoreApplicationPrivate::init()
Q_ASSERT_X(!QCoreApplication::self, "QCoreApplication", "there should be only one application object");
QCoreApplication::self = q;
-#ifdef Q_OS_WASM
- EM_ASM(
- // mount and sync persistent filesystem to sandbox
- FS.mount(IDBFS, {}, '/home/web_user');
- FS.syncfs(true, function(err) {
- if (err)
- Module.print(err);
- });
- );
-
#if QT_CONFIG(thread)
+#ifdef Q_OS_WASM
QThreadPrivate::idealThreadCount = emscripten::val::global("navigator")["hardwareConcurrency"].as<int>();
#endif
#endif
@@ -858,7 +826,8 @@ void QCoreApplicationPrivate::init()
#ifndef QT_NO_QOBJECT
// use the event dispatcher created by the app programmer (if any)
Q_ASSERT(!eventDispatcher);
- eventDispatcher = threadData->eventDispatcher.loadRelaxed();
+ auto thisThreadData = threadData.loadRelaxed();
+ eventDispatcher = thisThreadData->eventDispatcher.loadRelaxed();
// otherwise we create one
if (!eventDispatcher)
@@ -866,11 +835,11 @@ void QCoreApplicationPrivate::init()
Q_ASSERT(eventDispatcher);
if (!eventDispatcher->parent()) {
- eventDispatcher->moveToThread(threadData->thread.loadAcquire());
+ eventDispatcher->moveToThread(thisThreadData->thread.loadAcquire());
eventDispatcher->setParent(q);
}
- threadData->eventDispatcher = eventDispatcher;
+ thisThreadData->eventDispatcher = eventDispatcher;
eventDispatcherReady();
#endif
@@ -914,7 +883,7 @@ QCoreApplication::~QCoreApplication()
#endif
#ifndef QT_NO_QOBJECT
- d_func()->threadData->eventDispatcher = nullptr;
+ d_func()->threadData.loadRelaxed()->eventDispatcher = nullptr;
if (QCoreApplicationPrivate::eventDispatcher)
QCoreApplicationPrivate::eventDispatcher->closingDown();
QCoreApplicationPrivate::eventDispatcher = nullptr;
@@ -1170,7 +1139,7 @@ bool QCoreApplication::notify(QObject *receiver, QEvent *event)
static bool doNotify(QObject *receiver, QEvent *event)
{
- if (receiver == 0) { // serious error
+ if (receiver == nullptr) { // serious error
qWarning("QCoreApplication::notify: Unexpected null receiver");
return true;
}
@@ -1185,7 +1154,7 @@ static bool doNotify(QObject *receiver, QEvent *event)
bool QCoreApplicationPrivate::sendThroughApplicationEventFilters(QObject *receiver, QEvent *event)
{
// We can't access the application event filters outside of the main thread (race conditions)
- Q_ASSERT(receiver->d_func()->threadData->thread.loadAcquire() == mainThread());
+ Q_ASSERT(receiver->d_func()->threadData.loadRelaxed()->thread.loadAcquire() == mainThread());
if (extraData) {
// application event filters are only called for objects in the GUI thread
@@ -1238,7 +1207,7 @@ bool QCoreApplicationPrivate::notify_helper(QObject *receiver, QEvent * event)
// send to all application event filters (only does anything in the main thread)
if (QCoreApplication::self
- && receiver->d_func()->threadData->thread.loadAcquire() == mainThread()
+ && receiver->d_func()->threadData.loadRelaxed()->thread.loadAcquire() == mainThread()
&& QCoreApplication::self->d_func()->sendThroughApplicationEventFilters(receiver, event)) {
filtered = true;
return filtered;
@@ -1414,12 +1383,12 @@ int QCoreApplication::exec()
void QCoreApplicationPrivate::execCleanup()
{
- threadData->quitNow = false;
+ threadData.loadRelaxed()->quitNow = false;
in_exec = false;
if (!aboutToQuitEmitted)
emit q_func()->aboutToQuit(QCoreApplication::QPrivateSignal());
aboutToQuitEmitted = true;
- QCoreApplication::sendPostedEvents(0, QEvent::DeferredDelete);
+ QCoreApplication::sendPostedEvents(nullptr, QEvent::DeferredDelete);
}
@@ -1451,7 +1420,7 @@ void QCoreApplication::exit(int returnCode)
{
if (!self)
return;
- QThreadData *data = self->d_func()->threadData;
+ QThreadData *data = self->d_func()->threadData.loadRelaxed();
data->quitNow = true;
for (int i = 0; i < data->eventLoops.size(); ++i) {
QEventLoop *eventLoop = data->eventLoops.at(i);
@@ -1501,6 +1470,38 @@ bool QCoreApplication::sendSpontaneousEvent(QObject *receiver, QEvent *event)
#endif // QT_NO_QOBJECT
+QCoreApplicationPrivate::QPostEventListLocker QCoreApplicationPrivate::lockThreadPostEventList(QObject *object)
+{
+ QPostEventListLocker locker;
+
+ if (!object) {
+ locker.threadData = QThreadData::current();
+ locker.locker = qt_unique_lock(locker.threadData->postEventList.mutex);
+ return locker;
+ }
+
+ auto &threadData = QObjectPrivate::get(object)->threadData;
+
+ // if object has moved to another thread, follow it
+ for (;;) {
+ // synchronizes with the storeRelease in QObject::moveToThread
+ locker.threadData = threadData.loadAcquire();
+ if (!locker.threadData) {
+ // destruction in progress
+ return locker;
+ }
+
+ auto temporaryLocker = qt_unique_lock(locker.threadData->postEventList.mutex);
+ if (locker.threadData == threadData.loadAcquire()) {
+ locker.locker = std::move(temporaryLocker);
+ break;
+ }
+ }
+
+ Q_ASSERT(locker.threadData);
+ return locker;
+}
+
/*!
\since 4.3
@@ -1530,38 +1531,20 @@ void QCoreApplication::postEvent(QObject *receiver, QEvent *event, int priority)
{
Q_TRACE_SCOPE(QCoreApplication_postEvent, receiver, event, event->type());
- if (receiver == 0) {
+ if (receiver == nullptr) {
qWarning("QCoreApplication::postEvent: Unexpected null receiver");
delete event;
return;
}
- QThreadData * volatile * pdata = &receiver->d_func()->threadData;
- QThreadData *data = *pdata;
- if (!data) {
+ auto locker = QCoreApplicationPrivate::lockThreadPostEventList(receiver);
+ if (!locker.threadData) {
// posting during destruction? just delete the event to prevent a leak
delete event;
return;
}
- // lock the post event mutex
- data->postEventList.mutex.lock();
-
- // if object has moved to another thread, follow it
- while (data != *pdata) {
- data->postEventList.mutex.unlock();
-
- data = *pdata;
- if (!data) {
- // posting during destruction? just delete the event to prevent a leak
- delete event;
- return;
- }
-
- data->postEventList.mutex.lock();
- }
-
- QMutexUnlocker locker(&data->postEventList.mutex);
+ QThreadData *data = locker.threadData;
// if this is one of the compressible events, do compression
if (receiver->d_func()->postedEvents
@@ -1652,7 +1635,7 @@ bool QCoreApplication::compressEvent(QEvent *event, QObject *receiver, QPostEven
for (int i = 0; i < postedEvents->size(); ++i) {
const QPostEvent &cur = postedEvents->at(i);
if (cur.receiver != receiver
- || cur.event == 0
+ || cur.event == nullptr
|| cur.event->type() != event->type())
continue;
// found an event for this receiver
@@ -1801,7 +1784,7 @@ void QCoreApplicationPrivate::sendPostedEvents(QObject *receiver, int event_type
// null out the event so if sendPostedEvents recurses, it
// will ignore this one, as it's been re-posted.
- const_cast<QPostEvent &>(pe).event = 0;
+ const_cast<QPostEvent &>(pe).event = nullptr;
// re-post the copied event so it isn't lost
data->postEventList.addEvent(pe_copy);
@@ -1821,7 +1804,7 @@ void QCoreApplicationPrivate::sendPostedEvents(QObject *receiver, int event_type
// next, update the data structure so that we're ready
// for the next event.
- const_cast<QPostEvent &>(pe).event = 0;
+ const_cast<QPostEvent &>(pe).event = nullptr;
locker.unlock();
const auto relocker = qScopeGuard([&locker] { locker.lock(); });
@@ -1860,8 +1843,8 @@ void QCoreApplicationPrivate::sendPostedEvents(QObject *receiver, int event_type
void QCoreApplication::removePostedEvents(QObject *receiver, int eventType)
{
- QThreadData *data = receiver ? receiver->d_func()->threadData : QThreadData::current();
- auto locker = qt_unique_lock(data->postEventList.mutex);
+ auto locker = QCoreApplicationPrivate::lockThreadPostEventList(receiver);
+ QThreadData *data = locker.threadData;
// the QObject destructor calls this function directly. this can
// happen while the event loop is in the middle of posting events,
@@ -1884,7 +1867,7 @@ void QCoreApplication::removePostedEvents(QObject *receiver, int eventType)
--pe.receiver->d_func()->postedEvents;
pe.event->posted = false;
events.append(pe.event);
- const_cast<QPostEvent &>(pe).event = 0;
+ const_cast<QPostEvent &>(pe).event = nullptr;
} else if (!data->postEventList.recursion) {
if (i != j)
qSwap(data->postEventList[i], data->postEventList[j]);
@@ -1946,7 +1929,7 @@ void QCoreApplicationPrivate::removePostedEvent(QEvent * event)
--pe.receiver->d_func()->postedEvents;
pe.event->posted = false;
delete pe.event;
- const_cast<QPostEvent &>(pe).event = 0;
+ const_cast<QPostEvent &>(pe).event = nullptr;
return;
}
}
@@ -2221,7 +2204,7 @@ QString QCoreApplication::translate(const char *context, const char *sourceText,
// Declared in qglobal.h
QString qtTrId(const char *id, int n)
{
- return QCoreApplication::translate(0, id, 0, n);
+ return QCoreApplication::translate(nullptr, id, nullptr, n);
}
bool QCoreApplicationPrivate::isTranslatorInstalled(QTranslator *translator)
@@ -2973,7 +2956,7 @@ QAbstractEventDispatcher *QCoreApplication::eventDispatcher()
{
if (QCoreApplicationPrivate::theMainThread.loadAcquire())
return QCoreApplicationPrivate::theMainThread.loadRelaxed()->eventDispatcher();
- return 0;
+ return nullptr;
}
/*!
diff --git a/src/corelib/kernel/qcoreapplication_p.h b/src/corelib/kernel/qcoreapplication_p.h
index 3bad42d076..9d2fde619c 100644
--- a/src/corelib/kernel/qcoreapplication_p.h
+++ b/src/corelib/kernel/qcoreapplication_p.h
@@ -61,6 +61,7 @@
#endif
#ifndef QT_NO_QOBJECT
#include "private/qobject_p.h"
+#include "private/qlocking_p.h"
#endif
#ifdef Q_OS_MACOS
@@ -140,6 +141,15 @@ public:
static void checkReceiverThread(QObject *receiver);
void cleanupThreadData();
+
+ struct QPostEventListLocker
+ {
+ QThreadData *threadData;
+ std::unique_lock<QMutex> locker;
+
+ void unlock() { locker.unlock(); }
+ };
+ static QPostEventListLocker lockThreadPostEventList(QObject *object);
#endif // QT_NO_QOBJECT
int &argc;
diff --git a/src/corelib/kernel/qcoreapplication_win.cpp b/src/corelib/kernel/qcoreapplication_win.cpp
index 37c43dee4f..824c0535ed 100644
--- a/src/corelib/kernel/qcoreapplication_win.cpp
+++ b/src/corelib/kernel/qcoreapplication_win.cpp
@@ -918,7 +918,7 @@ QDebug operator<<(QDebug dbg, const MSG &msg)
#ifndef QT_NO_QOBJECT
void QCoreApplicationPrivate::removePostedTimerEvent(QObject *object, int timerId)
{
- QThreadData *data = object->d_func()->threadData;
+ QThreadData *data = object->d_func()->threadData.loadRelaxed();
const auto locker = qt_scoped_lock(data->postEventList.mutex);
if (data->postEventList.size() == 0)
diff --git a/src/corelib/kernel/qcoreevent.cpp b/src/corelib/kernel/qcoreevent.cpp
index 4cfc749386..e3326f00d7 100644
--- a/src/corelib/kernel/qcoreevent.cpp
+++ b/src/corelib/kernel/qcoreevent.cpp
@@ -295,7 +295,7 @@ QT_BEGIN_NAMESPACE
Contructs an event object of type \a type.
*/
QEvent::QEvent(Type type)
- : d(0), t(type), posted(false), spont(false), m_accept(true)
+ : d(nullptr), t(type), posted(false), spont(false), m_accept(true)
{
Q_TRACE(QEvent_ctor, this, t);
}
diff --git a/src/corelib/kernel/qdeadlinetimer.h b/src/corelib/kernel/qdeadlinetimer.h
index 9dd92481d2..99e09eb31f 100644
--- a/src/corelib/kernel/qdeadlinetimer.h
+++ b/src/corelib/kernel/qdeadlinetimer.h
@@ -52,7 +52,7 @@
#include <limits>
-#if QT_HAS_INCLUDE(<chrono>)
+#if __has_include(<chrono>)
# include <chrono>
#endif
@@ -120,7 +120,7 @@ public:
QDeadlineTimer &operator-=(qint64 msecs)
{ *this = *this + (-msecs); return *this; }
-#if QT_HAS_INCLUDE(<chrono>) || defined(Q_CLANG_QDOC)
+#if __has_include(<chrono>) || defined(Q_CLANG_QDOC)
template <class Clock, class Duration>
QDeadlineTimer(std::chrono::time_point<Clock, Duration> deadline_,
Qt::TimerType type_ = Qt::CoarseTimer) : t2(0)
diff --git a/src/corelib/kernel/qeventdispatcher_glib.cpp b/src/corelib/kernel/qeventdispatcher_glib.cpp
index d9746ef6e2..92f3553247 100644
--- a/src/corelib/kernel/qeventdispatcher_glib.cpp
+++ b/src/corelib/kernel/qeventdispatcher_glib.cpp
@@ -114,9 +114,9 @@ static GSourceFuncs socketNotifierSourceFuncs = {
socketNotifierSourcePrepare,
socketNotifierSourceCheck,
socketNotifierSourceDispatch,
- NULL,
- NULL,
- NULL
+ nullptr,
+ nullptr,
+ nullptr
};
struct GTimerSource
@@ -188,9 +188,9 @@ static GSourceFuncs timerSourceFuncs = {
timerSourcePrepare,
timerSourceCheck,
timerSourceDispatch,
- NULL,
- NULL,
- NULL
+ nullptr,
+ nullptr,
+ nullptr
};
struct GIdleTimerSource
@@ -227,7 +227,7 @@ static gboolean idleTimerSourceCheck(GSource *source)
static gboolean idleTimerSourceDispatch(GSource *source, GSourceFunc, gpointer)
{
GTimerSource *timerSource = reinterpret_cast<GIdleTimerSource *>(source)->timerSource;
- (void) timerSourceDispatch(&timerSource->source, 0, 0);
+ (void) timerSourceDispatch(&timerSource->source, nullptr, nullptr);
return true;
}
@@ -235,9 +235,9 @@ static GSourceFuncs idleTimerSourceFuncs = {
idleTimerSourcePrepare,
idleTimerSourceCheck,
idleTimerSourceDispatch,
- NULL,
- NULL,
- NULL
+ nullptr,
+ nullptr,
+ nullptr
};
struct GPostEventSource
@@ -267,7 +267,7 @@ static gboolean postEventSourcePrepare(GSource *s, gint *timeout)
static gboolean postEventSourceCheck(GSource *source)
{
- return postEventSourcePrepare(source, 0);
+ return postEventSourcePrepare(source, nullptr);
}
static gboolean postEventSourceDispatch(GSource *s, GSourceFunc, gpointer)
@@ -283,9 +283,9 @@ static GSourceFuncs postEventSourceFuncs = {
postEventSourcePrepare,
postEventSourceCheck,
postEventSourceDispatch,
- NULL,
- NULL,
- NULL
+ nullptr,
+ nullptr,
+ nullptr
};
@@ -372,10 +372,10 @@ QEventDispatcherGlib::~QEventDispatcherGlib()
d->timerSource->timerList.~QTimerInfoList();
g_source_destroy(&d->timerSource->source);
g_source_unref(&d->timerSource->source);
- d->timerSource = 0;
+ d->timerSource = nullptr;
g_source_destroy(&d->idleTimerSource->source);
g_source_unref(&d->idleTimerSource->source);
- d->idleTimerSource = 0;
+ d->idleTimerSource = nullptr;
// destroy socket notifier source
for (int i = 0; i < d->socketNotifierSource->pollfds.count(); ++i) {
@@ -386,19 +386,19 @@ QEventDispatcherGlib::~QEventDispatcherGlib()
d->socketNotifierSource->pollfds.~QList<GPollFDWithQSocketNotifier *>();
g_source_destroy(&d->socketNotifierSource->source);
g_source_unref(&d->socketNotifierSource->source);
- d->socketNotifierSource = 0;
+ d->socketNotifierSource = nullptr;
// destroy post event source
g_source_destroy(&d->postEventSource->source);
g_source_unref(&d->postEventSource->source);
- d->postEventSource = 0;
+ d->postEventSource = nullptr;
- Q_ASSERT(d->mainContext != 0);
+ Q_ASSERT(d->mainContext != nullptr);
#if GLIB_CHECK_VERSION (2, 22, 0)
g_main_context_pop_thread_default (d->mainContext);
#endif
g_main_context_unref(d->mainContext);
- d->mainContext = 0;
+ d->mainContext = nullptr;
}
bool QEventDispatcherGlib::processEvents(QEventLoop::ProcessEventsFlags flags)
diff --git a/src/corelib/kernel/qeventdispatcher_unix.cpp b/src/corelib/kernel/qeventdispatcher_unix.cpp
index 5bc65b7110..0165ce9075 100644
--- a/src/corelib/kernel/qeventdispatcher_unix.cpp
+++ b/src/corelib/kernel/qeventdispatcher_unix.cpp
@@ -463,13 +463,15 @@ bool QEventDispatcherUNIX::processEvents(QEventLoop::ProcessEventsFlags flags)
// we are awake, broadcast it
emit awake();
- QCoreApplicationPrivate::sendPostedEvents(0, 0, d->threadData);
+
+ auto threadData = d->threadData.loadRelaxed();
+ QCoreApplicationPrivate::sendPostedEvents(nullptr, 0, threadData);
const bool include_timers = (flags & QEventLoop::X11ExcludeTimers) == 0;
const bool include_notifiers = (flags & QEventLoop::ExcludeSocketNotifiers) == 0;
const bool wait_for_events = flags & QEventLoop::WaitForMoreEvents;
- const bool canWait = (d->threadData->canWaitLocked()
+ const bool canWait = (threadData->canWaitLocked()
&& !d->interrupt.loadRelaxed()
&& wait_for_events);
diff --git a/src/corelib/kernel/qeventdispatcher_unix_p.h b/src/corelib/kernel/qeventdispatcher_unix_p.h
index f37edfc967..581df9242c 100644
--- a/src/corelib/kernel/qeventdispatcher_unix_p.h
+++ b/src/corelib/kernel/qeventdispatcher_unix_p.h
@@ -118,7 +118,7 @@ public:
int remainingTime(int timerId) final;
- void wakeUp() final;
+ void wakeUp() override;
void interrupt() final;
void flush() override;
diff --git a/src/corelib/kernel/qeventdispatcher_win.cpp b/src/corelib/kernel/qeventdispatcher_win.cpp
index 87623f304a..8616631603 100644
--- a/src/corelib/kernel/qeventdispatcher_win.cpp
+++ b/src/corelib/kernel/qeventdispatcher_win.cpp
@@ -636,11 +636,11 @@ void QEventDispatcherWin32::registerSocketNotifier(QSocketNotifier *notifier)
int type = notifier->type();
#ifndef QT_NO_DEBUG
if (sockfd < 0) {
- qWarning("QSocketNotifier: Internal error");
+ qWarning("QEventDispatcherWin32::registerSocketNotifier: invalid socket identifier");
return;
}
if (notifier->thread() != thread() || thread() != QThread::currentThread()) {
- qWarning("QSocketNotifier: socket notifiers cannot be enabled from another thread");
+ qWarning("QEventDispatcherWin32: socket notifiers cannot be enabled from another thread");
return;
}
#endif
@@ -697,11 +697,11 @@ void QEventDispatcherWin32::unregisterSocketNotifier(QSocketNotifier *notifier)
#ifndef QT_NO_DEBUG
int sockfd = notifier->socket();
if (sockfd < 0) {
- qWarning("QSocketNotifier: Internal error");
+ qWarning("QEventDispatcherWin32::unregisterSocketNotifier: invalid socket identifier");
return;
}
if (notifier->thread() != thread() || thread() != QThread::currentThread()) {
- qWarning("QSocketNotifier: socket notifiers cannot be disabled from another thread");
+ qWarning("QEventDispatcherWin32: socket notifiers cannot be disabled from another thread");
return;
}
#endif
@@ -783,8 +783,7 @@ bool QEventDispatcherWin32::unregisterTimer(int timerId)
qWarning("QEventDispatcherWin32::unregisterTimer: invalid argument");
return false;
}
- QThread *currentThread = QThread::currentThread();
- if (thread() != currentThread) {
+ if (thread() != QThread::currentThread()) {
qWarning("QEventDispatcherWin32::unregisterTimer: timers cannot be stopped from another thread");
return false;
}
@@ -811,8 +810,7 @@ bool QEventDispatcherWin32::unregisterTimers(QObject *object)
qWarning("QEventDispatcherWin32::unregisterTimers: invalid argument");
return false;
}
- QThread *currentThread = QThread::currentThread();
- if (object->thread() != thread() || thread() != currentThread) {
+ if (object->thread() != thread() || thread() != QThread::currentThread()) {
qWarning("QEventDispatcherWin32::unregisterTimers: timers cannot be stopped from another thread");
return false;
}
@@ -837,10 +835,12 @@ bool QEventDispatcherWin32::unregisterTimers(QObject *object)
QList<QEventDispatcherWin32::TimerInfo>
QEventDispatcherWin32::registeredTimers(QObject *object) const
{
+#ifndef QT_NO_DEBUG
if (!object) {
qWarning("QEventDispatcherWin32:registeredTimers: invalid argument");
return QList<TimerInfo>();
}
+#endif
Q_D(const QEventDispatcherWin32);
QList<TimerInfo> list;
@@ -853,13 +853,13 @@ QEventDispatcherWin32::registeredTimers(QObject *object) const
bool QEventDispatcherWin32::registerEventNotifier(QWinEventNotifier *notifier)
{
- if (!notifier) {
- qWarning("QWinEventNotifier: Internal error");
- return false;
- } else if (notifier->thread() != thread() || thread() != QThread::currentThread()) {
- qWarning("QWinEventNotifier: event notifiers cannot be enabled from another thread");
+ Q_ASSERT(notifier);
+#ifndef QT_NO_DEBUG
+ if (notifier->thread() != thread() || thread() != QThread::currentThread()) {
+ qWarning("QEventDispatcherWin32: event notifiers cannot be enabled from another thread");
return false;
}
+#endif
Q_D(QEventDispatcherWin32);
@@ -877,13 +877,13 @@ bool QEventDispatcherWin32::registerEventNotifier(QWinEventNotifier *notifier)
void QEventDispatcherWin32::unregisterEventNotifier(QWinEventNotifier *notifier)
{
- if (!notifier) {
- qWarning("QWinEventNotifier: Internal error");
- return;
- } else if (notifier->thread() != thread() || thread() != QThread::currentThread()) {
- qWarning("QWinEventNotifier: event notifiers cannot be disabled from another thread");
+ Q_ASSERT(notifier);
+#ifndef QT_NO_DEBUG
+ if (notifier->thread() != thread() || thread() != QThread::currentThread()) {
+ qWarning("QEventDispatcherWin32: event notifiers cannot be disabled from another thread");
return;
}
+#endif
Q_D(QEventDispatcherWin32);
@@ -1048,7 +1048,7 @@ bool QEventDispatcherWin32::event(QEvent *e)
void QEventDispatcherWin32::sendPostedEvents()
{
Q_D(QEventDispatcherWin32);
- QCoreApplicationPrivate::sendPostedEvents(0, 0, d->threadData);
+ QCoreApplicationPrivate::sendPostedEvents(0, 0, d->threadData.loadRelaxed());
}
HWND QEventDispatcherWin32::internalHwnd()
diff --git a/src/corelib/kernel/qeventloop.cpp b/src/corelib/kernel/qeventloop.cpp
index eacd0c4e73..5a5dfb06aa 100644
--- a/src/corelib/kernel/qeventloop.cpp
+++ b/src/corelib/kernel/qeventloop.cpp
@@ -106,7 +106,7 @@ QEventLoop::QEventLoop(QObject *parent)
if (!QCoreApplication::instance() && QCoreApplicationPrivate::threadRequiresCoreApplication()) {
qWarning("QEventLoop: Cannot be used without QApplication");
} else {
- d->threadData->ensureEventDispatcher();
+ d->threadData.loadRelaxed()->ensureEventDispatcher();
}
}
@@ -133,9 +133,10 @@ QEventLoop::~QEventLoop()
bool QEventLoop::processEvents(ProcessEventsFlags flags)
{
Q_D(QEventLoop);
- if (!d->threadData->hasEventDispatcher())
+ auto threadData = d->threadData.loadRelaxed();
+ if (!threadData->hasEventDispatcher())
return false;
- return d->threadData->eventDispatcher.loadRelaxed()->processEvents(flags);
+ return threadData->eventDispatcher.loadRelaxed()->processEvents(flags);
}
/*!
@@ -164,9 +165,11 @@ bool QEventLoop::processEvents(ProcessEventsFlags flags)
int QEventLoop::exec(ProcessEventsFlags flags)
{
Q_D(QEventLoop);
+ auto threadData = d->threadData.loadRelaxed();
+
//we need to protect from race condition with QThread::exit
- QMutexLocker locker(&static_cast<QThreadPrivate *>(QObjectPrivate::get(d->threadData->thread.loadAcquire()))->mutex);
- if (d->threadData->quitNow)
+ QMutexLocker locker(&static_cast<QThreadPrivate *>(QObjectPrivate::get(threadData->thread.loadAcquire()))->mutex);
+ if (threadData->quitNow)
return -1;
if (d->inExec) {
@@ -183,8 +186,11 @@ int QEventLoop::exec(ProcessEventsFlags flags)
{
d->inExec = true;
d->exit.storeRelease(false);
- ++d->threadData->loopLevel;
- d->threadData->eventLoops.push(d->q_func());
+
+ auto threadData = d->threadData.loadRelaxed();
+ ++threadData->loopLevel;
+ threadData->eventLoops.push(d->q_func());
+
locker.unlock();
}
@@ -198,11 +204,12 @@ int QEventLoop::exec(ProcessEventsFlags flags)
"QCoreApplication::notify() and catch all exceptions there.\n");
}
locker.relock();
- QEventLoop *eventLoop = d->threadData->eventLoops.pop();
+ auto threadData = d->threadData.loadRelaxed();
+ QEventLoop *eventLoop = threadData->eventLoops.pop();
Q_ASSERT_X(eventLoop == d->q_func(), "QEventLoop::exec()", "internal error");
Q_UNUSED(eventLoop); // --release warning
d->inExec = false;
- --d->threadData->loopLevel;
+ --threadData->loopLevel;
}
};
LoopReference ref(d, locker);
@@ -217,7 +224,7 @@ int QEventLoop::exec(ProcessEventsFlags flags)
// exception, which returns control to the browser while preserving the C++ stack.
// Event processing then continues as normal. The sleep call below never returns.
// QTBUG-70185
- if (d->threadData->loopLevel > 1)
+ if (threadData->loopLevel > 1)
emscripten_sleep(1);
#endif
@@ -247,7 +254,7 @@ int QEventLoop::exec(ProcessEventsFlags flags)
void QEventLoop::processEvents(ProcessEventsFlags flags, int maxTime)
{
Q_D(QEventLoop);
- if (!d->threadData->hasEventDispatcher())
+ if (!d->threadData.loadRelaxed()->hasEventDispatcher())
return;
QElapsedTimer start;
@@ -276,21 +283,22 @@ void QEventLoop::processEvents(ProcessEventsFlags flags, int maxTime)
void QEventLoop::exit(int returnCode)
{
Q_D(QEventLoop);
- if (!d->threadData->hasEventDispatcher())
+ auto threadData = d->threadData.loadAcquire();
+ if (!threadData->hasEventDispatcher())
return;
d->returnCode.storeRelaxed(returnCode);
d->exit.storeRelease(true);
- d->threadData->eventDispatcher.loadRelaxed()->interrupt();
+ threadData->eventDispatcher.loadRelaxed()->interrupt();
#ifdef Q_OS_WASM
// QEventLoop::exec() never returns in emscripten. We implement approximate behavior here.
// QTBUG-70185
- if (d->threadData->loopLevel == 1) {
+ if (threadData->loopLevel == 1) {
emscripten_force_exit(returnCode);
} else {
d->inExec = false;
- --d->threadData->loopLevel;
+ --threadData->loopLevel;
}
#endif
}
@@ -316,9 +324,10 @@ bool QEventLoop::isRunning() const
void QEventLoop::wakeUp()
{
Q_D(QEventLoop);
- if (!d->threadData->hasEventDispatcher())
+ auto threadData = d->threadData.loadAcquire();
+ if (!threadData->hasEventDispatcher())
return;
- d->threadData->eventDispatcher.loadRelaxed()->wakeUp();
+ threadData->eventDispatcher.loadRelaxed()->wakeUp();
}
diff --git a/src/corelib/kernel/qmetaobject.cpp b/src/corelib/kernel/qmetaobject.cpp
index b1e1bb8b4a..3883613d49 100644
--- a/src/corelib/kernel/qmetaobject.cpp
+++ b/src/corelib/kernel/qmetaobject.cpp
@@ -154,20 +154,29 @@ QT_BEGIN_NAMESPACE
static inline const QMetaObjectPrivate *priv(const uint* data)
{ return reinterpret_cast<const QMetaObjectPrivate*>(data); }
+static inline const char *rawStringData(const QMetaObject *mo, int index)
+{
+ Q_ASSERT(priv(mo->d.data)->revision >= 7);
+ uint offset = mo->d.stringdata[2*index];
+ return reinterpret_cast<const char *>(mo->d.stringdata) + offset;
+}
+
static inline const QByteArray stringData(const QMetaObject *mo, int index)
{
Q_ASSERT(priv(mo->d.data)->revision >= 7);
- const QByteArrayDataPtr data = { const_cast<QByteArrayData*>(&mo->d.stringdata[index]) };
- Q_ASSERT(data.ptr->ref.isStatic());
- Q_ASSERT(data.ptr->alloc == 0);
- Q_ASSERT(data.ptr->capacityReserved == 0);
- Q_ASSERT(data.ptr->size >= 0);
- return data;
+ uint offset = mo->d.stringdata[2*index];
+ uint length = mo->d.stringdata[2*index + 1];
+ const char *string = reinterpret_cast<const char *>(mo->d.stringdata) + offset;
+ return QByteArray::fromRawData(string, length);
}
-static inline const char *rawStringData(const QMetaObject *mo, int index)
+static inline const char *rawTypeNameFromTypeInfo(const QMetaObject *mo, uint typeInfo)
{
- return stringData(mo, index).data();
+ if (typeInfo & IsUnresolvedType) {
+ return rawStringData(mo, typeInfo & TypeNameIndexMask);
+ } else {
+ return QMetaType::typeName(typeInfo);
+ }
}
static inline QByteArray typeNameFromTypeInfo(const QMetaObject *mo, uint typeInfo)
@@ -181,16 +190,11 @@ static inline QByteArray typeNameFromTypeInfo(const QMetaObject *mo, uint typeIn
}
}
-static inline const char *rawTypeNameFromTypeInfo(const QMetaObject *mo, uint typeInfo)
-{
- return typeNameFromTypeInfo(mo, typeInfo).constData();
-}
-
static inline int typeFromTypeInfo(const QMetaObject *mo, uint typeInfo)
{
if (!(typeInfo & IsUnresolvedType))
return typeInfo;
- return QMetaType::type(stringData(mo, typeInfo & TypeNameIndexMask));
+ return QMetaType::type(rawStringData(mo, typeInfo & TypeNameIndexMask));
}
class QMetaMethodPrivate : public QMetaMethod
@@ -282,14 +286,14 @@ QObject *QMetaObject::newInstance(QGenericArgument val0,
idx = indexOfConstructor(norm.constData());
}
if (idx < 0)
- return 0;
+ return nullptr;
- QObject *returnValue = 0;
+ QObject *returnValue = nullptr;
void *param[] = {&returnValue, val0.data(), val1.data(), val2.data(), val3.data(), val4.data(),
val5.data(), val6.data(), val7.data(), val8.data(), val9.data()};
if (static_metacall(CreateInstance, idx, param) >= 0)
- return 0;
+ return nullptr;
return returnValue;
}
@@ -301,7 +305,7 @@ int QMetaObject::static_metacall(Call cl, int idx, void **argv) const
Q_ASSERT(priv(d.data)->revision >= 6);
if (!d.static_metacall)
return 0;
- d.static_metacall(0, cl, idx, argv);
+ d.static_metacall(nullptr, cl, idx, argv);
return -1;
}
@@ -577,7 +581,7 @@ static bool methodMatch(const QMetaObject *m, int handle,
if (int(m->d.data[handle + 1]) != argc)
return false;
- if (stringData(m, m->d.data[handle]) != name)
+ if (rawStringData(m, m->d.data[handle]) != name)
return false;
int paramsIndex = m->d.data[handle + 2] + 1;
@@ -693,7 +697,7 @@ static void argumentTypesFromString(const char *str, const char *end,
QByteArray QMetaObjectPrivate::decodeMethodSignature(
const char *signature, QArgumentTypeArray &types)
{
- Q_ASSERT(signature != 0);
+ Q_ASSERT(signature != nullptr);
const char *lparens = strchr(signature, '(');
if (!lparens)
return QByteArray();
@@ -846,7 +850,7 @@ int QMetaObjectPrivate::indexOfConstructor(const QMetaObject *m, const QByteArra
*/
int QMetaObjectPrivate::absoluteSignalCount(const QMetaObject *m)
{
- Q_ASSERT(m != 0);
+ Q_ASSERT(m != nullptr);
int n = priv(m->d.data)->signalCount;
for (m = m->d.superdata; m; m = m->d.superdata)
n += priv(m->d.data)->signalCount;
@@ -883,7 +887,7 @@ QMetaMethod QMetaObjectPrivate::signal(const QMetaObject *m, int signal_index)
QMetaMethod result;
if (signal_index < 0)
return result;
- Q_ASSERT(m != 0);
+ Q_ASSERT(m != nullptr);
int i = signal_index;
i -= signalOffset(m);
if (i < 0 && m->d.superdata)
@@ -1033,7 +1037,7 @@ int QMetaObject::indexOfProperty(const char *name) const
QAbstractDynamicMetaObject *me =
const_cast<QAbstractDynamicMetaObject *>(static_cast<const QAbstractDynamicMetaObject *>(this));
- return me->createProperty(name, 0);
+ return me->createProperty(name, nullptr);
}
return -1;
@@ -1147,7 +1151,7 @@ QMetaProperty QMetaObject::property(int index) const
if (!result.menum.isValid()) {
const char *enum_name = type;
const char *scope_name = objectClassName(this);
- char *scope_buffer = 0;
+ char *scope_buffer = nullptr;
const char *colon = strrchr(enum_name, ':');
// ':' will always appear in pairs
@@ -1161,9 +1165,9 @@ QMetaProperty QMetaObject::property(int index) const
enum_name = colon+1;
}
- const QMetaObject *scope = 0;
+ const QMetaObject *scope = nullptr;
if (qstrcmp(scope_name, "Qt") == 0)
- scope = &QObject::staticQtMetaObject;
+ scope = &Qt::staticMetaObject;
else
scope = QMetaObject_findMetaObject(this, scope_name);
if (scope)
@@ -1544,14 +1548,14 @@ bool QMetaObject::invokeMethodImpl(QObject *object, QtPrivate::QSlotObjectBase *
return false;
}
- QCoreApplication::postEvent(object, new QMetaCallEvent(slot, 0, -1, 1));
+ QCoreApplication::postEvent(object, new QMetaCallEvent(slot, nullptr, -1, 1));
} else if (type == Qt::BlockingQueuedConnection) {
#if QT_CONFIG(thread)
if (currentThread == objectThread)
qWarning("QMetaObject::invokeMethod: Dead lock detected");
QSemaphore semaphore;
- QCoreApplication::postEvent(object, new QMetaCallEvent(slot, 0, -1, argv, &semaphore));
+ QCoreApplication::postEvent(object, new QMetaCallEvent(slot, nullptr, -1, argv, &semaphore));
semaphore.acquire();
#endif // QT_CONFIG(thread)
} else {
@@ -1990,7 +1994,7 @@ QList<QByteArray> QMetaMethod::parameterNames() const
const char *QMetaMethod::typeName() const
{
if (!mobj)
- return 0;
+ return nullptr;
return QMetaMethodPrivate::get(this)->rawReturnTypeName();
}
@@ -2022,7 +2026,7 @@ const char *QMetaMethod::typeName() const
const char *QMetaMethod::tag() const
{
if (!mobj)
- return 0;
+ return nullptr;
return QMetaMethodPrivate::get(this)->tag().constData();
}
@@ -2305,7 +2309,7 @@ bool QMetaMethod::invoke(QObject *object,
return false;
}
- QScopedPointer<QMetaCallEvent> event(new QMetaCallEvent(idx_offset, idx_relative, callFunction, 0, -1, paramCount));
+ QScopedPointer<QMetaCallEvent> event(new QMetaCallEvent(idx_offset, idx_relative, callFunction, nullptr, -1, paramCount));
int *types = event->types();
void **args = event->args();
@@ -2342,7 +2346,7 @@ bool QMetaMethod::invoke(QObject *object,
QSemaphore semaphore;
QCoreApplication::postEvent(object, new QMetaCallEvent(idx_offset, idx_relative, callFunction,
- 0, -1, param, &semaphore));
+ nullptr, -1, param, &semaphore));
semaphore.acquire();
#endif // QT_CONFIG(thread)
}
@@ -2565,7 +2569,7 @@ bool QMetaMethod::invokeOnGadget(void* gadget, QGenericReturnArgument returnValu
const char *QMetaEnum::name() const
{
if (!mobj)
- return 0;
+ return nullptr;
return rawStringData(mobj, mobj->d.data[handle]);
}
@@ -2584,7 +2588,7 @@ const char *QMetaEnum::name() const
const char *QMetaEnum::enumName() const
{
if (!mobj)
- return 0;
+ return nullptr;
const bool rev8p = priv(mobj->d.data)->revision >= 8;
if (rev8p)
return rawStringData(mobj, mobj->d.data[handle + 1]);
@@ -2612,13 +2616,13 @@ int QMetaEnum::keyCount() const
const char *QMetaEnum::key(int index) const
{
if (!mobj)
- return 0;
+ return nullptr;
const int offset = priv(mobj->d.data)->revision >= 8 ? 3 : 2;
int count = mobj->d.data[handle + offset];
int data = mobj->d.data[handle + offset + 1];
if (index >= 0 && index < count)
return rawStringData(mobj, mobj->d.data[data + 2*index]);
- return 0;
+ return nullptr;
}
/*!
@@ -2681,7 +2685,7 @@ bool QMetaEnum::isScoped() const
*/
const char *QMetaEnum::scope() const
{
- return mobj ? objectClassName(mobj) : 0;
+ return mobj ? objectClassName(mobj) : nullptr;
}
/*!
@@ -2697,7 +2701,7 @@ const char *QMetaEnum::scope() const
*/
int QMetaEnum::keyToValue(const char *key, bool *ok) const
{
- if (ok != 0)
+ if (ok != nullptr)
*ok = false;
if (!mobj || !key)
return -1;
@@ -2717,7 +2721,7 @@ int QMetaEnum::keyToValue(const char *key, bool *ok) const
const QByteArray className = stringData(mobj, priv(mobj->d.data)->className);
if ((!scope || (className.size() == int(scope) && strncmp(qualified_key, className.constData(), scope) == 0))
&& strcmp(key, rawStringData(mobj, mobj->d.data[data + 2*i])) == 0) {
- if (ok != 0)
+ if (ok != nullptr)
*ok = true;
return mobj->d.data[data + 2*i + 1];
}
@@ -2736,14 +2740,14 @@ int QMetaEnum::keyToValue(const char *key, bool *ok) const
const char* QMetaEnum::valueToKey(int value) const
{
if (!mobj)
- return 0;
+ return nullptr;
const int offset = priv(mobj->d.data)->revision >= 8 ? 3 : 2;
int count = mobj->d.data[handle + offset];
int data = mobj->d.data[handle + offset + 1];
for (int i = 0; i < count; ++i)
if (value == (int)mobj->d.data[data + 2*i + 1])
return rawStringData(mobj, mobj->d.data[data + 2*i]);
- return 0;
+ return nullptr;
}
/*!
@@ -2758,11 +2762,11 @@ const char* QMetaEnum::valueToKey(int value) const
*/
int QMetaEnum::keysToValue(const char *keys, bool *ok) const
{
- if (ok != 0)
+ if (ok != nullptr)
*ok = false;
if (!mobj || !keys)
return -1;
- if (ok != 0)
+ if (ok != nullptr)
*ok = true;
const QString keysString = QString::fromLatin1(keys);
const QVector<QStringRef> splitKeys = keysString.splitRef(QLatin1Char('|'));
@@ -2795,7 +2799,7 @@ int QMetaEnum::keysToValue(const char *keys, bool *ok) const
}
}
if (i < 0) {
- if (ok != 0)
+ if (ok != nullptr)
*ok = false;
value |= -1;
}
@@ -2898,7 +2902,7 @@ static QByteArray qualifiedName(const QMetaEnum &e)
\internal
*/
QMetaProperty::QMetaProperty()
- : mobj(0), handle(0), idx(0)
+ : mobj(nullptr), handle(0), idx(0)
{
}
@@ -2911,7 +2915,7 @@ QMetaProperty::QMetaProperty()
const char *QMetaProperty::name() const
{
if (!mobj)
- return 0;
+ return nullptr;
int handle = priv(mobj->d.data)->propertyData + 3*idx;
return rawStringData(mobj, mobj->d.data[handle]);
}
@@ -2924,7 +2928,7 @@ const char *QMetaProperty::name() const
const char *QMetaProperty::typeName() const
{
if (!mobj)
- return 0;
+ return nullptr;
int handle = priv(mobj->d.data)->propertyData + 3*idx;
return rawTypeNameFromTypeInfo(mobj, mobj->d.data[handle + 1]);
}
@@ -3114,7 +3118,7 @@ QVariant QMetaProperty::read(const QObject *object) const
t = enumMetaTypeId;
} else {
int handle = priv(mobj->d.data)->propertyData + 3*idx;
- const char *typeName = 0;
+ const char *typeName = nullptr;
Q_ASSERT(priv(mobj->d.data)->revision >= 7);
uint typeInfo = mobj->d.data[handle + 1];
if (!(typeInfo & IsUnresolvedType))
@@ -3140,11 +3144,11 @@ QVariant QMetaProperty::read(const QObject *object) const
// changed: result stored directly in value
int status = -1;
QVariant value;
- void *argv[] = { 0, &value, &status };
+ void *argv[] = { nullptr, &value, &status };
if (t == QMetaType::QVariant) {
argv[0] = &value;
} else {
- value = QVariant(t, (void*)0);
+ value = QVariant(t, (void*)nullptr);
argv[0] = value.data();
}
if (priv(mobj->d.data)->flags & PropertyAccessInStaticMetaCall && mobj->d.static_metacall) {
@@ -3198,7 +3202,7 @@ bool QMetaProperty::write(QObject *object, const QVariant &value) const
v.convert(QVariant::Int);
} else {
int handle = priv(mobj->d.data)->propertyData + 3*idx;
- const char *typeName = 0;
+ const char *typeName = nullptr;
Q_ASSERT(priv(mobj->d.data)->revision >= 7);
uint typeInfo = mobj->d.data[handle + 1];
if (!(typeInfo & IsUnresolvedType))
@@ -3215,7 +3219,7 @@ bool QMetaProperty::write(QObject *object, const QVariant &value) const
if (!value.isValid()) {
if (isResettable())
return reset(object);
- v = QVariant(t, 0);
+ v = QVariant(t, nullptr);
} else if (!v.convert(t)) {
return false;
}
@@ -3231,7 +3235,7 @@ bool QMetaProperty::write(QObject *object, const QVariant &value) const
// the flags variable is used by the declarative module to implement
// interception of property writes.
int flags = 0;
- void *argv[] = { 0, &v, &status, &flags };
+ void *argv[] = { nullptr, &v, &status, &flags };
if (t == QMetaType::QVariant)
argv[0] = &v;
else
@@ -3256,7 +3260,7 @@ bool QMetaProperty::reset(QObject *object) const
{
if (!object || !mobj || !isResettable())
return false;
- void *argv[] = { 0 };
+ void *argv[] = { nullptr };
if (priv(mobj->d.data)->flags & PropertyAccessInStaticMetaCall && mobj->d.static_metacall)
mobj->d.static_metacall(object, QMetaObject::ResetProperty, idx, argv);
else
@@ -3640,7 +3644,7 @@ bool QMetaProperty::isEditable(const QObject *object) const
const char *QMetaClassInfo::name() const
{
if (!mobj)
- return 0;
+ return nullptr;
return rawStringData(mobj, mobj->d.data[handle]);
}
@@ -3652,7 +3656,7 @@ const char *QMetaClassInfo::name() const
const char* QMetaClassInfo::value() const
{
if (!mobj)
- return 0;
+ return nullptr;
return rawStringData(mobj, mobj->d.data[handle + 1]);
}
diff --git a/src/corelib/kernel/qmetaobjectbuilder.cpp b/src/corelib/kernel/qmetaobjectbuilder.cpp
index aab9e05182..d02708540a 100644
--- a/src/corelib/kernel/qmetaobjectbuilder.cpp
+++ b/src/corelib/kernel/qmetaobjectbuilder.cpp
@@ -210,7 +210,7 @@ public:
: flags(0)
{
superClass = &QObject::staticMetaObject;
- staticMetacallFunction = 0;
+ staticMetacallFunction = nullptr;
}
bool hasRevisionedProperties() const;
@@ -749,7 +749,7 @@ void QMetaObjectBuilder::addMetaObject
Q_ASSERT(priv(prototype->d.data)->revision >= 2);
const auto *objects = prototype->d.relatedMetaObjects;
if (objects) {
- while (*objects != 0) {
+ while (*objects != nullptr) {
addRelatedMetaObject(*objects);
++objects;
}
@@ -831,7 +831,7 @@ const QMetaObject *QMetaObjectBuilder::relatedMetaObject(int index) const
if (index >= 0 && index < d->relatedMetaObjects.size())
return d->relatedMetaObjects[index];
else
- return 0;
+ return nullptr;
}
/*!
@@ -1103,13 +1103,13 @@ int QMetaStringTable::enter(const QByteArray &value)
int QMetaStringTable::preferredAlignment()
{
- return alignof(QByteArrayData);
+ return alignof(uint);
}
// Returns the size (in bytes) required for serializing this string table.
int QMetaStringTable::blobSize() const
{
- int size = m_entries.size() * sizeof(QByteArrayData);
+ int size = m_entries.size() * 2*sizeof(uint);
Entries::const_iterator it;
for (it = m_entries.constBegin(); it != m_entries.constEnd(); ++it)
size += it.key().size() + 1;
@@ -1120,14 +1120,12 @@ static void writeString(char *out, int i, const QByteArray &str,
const int offsetOfStringdataMember, int &stringdataOffset)
{
int size = str.size();
- qptrdiff offset = offsetOfStringdataMember + stringdataOffset
- - i * sizeof(QByteArrayData);
- const QByteArrayData data =
- Q_STATIC_BYTE_ARRAY_DATA_HEADER_INITIALIZER_WITH_OFFSET(size, offset);
+ int offset = offsetOfStringdataMember + stringdataOffset;
+ uint offsetLen[2] = { uint(offset), uint(size) };
- memcpy(out + i * sizeof(QByteArrayData), &data, sizeof(QByteArrayData));
+ memcpy(out + 2 * i * sizeof(uint), &offsetLen, 2*sizeof(uint));
- memcpy(out + offsetOfStringdataMember + stringdataOffset, str.constData(), size);
+ memcpy(out + offset, str.constData(), size);
out[offsetOfStringdataMember + stringdataOffset + size] = '\0';
stringdataOffset += size + 1;
@@ -1141,7 +1139,7 @@ void QMetaStringTable::writeBlob(char *out) const
{
Q_ASSERT(!(reinterpret_cast<quintptr>(out) & (preferredAlignment()-1)));
- int offsetOfStringdataMember = m_entries.size() * sizeof(QByteArrayData);
+ int offsetOfStringdataMember = m_entries.size() * 2*sizeof(uint);
int stringdataOffset = 0;
// qt_metacast expects the first string in the string table to be the class name.
@@ -1196,8 +1194,8 @@ static int buildMetaObject(QMetaObjectBuilderPrivate *d, char *buf,
ALIGN(size, int);
if (buf) {
if (!relocatable) meta->d.superdata = d->superClass;
- meta->d.relatedMetaObjects = 0;
- meta->d.extradata = 0;
+ meta->d.relatedMetaObjects = nullptr;
+ meta->d.extradata = nullptr;
meta->d.static_metacall = d->staticMetacallFunction;
}
@@ -1282,10 +1280,10 @@ static int buildMetaObject(QMetaObjectBuilderPrivate *d, char *buf,
char *str = reinterpret_cast<char *>(buf + size);
if (buf) {
if (relocatable) {
- meta->d.stringdata = reinterpret_cast<const QByteArrayData *>((quintptr)size);
+ meta->d.stringdata = reinterpret_cast<const uint *>((quintptr)size);
meta->d.data = reinterpret_cast<uint *>((quintptr)pmetaSize);
} else {
- meta->d.stringdata = reinterpret_cast<const QByteArrayData *>(str);
+ meta->d.stringdata = reinterpret_cast<const uint *>(str);
meta->d.data = reinterpret_cast<uint *>(data);
}
}
@@ -1494,7 +1492,7 @@ static int buildMetaObject(QMetaObjectBuilderPrivate *d, char *buf,
*/
QMetaObject *QMetaObjectBuilder::toMetaObject() const
{
- int size = buildMetaObject(d, 0, 0, false);
+ int size = buildMetaObject(d, nullptr, 0, false);
char *buf = reinterpret_cast<char *>(malloc(size));
memset(buf, 0, size);
buildMetaObject(d, buf, size, false);
@@ -1517,7 +1515,7 @@ QMetaObject *QMetaObjectBuilder::toMetaObject() const
*/
QByteArray QMetaObjectBuilder::toRelocatableData(bool *ok) const
{
- int size = buildMetaObject(d, 0, 0, true);
+ int size = buildMetaObject(d, nullptr, 0, true);
if (size == -1) {
if (ok) *ok = false;
return QByteArray();
@@ -1553,11 +1551,11 @@ void QMetaObjectBuilder::fromRelocatableData(QMetaObject *output,
quintptr dataOffset = (quintptr)dataMo->d.data;
output->d.superdata = superclass;
- output->d.stringdata = reinterpret_cast<const QByteArrayData *>(buf + stringdataOffset);
+ output->d.stringdata = reinterpret_cast<const uint *>(buf + stringdataOffset);
output->d.data = reinterpret_cast<const uint *>(buf + dataOffset);
- output->d.extradata = 0;
- output->d.relatedMetaObjects = 0;
- output->d.static_metacall = 0;
+ output->d.extradata = nullptr;
+ output->d.relatedMetaObjects = nullptr;
+ output->d.static_metacall = nullptr;
}
/*!
@@ -1720,14 +1718,14 @@ void QMetaObjectBuilder::deserialize
d->enumerators.clear();
d->constructors.clear();
d->relatedMetaObjects.clear();
- d->staticMetacallFunction = 0;
+ d->staticMetacallFunction = nullptr;
// Read the class and super class names.
stream >> d->className;
stream >> name;
if (name.isEmpty()) {
- d->superClass = 0;
- } else if ((cl = resolveClassName(references, name)) != 0) {
+ d->superClass = nullptr;
+ } else if ((cl = resolveClassName(references, name)) != nullptr) {
d->superClass = cl;
} else {
stream.setStatus(QDataStream::ReadCorruptData);
@@ -1877,7 +1875,7 @@ QMetaMethodBuilderPrivate *QMetaMethodBuilder::d_func() const
else if (_mobj && -_index >= 1 && -_index <= int(_mobj->d->constructors.size()))
return &(_mobj->d->constructors[(-_index) - 1]);
else
- return 0;
+ return nullptr;
}
/*!
@@ -2116,7 +2114,7 @@ QMetaPropertyBuilderPrivate *QMetaPropertyBuilder::d_func() const
if (_mobj && _index >= 0 && _index < int(_mobj->d->properties.size()))
return &(_mobj->d->properties[_index]);
else
- return 0;
+ return nullptr;
}
/*!
@@ -2588,7 +2586,7 @@ QMetaEnumBuilderPrivate *QMetaEnumBuilder::d_func() const
if (_mobj && _index >= 0 && _index < int(_mobj->d->enumerators.size()))
return &(_mobj->d->enumerators[_index]);
else
- return 0;
+ return nullptr;
}
/*!
diff --git a/src/corelib/kernel/qmetatype.cpp b/src/corelib/kernel/qmetatype.cpp
index 5c1e4b4ddd..79d6d0aa93 100644
--- a/src/corelib/kernel/qmetatype.cpp
+++ b/src/corelib/kernel/qmetatype.cpp
@@ -508,19 +508,43 @@ struct DefinedTypesFilter {
Destructs this object.
*/
+/*!
+ \fn template<typename T> QMetaType QMetaType::fromType()
+ \since 5.15
+
+ Returns the QMetaType corresponding to the type in the template parameter.
+*/
+
+/*! \fn bool operator==(const QMetaType &a, const QMetaType &b)
+ \since 5.15
+ \relates QMetaType
+ \overload
+
+ Returns \c true if the QMetaType \a a represents the same type
+ as the QMetaType \a b, otherwise returns \c false.
+*/
+
+/*! \fn bool operator!=(const QMetaType &a, const QMetaType &c)
+ \since 5.15
+ \relates QMetaType
+ \overload
+
+ Returns \c true if the QMetaType \a a represents a difference type
+ than the QMetaType \a b, otherwise returns \c false.
+*/
+
#define QT_ADD_STATIC_METATYPE(MetaTypeName, MetaTypeId, RealName) \
{ #RealName, sizeof(#RealName) - 1, MetaTypeId },
#define QT_ADD_STATIC_METATYPE_ALIASES_ITER(MetaTypeName, MetaTypeId, AliasingName, RealNameStr) \
{ RealNameStr, sizeof(RealNameStr) - 1, QMetaType::MetaTypeName },
-#define QT_ADD_STATIC_METATYPE_HACKS_ITER(MetaTypeName, TypeId, Name) \
- QT_ADD_STATIC_METATYPE(MetaTypeName, MetaTypeName, Name)
+
static const struct { const char * typeName; int typeNameLength; int type; } types[] = {
QT_FOR_EACH_STATIC_TYPE(QT_ADD_STATIC_METATYPE)
QT_FOR_EACH_STATIC_ALIAS_TYPE(QT_ADD_STATIC_METATYPE_ALIASES_ITER)
- QT_FOR_EACH_STATIC_HACKS_TYPE(QT_ADD_STATIC_METATYPE_HACKS_ITER)
+ QT_ADD_STATIC_METATYPE(_, QMetaTypeId2<qreal>::MetaType, qreal)
{nullptr, 0, QMetaType::UnknownType}
};
@@ -932,7 +956,7 @@ constexpr MetaTypeOffsets<QtPrivate::Indexes<QMetaType::HighestInternalId + 1>::
pointer if no matching type was found. The returned pointer must not be
deleted.
- \sa type(), isRegistered(), Type
+ \sa type(), isRegistered(), Type, name()
*/
const char *QMetaType::typeName(int typeId)
{
@@ -952,6 +976,20 @@ const char *QMetaType::typeName(int typeId)
#undef QT_METATYPE_TYPEID_TYPENAME_CONVERTER
}
+/*!
+ \since 5.15
+
+ Returns the type name associated with this QMetaType, or a null
+ pointer if no matching type was found. The returned pointer must not be
+ deleted.
+
+ \sa typeName()
+*/
+QByteArray QMetaType::name() const
+{
+ return QMetaType::typeName(m_typeId);
+}
+
/*
Similar to QMetaType::type(), but only looks in the static set of types.
*/
@@ -1115,8 +1153,8 @@ static int registerNormalizedType(const NS(QByteArray) &normalizedTypeName,
QCustomTypeInfo inf;
inf.typeName = normalizedTypeName;
#ifndef QT_NO_DATASTREAM
- inf.loadOp = 0;
- inf.saveOp = 0;
+ inf.loadOp = nullptr;
+ inf.saveOp = nullptr;
#endif
inf.alias = -1;
inf.typedConstructor = typedConstructor;
@@ -1957,7 +1995,7 @@ public:
return Q_LIKELY(qMetaTypeWidgetsHelper)
? qMetaTypeWidgetsHelper[type - QMetaType::FirstWidgetsType].metaObject
: nullptr;
- return 0;
+ return nullptr;
}
};
@@ -2216,6 +2254,8 @@ QMetaType QMetaType::typeInfo(const int type)
\since 5.0
Constructs a QMetaType object that contains all information about type \a typeId.
+
+ \note: The default parameter was added in Qt 5.15
*/
QMetaType::QMetaType(const int typeId)
: m_typeId(typeId)
diff --git a/src/corelib/kernel/qmetatype.h b/src/corelib/kernel/qmetatype.h
index caa158841c..7628f5f6b3 100644
--- a/src/corelib/kernel/qmetatype.h
+++ b/src/corelib/kernel/qmetatype.h
@@ -187,10 +187,6 @@ inline Q_DECL_CONSTEXPR int qMetaTypeId();
#define QT_FOR_EACH_STATIC_WIDGETS_CLASS(F)\
F(QSizePolicy, 121, QSizePolicy) \
-// ### FIXME kill that set
-#define QT_FOR_EACH_STATIC_HACKS_TYPE(F)\
- F(QMetaTypeId2<qreal>::MetaType, -1, qreal)
-
// F is a tuple: (QMetaType::TypeName, QMetaType::TypeNameID, AliasingType, "RealType")
#define QT_FOR_EACH_STATIC_ALIAS_TYPE(F)\
F(ULong, -1, ulong, "unsigned long") \
@@ -579,7 +575,7 @@ public:
static bool load(QDataStream &stream, int type, void *data);
#endif
- explicit QMetaType(const int type); // ### Qt6: drop const
+ explicit QMetaType(const int type = QMetaType::UnknownType); // ### Qt6: drop const
inline ~QMetaType();
inline bool isValid() const;
@@ -588,12 +584,24 @@ public:
inline int sizeOf() const;
inline TypeFlags flags() const;
inline const QMetaObject *metaObject() const;
+ QT_PREPEND_NAMESPACE(QByteArray) name() const;
inline void *create(const void *copy = nullptr) const;
inline void destroy(void *data) const;
inline void *construct(void *where, const void *copy = nullptr) const;
inline void destruct(void *data) const;
+ template<typename T>
+ static QMetaType fromType()
+ { return QMetaType(qMetaTypeId<T>()); }
+
+ friend bool operator==(const QMetaType &a, const QMetaType &b)
+ { return a.m_typeId == b.m_typeId; }
+
+ friend bool operator!=(const QMetaType &a, const QMetaType &b)
+ { return a.m_typeId != b.m_typeId; }
+
+
public:
template<typename T>
static bool registerComparators()
@@ -743,8 +751,6 @@ private:
static bool registerDebugStreamOperatorFunction(const QtPrivate::AbstractDebugStreamFunction *f, int type);
#endif
-// ### Qt6: FIXME: Remove the special Q_CC_MSVC handling, it was introduced to maintain BC.
-#if !defined(Q_NO_TEMPLATE_FRIENDS) && !defined(Q_CC_MSVC)
#ifndef Q_CLANG_QDOC
template<typename, bool> friend struct QtPrivate::ValueTypeIsMetaType;
template<typename, typename> friend struct QtPrivate::ConverterMemberFunction;
@@ -754,9 +760,6 @@ private:
template<typename, bool> friend struct QtPrivate::IsMetaTypePair;
template<typename, typename> friend struct QtPrivate::MetaTypeSmartPointerHelper;
#endif
-#else
-public:
-#endif
static bool registerConverterFunction(const QtPrivate::AbstractConverterFunction *f, int from, int to);
static void unregisterConverterFunction(int from, int to);
private:
@@ -1215,9 +1218,12 @@ public:
{ IteratorOwner<typename T::const_iterator>::assign(iterator,
static_cast<const T*>(container)->find(*static_cast<const typename T::key_type*>(p))); }
+ QT_WARNING_PUSH
+ QT_WARNING_DISABLE_DEPRECATED // Hits on the deprecated QHash::iterator::operator--()
template<class T>
static void advanceImpl(void **p, int step)
{ std::advance(*static_cast<typename T::const_iterator*>(*p), step); }
+ QT_WARNING_POP
template<class T>
static void beginImpl(const void *container, void **iterator)
diff --git a/src/corelib/kernel/qmimedata.cpp b/src/corelib/kernel/qmimedata.cpp
index 9a98db21d3..00e5183eb1 100644
--- a/src/corelib/kernel/qmimedata.cpp
+++ b/src/corelib/kernel/qmimedata.cpp
@@ -319,7 +319,7 @@ QVariant QMimeDataPrivate::retrieveTypedData(const QString &format, QVariant::Ty
Constructs a new MIME data object with no data in it.
*/
QMimeData::QMimeData()
- : QObject(*new QMimeDataPrivate, 0)
+ : QObject(*new QMimeDataPrivate, nullptr)
{
}
diff --git a/src/corelib/kernel/qobject.cpp b/src/corelib/kernel/qobject.cpp
index d713555bb6..c72383ff4a 100644
--- a/src/corelib/kernel/qobject.cpp
+++ b/src/corelib/kernel/qobject.cpp
@@ -109,7 +109,7 @@ static int *queuedConnectionTypes(const QList<QByteArray> &typeNames)
"(Make sure '%s' is registered using qRegisterMetaType().)",
typeName.constData(), typeName.constData());
delete [] types;
- return 0;
+ return nullptr;
}
}
types[typeNames.count()] = 0;
@@ -133,7 +133,7 @@ static int *queuedConnectionTypes(const QArgumentType *argumentTypes, int argc)
qWarning("QObject::connect: Cannot queue arguments of type '%s'\n"
"(Make sure '%s' is registered using qRegisterMetaType().)",
type.name().constData(), type.name().constData());
- return 0;
+ return nullptr;
}
}
types[argc] = 0;
@@ -160,12 +160,12 @@ extern "C" Q_CORE_EXPORT void qt_removeObject(QObject *)
{}
#endif
-void (*QAbstractDeclarativeData::destroyed)(QAbstractDeclarativeData *, QObject *) = 0;
-void (*QAbstractDeclarativeData::parentChanged)(QAbstractDeclarativeData *, QObject *, QObject *) = 0;
-void (*QAbstractDeclarativeData::signalEmitted)(QAbstractDeclarativeData *, QObject *, int, void **) = 0;
-int (*QAbstractDeclarativeData::receivers)(QAbstractDeclarativeData *, const QObject *, int) = 0;
-bool (*QAbstractDeclarativeData::isSignalConnected)(QAbstractDeclarativeData *, const QObject *, int) = 0;
-void (*QAbstractDeclarativeData::setWidgetParent)(QObject *, QObject *) = 0;
+void (*QAbstractDeclarativeData::destroyed)(QAbstractDeclarativeData *, QObject *) = nullptr;
+void (*QAbstractDeclarativeData::parentChanged)(QAbstractDeclarativeData *, QObject *, QObject *) = nullptr;
+void (*QAbstractDeclarativeData::signalEmitted)(QAbstractDeclarativeData *, QObject *, int, void **) = nullptr;
+int (*QAbstractDeclarativeData::receivers)(QAbstractDeclarativeData *, const QObject *, int) = nullptr;
+bool (*QAbstractDeclarativeData::isSignalConnected)(QAbstractDeclarativeData *, const QObject *, int) = nullptr;
+void (*QAbstractDeclarativeData::setWidgetParent)(QObject *, QObject *) = nullptr;
/*!
\fn QObjectData::QObjectData()
@@ -181,7 +181,7 @@ QMetaObject *QObjectData::dynamicMetaObject() const
}
QObjectPrivate::QObjectPrivate(int version)
- : threadData(0), currentChildBeingDeleted(0)
+ : threadData(nullptr), currentChildBeingDeleted(nullptr)
{
#ifdef QT_BUILD_INTERNAL
// Don't check the version parameter in internal builds.
@@ -194,8 +194,8 @@ QObjectPrivate::QObjectPrivate(int version)
#endif
// QObjectData initialization
- q_ptr = 0;
- parent = 0; // no parent yet. It is set by setParent()
+ q_ptr = nullptr;
+ parent = nullptr; // no parent yet. It is set by setParent()
isWidget = false; // assume not a widget object
blockSig = false; // not blocking signals
wasDeleted = false; // double-delete catcher
@@ -203,19 +203,20 @@ QObjectPrivate::QObjectPrivate(int version)
sendChildEvents = true; // if we should send ChildAdded and ChildRemoved events to parent
receiveChildEvents = true;
postedEvents = 0;
- extraData = 0;
- metaObject = 0;
+ extraData = nullptr;
+ metaObject = nullptr;
isWindow = false;
deleteLaterCalled = false;
}
QObjectPrivate::~QObjectPrivate()
{
+ auto thisThreadData = threadData.loadRelaxed();
if (extraData && !extraData->runningTimers.isEmpty()) {
- if (Q_LIKELY(threadData->thread.loadAcquire() == QThread::currentThread())) {
+ if (Q_LIKELY(thisThreadData->thread.loadAcquire() == QThread::currentThread())) {
// unregister pending timers
- if (threadData->hasEventDispatcher())
- threadData->eventDispatcher.loadRelaxed()->unregisterTimers(q_ptr);
+ if (thisThreadData->hasEventDispatcher())
+ thisThreadData->eventDispatcher.loadRelaxed()->unregisterTimers(q_ptr);
// release the timer ids back to the pool
for (int i = 0; i < extraData->runningTimers.size(); ++i)
@@ -228,7 +229,7 @@ QObjectPrivate::~QObjectPrivate()
if (postedEvents)
QCoreApplication::removePostedEvents(q_ptr, 0);
- threadData->deref();
+ thisThreadData->deref();
if (metaObject) metaObject->objectDestroyed(q_ptr);
@@ -915,12 +916,13 @@ QObject::QObject(QObjectPrivate &dd, QObject *parent)
Q_D(QObject);
d_ptr->q_ptr = this;
- d->threadData = (parent && !parent->thread()) ? parent->d_func()->threadData : QThreadData::current();
- d->threadData->ref();
+ auto threadData = (parent && !parent->thread()) ? parent->d_func()->threadData.loadRelaxed() : QThreadData::current();
+ threadData->ref();
+ d->threadData.storeRelaxed(threadData);
if (parent) {
QT_TRY {
- if (!check_parent_thread(parent, parent ? parent->d_func()->threadData : 0, d->threadData))
- parent = 0;
+ if (!check_parent_thread(parent, parent ? parent->d_func()->threadData.loadRelaxed() : nullptr, threadData))
+ parent = nullptr;
if (d->isWidget) {
if (parent) {
d->parent = parent;
@@ -931,7 +933,7 @@ QObject::QObject(QObjectPrivate &dd, QObject *parent)
setParent(parent);
}
} QT_CATCH(...) {
- d->threadData->deref();
+ threadData->deref();
QT_RETHROW;
}
}
@@ -1081,7 +1083,7 @@ QObject::~QObject()
Q_TRACE(QObject_dtor, this);
if (d->parent) // remove it from parent object
- d->setParent_helper(0);
+ d->setParent_helper(nullptr);
}
QObjectPrivate::Connection::~Connection()
@@ -1151,8 +1153,8 @@ QObjectPrivate::Connection::~Connection()
\relates QObject
Returns the given \a object cast to type T if the object is of type
- T (or of a subclass); otherwise returns 0. If \a object is 0 then
- it will also return 0.
+ T (or of a subclass); otherwise returns \nullptr. If \a object is
+ \nullptr then it will also return \nullptr.
The class T must inherit (directly or indirectly) QObject and be
declared with the \l Q_OBJECT macro.
@@ -1308,7 +1310,7 @@ bool QObject::event(QEvent *e)
case QEvent::ThreadChange: {
Q_D(QObject);
- QThreadData *threadData = d->threadData;
+ QThreadData *threadData = d->threadData.loadRelaxed();
QAbstractEventDispatcher *eventDispatcher = threadData->eventDispatcher.loadRelaxed();
if (eventDispatcher) {
QList<QAbstractEventDispatcher::TimerInfo> timers = eventDispatcher->registeredTimers(this);
@@ -1475,7 +1477,7 @@ bool QObject::blockSignals(bool block) noexcept
*/
QThread *QObject::thread() const
{
- return d_func()->threadData->thread.loadAcquire();
+ return d_func()->threadData.loadRelaxed()->thread.loadAcquire();
}
/*!
@@ -1504,7 +1506,7 @@ QThread *QObject::thread() const
the thread affinity is changed. You can handle this event to
perform any special processing. Note that any new events that are
posted to this object will be handled in the \a targetThread,
- provided it is non-null: when it is \nullptr, no event processing
+ provided it is not \nullptr: when it is \nullptr, no event processing
for this object or its children can happen, as they are no longer
associated with any thread.
@@ -1522,12 +1524,12 @@ void QObject::moveToThread(QThread *targetThread)
{
Q_D(QObject);
- if (d->threadData->thread.loadAcquire() == targetThread) {
+ if (d->threadData.loadRelaxed()->thread.loadAcquire() == targetThread) {
// object is already in this thread
return;
}
- if (d->parent != 0) {
+ if (d->parent != nullptr) {
qWarning("QObject::moveToThread: Cannot move objects with a parent");
return;
}
@@ -1538,13 +1540,14 @@ void QObject::moveToThread(QThread *targetThread)
QThreadData *currentData = QThreadData::current();
QThreadData *targetData = targetThread ? QThreadData::get2(targetThread) : nullptr;
- if (d->threadData->thread.loadAcquire() == 0 && currentData == targetData) {
+ QThreadData *thisThreadData = d->threadData.loadRelaxed();
+ if (!thisThreadData->thread.loadAcquire() && currentData == targetData) {
// one exception to the rule: we allow moving objects with no thread affinity to the current thread
currentData = d->threadData;
- } else if (d->threadData != currentData) {
+ } else if (thisThreadData != currentData) {
qWarning("QObject::moveToThread: Current thread (%p) is not the object's thread (%p).\n"
"Cannot move to target thread (%p)\n",
- currentData->thread.loadRelaxed(), d->threadData->thread.loadRelaxed(), targetData ? targetData->thread.loadRelaxed() : nullptr);
+ currentData->thread.loadRelaxed(), thisThreadData->thread.loadRelaxed(), targetData ? targetData->thread.loadRelaxed() : nullptr);
#ifdef Q_OS_MAC
qWarning("You might be loading two sets of Qt binaries into the same process. "
@@ -1603,7 +1606,7 @@ void QObjectPrivate::setThreadData_helper(QThreadData *currentData, QThreadData
if (pe.receiver == q) {
// move this post event to the targetList
targetData->postEventList.addEvent(pe);
- const_cast<QPostEvent &>(pe).event = 0;
+ const_cast<QPostEvent &>(pe).event = nullptr;
++eventsMoved;
}
}
@@ -1641,8 +1644,10 @@ void QObjectPrivate::setThreadData_helper(QThreadData *currentData, QThreadData
// set new thread data
targetData->ref();
- threadData->deref();
- threadData = targetData;
+ threadData.loadRelaxed()->deref();
+
+ // synchronizes with loadAcquire e.g. in QCoreApplication::postEvent
+ threadData.storeRelease(targetData);
for (int i = 0; i < children.size(); ++i) {
QObject *child = children.at(i);
@@ -1654,7 +1659,7 @@ void QObjectPrivate::_q_reregisterTimers(void *pointer)
{
Q_Q(QObject);
QList<QAbstractEventDispatcher::TimerInfo> *timerList = reinterpret_cast<QList<QAbstractEventDispatcher::TimerInfo> *>(pointer);
- QAbstractEventDispatcher *eventDispatcher = threadData->eventDispatcher.loadRelaxed();
+ QAbstractEventDispatcher *eventDispatcher = threadData.loadRelaxed()->eventDispatcher.loadRelaxed();
for (int i = 0; i < timerList->size(); ++i) {
const QAbstractEventDispatcher::TimerInfo &ti = timerList->at(i);
eventDispatcher->registerTimer(ti.timerId, ti.interval, ti.timerType, q);
@@ -1712,7 +1717,9 @@ int QObject::startTimer(int interval, Qt::TimerType timerType)
qWarning("QObject::startTimer: Timers cannot have negative intervals");
return 0;
}
- if (Q_UNLIKELY(!d->threadData->hasEventDispatcher())) {
+
+ auto thisThreadData = d->threadData.loadRelaxed();
+ if (Q_UNLIKELY(!thisThreadData->hasEventDispatcher())) {
qWarning("QObject::startTimer: Timers can only be used with threads started with QThread");
return 0;
}
@@ -1720,7 +1727,7 @@ int QObject::startTimer(int interval, Qt::TimerType timerType)
qWarning("QObject::startTimer: Timers cannot be started from another thread");
return 0;
}
- int timerId = d->threadData->eventDispatcher.loadRelaxed()->registerTimer(interval, timerType, this);
+ int timerId = thisThreadData->eventDispatcher.loadRelaxed()->registerTimer(interval, timerType, this);
if (!d->extraData)
d->extraData = new QObjectPrivate::ExtraData;
d->extraData->runningTimers.append(timerId);
@@ -1794,8 +1801,9 @@ void QObject::killTimer(int id)
return;
}
- if (d->threadData->hasEventDispatcher())
- d->threadData->eventDispatcher.loadRelaxed()->unregisterTimer(id);
+ auto thisThreadData = d->threadData.loadRelaxed();
+ if (thisThreadData->hasEventDispatcher())
+ thisThreadData->eventDispatcher.loadRelaxed()->unregisterTimer(id);
d->extraData->runningTimers.remove(at);
QAbstractEventDispatcherPrivate::releaseTimerId(id);
@@ -2045,7 +2053,7 @@ void qt_qFindChildren_helper(const QObject *parent, const QRegularExpression &re
QObject *qt_qFindChild_helper(const QObject *parent, const QString &name, const QMetaObject &mo, Qt::FindChildOptions options)
{
if (!parent)
- return 0;
+ return nullptr;
const QObjectList &children = parent->children();
QObject *obj;
int i;
@@ -2061,7 +2069,7 @@ QObject *qt_qFindChild_helper(const QObject *parent, const QString &name, const
return obj;
}
}
- return 0;
+ return nullptr;
}
/*!
@@ -2089,7 +2097,7 @@ void QObjectPrivate::deleteChildren()
delete currentChildBeingDeleted;
}
children.clear();
- currentChildBeingDeleted = 0;
+ currentChildBeingDeleted = nullptr;
isDeletingChildren = false;
}
@@ -2141,7 +2149,7 @@ void QObjectPrivate::setParent_helper(QObject *o)
// object hierarchies are constrained to a single thread
if (threadData != parent->d_func()->threadData) {
qWarning("QObject::setParent: Cannot set parent, new parent is in a different thread");
- parent = 0;
+ parent = nullptr;
return;
}
parent->d_func()->children.append(q);
@@ -2212,7 +2220,7 @@ void QObject::installEventFilter(QObject *obj)
d->extraData = new QObjectPrivate::ExtraData;
// clean up unused items in the list
- d->extraData->eventFilters.removeAll((QObject*)0);
+ d->extraData->eventFilters.removeAll((QObject*)nullptr);
d->extraData->eventFilters.removeAll(obj);
d->extraData->eventFilters.prepend(obj);
}
@@ -2236,7 +2244,7 @@ void QObject::removeEventFilter(QObject *obj)
if (d->extraData) {
for (int i = 0; i < d->extraData->eventFilters.count(); ++i) {
if (d->extraData->eventFilters.at(i) == obj)
- d->extraData->eventFilters[i] = 0;
+ d->extraData->eventFilters[i] = nullptr;
}
}
}
@@ -2303,7 +2311,7 @@ void QObject::deleteLater()
If the same \a sourceText is used in different roles within the
same context, an additional identifying string may be passed in
- \a disambiguation (0 by default). In Qt 4.4 and earlier, this was
+ \a disambiguation (\nullptr by default). In Qt 4.4 and earlier, this was
the preferred way to pass comments to translators.
Example:
@@ -2359,7 +2367,7 @@ void QObject::deleteLater()
const char *qFlagLocation(const char *method)
{
QThreadData *currentThreadData = QThreadData::current(false);
- if (currentThreadData != 0)
+ if (currentThreadData != nullptr)
currentThreadData->flaggedSignatures.store(method);
return method;
}
@@ -2378,7 +2386,7 @@ static const char * extract_location(const char *member)
if (*location != '\0')
return location;
}
- return 0;
+ return nullptr;
}
static bool check_signal_macro(const QObject *sender, const char *signal,
@@ -2417,7 +2425,7 @@ static void err_method_notfound(const QObject *object,
case QSIGNAL_CODE: type = "signal"; break;
}
const char *loc = extract_location(method);
- if (strchr(method,')') == 0) // common typing mistake
+ if (strchr(method,')') == nullptr) // common typing mistake
qWarning("QObject::%s: Parentheses expected, %s %s::%s%s%s",
func, type, object->metaObject()->className(), method+1,
loc ? " in ": "", loc ? loc : "");
@@ -2477,7 +2485,7 @@ QObject *QObject::sender() const
return cd->currentSender->sender;
}
- return 0;
+ return nullptr;
}
/*!
@@ -2489,7 +2497,7 @@ QObject *QObject::sender() const
For signals with default parameters, this function will always return
the index with all parameters, regardless of which was used with
- connect(). For example, the signal \c {destroyed(QObject *obj = 0)}
+ connect(). For example, the signal \c {destroyed(QObject *obj = \nullptr)}
will have two different indexes (with and without the parameter), but
this function will always return the index with a parameter. This does
not apply when overloading signals with different parameters.
@@ -2630,7 +2638,7 @@ bool QObject::isSignalConnected(const QMetaMethod &signal) const
member in the specified class.
\list
- \li If member.mobj is 0 then both signalIndex and methodIndex are set to -1.
+ \li If member.mobj is \nullptr then both signalIndex and methodIndex are set to -1.
\li If specified member is not a member of obj instance class (or one of
its parent classes) then both signalIndex and methodIndex are set to -1.
@@ -2656,7 +2664,7 @@ void QMetaObjectPrivate::memberIndexes(const QObject *obj,
return;
const QMetaObject *m = obj->metaObject();
// Check that member is member of obj class
- while (m != 0 && m != member.mobj)
+ while (m != nullptr && m != member.mobj)
m = m->d.superdata;
if (!m)
return;
@@ -2767,18 +2775,18 @@ QMetaObject::Connection QObject::connect(const QObject *sender, const char *sign
const QObject *receiver, const char *method,
Qt::ConnectionType type)
{
- if (sender == 0 || receiver == 0 || signal == 0 || method == 0) {
+ if (sender == nullptr || receiver == nullptr || signal == nullptr || method == nullptr) {
qWarning("QObject::connect: Cannot connect %s::%s to %s::%s",
- sender ? sender->metaObject()->className() : "(null)",
- (signal && *signal) ? signal+1 : "(null)",
- receiver ? receiver->metaObject()->className() : "(null)",
- (method && *method) ? method+1 : "(null)");
- return QMetaObject::Connection(0);
+ sender ? sender->metaObject()->className() : "(nullptr)",
+ (signal && *signal) ? signal+1 : "(nullptr)",
+ receiver ? receiver->metaObject()->className() : "(nullptr)",
+ (method && *method) ? method+1 : "(nullptr)");
+ return QMetaObject::Connection(nullptr);
}
QByteArray tmp_signal_name;
if (!check_signal_macro(sender, signal, "connect", "bind"))
- return QMetaObject::Connection(0);
+ return QMetaObject::Connection(nullptr);
const QMetaObject *smeta = sender->metaObject();
const char *signal_arg = signal;
++signal; //skip code
@@ -2801,7 +2809,7 @@ QMetaObject::Connection QObject::connect(const QObject *sender, const char *sign
if (signal_index < 0) {
err_method_notfound(sender, signal_arg, "connect");
err_info_about_objects("connect", sender, receiver);
- return QMetaObject::Connection(0);
+ return QMetaObject::Connection(nullptr);
}
signal_index = QMetaObjectPrivate::originalClone(smeta, signal_index);
signal_index += QMetaObjectPrivate::signalOffset(smeta);
@@ -2810,7 +2818,7 @@ QMetaObject::Connection QObject::connect(const QObject *sender, const char *sign
int membcode = extract_code(method);
if (!check_method_code(membcode, receiver, method, "connect"))
- return QMetaObject::Connection(0);
+ return QMetaObject::Connection(nullptr);
const char *method_arg = method;
++method; // skip code
@@ -2853,7 +2861,7 @@ QMetaObject::Connection QObject::connect(const QObject *sender, const char *sign
if (method_index_relative < 0) {
err_method_notfound(receiver, method_arg, "connect");
err_info_about_objects("connect", sender, receiver);
- return QMetaObject::Connection(0);
+ return QMetaObject::Connection(nullptr);
}
if (!QMetaObjectPrivate::checkConnectArgs(signalTypes.size(), signalTypes.constData(),
@@ -2862,13 +2870,13 @@ QMetaObject::Connection QObject::connect(const QObject *sender, const char *sign
"\n %s::%s --> %s::%s",
sender->metaObject()->className(), signal,
receiver->metaObject()->className(), method);
- return QMetaObject::Connection(0);
+ return QMetaObject::Connection(nullptr);
}
- int *types = 0;
+ int *types = nullptr;
if ((type == Qt::QueuedConnection)
&& !(types = queuedConnectionTypes(signalTypes.constData(), signalTypes.size()))) {
- return QMetaObject::Connection(0);
+ return QMetaObject::Connection(nullptr);
}
#ifndef QT_NO_DEBUG
@@ -2905,16 +2913,16 @@ QMetaObject::Connection QObject::connect(const QObject *sender, const QMetaMetho
const QObject *receiver, const QMetaMethod &method,
Qt::ConnectionType type)
{
- if (sender == 0
- || receiver == 0
+ if (sender == nullptr
+ || receiver == nullptr
|| signal.methodType() != QMetaMethod::Signal
|| method.methodType() == QMetaMethod::Constructor) {
qWarning("QObject::connect: Cannot connect %s::%s to %s::%s",
- sender ? sender->metaObject()->className() : "(null)",
+ sender ? sender->metaObject()->className() : "(nullptr)",
signal.methodSignature().constData(),
- receiver ? receiver->metaObject()->className() : "(null)",
+ receiver ? receiver->metaObject()->className() : "(nullptr)",
method.methodSignature().constData() );
- return QMetaObject::Connection(0);
+ return QMetaObject::Connection(nullptr);
}
int signal_index;
@@ -2930,12 +2938,12 @@ QMetaObject::Connection QObject::connect(const QObject *sender, const QMetaMetho
if (signal_index == -1) {
qWarning("QObject::connect: Can't find signal %s on instance of class %s",
signal.methodSignature().constData(), smeta->className());
- return QMetaObject::Connection(0);
+ return QMetaObject::Connection(nullptr);
}
if (method_index == -1) {
qWarning("QObject::connect: Can't find method %s on instance of class %s",
method.methodSignature().constData(), rmeta->className());
- return QMetaObject::Connection(0);
+ return QMetaObject::Connection(nullptr);
}
if (!QMetaObject::checkConnectArgs(signal.methodSignature().constData(), method.methodSignature().constData())) {
@@ -2943,19 +2951,19 @@ QMetaObject::Connection QObject::connect(const QObject *sender, const QMetaMetho
"\n %s::%s --> %s::%s",
smeta->className(), signal.methodSignature().constData(),
rmeta->className(), method.methodSignature().constData());
- return QMetaObject::Connection(0);
+ return QMetaObject::Connection(nullptr);
}
- int *types = 0;
+ int *types = nullptr;
if ((type == Qt::QueuedConnection)
&& !(types = queuedConnectionTypes(signal.parameterTypes())))
- return QMetaObject::Connection(0);
+ return QMetaObject::Connection(nullptr);
#ifndef QT_NO_DEBUG
check_and_warn_compat(smeta, signal, rmeta, method);
#endif
QMetaObject::Connection handle = QMetaObject::Connection(QMetaObjectPrivate::connect(
- sender, signal_index, signal.enclosingMetaObject(), receiver, method_index, 0, type, types));
+ sender, signal_index, signal.enclosingMetaObject(), receiver, method_index, nullptr, type, types));
return handle;
}
@@ -3014,20 +3022,20 @@ QMetaObject::Connection QObject::connect(const QObject *sender, const QMetaMetho
\endlist
- 0 may be used as a wildcard, meaning "any signal", "any receiving
+ \nullptr may be used as a wildcard, meaning "any signal", "any receiving
object", or "any slot in the receiving object", respectively.
The \a sender may never be \nullptr. (You cannot disconnect signals
from more than one object in a single call.)
- If \a signal is 0, it disconnects \a receiver and \a method from
+ If \a signal is \nullptr, it disconnects \a receiver and \a method from
any signal. If not, only the specified signal is disconnected.
- If \a receiver is 0, it disconnects anything connected to \a
+ If \a receiver is \nullptr, it disconnects anything connected to \a
signal. If not, slots in objects other than \a receiver are not
disconnected.
- If \a method is 0, it disconnects anything that is connected to \a
+ If \a method is \nullptr, it disconnects anything that is connected to \a
receiver. If not, only slots named \a method will be disconnected,
and all other slots are left alone. The \a method must be \nullptr
if \a receiver is left out, so you cannot disconnect a
@@ -3038,8 +3046,8 @@ QMetaObject::Connection QObject::connect(const QObject *sender, const QMetaMetho
bool QObject::disconnect(const QObject *sender, const char *signal,
const QObject *receiver, const char *method)
{
- if (sender == 0 || (receiver == 0 && method != 0)) {
- qWarning("QObject::disconnect: Unexpected null parameter");
+ if (sender == nullptr || (receiver == nullptr && method != nullptr)) {
+ qWarning("QObject::disconnect: Unexpected nullptr parameter");
return false;
}
@@ -3110,7 +3118,7 @@ bool QObject::disconnect(const QObject *sender, const char *signal,
}
if (!method) {
- res |= QMetaObjectPrivate::disconnect(sender, signal_index, smeta, receiver, -1, 0);
+ res |= QMetaObjectPrivate::disconnect(sender, signal_index, smeta, receiver, -1, nullptr);
} else {
const QMetaObject *rmeta = receiver->metaObject();
do {
@@ -3121,7 +3129,7 @@ bool QObject::disconnect(const QObject *sender, const char *signal,
rmeta = rmeta->superClass();
if (method_index < 0)
break;
- res |= QMetaObjectPrivate::disconnect(sender, signal_index, smeta, receiver, method_index, 0);
+ res |= QMetaObjectPrivate::disconnect(sender, signal_index, smeta, receiver, method_index, nullptr);
method_found = true;
} while ((rmeta = rmeta->superClass()));
}
@@ -3165,16 +3173,16 @@ bool QObject::disconnect(const QObject *sender, const char *signal,
\endlist
QMetaMethod() may be used as wildcard in the meaning "any signal" or "any slot in receiving object".
- In the same way 0 can be used for \a receiver in the meaning "any receiving object". In this case
- method should also be QMetaMethod(). \a sender parameter should be never 0.
+ In the same way \nullptr can be used for \a receiver in the meaning "any receiving object".
+ In this case method should also be QMetaMethod(). \a sender parameter should be never \nullptr.
\sa disconnect(const QObject *sender, const char *signal, const QObject *receiver, const char *method)
*/
bool QObject::disconnect(const QObject *sender, const QMetaMethod &signal,
const QObject *receiver, const QMetaMethod &method)
{
- if (sender == 0 || (receiver == 0 && method.mobj != 0)) {
- qWarning("QObject::disconnect: Unexpected null parameter");
+ if (sender == nullptr || (receiver == nullptr && method.mobj != nullptr)) {
+ qWarning("QObject::disconnect: Unexpected nullptr parameter");
return false;
}
if (signal.mobj) {
@@ -3208,7 +3216,7 @@ bool QObject::disconnect(const QObject *sender, const QMetaMethod &signal,
QMetaObjectPrivate::memberIndexes(sender, signal, &signal_index, &dummy);
QMetaObjectPrivate::memberIndexes(receiver, method, &dummy, &method_index);
}
- // If we are here sender is not null. If signal is not null while signal_index
+ // If we are here sender is not nullptr. If signal is not nullptr while signal_index
// is -1 then this signal is not a member of sender.
if (signal.mobj && signal_index == -1) {
qWarning("QObject::disconect: signal %s not found on class %s",
@@ -3222,7 +3230,7 @@ bool QObject::disconnect(const QObject *sender, const QMetaMethod &signal,
return false;
}
- if (!QMetaObjectPrivate::disconnect(sender, signal_index, signal.mobj, receiver, method_index, 0))
+ if (!QMetaObjectPrivate::disconnect(sender, signal_index, signal.mobj, receiver, method_index, nullptr))
return false;
if (!signal.isValid()) {
@@ -3297,7 +3305,7 @@ void QObject::connectNotify(const QMetaMethod &signal)
\a signal with a specific signal.
If all signals were disconnected from this object (e.g., the
- signal argument to disconnect() was 0), disconnectNotify()
+ signal argument to disconnect() was \nullptr), disconnectNotify()
is only called once, and the \a signal will be an invalid
QMetaMethod (QMetaMethod::isValid() returns \c false).
@@ -3361,7 +3369,7 @@ QMetaObject::Connection QMetaObject::connect(const QObject *sender, int signal_i
signal_index = methodIndexToSignalIndex(&smeta, signal_index);
return Connection(QMetaObjectPrivate::connect(sender, signal_index, smeta,
receiver, method_index,
- 0, //FIXME, we could speed this connection up by computing the relative index
+ nullptr, //FIXME, we could speed this connection up by computing the relative index
type, types));
}
@@ -3437,7 +3445,7 @@ bool QMetaObject::disconnect(const QObject *sender, int signal_index,
const QMetaObject *smeta = sender->metaObject();
signal_index = methodIndexToSignalIndex(&smeta, signal_index);
return QMetaObjectPrivate::disconnect(sender, signal_index, smeta,
- receiver, method_index, 0);
+ receiver, method_index, nullptr);
}
/*!
@@ -3453,7 +3461,7 @@ bool QMetaObject::disconnectOne(const QObject *sender, int signal_index,
const QMetaObject *smeta = sender->metaObject();
signal_index = methodIndexToSignalIndex(&smeta, signal_index);
return QMetaObjectPrivate::disconnect(sender, signal_index, smeta,
- receiver, method_index, 0,
+ receiver, method_index, nullptr,
QMetaObjectPrivate::DisconnectOne);
}
@@ -3662,7 +3670,7 @@ static void queued_activate(QObject *sender, int signal, QObjectPrivate::Connect
argumentTypes = queuedConnectionTypes(m.parameterTypes());
if (!argumentTypes) // cannot queue arguments
argumentTypes = &DIRECT_CONNECTION_ONLY;
- if (!c->argumentTypes.testAndSetOrdered(0, argumentTypes)) {
+ if (!c->argumentTypes.testAndSetOrdered(nullptr, argumentTypes)) {
if (argumentTypes != &DIRECT_CONNECTION_ONLY)
delete [] argumentTypes;
argumentTypes = c->argumentTypes.loadRelaxed();
@@ -3762,7 +3770,7 @@ void doActivate(QObject *sender, int signal_index, void **argv)
list = &signalVector->at(-1);
Qt::HANDLE currentThreadId = QThread::currentThreadId();
- bool inSenderThread = currentThreadId == QObjectPrivate::get(sender)->threadData->threadId.loadRelaxed();
+ bool inSenderThread = currentThreadId == QObjectPrivate::get(sender)->threadData.loadRelaxed()->threadId.loadRelaxed();
// We need to check against the highest connection id to ensure that signals added
// during the signal emission are not emitted in this emission.
@@ -4528,13 +4536,30 @@ QDebug operator<<(QDebug dbg, const QObject *o)
It works exactly like the Q_NAMESPACE macro. However, the external
\c{staticMetaObject} variable that gets defined in the namespace
- is declared with the supplied \c{EXPORT_MACRO} qualifier. This is
+ is declared with the supplied \a EXPORT_MACRO qualifier. This is
useful if the object needs to be exported from a dynamic library.
\sa Q_NAMESPACE, {Creating Shared Libraries}
*/
/*!
+ \macro Q_MOC_INCLUDE
+ \relates QObject
+ \since 6.0
+
+ The Q_MOC_INCLUDE macro can be used within or outside a class, and tell the
+ \l{moc}{Meta Object Compiler} to add an include.
+
+ \code
+ // Put this in your code and the generated code will include this header.
+ Q_MOC_INCLUDE("myheader.h")
+ \endcode
+
+ This is useful if the types you use as properties or signal/slots arguments
+ are forward declared.
+*/
+
+/*!
\macro Q_SIGNALS
\relates QObject
@@ -4845,7 +4870,7 @@ void qDeleteInEventHandler(QObject *o)
\a sender is the sender object
\a signal is a pointer to a pointer to a member signal of the sender
- \a receiver is the receiver object, may not be null, will be equal to sender when
+ \a receiver is the receiver object, may not be \nullptr, will be equal to sender when
connecting to a static function or a functor
\a slot a pointer only used when using Qt::UniqueConnection
\a type the Qt::ConnctionType passed as argument to connect
@@ -4853,7 +4878,7 @@ void qDeleteInEventHandler(QObject *o)
to be used with queued connection
must stay valid at least for the whole time of the connection, this function
do not take ownership. typically static data.
- If null, then the types will be computed when the signal is emit in a queued
+ If \nullptr, then the types will be computed when the signal is emit in a queued
connection from the types from the signature.
\a senderMetaObject is the metaobject used to lookup the signal, the signal must be in
this metaobject
@@ -4864,7 +4889,7 @@ QMetaObject::Connection QObject::connectImpl(const QObject *sender, void **signa
const int *types, const QMetaObject *senderMetaObject)
{
if (!signal) {
- qWarning("QObject::connect: invalid null parameter");
+ qWarning("QObject::connect: invalid nullptr parameter");
if (slotObj)
slotObj->destroyIfLastRef();
return QMetaObject::Connection();
@@ -4880,7 +4905,7 @@ QMetaObject::Connection QObject::connectImpl(const QObject *sender, void **signa
if (!senderMetaObject) {
qWarning("QObject::connect: signal not found in %s", sender->metaObject()->className());
slotObj->destroyIfLastRef();
- return QMetaObject::Connection(0);
+ return QMetaObject::Connection(nullptr);
}
signal_index += QMetaObjectPrivate::signalOffset(senderMetaObject);
return QObjectPrivate::connectImpl(sender, signal_index, receiver, slot, slotObj, type, types, senderMetaObject);
@@ -4904,7 +4929,7 @@ QMetaObject::Connection QObjectPrivate::connectImpl(const QObject *sender, int s
: "Unknown";
const char *receiverString = receiver ? receiver->metaObject()->className()
: "Unknown";
- qWarning("QObject::connect(%s, %s): invalid null parameter", senderString, receiverString);
+ qWarning("QObject::connect(%s, %s): invalid nullptr parameter", senderString, receiverString);
if (slotObj)
slotObj->destroyIfLastRef();
return QMetaObject::Connection();
@@ -5037,20 +5062,20 @@ bool QObject::disconnect(const QMetaObject::Connection &connection)
\endlist
- 0 may be used as a wildcard, meaning "any signal", "any receiving
+ \nullptr may be used as a wildcard, meaning "any signal", "any receiving
object", or "any slot in the receiving object", respectively.
The \a sender may never be \nullptr. (You cannot disconnect signals
from more than one object in a single call.)
- If \a signal is 0, it disconnects \a receiver and \a method from
+ If \a signal is \nullptr, it disconnects \a receiver and \a method from
any signal. If not, only the specified signal is disconnected.
- If \a receiver is 0, it disconnects anything connected to \a
+ If \a receiver is \nullptr, it disconnects anything connected to \a
signal. If not, slots in objects other than \a receiver are not
disconnected.
- If \a method is 0, it disconnects anything that is connected to \a
+ If \a method is \nullptr, it disconnects anything that is connected to \a
receiver. If not, only slots named \a method will be disconnected,
and all other slots are left alone. The \a method must be \nullptr
if \a receiver is left out, so you cannot disconnect a
@@ -5066,8 +5091,8 @@ bool QObject::disconnect(const QMetaObject::Connection &connection)
bool QObject::disconnectImpl(const QObject *sender, void **signal, const QObject *receiver, void **slot, const QMetaObject *senderMetaObject)
{
- if (sender == 0 || (receiver == 0 && slot != 0)) {
- qWarning("QObject::disconnect: Unexpected null parameter");
+ if (sender == nullptr || (receiver == nullptr && slot != nullptr)) {
+ qWarning("QObject::disconnect: Unexpected nullptr parameter");
return false;
}
@@ -5098,7 +5123,7 @@ bool QObject::disconnectImpl(const QObject *sender, void **signal, const QObject
QMetaObject::Connection QObjectPrivate::connect(const QObject *sender, int signal_index, QtPrivate::QSlotObjectBase *slotObj, Qt::ConnectionType type)
{
if (!sender) {
- qWarning("QObject::connect: invalid null parameter");
+ qWarning("QObject::connect: invalid nullptr parameter");
if (slotObj)
slotObj->destroyIfLastRef();
return QMetaObject::Connection();
@@ -5106,7 +5131,7 @@ QMetaObject::Connection QObjectPrivate::connect(const QObject *sender, int signa
const QMetaObject *senderMetaObject = sender->metaObject();
signal_index = methodIndexToSignalIndex(&senderMetaObject, signal_index);
- return QObjectPrivate::connectImpl(sender, signal_index, sender, /*slot*/0, slotObj, type, /*types*/0, senderMetaObject);
+ return QObjectPrivate::connectImpl(sender, signal_index, sender, /*slot*/nullptr, slotObj, type, /*types*/nullptr, senderMetaObject);
}
/*!
@@ -5163,7 +5188,7 @@ QMetaObject::Connection& QMetaObject::Connection::operator=(const QMetaObject::C
Creates a Connection instance.
*/
-QMetaObject::Connection::Connection() : d_ptr(0) {}
+QMetaObject::Connection::Connection() : d_ptr(nullptr) {}
/*!
Destructor for QMetaObject::Connection.
diff --git a/src/corelib/kernel/qobject.h b/src/corelib/kernel/qobject.h
index 296552c2f2..8d9cc3ab83 100644
--- a/src/corelib/kernel/qobject.h
+++ b/src/corelib/kernel/qobject.h
@@ -55,7 +55,7 @@
#include <QtCore/qobject_impl.h>
-#if QT_HAS_INCLUDE(<chrono>)
+#if __has_include(<chrono>)
# include <chrono>
#endif
@@ -154,7 +154,7 @@ public:
void moveToThread(QThread *thread);
int startTimer(int interval, Qt::TimerType timerType = Qt::CoarseTimer);
-#if QT_HAS_INCLUDE(<chrono>)
+#if __has_include(<chrono>)
Q_ALWAYS_INLINE
int startTimer(std::chrono::milliseconds time, Qt::TimerType timerType = Qt::CoarseTimer)
{
@@ -434,9 +434,6 @@ protected:
protected:
QScopedPointer<QObjectData> d_ptr;
- static const QMetaObject staticQtMetaObject;
- friend inline const QMetaObject *qt_getQtMetaObject() noexcept;
-
friend struct QMetaObject;
friend struct QMetaObjectPrivate;
friend class QMetaCallEvent;
@@ -467,9 +464,6 @@ inline QMetaObject::Connection QObject::connect(const QObject *asender, const ch
const char *amember, Qt::ConnectionType atype) const
{ return connect(asender, asignal, this, amember, atype); }
-inline const QMetaObject *qt_getQtMetaObject() noexcept
-{ return &QObject::staticQtMetaObject; }
-
#if QT_DEPRECATED_SINCE(5, 0)
template<typename T>
inline QT_DEPRECATED T qFindChild(const QObject *o, const QString &name = QString())
diff --git a/src/corelib/kernel/qobject_p.h b/src/corelib/kernel/qobject_p.h
index db62c03b7a..d6e73fbefc 100644
--- a/src/corelib/kernel/qobject_p.h
+++ b/src/corelib/kernel/qobject_p.h
@@ -362,8 +362,12 @@ public:
}
public:
ExtraData *extraData; // extra data set by the user
- QThreadData *getThreadData() const { return threadData; }
- QThreadData *threadData; // id of the thread that owns the object
+ // This atomic requires acquire/release semantics in a few places,
+ // e.g. QObject::moveToThread must synchronize with QCoreApplication::postEvent,
+ // because postEvent is thread-safe.
+ // However, most of the code paths involving QObject are only reentrant and
+ // not thread-safe, so synchronization should not be necessary there.
+ QAtomicPointer<QThreadData> threadData; // id of the thread that owns the object
using ConnectionDataPointer = QExplicitlySharedDataPointer<ConnectionData>;
QAtomicPointer<ConnectionData> connections;
diff --git a/src/corelib/kernel/qobjectcleanuphandler.cpp b/src/corelib/kernel/qobjectcleanuphandler.cpp
index b6c62af4b3..8bf0e1fcab 100644
--- a/src/corelib/kernel/qobjectcleanuphandler.cpp
+++ b/src/corelib/kernel/qobjectcleanuphandler.cpp
@@ -94,7 +94,7 @@ QObjectCleanupHandler::~QObjectCleanupHandler()
QObject *QObjectCleanupHandler::add(QObject* object)
{
if (!object)
- return 0;
+ return nullptr;
connect(object, SIGNAL(destroyed(QObject*)), this, SLOT(objectDestroyed(QObject*)));
cleanupObjects.insert(0, object);
diff --git a/src/corelib/kernel/qobjectdefs.h b/src/corelib/kernel/qobjectdefs.h
index 9f654b0318..657cb9940b 100644
--- a/src/corelib/kernel/qobjectdefs.h
+++ b/src/corelib/kernel/qobjectdefs.h
@@ -46,199 +46,15 @@
#endif
#include <QtCore/qnamespace.h>
-
#include <QtCore/qobjectdefs_impl.h>
+#include <QtCore/qtmetamacros.h>
QT_BEGIN_NAMESPACE
-
class QByteArray;
struct QArrayData;
-typedef QArrayData QByteArrayData;
class QString;
-#ifndef Q_MOC_OUTPUT_REVISION
-#define Q_MOC_OUTPUT_REVISION 67
-#endif
-
-// The following macros can be defined by tools that understand Qt
-// to have the information from the macro.
-#ifndef QT_ANNOTATE_CLASS
-# define QT_ANNOTATE_CLASS(type, ...)
-#endif
-#ifndef QT_ANNOTATE_CLASS2
-# define QT_ANNOTATE_CLASS2(type, a1, a2)
-#endif
-#ifndef QT_ANNOTATE_FUNCTION
-# define QT_ANNOTATE_FUNCTION(x)
-#endif
-#ifndef QT_ANNOTATE_ACCESS_SPECIFIER
-# define QT_ANNOTATE_ACCESS_SPECIFIER(x)
-#endif
-
-// The following macros are our "extensions" to C++
-// They are used, strictly speaking, only by the moc.
-
-#ifndef Q_MOC_RUN
-#ifndef QT_NO_META_MACROS
-# if defined(QT_NO_KEYWORDS)
-# define QT_NO_EMIT
-# else
-# ifndef QT_NO_SIGNALS_SLOTS_KEYWORDS
-# define slots Q_SLOTS
-# define signals Q_SIGNALS
-# endif
-# endif
-# define Q_SLOTS QT_ANNOTATE_ACCESS_SPECIFIER(qt_slot)
-# define Q_SIGNALS public QT_ANNOTATE_ACCESS_SPECIFIER(qt_signal)
-# define Q_PRIVATE_SLOT(d, signature) QT_ANNOTATE_CLASS2(qt_private_slot, d, signature)
-# define Q_EMIT
-#ifndef QT_NO_EMIT
-# define emit
-#endif
-#ifndef Q_CLASSINFO
-# define Q_CLASSINFO(name, value)
-#endif
-#define Q_PLUGIN_METADATA(x) QT_ANNOTATE_CLASS(qt_plugin_metadata, x)
-#define Q_INTERFACES(x) QT_ANNOTATE_CLASS(qt_interfaces, x)
-#define Q_PROPERTY(...) QT_ANNOTATE_CLASS(qt_property, __VA_ARGS__)
-#define Q_PRIVATE_PROPERTY(d, text) QT_ANNOTATE_CLASS2(qt_private_property, d, text)
-#ifndef Q_REVISION
-# define Q_REVISION(v)
-#endif
-#define Q_OVERRIDE(text) QT_ANNOTATE_CLASS(qt_override, text)
-#define QDOC_PROPERTY(text) QT_ANNOTATE_CLASS(qt_qdoc_property, text)
-#define Q_ENUMS(x) QT_ANNOTATE_CLASS(qt_enums, x)
-#define Q_FLAGS(x) QT_ANNOTATE_CLASS(qt_enums, x)
-#define Q_ENUM_IMPL(ENUM) \
- friend Q_DECL_CONSTEXPR const QMetaObject *qt_getEnumMetaObject(ENUM) noexcept { return &staticMetaObject; } \
- friend Q_DECL_CONSTEXPR const char *qt_getEnumName(ENUM) noexcept { return #ENUM; }
-#define Q_ENUM(x) Q_ENUMS(x) Q_ENUM_IMPL(x)
-#define Q_FLAG(x) Q_FLAGS(x) Q_ENUM_IMPL(x)
-#define Q_ENUM_NS_IMPL(ENUM) \
- inline Q_DECL_CONSTEXPR const QMetaObject *qt_getEnumMetaObject(ENUM) noexcept { return &staticMetaObject; } \
- inline Q_DECL_CONSTEXPR const char *qt_getEnumName(ENUM) noexcept { return #ENUM; }
-#define Q_ENUM_NS(x) Q_ENUMS(x) Q_ENUM_NS_IMPL(x)
-#define Q_FLAG_NS(x) Q_FLAGS(x) Q_ENUM_NS_IMPL(x)
-#define Q_SCRIPTABLE QT_ANNOTATE_FUNCTION(qt_scriptable)
-#define Q_INVOKABLE QT_ANNOTATE_FUNCTION(qt_invokable)
-#define Q_SIGNAL QT_ANNOTATE_FUNCTION(qt_signal)
-#define Q_SLOT QT_ANNOTATE_FUNCTION(qt_slot)
-#endif // QT_NO_META_MACROS
-
-#ifndef QT_NO_TRANSLATION
-// full set of tr functions
-# define QT_TR_FUNCTIONS \
- static inline QString tr(const char *s, const char *c = nullptr, int n = -1) \
- { return staticMetaObject.tr(s, c, n); } \
- QT_DEPRECATED static inline QString trUtf8(const char *s, const char *c = nullptr, int n = -1) \
- { return staticMetaObject.tr(s, c, n); }
-#else
-// inherit the ones from QObject
-# define QT_TR_FUNCTIONS
-#endif
-
-#ifdef Q_CLANG_QDOC
-#define QT_TR_FUNCTIONS
-#endif
-
-// ### Qt6: remove
-#define Q_OBJECT_CHECK /* empty, unused since Qt 5.2 */
-
-#if defined(Q_CC_INTEL)
-// Cannot redefine the visibility of a method in an exported class
-# define Q_DECL_HIDDEN_STATIC_METACALL
-#else
-# define Q_DECL_HIDDEN_STATIC_METACALL Q_DECL_HIDDEN
-#endif
-
-#if defined(Q_CC_CLANG) && Q_CC_CLANG >= 306
-# define Q_OBJECT_NO_OVERRIDE_WARNING QT_WARNING_DISABLE_CLANG("-Winconsistent-missing-override")
-#elif defined(Q_CC_GNU) && !defined(Q_CC_INTEL) && Q_CC_GNU >= 501
-# define Q_OBJECT_NO_OVERRIDE_WARNING QT_WARNING_DISABLE_GCC("-Wsuggest-override")
-#else
-# define Q_OBJECT_NO_OVERRIDE_WARNING
-#endif
-
-#if defined(Q_CC_GNU) && !defined(Q_CC_INTEL) && Q_CC_GNU >= 600
-# define Q_OBJECT_NO_ATTRIBUTES_WARNING QT_WARNING_DISABLE_GCC("-Wattributes")
-#else
-# define Q_OBJECT_NO_ATTRIBUTES_WARNING
-#endif
-
-/* qmake ignore Q_OBJECT */
-#define Q_OBJECT \
-public: \
- QT_WARNING_PUSH \
- Q_OBJECT_NO_OVERRIDE_WARNING \
- static const QMetaObject staticMetaObject; \
- virtual const QMetaObject *metaObject() const; \
- virtual void *qt_metacast(const char *); \
- virtual int qt_metacall(QMetaObject::Call, int, void **); \
- QT_TR_FUNCTIONS \
-private: \
- Q_OBJECT_NO_ATTRIBUTES_WARNING \
- Q_DECL_HIDDEN_STATIC_METACALL static void qt_static_metacall(QObject *, QMetaObject::Call, int, void **); \
- QT_WARNING_POP \
- struct QPrivateSignal {}; \
- QT_ANNOTATE_CLASS(qt_qobject, "")
-
-/* qmake ignore Q_OBJECT */
-#define Q_OBJECT_FAKE Q_OBJECT QT_ANNOTATE_CLASS(qt_fake, "")
-
-#ifndef QT_NO_META_MACROS
-/* qmake ignore Q_GADGET */
-#define Q_GADGET \
-public: \
- static const QMetaObject staticMetaObject; \
- void qt_check_for_QGADGET_macro(); \
- typedef void QtGadgetHelper; \
-private: \
- QT_WARNING_PUSH \
- Q_OBJECT_NO_ATTRIBUTES_WARNING \
- Q_DECL_HIDDEN_STATIC_METACALL static void qt_static_metacall(QObject *, QMetaObject::Call, int, void **); \
- QT_WARNING_POP \
- QT_ANNOTATE_CLASS(qt_qgadget, "") \
- /*end*/
-
-/* qmake ignore Q_NAMESPACE_EXPORT */
-#define Q_NAMESPACE_EXPORT(...) \
- extern __VA_ARGS__ const QMetaObject staticMetaObject; \
- QT_ANNOTATE_CLASS(qt_qnamespace, "") \
- /*end*/
-
-/* qmake ignore Q_NAMESPACE */
-#define Q_NAMESPACE Q_NAMESPACE_EXPORT() \
- /*end*/
-
-#endif // QT_NO_META_MACROS
-
-#else // Q_MOC_RUN
-#define slots slots
-#define signals signals
-#define Q_SLOTS Q_SLOTS
-#define Q_SIGNALS Q_SIGNALS
-#define Q_CLASSINFO(name, value) Q_CLASSINFO(name, value)
-#define Q_INTERFACES(x) Q_INTERFACES(x)
-#define Q_PROPERTY(text) Q_PROPERTY(text)
-#define Q_PRIVATE_PROPERTY(d, text) Q_PRIVATE_PROPERTY(d, text)
-#define Q_REVISION(v) Q_REVISION(v)
-#define Q_OVERRIDE(text) Q_OVERRIDE(text)
-#define Q_ENUMS(x) Q_ENUMS(x)
-#define Q_FLAGS(x) Q_FLAGS(x)
-#define Q_ENUM(x) Q_ENUM(x)
-#define Q_FLAGS(x) Q_FLAGS(x)
- /* qmake ignore Q_OBJECT */
-#define Q_OBJECT Q_OBJECT
- /* qmake ignore Q_OBJECT */
-#define Q_OBJECT_FAKE Q_OBJECT_FAKE
- /* qmake ignore Q_GADGET */
-#define Q_GADGET Q_GADGET
-#define Q_SCRIPTABLE Q_SCRIPTABLE
-#define Q_INVOKABLE Q_INVOKABLE
-#define Q_SIGNAL Q_SIGNAL
-#define Q_SLOT Q_SLOT
-#endif //Q_MOC_RUN
#ifndef QT_NO_META_MACROS
// macro for onaming members
@@ -607,7 +423,7 @@ struct Q_CORE_EXPORT QMetaObject
struct { // private data
SuperData superdata;
- const QByteArrayData *stringdata;
+ const uint *stringdata;
const uint *data;
typedef void (*StaticMetacallFunction)(QObject *, QMetaObject::Call, int, void **);
StaticMetacallFunction static_metacall;
diff --git a/src/corelib/kernel/qsharedmemory.cpp b/src/corelib/kernel/qsharedmemory.cpp
index 39f3002394..2d65e0bbe4 100644
--- a/src/corelib/kernel/qsharedmemory.cpp
+++ b/src/corelib/kernel/qsharedmemory.cpp
@@ -441,7 +441,7 @@ bool QSharedMemory::attach(AccessMode mode)
bool QSharedMemory::isAttached() const
{
Q_D(const QSharedMemory);
- return (0 != d->memory);
+ return (nullptr != d->memory);
}
/*!
diff --git a/src/corelib/kernel/qsharedmemory_systemv.cpp b/src/corelib/kernel/qsharedmemory_systemv.cpp
index fea4a65b5c..0ba5f65641 100644
--- a/src/corelib/kernel/qsharedmemory_systemv.cpp
+++ b/src/corelib/kernel/qsharedmemory_systemv.cpp
@@ -182,9 +182,9 @@ bool QSharedMemoryPrivate::attach(QSharedMemory::AccessMode mode)
}
// grab the memory
- memory = shmat(id, 0, (mode == QSharedMemory::ReadOnly ? SHM_RDONLY : 0));
+ memory = shmat(id, nullptr, (mode == QSharedMemory::ReadOnly ? SHM_RDONLY : 0));
if ((void*) - 1 == memory) {
- memory = 0;
+ memory = nullptr;
setErrorString(QLatin1String("QSharedMemory::attach (shmat)"));
return false;
}
@@ -216,7 +216,7 @@ bool QSharedMemoryPrivate::detach()
}
return false;
}
- memory = 0;
+ memory = nullptr;
size = 0;
// Get the number of current attachments
diff --git a/src/corelib/kernel/qsharedmemory_unix.cpp b/src/corelib/kernel/qsharedmemory_unix.cpp
index f6d7e78441..bc0f3b03ca 100644
--- a/src/corelib/kernel/qsharedmemory_unix.cpp
+++ b/src/corelib/kernel/qsharedmemory_unix.cpp
@@ -68,7 +68,7 @@ QSharedMemoryPrivate::QSharedMemoryPrivate() :
#ifndef QT_NO_QOBJECT
QObjectPrivate(),
#endif
- memory(0), size(0), error(QSharedMemory::NoError),
+ memory(nullptr), size(0), error(QSharedMemory::NoError),
#ifndef QT_NO_SYSTEMSEMAPHORE
systemSemaphore(QString()), lockedByMe(false),
#endif
diff --git a/src/corelib/kernel/qsocketnotifier.cpp b/src/corelib/kernel/qsocketnotifier.cpp
index 2a246b1204..78269ee605 100644
--- a/src/corelib/kernel/qsocketnotifier.cpp
+++ b/src/corelib/kernel/qsocketnotifier.cpp
@@ -147,12 +147,14 @@ QSocketNotifier::QSocketNotifier(qintptr socket, Type type, QObject *parent)
d->sntype = type;
d->snenabled = true;
+ auto thisThreadData = d->threadData.loadRelaxed();
+
if (socket < 0)
qWarning("QSocketNotifier: Invalid socket specified");
- else if (!d->threadData->hasEventDispatcher())
+ else if (!thisThreadData->hasEventDispatcher())
qWarning("QSocketNotifier: Can only be used with threads started with QThread");
else
- d->threadData->eventDispatcher.loadRelaxed()->registerSocketNotifier(this);
+ thisThreadData->eventDispatcher.loadRelaxed()->registerSocketNotifier(this);
}
/*!
@@ -234,16 +236,19 @@ void QSocketNotifier::setEnabled(bool enable)
return;
d->snenabled = enable;
- if (!d->threadData->hasEventDispatcher()) // perhaps application/thread is shutting down
+
+ auto thisThreadData = d->threadData.loadRelaxed();
+
+ if (!thisThreadData->hasEventDispatcher()) // perhaps application/thread is shutting down
return;
if (Q_UNLIKELY(thread() != QThread::currentThread())) {
qWarning("QSocketNotifier: Socket notifiers cannot be enabled or disabled from another thread");
return;
}
if (d->snenabled)
- d->threadData->eventDispatcher.loadRelaxed()->registerSocketNotifier(this);
+ thisThreadData->eventDispatcher.loadRelaxed()->registerSocketNotifier(this);
else
- d->threadData->eventDispatcher.loadRelaxed()->unregisterSocketNotifier(this);
+ thisThreadData->eventDispatcher.loadRelaxed()->unregisterSocketNotifier(this);
}
diff --git a/src/corelib/kernel/qtestsupport_core.cpp b/src/corelib/kernel/qtestsupport_core.cpp
index 7bd81ed498..8498f7f025 100644
--- a/src/corelib/kernel/qtestsupport_core.cpp
+++ b/src/corelib/kernel/qtestsupport_core.cpp
@@ -55,7 +55,7 @@ Q_CORE_EXPORT void QTestPrivate::qSleep(int ms)
Sleep(uint(ms));
#else
struct timespec ts = { time_t(ms / 1000), (ms % 1000) * 1000 * 1000 };
- nanosleep(&ts, NULL);
+ nanosleep(&ts, nullptr);
#endif
}
diff --git a/src/corelib/kernel/qtimer.cpp b/src/corelib/kernel/qtimer.cpp
index 948f697dc5..25ce0c032f 100644
--- a/src/corelib/kernel/qtimer.cpp
+++ b/src/corelib/kernel/qtimer.cpp
@@ -84,10 +84,10 @@ QT_BEGIN_NAMESPACE
must start and stop the timer in its thread; it is not possible to
start a timer from another thread.
- As a special case, a QTimer with a timeout of 0 will time out as
- soon as all the events in the window system's event queue have
- been processed. This can be used to do heavy work while providing
- a snappy user interface:
+ As a special case, a QTimer with a timeout of 0 will time out as soon as
+ possible, though the ordering between zero timers and other sources of
+ events is unspecified. Zero timers can be used to do some work while still
+ providing a snappy user interface:
\snippet timers/timers.cpp 4
\snippet timers/timers.cpp 5
@@ -277,7 +277,7 @@ protected:
};
QSingleShotTimer::QSingleShotTimer(int msec, Qt::TimerType timerType, const QObject *r, const char *member)
- : QObject(QAbstractEventDispatcher::instance()), hasValidReceiver(true), slotObj(0)
+ : QObject(QAbstractEventDispatcher::instance()), hasValidReceiver(true), slotObj(nullptr)
{
timerId = startTimer(msec, timerType);
connect(this, SIGNAL(timeout()), r, member);
@@ -290,7 +290,7 @@ QSingleShotTimer::QSingleShotTimer(int msec, Qt::TimerType timerType, const QObj
if (r && thread() != r->thread()) {
// Avoid leaking the QSingleShotTimer instance in case the application exits before the timer fires
connect(QCoreApplication::instance(), &QCoreApplication::aboutToQuit, this, &QObject::deleteLater);
- setParent(0);
+ setParent(nullptr);
moveToThread(r->thread());
}
}
@@ -316,7 +316,7 @@ void QSingleShotTimer::timerEvent(QTimerEvent *)
if (Q_LIKELY(!receiver.isNull() || !hasValidReceiver)) {
// We allocate only the return type - we previously checked the function had
// no arguments.
- void *args[1] = { 0 };
+ void *args[1] = { nullptr };
slotObj->call(const_cast<QObject*>(receiver.data()), args);
}
} else {
diff --git a/src/corelib/kernel/qtimer.h b/src/corelib/kernel/qtimer.h
index eb7185c12d..6bbfd741d9 100644
--- a/src/corelib/kernel/qtimer.h
+++ b/src/corelib/kernel/qtimer.h
@@ -47,7 +47,7 @@
#include <QtCore/qbasictimer.h> // conceptual inheritance
#include <QtCore/qobject.h>
-#if QT_HAS_INCLUDE(<chrono>)
+#if __has_include(<chrono>)
# include <chrono>
#endif
@@ -177,7 +177,7 @@ Q_SIGNALS:
void timeout(QPrivateSignal);
public:
-#if QT_HAS_INCLUDE(<chrono>) || defined(Q_QDOC)
+#if __has_include(<chrono>) || defined(Q_QDOC)
void setInterval(std::chrono::milliseconds value)
{
setInterval(int(value.count()));
@@ -223,7 +223,7 @@ private:
static void singleShotImpl(int msec, Qt::TimerType timerType,
const QObject *receiver, QtPrivate::QSlotObjectBase *slotObj);
-#if QT_HAS_INCLUDE(<chrono>)
+#if __has_include(<chrono>)
static Qt::TimerType defaultTypeFor(std::chrono::milliseconds interval)
{ return defaultTypeFor(int(interval.count())); }
diff --git a/src/corelib/kernel/qtimerinfo_unix.cpp b/src/corelib/kernel/qtimerinfo_unix.cpp
index 39010c19cb..b425ca3dcb 100644
--- a/src/corelib/kernel/qtimerinfo_unix.cpp
+++ b/src/corelib/kernel/qtimerinfo_unix.cpp
@@ -83,7 +83,7 @@ QTimerInfoList::QTimerInfoList()
}
#endif
- firstTimerInfo = 0;
+ firstTimerInfo = nullptr;
}
timespec QTimerInfoList::updateCurrentTime()
@@ -389,7 +389,7 @@ bool QTimerInfoList::timerWait(timespec &tm)
repairTimersIfNeeded();
// Find first waiting timer not already active
- QTimerInfo *t = 0;
+ QTimerInfo *t = nullptr;
for (QTimerInfoList::const_iterator it = constBegin(); it != constEnd(); ++it) {
if (!(*it)->activateRef) {
t = *it;
@@ -450,7 +450,7 @@ void QTimerInfoList::registerTimer(int timerId, int interval, Qt::TimerType time
t->interval = interval;
t->timerType = timerType;
t->obj = object;
- t->activateRef = 0;
+ t->activateRef = nullptr;
timespec expected = updateCurrentTime() + interval;
@@ -514,9 +514,9 @@ bool QTimerInfoList::unregisterTimer(int timerId)
// found it
removeAt(i);
if (t == firstTimerInfo)
- firstTimerInfo = 0;
+ firstTimerInfo = nullptr;
if (t->activateRef)
- *(t->activateRef) = 0;
+ *(t->activateRef) = nullptr;
delete t;
return true;
}
@@ -535,9 +535,9 @@ bool QTimerInfoList::unregisterTimers(QObject *object)
// object found
removeAt(i);
if (t == firstTimerInfo)
- firstTimerInfo = 0;
+ firstTimerInfo = nullptr;
if (t->activateRef)
- *(t->activateRef) = 0;
+ *(t->activateRef) = nullptr;
delete t;
// move back one so that we don't skip the new current item
--i;
@@ -571,7 +571,7 @@ int QTimerInfoList::activateTimers()
return 0; // nothing to do
int n_act = 0, maxCount = 0;
- firstTimerInfo = 0;
+ firstTimerInfo = nullptr;
timespec currentTime = updateCurrentTime();
// qDebug() << "Thread" << QThread::currentThreadId() << "woken up at" << currentTime;
@@ -643,11 +643,11 @@ int QTimerInfoList::activateTimers()
QCoreApplication::sendEvent(currentTimerInfo->obj, &e);
if (currentTimerInfo)
- currentTimerInfo->activateRef = 0;
+ currentTimerInfo->activateRef = nullptr;
}
}
- firstTimerInfo = 0;
+ firstTimerInfo = nullptr;
// qDebug() << "Thread" << QThread::currentThreadId() << "activated" << n_act << "timers";
return n_act;
}
diff --git a/src/corelib/kernel/qtmetamacros.h b/src/corelib/kernel/qtmetamacros.h
new file mode 100644
index 0000000000..1d095c0d7c
--- /dev/null
+++ b/src/corelib/kernel/qtmetamacros.h
@@ -0,0 +1,234 @@
+/****************************************************************************
+**
+** Copyright (C) 2019 The Qt Company Ltd.
+** Copyright (C) 2019 Olivier Goffart <ogoffart@woboq.com>
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the QtCore module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QTMETAMACROS_H
+#define QTMETAMACROS_H
+
+#include <QtCore/qglobal.h>
+
+QT_BEGIN_NAMESPACE
+
+#ifndef Q_MOC_OUTPUT_REVISION
+#define Q_MOC_OUTPUT_REVISION 67
+#endif
+
+// The following macros can be defined by tools that understand Qt
+// to have the information from the macro.
+#ifndef QT_ANNOTATE_CLASS
+# define QT_ANNOTATE_CLASS(type, ...)
+#endif
+#ifndef QT_ANNOTATE_CLASS2
+# define QT_ANNOTATE_CLASS2(type, a1, a2)
+#endif
+#ifndef QT_ANNOTATE_FUNCTION
+# define QT_ANNOTATE_FUNCTION(x)
+#endif
+#ifndef QT_ANNOTATE_ACCESS_SPECIFIER
+# define QT_ANNOTATE_ACCESS_SPECIFIER(x)
+#endif
+
+// The following macros are our "extensions" to C++
+// They are used, strictly speaking, only by the moc.
+
+#ifndef Q_MOC_RUN
+#ifndef QT_NO_META_MACROS
+# if defined(QT_NO_KEYWORDS)
+# define QT_NO_EMIT
+# else
+# ifndef QT_NO_SIGNALS_SLOTS_KEYWORDS
+# define slots Q_SLOTS
+# define signals Q_SIGNALS
+# endif
+# endif
+# define Q_SLOTS QT_ANNOTATE_ACCESS_SPECIFIER(qt_slot)
+# define Q_SIGNALS public QT_ANNOTATE_ACCESS_SPECIFIER(qt_signal)
+# define Q_PRIVATE_SLOT(d, signature) QT_ANNOTATE_CLASS2(qt_private_slot, d, signature)
+# define Q_EMIT
+#ifndef QT_NO_EMIT
+# define emit
+#endif
+#ifndef Q_CLASSINFO
+# define Q_CLASSINFO(name, value)
+#endif
+#define Q_PLUGIN_METADATA(x) QT_ANNOTATE_CLASS(qt_plugin_metadata, x)
+#define Q_INTERFACES(x) QT_ANNOTATE_CLASS(qt_interfaces, x)
+#define Q_PROPERTY(...) QT_ANNOTATE_CLASS(qt_property, __VA_ARGS__)
+#define Q_PRIVATE_PROPERTY(d, text) QT_ANNOTATE_CLASS2(qt_private_property, d, text)
+#ifndef Q_REVISION
+# define Q_REVISION(v)
+#endif
+#define Q_OVERRIDE(text) QT_ANNOTATE_CLASS(qt_override, text)
+#define QDOC_PROPERTY(text) QT_ANNOTATE_CLASS(qt_qdoc_property, text)
+#define Q_ENUMS(x) QT_ANNOTATE_CLASS(qt_enums, x)
+#define Q_FLAGS(x) QT_ANNOTATE_CLASS(qt_enums, x)
+#define Q_ENUM_IMPL(ENUM) \
+ friend Q_DECL_CONSTEXPR const QMetaObject *qt_getEnumMetaObject(ENUM) noexcept { return &staticMetaObject; } \
+ friend Q_DECL_CONSTEXPR const char *qt_getEnumName(ENUM) noexcept { return #ENUM; }
+#define Q_ENUM(x) Q_ENUMS(x) Q_ENUM_IMPL(x)
+#define Q_FLAG(x) Q_FLAGS(x) Q_ENUM_IMPL(x)
+#define Q_ENUM_NS_IMPL(ENUM) \
+ inline Q_DECL_CONSTEXPR const QMetaObject *qt_getEnumMetaObject(ENUM) noexcept { return &staticMetaObject; } \
+ inline Q_DECL_CONSTEXPR const char *qt_getEnumName(ENUM) noexcept { return #ENUM; }
+#define Q_ENUM_NS(x) Q_ENUMS(x) Q_ENUM_NS_IMPL(x)
+#define Q_FLAG_NS(x) Q_FLAGS(x) Q_ENUM_NS_IMPL(x)
+#define Q_SCRIPTABLE QT_ANNOTATE_FUNCTION(qt_scriptable)
+#define Q_INVOKABLE QT_ANNOTATE_FUNCTION(qt_invokable)
+#define Q_SIGNAL QT_ANNOTATE_FUNCTION(qt_signal)
+#define Q_SLOT QT_ANNOTATE_FUNCTION(qt_slot)
+#define Q_MOC_INCLUDE(...) QT_ANNOTATE_CLASS(qt_moc_include, __VA_ARGS__)
+#endif // QT_NO_META_MACROS
+
+#ifndef QT_NO_TRANSLATION
+// full set of tr functions
+# define QT_TR_FUNCTIONS \
+ static inline QString tr(const char *s, const char *c = nullptr, int n = -1) \
+ { return staticMetaObject.tr(s, c, n); } \
+ QT_DEPRECATED static inline QString trUtf8(const char *s, const char *c = nullptr, int n = -1) \
+ { return staticMetaObject.tr(s, c, n); }
+#else
+// inherit the ones from QObject
+# define QT_TR_FUNCTIONS
+#endif
+
+#ifdef Q_CLANG_QDOC
+#define QT_TR_FUNCTIONS
+#endif
+
+// ### Qt6: remove
+#define Q_OBJECT_CHECK /* empty, unused since Qt 5.2 */
+
+#if defined(Q_CC_INTEL)
+// Cannot redefine the visibility of a method in an exported class
+# define Q_DECL_HIDDEN_STATIC_METACALL
+#else
+# define Q_DECL_HIDDEN_STATIC_METACALL Q_DECL_HIDDEN
+#endif
+
+#if defined(Q_CC_CLANG) && Q_CC_CLANG >= 306
+# define Q_OBJECT_NO_OVERRIDE_WARNING QT_WARNING_DISABLE_CLANG("-Winconsistent-missing-override")
+#elif defined(Q_CC_GNU) && !defined(Q_CC_INTEL) && Q_CC_GNU >= 501
+# define Q_OBJECT_NO_OVERRIDE_WARNING QT_WARNING_DISABLE_GCC("-Wsuggest-override")
+#else
+# define Q_OBJECT_NO_OVERRIDE_WARNING
+#endif
+
+#if defined(Q_CC_GNU) && !defined(Q_CC_INTEL) && Q_CC_GNU >= 600
+# define Q_OBJECT_NO_ATTRIBUTES_WARNING QT_WARNING_DISABLE_GCC("-Wattributes")
+#else
+# define Q_OBJECT_NO_ATTRIBUTES_WARNING
+#endif
+
+/* qmake ignore Q_OBJECT */
+#define Q_OBJECT \
+public: \
+ QT_WARNING_PUSH \
+ Q_OBJECT_NO_OVERRIDE_WARNING \
+ static const QMetaObject staticMetaObject; \
+ virtual const QMetaObject *metaObject() const; \
+ virtual void *qt_metacast(const char *); \
+ virtual int qt_metacall(QMetaObject::Call, int, void **); \
+ QT_TR_FUNCTIONS \
+private: \
+ Q_OBJECT_NO_ATTRIBUTES_WARNING \
+ Q_DECL_HIDDEN_STATIC_METACALL static void qt_static_metacall(QObject *, QMetaObject::Call, int, void **); \
+ QT_WARNING_POP \
+ struct QPrivateSignal {}; \
+ QT_ANNOTATE_CLASS(qt_qobject, "")
+
+/* qmake ignore Q_OBJECT */
+#define Q_OBJECT_FAKE Q_OBJECT QT_ANNOTATE_CLASS(qt_fake, "")
+
+#ifndef QT_NO_META_MACROS
+/* qmake ignore Q_GADGET */
+#define Q_GADGET \
+public: \
+ static const QMetaObject staticMetaObject; \
+ void qt_check_for_QGADGET_macro(); \
+ typedef void QtGadgetHelper; \
+private: \
+ QT_WARNING_PUSH \
+ Q_OBJECT_NO_ATTRIBUTES_WARNING \
+ Q_DECL_HIDDEN_STATIC_METACALL static void qt_static_metacall(QObject *, QMetaObject::Call, int, void **); \
+ QT_WARNING_POP \
+ QT_ANNOTATE_CLASS(qt_qgadget, "") \
+ /*end*/
+
+/* qmake ignore Q_NAMESPACE_EXPORT */
+#define Q_NAMESPACE_EXPORT(...) \
+ extern __VA_ARGS__ const QMetaObject staticMetaObject; \
+ QT_ANNOTATE_CLASS(qt_qnamespace, "") \
+ /*end*/
+
+/* qmake ignore Q_NAMESPACE */
+#define Q_NAMESPACE Q_NAMESPACE_EXPORT() \
+ /*end*/
+
+#endif // QT_NO_META_MACROS
+
+#else // Q_MOC_RUN
+#define slots slots
+#define signals signals
+#define Q_SLOTS Q_SLOTS
+#define Q_SIGNALS Q_SIGNALS
+#define Q_CLASSINFO(name, value) Q_CLASSINFO(name, value)
+#define Q_INTERFACES(x) Q_INTERFACES(x)
+#define Q_PROPERTY(text) Q_PROPERTY(text)
+#define Q_PRIVATE_PROPERTY(d, text) Q_PRIVATE_PROPERTY(d, text)
+#define Q_REVISION(v) Q_REVISION(v)
+#define Q_OVERRIDE(text) Q_OVERRIDE(text)
+#define Q_ENUMS(x) Q_ENUMS(x)
+#define Q_FLAGS(x) Q_FLAGS(x)
+#define Q_ENUM(x) Q_ENUM(x)
+#define Q_FLAGS(x) Q_FLAGS(x)
+ /* qmake ignore Q_OBJECT */
+#define Q_OBJECT Q_OBJECT
+ /* qmake ignore Q_OBJECT */
+#define Q_OBJECT_FAKE Q_OBJECT_FAKE
+ /* qmake ignore Q_GADGET */
+#define Q_GADGET Q_GADGET
+#define Q_SCRIPTABLE Q_SCRIPTABLE
+#define Q_INVOKABLE Q_INVOKABLE
+#define Q_SIGNAL Q_SIGNAL
+#define Q_SLOT Q_SLOT
+#endif //Q_MOC_RUN
+
+QT_END_NAMESPACE
+
+#endif // QTMETAMACROS_H
diff --git a/src/corelib/kernel/qtranslator.cpp b/src/corelib/kernel/qtranslator.cpp
index 31c1277b03..4bd8874630 100644
--- a/src/corelib/kernel/qtranslator.cpp
+++ b/src/corelib/kernel/qtranslator.cpp
@@ -289,8 +289,8 @@ public:
#if defined(QT_USE_MMAP)
used_mmap(0),
#endif
- unmapPointer(0), unmapLength(0), resource(0),
- messageArray(0), offsetArray(0), contextArray(0), numerusRulesArray(0),
+ unmapPointer(nullptr), unmapLength(0), resource(nullptr),
+ messageArray(nullptr), offsetArray(nullptr), contextArray(nullptr), numerusRulesArray(nullptr),
messageLength(0), offsetLength(0), contextLength(0), numerusRulesLength(0) {}
#if defined(QT_USE_MMAP)
@@ -539,7 +539,7 @@ bool QTranslatorPrivate::do_load(const QString &realname, const QString &directo
ok = true;
} else {
delete resource;
- resource = 0;
+ resource = nullptr;
}
}
@@ -610,8 +610,8 @@ bool QTranslatorPrivate::do_load(const QString &realname, const QString &directo
delete [] unmapPointer;
delete d->resource;
- d->resource = 0;
- d->unmapPointer = 0;
+ d->resource = nullptr;
+ d->unmapPointer = nullptr;
d->unmapLength = 0;
return false;
@@ -874,10 +874,10 @@ bool QTranslatorPrivate::do_load(const uchar *data, qsizetype len, const QString
}
if (!ok) {
- messageArray = 0;
- contextArray = 0;
- offsetArray = 0;
- numerusRulesArray = 0;
+ messageArray = nullptr;
+ contextArray = nullptr;
+ offsetArray = nullptr;
+ numerusRulesArray = nullptr;
messageLength = 0;
contextLength = 0;
offsetLength = 0;
@@ -890,7 +890,7 @@ bool QTranslatorPrivate::do_load(const uchar *data, qsizetype len, const QString
static QString getMessage(const uchar *m, const uchar *end, const char *context,
const char *sourceText, const char *comment, uint numerus)
{
- const uchar *tn = 0;
+ const uchar *tn = nullptr;
uint tn_length = 0;
const uint sourceTextLen = uint(strlen(sourceText));
const uint contextLen = uint(strlen(context));
@@ -957,11 +957,11 @@ end:
QString QTranslatorPrivate::do_translate(const char *context, const char *sourceText,
const char *comment, int n) const
{
- if (context == 0)
+ if (context == nullptr)
context = "";
- if (sourceText == 0)
+ if (sourceText == nullptr)
sourceText = "";
- if (comment == 0)
+ if (comment == nullptr)
comment = "";
uint numerus = 0;
@@ -1076,13 +1076,13 @@ void QTranslatorPrivate::clear()
}
delete resource;
- resource = 0;
- unmapPointer = 0;
+ resource = nullptr;
+ unmapPointer = nullptr;
unmapLength = 0;
- messageArray = 0;
- contextArray = 0;
- offsetArray = 0;
- numerusRulesArray = 0;
+ messageArray = nullptr;
+ contextArray = nullptr;
+ offsetArray = nullptr;
+ numerusRulesArray = nullptr;
messageLength = 0;
contextLength = 0;
offsetLength = 0;
diff --git a/src/corelib/kernel/qvariant.cpp b/src/corelib/kernel/qvariant.cpp
index 60d1a91eef..d1bd2d308f 100644
--- a/src/corelib/kernel/qvariant.cpp
+++ b/src/corelib/kernel/qvariant.cpp
@@ -944,7 +944,7 @@ static bool convert(const QVariant::Private *d, int t, void *result, bool *ok)
const QVariantHash *hash = v_cast<QVariantHash>(d);
const auto end = hash->end();
for (auto it = hash->begin(); it != end; ++it)
- map->insertMulti(it.key(), it.value());
+ static_cast<QMultiMap<QString, QVariant> *>(map)->insert(it.key(), it.value());
#ifndef QT_BOOTSTRAPPED
} else if (d->type == QMetaType::QCborValue) {
if (!v_cast<QCborValue>(d)->isMap())
@@ -972,7 +972,7 @@ static bool convert(const QVariant::Private *d, int t, void *result, bool *ok)
const QVariantMap *map = v_cast<QVariantMap>(d);
const auto end = map->end();
for (auto it = map->begin(); it != end; ++it)
- hash->insertMulti(it.key(), it.value());
+ static_cast<QMultiHash<QString, QVariant> *>(hash)->insert(it.key(), it.value());
#ifndef QT_BOOTSTRAPPED
} else if (d->type == QMetaType::QCborValue) {
if (!v_cast<QCborValue>(d)->isMap())
@@ -1544,7 +1544,7 @@ static void customStreamDebug(QDebug dbg, const QVariant &variant) {
#ifndef QT_BOOTSTRAPPED
QMetaType::TypeFlags flags = QMetaType::typeFlags(variant.userType());
if (flags & QMetaType::PointerToQObject)
- dbg.nospace() << variant.value<QObject*>();
+ dbg.nospace() << qvariant_cast<QObject*>(variant);
#else
Q_UNUSED(dbg);
Q_UNUSED(variant);
@@ -2525,7 +2525,7 @@ void QVariant::load(QDataStream &s)
return;
}
}
- create(typeId, 0);
+ create(typeId, nullptr);
d.is_null = is_null;
if (!isValid()) {
@@ -2583,8 +2583,8 @@ void QVariant::save(QDataStream &s) const
#endif
// and as a result these types received lower ids too
typeId +=1;
- } else if (typeId == QMetaType::QPolygonF) {
- // This existed in Qt 4 only as a custom type
+ } else if (typeId == QMetaType::QPolygonF || typeId == QMetaType::QUuid) {
+ // These existed in Qt 4 only as a custom type
typeId = 127;
fakeUserType = true;
}
@@ -3840,58 +3840,6 @@ bool QVariant::convert(const int type, void *ptr) const
QMetaType::registerComparators().
*/
-/*!
- \fn bool QVariant::operator<(const QVariant &v) const
-
- Compares this QVariant with \a v and returns \c true if this is less than \a v.
-
- \note Comparability might not be availabe for the type stored in this QVariant
- or in \a v.
-
- \warning To make this function work with a custom type registered with
- qRegisterMetaType(), its comparison operator must be registered using
- QMetaType::registerComparators().
-*/
-
-/*!
- \fn bool QVariant::operator<=(const QVariant &v) const
-
- Compares this QVariant with \a v and returns \c true if this is less or equal than \a v.
-
- \note Comparability might not be available for the type stored in this QVariant
- or in \a v.
-
- \warning To make this function work with a custom type registered with
- qRegisterMetaType(), its comparison operator must be registered using
- QMetaType::registerComparators().
-*/
-
-/*!
- \fn bool QVariant::operator>(const QVariant &v) const
-
- Compares this QVariant with \a v and returns \c true if this is larger than \a v.
-
- \note Comparability might not be available for the type stored in this QVariant
- or in \a v.
-
- \warning To make this function work with a custom type registered with
- qRegisterMetaType(), its comparison operator must be registered using
- QMetaType::registerComparators().
-*/
-
-/*!
- \fn bool QVariant::operator>=(const QVariant &v) const
-
- Compares this QVariant with \a v and returns \c true if this is larger or equal than \a v.
-
- \note Comparability might not be available for the type stored in this QVariant
- or in \a v.
-
- \warning To make this function work with a custom type registered with
- qRegisterMetaType(), its comparison operator must be registered using
- QMetaType::registerComparators().
-*/
-
static bool qIsNumericType(uint tp)
{
static const qulonglong numericTypeBits =
@@ -4072,73 +4020,6 @@ bool QVariant::cmp(const QVariant &v) const
/*!
\internal
*/
-int QVariant::compare(const QVariant &v) const
-{
- // try numerics first, with C++ type promotion rules (no conversion)
- if (qIsNumericType(d.type) && qIsNumericType(v.d.type))
- return numericCompare(&d, &v.d);
-
- // check for equality next, as more types implement operator== than operator<
- if (cmp(v))
- return 0;
-
- const QVariant *v1 = this;
- const QVariant *v2 = &v;
- QVariant converted1;
- QVariant converted2;
-
- if (d.type != v.d.type) {
- // if both types differ, try to convert
- if (v2->canConvert(v1->d.type)) {
- converted2 = *v2;
- if (converted2.convert(v1->d.type))
- v2 = &converted2;
- }
- if (v1->d.type != v2->d.type && v1->canConvert(v2->d.type)) {
- converted1 = *v1;
- if (converted1.convert(v2->d.type))
- v1 = &converted1;
- }
- if (v1->d.type != v2->d.type) {
- // if conversion fails, default to toString
- int r = v1->toString().compare(v2->toString(), Qt::CaseInsensitive);
- if (r == 0) {
- // cmp(v) returned false, so we should try to agree with it.
- return (v1->d.type < v2->d.type) ? -1 : 1;
- }
- return r;
- }
-
- // did we end up with two numerics? If so, restart
- if (qIsNumericType(v1->d.type) && qIsNumericType(v2->d.type))
- return v1->compare(*v2);
- }
- if (v1->d.type >= QMetaType::User) {
- int result;
- if (QMetaType::compare(QT_PREPEND_NAMESPACE(constData(d)), QT_PREPEND_NAMESPACE(constData(v2->d)), d.type, &result))
- return result;
- }
- switch (v1->d.type) {
- case QVariant::Date:
- return v1->toDate() < v2->toDate() ? -1 : 1;
- case QVariant::Time:
- return v1->toTime() < v2->toTime() ? -1 : 1;
- case QVariant::DateTime:
- return v1->toDateTime() < v2->toDateTime() ? -1 : 1;
- case QVariant::StringList:
- return v1->toStringList() < v2->toStringList() ? -1 : 1;
- }
- int r = v1->toString().compare(v2->toString(), Qt::CaseInsensitive);
- if (r == 0) {
- // cmp(v) returned false, so we should try to agree with it.
- return (d.type < v.d.type) ? -1 : 1;
- }
- return r;
-}
-
-/*!
- \internal
- */
const void *QVariant::constData() const
{
@@ -4533,15 +4414,24 @@ QSequentialIterable::const_iterator QSequentialIterable::end() const
return it;
}
+static const QVariant variantFromVariantDataHelper(const QtMetaTypePrivate::VariantData &d) {
+ QVariant v;
+ if (d.metaTypeId == qMetaTypeId<QVariant>())
+ v = *reinterpret_cast<const QVariant*>(d.data);
+ else
+ v = QVariant(d.metaTypeId, d.data, d.flags & ~QVariantConstructionFlags::ShouldDeleteVariantData);
+ if (d.flags & QVariantConstructionFlags::ShouldDeleteVariantData)
+ QMetaType::destroy(d.metaTypeId, const_cast<void *>(d.data));
+ return v;
+}
+
/*!
Returns the element at position \a idx in the container.
*/
QVariant QSequentialIterable::at(int idx) const
{
const QtMetaTypePrivate::VariantData d = m_impl.at(idx);
- if (d.metaTypeId == qMetaTypeId<QVariant>())
- return *reinterpret_cast<const QVariant*>(d.data);
- return QVariant(d.metaTypeId, d.data, d.flags);
+ return variantFromVariantDataHelper(d);
}
/*!
@@ -4618,9 +4508,7 @@ QSequentialIterable::const_iterator::operator=(const const_iterator &other)
const QVariant QSequentialIterable::const_iterator::operator*() const
{
const QtMetaTypePrivate::VariantData d = m_impl.getCurrent();
- if (d.metaTypeId == qMetaTypeId<QVariant>())
- return *reinterpret_cast<const QVariant*>(d.data);
- return QVariant(d.metaTypeId, d.data, d.flags);
+ return variantFromVariantDataHelper(d);
}
/*!
@@ -4952,10 +4840,7 @@ QAssociativeIterable::const_iterator::operator=(const const_iterator &other)
const QVariant QAssociativeIterable::const_iterator::operator*() const
{
const QtMetaTypePrivate::VariantData d = m_impl.getCurrentValue();
- QVariant v(d.metaTypeId, d.data, d.flags);
- if (d.metaTypeId == qMetaTypeId<QVariant>())
- return *reinterpret_cast<const QVariant*>(d.data);
- return v;
+ return variantFromVariantDataHelper(d);
}
/*!
@@ -4964,10 +4849,7 @@ const QVariant QAssociativeIterable::const_iterator::operator*() const
const QVariant QAssociativeIterable::const_iterator::key() const
{
const QtMetaTypePrivate::VariantData d = m_impl.getCurrentKey();
- QVariant v(d.metaTypeId, d.data, d.flags);
- if (d.metaTypeId == qMetaTypeId<QVariant>())
- return *reinterpret_cast<const QVariant*>(d.data);
- return v;
+ return variantFromVariantDataHelper(d);
}
/*!
@@ -4975,11 +4857,7 @@ const QVariant QAssociativeIterable::const_iterator::key() const
*/
const QVariant QAssociativeIterable::const_iterator::value() const
{
- const QtMetaTypePrivate::VariantData d = m_impl.getCurrentValue();
- QVariant v(d.metaTypeId, d.data, d.flags);
- if (d.metaTypeId == qMetaTypeId<QVariant>())
- return *reinterpret_cast<const QVariant*>(d.data);
- return v;
+ return operator*();
}
/*!
diff --git a/src/corelib/kernel/qvariant.h b/src/corelib/kernel/qvariant.h
index 331adea4e7..353bfa7ce7 100644
--- a/src/corelib/kernel/qvariant.h
+++ b/src/corelib/kernel/qvariant.h
@@ -53,7 +53,7 @@
#include <QtCore/qbytearraylist.h>
#endif
-#if QT_HAS_INCLUDE(<variant>) && __cplusplus >= 201703L
+#if __has_include(<variant>) && __cplusplus >= 201703L
#include <variant>
#elif defined(Q_CLANG_QDOC)
namespace std { template<typename...> struct variant; }
@@ -372,7 +372,7 @@ class Q_CORE_EXPORT QVariant
static inline QVariant fromValue(const T &value)
{ return QVariant(qMetaTypeId<T>(), &value, QTypeInfo<T>::isPointer); }
-#if (QT_HAS_INCLUDE(<variant>) && __cplusplus >= 201703L) || defined(Q_CLANG_QDOC)
+#if (__has_include(<variant>) && __cplusplus >= 201703L) || defined(Q_CLANG_QDOC)
template<typename... Types>
static inline QVariant fromStdVariant(const std::variant<Types...> &value)
{
@@ -396,7 +396,7 @@ class Q_CORE_EXPORT QVariant
struct Private
{
inline Private() noexcept : type(Invalid), is_shared(false), is_null(true)
- { data.ptr = nullptr; }
+ {}
// Internal constructor for initialized variants.
explicit inline Private(uint variantType) noexcept
@@ -412,6 +412,7 @@ class Q_CORE_EXPORT QVariant
#endif
union Data
{
+ void *threeptr[3] = { nullptr, nullptr, nullptr };
char c;
uchar uc;
short s;
@@ -465,14 +466,6 @@ class Q_CORE_EXPORT QVariant
{ return cmp(v); }
inline bool operator!=(const QVariant &v) const
{ return !cmp(v); }
- inline bool operator<(const QVariant &v) const
- { return compare(v) < 0; }
- inline bool operator<=(const QVariant &v) const
- { return compare(v) <= 0; }
- inline bool operator>(const QVariant &v) const
- { return compare(v) > 0; }
- inline bool operator>=(const QVariant &v) const
- { return compare(v) >= 0; }
protected:
friend inline bool operator==(const QVariant &, const QVariantComparisonHelper &);
@@ -491,7 +484,6 @@ public:
Private d;
void create(int type, const void *copy);
bool cmp(const QVariant &other) const;
- int compare(const QVariant &other) const;
bool convert(const int t, void *ptr) const; // ### Qt6: drop const
private:
@@ -546,7 +538,7 @@ inline QVariant QVariant::fromValue(const QVariant &value)
return value;
}
-#if QT_HAS_INCLUDE(<variant>) && __cplusplus >= 201703L
+#if __has_include(<variant>) && __cplusplus >= 201703L
template<>
inline QVariant QVariant::fromValue(const std::monostate &)
{
@@ -779,7 +771,7 @@ namespace QtPrivate {
return QSequentialIterable(QtMetaTypePrivate::QSequentialIterableImpl(reinterpret_cast<const QByteArrayList*>(v.constData())));
}
#endif
- return QSequentialIterable(v.value<QtMetaTypePrivate::QSequentialIterableImpl>());
+ return QSequentialIterable(qvariant_cast<QtMetaTypePrivate::QSequentialIterableImpl>(v));
}
};
template<>
@@ -794,7 +786,7 @@ namespace QtPrivate {
if (typeId == qMetaTypeId<QVariantHash>()) {
return QAssociativeIterable(QtMetaTypePrivate::QAssociativeIterableImpl(reinterpret_cast<const QVariantHash*>(v.constData())));
}
- return QAssociativeIterable(v.value<QtMetaTypePrivate::QAssociativeIterableImpl>());
+ return QAssociativeIterable(qvariant_cast<QtMetaTypePrivate::QAssociativeIterableImpl>(v));
}
};
template<>
@@ -803,7 +795,8 @@ namespace QtPrivate {
static QVariantList invoke(const QVariant &v)
{
const int typeId = v.userType();
- if (typeId == qMetaTypeId<QStringList>() || typeId == qMetaTypeId<QByteArrayList>() || QMetaType::hasRegisteredConverterFunction(typeId, qMetaTypeId<QtMetaTypePrivate::QSequentialIterableImpl>())) {
+ if (typeId == qMetaTypeId<QStringList>() || typeId == qMetaTypeId<QByteArrayList>() ||
+ (QMetaType::hasRegisteredConverterFunction(typeId, qMetaTypeId<QtMetaTypePrivate::QSequentialIterableImpl>()) && !QMetaType::hasRegisteredConverterFunction(typeId, qMetaTypeId<QVariantList>()))) {
QSequentialIterable iter = QVariantValueHelperInterface<QSequentialIterable>::invoke(v);
QVariantList l;
l.reserve(iter.size());
@@ -820,12 +813,12 @@ namespace QtPrivate {
static QVariantHash invoke(const QVariant &v)
{
const int typeId = v.userType();
- if (typeId == qMetaTypeId<QVariantMap>() || QMetaType::hasRegisteredConverterFunction(typeId, qMetaTypeId<QtMetaTypePrivate::QAssociativeIterableImpl>())) {
+ if (typeId == qMetaTypeId<QVariantMap>() || ((QMetaType::hasRegisteredConverterFunction(typeId, qMetaTypeId<QtMetaTypePrivate::QAssociativeIterableImpl>())) && !QMetaType::hasRegisteredConverterFunction(typeId, qMetaTypeId<QVariantHash>()))) {
QAssociativeIterable iter = QVariantValueHelperInterface<QAssociativeIterable>::invoke(v);
QVariantHash l;
l.reserve(iter.size());
for (QAssociativeIterable::const_iterator it = iter.begin(), end = iter.end(); it != end; ++it)
- l.insertMulti(it.key().toString(), it.value());
+ static_cast<QMultiHash<QString, QVariant> &>(l).insert(it.key().toString(), it.value());
return l;
}
return QVariantValueHelper<QVariantHash>::invoke(v);
@@ -837,11 +830,11 @@ namespace QtPrivate {
static QVariantMap invoke(const QVariant &v)
{
const int typeId = v.userType();
- if (typeId == qMetaTypeId<QVariantHash>() || QMetaType::hasRegisteredConverterFunction(typeId, qMetaTypeId<QtMetaTypePrivate::QAssociativeIterableImpl>())) {
+ if (typeId == qMetaTypeId<QVariantHash>() || (QMetaType::hasRegisteredConverterFunction(typeId, qMetaTypeId<QtMetaTypePrivate::QAssociativeIterableImpl>()) && !QMetaType::hasRegisteredConverterFunction(typeId, qMetaTypeId<QVariantMap>()))) {
QAssociativeIterable iter = QVariantValueHelperInterface<QAssociativeIterable>::invoke(v);
QVariantMap l;
for (QAssociativeIterable::const_iterator it = iter.begin(), end = iter.end(); it != end; ++it)
- l.insertMulti(it.key().toString(), it.value());
+ static_cast<QMultiMap<QString, QVariant> &>(l).insert(it.key().toString(), it.value());
return l;
}
return QVariantValueHelper<QVariantMap>::invoke(v);
@@ -853,12 +846,9 @@ namespace QtPrivate {
static QPair<QVariant, QVariant> invoke(const QVariant &v)
{
const int typeId = v.userType();
- if (typeId == qMetaTypeId<QPair<QVariant, QVariant> >())
- return QVariantValueHelper<QPair<QVariant, QVariant> >::invoke(v);
- if (QMetaType::hasRegisteredConverterFunction(typeId, qMetaTypeId<QtMetaTypePrivate::QPairVariantInterfaceImpl>())) {
+ if (QMetaType::hasRegisteredConverterFunction(typeId, qMetaTypeId<QtMetaTypePrivate::QPairVariantInterfaceImpl>()) && !(typeId == qMetaTypeId<QPair<QVariant, QVariant> >())) {
QtMetaTypePrivate::QPairVariantInterfaceImpl pi = v.value<QtMetaTypePrivate::QPairVariantInterfaceImpl>();
-
const QtMetaTypePrivate::VariantData d1 = pi.first();
QVariant v1(d1.metaTypeId, d1.data, d1.flags);
if (d1.metaTypeId == qMetaTypeId<QVariant>())
diff --git a/src/corelib/kernel/qvariant_p.h b/src/corelib/kernel/qvariant_p.h
index 3d87beac83..b8b63b5e6f 100644
--- a/src/corelib/kernel/qvariant_p.h
+++ b/src/corelib/kernel/qvariant_p.h
@@ -105,6 +105,11 @@ inline T *v_cast(QVariant::Private *d, T * = nullptr)
#endif
+enum QVariantConstructionFlags : uint {
+ Default = 0x0,
+ PointerType = 0x1,
+ ShouldDeleteVariantData = 0x2 // only used in Q*Iterable
+};
//a simple template that avoids to allocate 2 memory chunks when creating a QVariant
template <class T> class QVariantPrivateSharedEx : public QVariant::PrivateShared
diff --git a/src/corelib/kernel/qwineventnotifier.cpp b/src/corelib/kernel/qwineventnotifier.cpp
index d2ae9668fe..db5d44b276 100644
--- a/src/corelib/kernel/qwineventnotifier.cpp
+++ b/src/corelib/kernel/qwineventnotifier.cpp
@@ -124,7 +124,7 @@ QWinEventNotifier::QWinEventNotifier(HANDLE hEvent, QObject *parent)
: QObject(*new QWinEventNotifierPrivate(hEvent, false), parent)
{
Q_D(QWinEventNotifier);
- QAbstractEventDispatcher *eventDispatcher = d->threadData->eventDispatcher.loadRelaxed();
+ QAbstractEventDispatcher *eventDispatcher = d->threadData.loadRelaxed()->eventDispatcher.loadRelaxed();
if (Q_UNLIKELY(!eventDispatcher)) {
qWarning("QWinEventNotifier: Can only be used with threads started with QThread");
return;
@@ -197,7 +197,7 @@ void QWinEventNotifier::setEnabled(bool enable)
return;
d->enabled = enable;
- QAbstractEventDispatcher *eventDispatcher = d->threadData->eventDispatcher.loadRelaxed();
+ QAbstractEventDispatcher *eventDispatcher = d->threadData.loadRelaxed()->eventDispatcher.loadRelaxed();
if (!eventDispatcher) { // perhaps application is shutting down
if (!enable && d->waitHandle != nullptr)
d->unregisterWaitObject();
@@ -256,7 +256,7 @@ void QWinEventNotifierPrivate::unregisterWaitObject()
static void CALLBACK wfsoCallback(void *context, BOOLEAN /*ignore*/)
{
QWinEventNotifierPrivate *nd = reinterpret_cast<QWinEventNotifierPrivate *>(context);
- QAbstractEventDispatcher *eventDispatcher = nd->threadData->eventDispatcher.loadRelaxed();
+ QAbstractEventDispatcher *eventDispatcher = nd->threadData.loadRelaxed()->eventDispatcher.loadRelaxed();
// Happens when Q(Core)Application is destroyed before QWinEventNotifier.
// https://bugreports.qt.io/browse/QTBUG-70214