diff options
Diffstat (limited to 'src/corelib')
-rw-r--r-- | src/corelib/corelib.pro | 14 | ||||
-rw-r--r-- | src/corelib/global/qcompilerdetection.h | 6 | ||||
-rw-r--r-- | src/corelib/global/qglobal.h | 12 | ||||
-rw-r--r-- | src/corelib/io/io.pri | 2 | ||||
-rw-r--r-- | src/corelib/io/qdir.cpp | 13 | ||||
-rw-r--r-- | src/corelib/io/qstandardpaths_android.cpp | 331 | ||||
-rw-r--r-- | src/corelib/io/qurl.cpp | 2 | ||||
-rw-r--r-- | src/corelib/itemmodels/qabstractitemmodel.cpp | 28 | ||||
-rw-r--r-- | src/corelib/kernel/qjnihelpers.cpp | 21 | ||||
-rw-r--r-- | src/corelib/kernel/qjnihelpers_p.h | 1 | ||||
-rw-r--r-- | src/corelib/kernel/qobject.cpp | 9 | ||||
-rw-r--r-- | src/corelib/kernel/qobject_p.h | 6 | ||||
-rw-r--r-- | src/corelib/thread/qthread_p.h | 2 | ||||
-rw-r--r-- | src/corelib/thread/qthread_unix.cpp | 4 | ||||
-rw-r--r-- | src/corelib/thread/qthread_win.cpp | 4 | ||||
-rw-r--r-- | src/corelib/tools/qcommandlineparser.cpp | 3 | ||||
-rw-r--r-- | src/corelib/tools/qdatetime.cpp | 42 | ||||
-rw-r--r-- | src/corelib/tools/qstring.cpp | 35 | ||||
-rw-r--r-- | src/corelib/tools/qstring_mips_dsp_asm.S | 449 | ||||
-rw-r--r-- | src/corelib/tools/qvector.h | 21 | ||||
-rw-r--r-- | src/corelib/tools/tools.pri | 4 |
21 files changed, 965 insertions, 44 deletions
diff --git a/src/corelib/corelib.pro b/src/corelib/corelib.pro index b513149e7c..df28183fdc 100644 --- a/src/corelib/corelib.pro +++ b/src/corelib/corelib.pro @@ -111,3 +111,17 @@ ctest_qt5_module_files.files += $$ctest_macros_file.output $$cmake_extras_mkspec ctest_qt5_module_files.path = $$[QT_INSTALL_LIBS]/cmake/Qt5Core INSTALLS += ctest_qt5_module_files cmake_qt5_umbrella_module_files + +mips_dsp:*-g++* { + HEADERS += $$MIPS_DSP_HEADERS + + mips_dsp_corelib_assembler.commands = $$QMAKE_CXX -c + mips_dsp_corelib_assembler.commands += $(CXXFLAGS) $(INCPATH) -mips32r2 -mdsp ${QMAKE_FILE_IN} -o ${QMAKE_FILE_OUT} + mips_dsp_corelib_assembler.dependency_type = TYPE_C + mips_dsp_corelib_assembler.output = ${QMAKE_VAR_OBJECTS_DIR}${QMAKE_FILE_BASE}$${first(QMAKE_EXT_OBJ)} + mips_dsp_corelib_assembler.input = MIPS_DSP_ASM + mips_dsp_corelib_assembler.variable_out = OBJECTS + mips_dsp_corelib_assembler.name = assembling[mips_dsp] ${QMAKE_FILE_IN} + silent:mips_dsp_corelib_assembler.commands = @echo assembling[mips_dsp] ${QMAKE_FILE_IN} && $$mips_dsp_corelib_assembler.commands + QMAKE_EXTRA_COMPILERS += mips_dsp_corelib_assembler +} diff --git a/src/corelib/global/qcompilerdetection.h b/src/corelib/global/qcompilerdetection.h index 44077132d4..d526d40398 100644 --- a/src/corelib/global/qcompilerdetection.h +++ b/src/corelib/global/qcompilerdetection.h @@ -251,7 +251,7 @@ # if defined(__EDG__) # define Q_CC_EDG # endif -/* Compaq have disabled EDG's _BOOL macro and use _BOOL_EXISTS instead +/* Compaq has disabled EDG's _BOOL macro and uses _BOOL_EXISTS instead - observed on Compaq C++ V6.3-002. In any case versions prior to Compaq C++ V6.0-005 do not have bool. */ # if !defined(_BOOL_EXISTS) @@ -722,13 +722,13 @@ # define Q_COMPILER_DECLTYPE # define Q_COMPILER_RVALUE_REFS # define Q_COMPILER_STATIC_ASSERT -// MSVC's library has std::initilizer_list, but the compiler does not support the braces initialization +// MSVC's library has std::initializer_list, but the compiler does not support the braces initialization //# define Q_COMPILER_INITIALIZER_LISTS //# define Q_COMPILER_UNIFORM_INIT # endif # if _MSC_VER >= 1700 /* C++11 features supported in VC11 = VC2012: */ -# undef Q_DECL_OVERRIDE /* undo 2005/2098 settings... */ +# undef Q_DECL_OVERRIDE /* undo 2005/2008 settings... */ # undef Q_DECL_FINAL /* undo 2005/2008 settings... */ # define Q_COMPILER_EXPLICIT_OVERRIDES /* ...and use std C++11 now */ # define Q_COMPILER_RANGE_FOR diff --git a/src/corelib/global/qglobal.h b/src/corelib/global/qglobal.h index d8c987d2e0..30db4e75cf 100644 --- a/src/corelib/global/qglobal.h +++ b/src/corelib/global/qglobal.h @@ -45,11 +45,11 @@ #include <stddef.h> -#define QT_VERSION_STR "5.2.1" +#define QT_VERSION_STR "5.2.2" /* QT_VERSION is (major << 16) + (minor << 8) + patch. */ -#define QT_VERSION 0x050201 +#define QT_VERSION 0x050202 /* can be used like #if (QT_VERSION >= QT_VERSION_CHECK(4, 4, 0)) */ @@ -826,9 +826,13 @@ Q_CORE_EXPORT void qFreeAligned(void *ptr); # pragma warning(disable: 4800) /* 'type' : forcing value to bool 'true' or 'false' (performance warning) */ # pragma warning(disable: 4097) /* typedef-name 'identifier1' used as synonym for class-name 'identifier2' */ # pragma warning(disable: 4706) /* assignment within conditional expression */ -# pragma warning(disable: 4786) /* 'identifier' : identifier was truncated to 'number' characters in the debug information */ +# if _MSC_VER <= 1310 // MSVC 2003 +# pragma warning(disable: 4786) /* 'identifier' : identifier was truncated to 'number' characters in the debug information */ +# endif # pragma warning(disable: 4355) /* 'this' : used in base member initializer list */ -# pragma warning(disable: 4231) /* nonstandard extension used : 'identifier' before template explicit instantiation */ +# if _MSC_VER < 1800 // MSVC 2013 +# pragma warning(disable: 4231) /* nonstandard extension used : 'identifier' before template explicit instantiation */ +# endif # pragma warning(disable: 4710) /* function not inlined */ # pragma warning(disable: 4530) /* C++ exception handler used, but unwind semantics are not enabled. Specify /EHsc */ # elif defined(Q_CC_BOR) diff --git a/src/corelib/io/io.pri b/src/corelib/io/io.pri index f06bf61b09..649493f8b7 100644 --- a/src/corelib/io/io.pri +++ b/src/corelib/io/io.pri @@ -142,6 +142,8 @@ win32 { } } else:blackberry { SOURCES += io/qstandardpaths_blackberry.cpp + } else:android { + SOURCES += io/qstandardpaths_android.cpp } else { SOURCES += io/qstandardpaths_unix.cpp } diff --git a/src/corelib/io/qdir.cpp b/src/corelib/io/qdir.cpp index 43db2ec1fe..b704126efa 100644 --- a/src/corelib/io/qdir.cpp +++ b/src/corelib/io/qdir.cpp @@ -716,11 +716,12 @@ QString QDir::absoluteFilePath(const QString &fileName) const return fileName; d->resolveAbsoluteEntry(); + const QString absoluteDirPath = d->absoluteDirEntry.filePath(); if (fileName.isEmpty()) - return d->absoluteDirEntry.filePath(); - if (!d->absoluteDirEntry.isRoot()) - return d->absoluteDirEntry.filePath() % QLatin1Char('/') % fileName; - return d->absoluteDirEntry.filePath() % fileName; + return absoluteDirPath; + if (!absoluteDirPath.endsWith(QLatin1Char('/'))) + return absoluteDirPath % QLatin1Char('/') % fileName; + return absoluteDirPath % fileName; } /*! @@ -855,7 +856,7 @@ QString QDir::fromNativeSeparators(const QString &pathName) /*! Changes the QDir's directory to \a dirName. - Returns \c true if the new directory exists and is readable; + Returns \c true if the new directory exists; otherwise returns \c false. Note that the logical cd() operation is not performed if the new directory does not exist. @@ -923,7 +924,7 @@ bool QDir::cd(const QString &dirName) Changes directory by moving one directory up from the QDir's current directory. - Returns \c true if the new directory exists and is readable; + Returns \c true if the new directory exists; otherwise returns \c false. Note that the logical cdUp() operation is not performed if the new directory does not exist. diff --git a/src/corelib/io/qstandardpaths_android.cpp b/src/corelib/io/qstandardpaths_android.cpp new file mode 100644 index 0000000000..60b285a3d6 --- /dev/null +++ b/src/corelib/io/qstandardpaths_android.cpp @@ -0,0 +1,331 @@ +/**************************************************************************** +** +** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** 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 Digia. For licensing terms and +** conditions see http://qt.digia.com/licensing. For further information +** use the contact form at http://qt.digia.com/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 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Digia gives you certain additional +** rights. These rights are described in the Digia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qstandardpaths.h" + +#ifndef QT_NO_STANDARDPATHS + +#include <QtCore/private/qjni_p.h> +#include <QtCore/private/qjnihelpers_p.h> +#include <QtCore/qmap.h> +#include <QDir> + +QT_BEGIN_NAMESPACE + +typedef QMap<QString, QString> AndroidDirCache; +Q_GLOBAL_STATIC(AndroidDirCache, androidDirCache) + +static QString testDir() +{ + return QStandardPaths::isTestModeEnabled() ? QLatin1String("/qttest") + : QLatin1String(""); +} + +static QJNIObjectPrivate applicationContext() +{ + static QJNIObjectPrivate appCtx; + if (appCtx.isValid()) + return appCtx; + + QJNIObjectPrivate activity = QtAndroidPrivate::activity(); + if (!activity.isValid()) + return appCtx; + + appCtx = activity.callObjectMethod("getApplicationContext", + "()Landroid/content/Context;"); + return appCtx; +} + +static inline QString getAbsolutePath(const QJNIObjectPrivate &file) +{ + QJNIObjectPrivate path = file.callObjectMethod("getAbsolutePath", + "()Ljava/lang/String;"); + if (!path.isValid()) + return QString(); + + return path.toString(); +} + +/* + * The root of the external storage + * + */ +static QString getExternalStorageDirectory() +{ + QString &path = (*androidDirCache)[QStringLiteral("EXT_ROOT")]; + if (!path.isEmpty()) + return path; + + QJNIObjectPrivate file = QJNIObjectPrivate::callStaticObjectMethod("android/os/Environment", + "getExternalStorageDirectory", + "()Ljava/io/File;"); + if (!file.isValid()) + return QString(); + + return (path = getAbsolutePath(file)); +} + +/* + * Locations where applications can place user files (public). + * E.g., /storage/Music + */ +static QString getExternalStoragePublicDirectory(const char *directoryField) +{ + QString &path = (*androidDirCache)[QLatin1String(directoryField)]; + if (!path.isEmpty()) + return path; + + QJNIObjectPrivate dirField = QJNIObjectPrivate::getStaticObjectField("android/os/Environment", + directoryField, + "Ljava/lang/String;"); + if (!dirField.isValid()) + return QString(); + + QJNIObjectPrivate file = QJNIObjectPrivate::callStaticObjectMethod("android/os/Environment", + "getExternalStoragePublicDirectory", + "(Ljava/lang/String;)Ljava/io/File;", + dirField.object()); + if (!file.isValid()) + return QString(); + + return (path = getAbsolutePath(file)); +} + +/* + * Locations where applications can place persistent files it owns. + * E.g., /storage/org.app/Music + */ +static QString getExternalFilesDir(const char *directoryField = 0) +{ + QString &path = (*androidDirCache)[QString(QLatin1String("APPNAME_%1")).arg(QLatin1String(directoryField))]; + if (!path.isEmpty()) + return path; + + QJNIObjectPrivate activity = QtAndroidPrivate::activity(); + if (!activity.isValid()) + return QString(); + + QJNIObjectPrivate appCtx = applicationContext(); + if (!appCtx.isValid()) + return QString(); + + QJNIObjectPrivate dirField = QJNIObjectPrivate::fromString(QLatin1String("")); + if (directoryField) { + dirField = QJNIObjectPrivate::getStaticObjectField("android/os/Environment", + directoryField, + "Ljava/lang/String;"); + if (!dirField.isValid()) + return QString(); + } + + QJNIObjectPrivate file = appCtx.callObjectMethod("getExternalFilesDir", + "(Ljava/lang/String;)Ljava/io/File;", + dirField.object()); + + if (!file.isValid()) + return QString(); + + return (path = getAbsolutePath(file)); +} + +/* + * Directory where applications can store cache files it owns (public). + * E.g., /storage/org.app/ + */ +static QString getExternalCacheDir() +{ + QString &path = (*androidDirCache)[QStringLiteral("APPNAME_CACHE")]; + if (!path.isEmpty()) + return path; + + QJNIObjectPrivate appCtx = applicationContext(); + if (!appCtx.isValid()) + return QString(); + + QJNIObjectPrivate file = appCtx.callObjectMethod("getExternalCacheDir", + "()Ljava/io/File;"); + + if (!file.isValid()) + return QString(); + + return (path = getAbsolutePath(file)); +} + +/* + * Directory where applications can store cache files it owns (private). + */ +static QString getCacheDir() +{ + QString &path = (*androidDirCache)[QStringLiteral("APPROOT_CACHE")]; + if (!path.isEmpty()) + return path; + + QJNIObjectPrivate appCtx = applicationContext(); + if (!appCtx.isValid()) + return QString(); + + QJNIObjectPrivate file = appCtx.callObjectMethod("getCacheDir", + "()Ljava/io/File;"); + if (!file.isValid()) + return QString(); + + return (path = getAbsolutePath(file)); +} + +/* + * Directory where applications can store files it owns (private). + * (Same location as $HOME) + */ +static QString getFilesDir() +{ + QString &path = (*androidDirCache)[QStringLiteral("APPROOT_FILES")]; + if (!path.isEmpty()) + return path; + + return (path = QDir::homePath()); +} + +QString QStandardPaths::writableLocation(StandardLocation type) +{ + switch (type) { + case QStandardPaths::MusicLocation: + return getExternalStoragePublicDirectory("DIRECTORY_MUSIC"); + case QStandardPaths::MoviesLocation: + return getExternalStoragePublicDirectory("DIRECTORY_MOVIES"); + case QStandardPaths::PicturesLocation: + return getExternalStoragePublicDirectory("DIRECTORY_PICTURES"); + case QStandardPaths::DocumentsLocation: + if (QtAndroidPrivate::androidSdkVersion() > 18) + return getExternalStoragePublicDirectory("DIRECTORY_DOCUMENTS"); + else + return getExternalStorageDirectory() + QLatin1String("/Documents"); + case QStandardPaths::DownloadLocation: + return getExternalStoragePublicDirectory("DIRECTORY_DOWNLOADS"); + case QStandardPaths::GenericConfigLocation: + case QStandardPaths::ConfigLocation: + return getFilesDir() + testDir() + QLatin1String("/settings"); + case QStandardPaths::GenericDataLocation: + return getExternalStorageDirectory() + testDir(); + case QStandardPaths::DataLocation: + return getFilesDir() + testDir(); + case QStandardPaths::GenericCacheLocation: + case QStandardPaths::RuntimeLocation: + case QStandardPaths::TempLocation: + case QStandardPaths::CacheLocation: + return getCacheDir() + testDir(); + case QStandardPaths::DesktopLocation: + case QStandardPaths::HomeLocation: + return getFilesDir(); + case QStandardPaths::ApplicationsLocation: + case QStandardPaths::FontsLocation: + default: + break; + } + + return QString(); +} + +QStringList QStandardPaths::standardLocations(StandardLocation type) +{ + if (type == MusicLocation) { + return QStringList() << writableLocation(type) + << getExternalFilesDir("DIRECTORY_MUSIC") + << getExternalStoragePublicDirectory("DIRECTORY_PODCASTS") + << getExternalFilesDir("DIRECTORY_PODCASTS") + << getExternalStoragePublicDirectory("DIRECTORY_NOTIFICATIONS") + << getExternalFilesDir("DIRECTORY_NOTIFICATIONS") + << getExternalStoragePublicDirectory("DIRECTORY_ALARMS") + << getExternalFilesDir("DIRECTORY_ALARMS"); + } + + if (type == MoviesLocation) { + return QStringList() << writableLocation(type) + << getExternalFilesDir("DIRECTORY_MOVIES"); + } + + if (type == PicturesLocation) { + return QStringList() << writableLocation(type) + << getExternalFilesDir("DIRECTORY_PICTURES"); + } + + if (type == DocumentsLocation) { + if (QtAndroidPrivate::androidSdkVersion() > 18) { + return QStringList() << writableLocation(type) + << getExternalFilesDir("DIRECTORY_DOCUMENTS"); + } else { + return QStringList() << writableLocation(type) + << getExternalFilesDir() + QLatin1String("/Documents"); + } + } + + if (type == DownloadLocation) { + return QStringList() << writableLocation(type) + << getExternalFilesDir("DIRECTORY_DOWNLOADS"); + } + + if (type == DataLocation) { + return QStringList() << writableLocation(type) + << getExternalFilesDir(); + } + + if (type == CacheLocation) { + return QStringList() << writableLocation(type) + << getExternalCacheDir(); + } + + if (type == FontsLocation) { + QString &fontLocation = (*androidDirCache)[QStringLiteral("FONT_LOCATION")]; + if (!fontLocation.isEmpty()) + return QStringList(fontLocation); + + const QByteArray ba = qgetenv("QT_ANDROID_FONT_LOCATION"); + if (!ba.isEmpty()) + return QStringList((fontLocation = QDir::cleanPath(QString::fromLocal8Bit(ba)))); + + return QStringList((fontLocation = QLatin1String("/system/fonts"))); + } + + return QStringList(writableLocation(type)); +} + +QT_END_NAMESPACE + +#endif // QT_NO_STANDARDPATHS diff --git a/src/corelib/io/qurl.cpp b/src/corelib/io/qurl.cpp index 77aa3c4821..eac5a0b738 100644 --- a/src/corelib/io/qurl.cpp +++ b/src/corelib/io/qurl.cpp @@ -3437,7 +3437,7 @@ QString QUrl::fromAce(const QByteArray &domain) (like \c "example.com") to be written using international characters. - This function return an empty QByteArra if \a domain is not a valid + This function returns an empty QByteArray if \a domain is not a valid hostname. Note, in particular, that IPv6 literals are not valid domain names. */ diff --git a/src/corelib/itemmodels/qabstractitemmodel.cpp b/src/corelib/itemmodels/qabstractitemmodel.cpp index ab257a996d..4241fe08ca 100644 --- a/src/corelib/itemmodels/qabstractitemmodel.cpp +++ b/src/corelib/itemmodels/qabstractitemmodel.cpp @@ -2334,6 +2334,31 @@ void QAbstractItemModel::doSetRoleNames(const QHash<int,QByteArray> &roleNames) Returns the model's role names. + The default role names set by Qt are: + + \table + \header + \li Qt Role + \li QML Role Name + \row + \li Qt::DisplayRole + \li display + \row + \li Qt::DecorationRole + \li decoration + \row + \li Qt::EditRole + \li edit + \row + \li Qt::ToolTipRole + \li toolTip + \row + \li Qt::StatusTipRole + \li statusTip + \row + \li Qt::WhatsThisRole + \li whatsThis + \endtable */ QHash<int,QByteArray> QAbstractItemModel::roleNames() const { @@ -3378,6 +3403,9 @@ Qt::ItemFlags QAbstractTableModel::flags(const QModelIndex &index) const of the rowCount() and data() functions. Well behaved models also provide a headerData() implementation. + If your model is used within QML and requires roles other than the + default ones provided by the roleNames() function, you must override it. + For editable list models, you must also provide an implementation of setData(), implement the flags() function so that it returns a value containing \l{Qt::ItemFlags}{Qt::ItemIsEditable}. diff --git a/src/corelib/kernel/qjnihelpers.cpp b/src/corelib/kernel/qjnihelpers.cpp index 9ec491f6a9..74eb6f5b27 100644 --- a/src/corelib/kernel/qjnihelpers.cpp +++ b/src/corelib/kernel/qjnihelpers.cpp @@ -46,6 +46,7 @@ QT_BEGIN_NAMESPACE static JavaVM *g_javaVM = Q_NULLPTR; static jobject g_jActivity = Q_NULLPTR; static jobject g_jClassLoader = Q_NULLPTR; +static jint g_androidSdkVersion = 0; static inline bool exceptionCheck(JNIEnv *env) { @@ -60,6 +61,19 @@ static inline bool exceptionCheck(JNIEnv *env) return false; } +static void setAndroidSdkVersion(JNIEnv *env) +{ + jclass androidVersionClass = env->FindClass("android/os/Build$VERSION"); + if (exceptionCheck(env)) + return; + + jfieldID androidSDKFieldID = env->GetStaticFieldID(androidVersionClass, "SDK_INT", "I"); + if (exceptionCheck(env)) + return; + + g_androidSdkVersion = env->GetStaticIntField(androidVersionClass, androidSDKFieldID); +} + jint QtAndroidPrivate::initJNI(JavaVM *vm, JNIEnv *env) { jclass jQtNative = env->FindClass("org/qtproject/qt5/android/QtNative"); @@ -93,6 +107,8 @@ jint QtAndroidPrivate::initJNI(JavaVM *vm, JNIEnv *env) if (exceptionCheck(env)) return JNI_ERR; + setAndroidSdkVersion(env); + g_jClassLoader = env->NewGlobalRef(classLoader); env->DeleteLocalRef(classLoader); g_jActivity = env->NewGlobalRef(activity); @@ -118,4 +134,9 @@ jobject QtAndroidPrivate::classLoader() return g_jClassLoader; } +jint QtAndroidPrivate::androidSdkVersion() +{ + return g_androidSdkVersion; +} + QT_END_NAMESPACE diff --git a/src/corelib/kernel/qjnihelpers_p.h b/src/corelib/kernel/qjnihelpers_p.h index 39059db215..c92dbdde7f 100644 --- a/src/corelib/kernel/qjnihelpers_p.h +++ b/src/corelib/kernel/qjnihelpers_p.h @@ -64,6 +64,7 @@ namespace QtAndroidPrivate Q_CORE_EXPORT JavaVM *javaVM(); Q_CORE_EXPORT jint initJNI(JavaVM *vm, JNIEnv *env); jobject classLoader(); + jint androidSdkVersion(); } QT_END_NAMESPACE diff --git a/src/corelib/kernel/qobject.cpp b/src/corelib/kernel/qobject.cpp index f1351f5a07..43b88d21b5 100644 --- a/src/corelib/kernel/qobject.cpp +++ b/src/corelib/kernel/qobject.cpp @@ -2086,7 +2086,9 @@ void QObject::deleteLater() const char *qFlagLocation(const char *method) { - QThreadData::current()->flaggedSignatures.store(method); + QThreadData *currentThreadData = QThreadData::current(false); + if (currentThreadData != 0) + currentThreadData->flaggedSignatures.store(method); return method; } @@ -3451,8 +3453,11 @@ void QMetaObject::activate(QObject *sender, int signalOffset, int local_signal_i { int signal_index = signalOffset + local_signal_index; - if (!sender->d_func()->isSignalConnected(signal_index)) + if (!sender->d_func()->isSignalConnected(signal_index) + && !qt_signal_spy_callback_set.signal_begin_callback + && !qt_signal_spy_callback_set.signal_end_callback) { return; // nothing connected to these signals, and no spy + } if (sender->d_func()->blockSig) return; diff --git a/src/corelib/kernel/qobject_p.h b/src/corelib/kernel/qobject_p.h index 011e140e3b..8cbb244451 100644 --- a/src/corelib/kernel/qobject_p.h +++ b/src/corelib/kernel/qobject_p.h @@ -248,7 +248,7 @@ public: Returns \c true if the signal with index \a signal_index from object \a sender is connected. Signals with indices above a certain range are always considered connected (see connectedSignals - in QObjectPrivate). If a signal spy is installed, all signals are considered connected. + in QObjectPrivate). \a signal_index must be the index returned by QObjectPrivate::signalIndex; */ @@ -257,9 +257,7 @@ inline bool QObjectPrivate::isSignalConnected(uint signal_index) const return signal_index >= sizeof(connectedSignals) * 8 || (connectedSignals[signal_index >> 5] & (1 << (signal_index & 0x1f)) || (declarativeData && QAbstractDeclarativeData::isSignalConnected - && QAbstractDeclarativeData::isSignalConnected(declarativeData, q_func(), signal_index)) - || qt_signal_spy_callback_set.signal_begin_callback - || qt_signal_spy_callback_set.signal_end_callback); + && QAbstractDeclarativeData::isSignalConnected(declarativeData, q_func(), signal_index))); } inline QObjectPrivate::Sender *QObjectPrivate::setCurrentSender(QObject *receiver, diff --git a/src/corelib/thread/qthread_p.h b/src/corelib/thread/qthread_p.h index 8429e41433..fce84e881b 100644 --- a/src/corelib/thread/qthread_p.h +++ b/src/corelib/thread/qthread_p.h @@ -223,7 +223,7 @@ public: QThreadData(int initialRefCount = 1); ~QThreadData(); - static QThreadData *current(); + static QThreadData *current(bool createIfNecessary = true); static void clearCurrentThreadData(); static QThreadData *get2(QThread *thread) { Q_ASSERT_X(thread != 0, "QThread", "internal error"); return thread->d_func()->data; } diff --git a/src/corelib/thread/qthread_unix.cpp b/src/corelib/thread/qthread_unix.cpp index 15558cb148..b838cb4b28 100644 --- a/src/corelib/thread/qthread_unix.cpp +++ b/src/corelib/thread/qthread_unix.cpp @@ -215,10 +215,10 @@ void QThreadData::clearCurrentThreadData() clear_thread_data(); } -QThreadData *QThreadData::current() +QThreadData *QThreadData::current(bool createIfNecessary) { QThreadData *data = get_thread_data(); - if (!data) { + if (!data && createIfNecessary) { data = new QThreadData; QT_TRY { set_thread_data(data); diff --git a/src/corelib/thread/qthread_win.cpp b/src/corelib/thread/qthread_win.cpp index 037343c996..865b1e6af5 100644 --- a/src/corelib/thread/qthread_win.cpp +++ b/src/corelib/thread/qthread_win.cpp @@ -101,11 +101,11 @@ void QThreadData::clearCurrentThreadData() TlsSetValue(qt_current_thread_data_tls_index, 0); } -QThreadData *QThreadData::current() +QThreadData *QThreadData::current(bool createIfNecessary) { qt_create_tls(); QThreadData *threadData = reinterpret_cast<QThreadData *>(TlsGetValue(qt_current_thread_data_tls_index)); - if (!threadData) { + if (!threadData && createIfNecessary) { threadData = new QThreadData; // This needs to be called prior to new AdoptedThread() to // avoid recursion. diff --git a/src/corelib/tools/qcommandlineparser.cpp b/src/corelib/tools/qcommandlineparser.cpp index db4c2961f0..c860b4d155 100644 --- a/src/corelib/tools/qcommandlineparser.cpp +++ b/src/corelib/tools/qcommandlineparser.cpp @@ -720,7 +720,8 @@ QStringList QCommandLineParser::values(const QString &optionName) const */ bool QCommandLineParser::isSet(const QCommandLineOption &option) const { - return isSet(option.names().first()); + // option.names() might be empty if the constructor failed + return !option.names().isEmpty() && isSet(option.names().first()); } /*! diff --git a/src/corelib/tools/qdatetime.cpp b/src/corelib/tools/qdatetime.cpp index 5438f00c67..6177012e4b 100644 --- a/src/corelib/tools/qdatetime.cpp +++ b/src/corelib/tools/qdatetime.cpp @@ -1902,7 +1902,7 @@ int QTime::msecsTo(const QTime &t) const #ifndef QT_NO_DATESTRING -static QTime fromIsoTimeString(const QString &string, Qt::DateFormat format, bool *isMidnight24) +static QTime fromIsoTimeString(const QStringRef &string, Qt::DateFormat format, bool *isMidnight24) { if (isMidnight24) *isMidnight24 = false; @@ -1935,9 +1935,13 @@ static QTime fromIsoTimeString(const QString &string, Qt::DateFormat format, boo // the maximum amount of millisecond digits it will expand to once converted to // seconds is 4. E.g. 12:34,99999 will expand to 12:34:59.9994. The milliseconds // will then be rounded up AND clamped to 999. - const float minuteFraction = QString::fromUtf8("0.%1").arg(string.mid(6, 5)).toFloat(&ok); + + const QStringRef minuteFractionStr = string.mid(6, 5); + const long minuteFractionInt = minuteFractionStr.toLong(&ok); if (!ok) return QTime(); + const float minuteFraction = double(minuteFractionInt) / (std::pow(double(10), minuteFractionStr.count())); + const float secondWithMs = minuteFraction * 60; const float secondNoMs = std::floor(secondWithMs); const float secondFraction = secondWithMs - secondNoMs; @@ -1949,9 +1953,11 @@ static QTime fromIsoTimeString(const QString &string, Qt::DateFormat format, boo if (!ok) return QTime(); if (size > 8 && (string.at(8) == QLatin1Char(',') || string.at(8) == QLatin1Char('.'))) { - const double secondFraction = QString::fromUtf8("0.%1").arg(string.mid(9, 4)).toDouble(&ok); + const QStringRef msecStr(string.mid(9, 4)); + int msecInt = msecStr.isEmpty() ? 0 : msecStr.toInt(&ok); if (!ok) return QTime(); + const double secondFraction(msecInt / (std::pow(double(10), msecStr.count()))); msec = qMin(qRound(secondFraction * 1000.0), 999); } } @@ -2001,7 +2007,7 @@ QTime QTime::fromString(const QString& string, Qt::DateFormat format) case Qt::ISODate: case Qt::TextDate: default: - return fromIsoTimeString(string, format, 0); + return fromIsoTimeString(&string, format, 0); } } @@ -4383,26 +4389,40 @@ QDateTime QDateTime::fromString(const QString& string, Qt::DateFormat format) if (size < 10) return QDateTime(); - QString isoString = string; + QStringRef isoString(&string); Qt::TimeSpec spec = Qt::LocalTime; - QDate date = QDate::fromString(isoString.left(10), Qt::ISODate); + QDate date = QDate::fromString(string.left(10), Qt::ISODate); if (!date.isValid()) return QDateTime(); if (size == 10) return QDateTime(date); - isoString.remove(0, 11); + isoString = isoString.right(11); int offset = 0; // Check end of string for Time Zone definition, either Z for UTC or [+-]HH:MM for Offset if (isoString.endsWith(QLatin1Char('Z'))) { spec = Qt::UTC; - isoString.chop(1); + isoString = isoString.left(isoString.size() - 1); } else { - const int signIndex = isoString.indexOf(QRegExp(QStringLiteral("[+-]"))); - if (signIndex >= 0) { + // the loop below is faster but functionally equal to: + // const int signIndex = isoString.indexOf(QRegExp(QStringLiteral("[+-]"))); + const int sizeOfTimeZoneString = 4; + int signIndex = isoString.size() - sizeOfTimeZoneString - 1; + bool found = false; + { + const QChar plus = QLatin1Char('+'); + const QChar minus = QLatin1Char('-'); + do { + QChar character(isoString.at(signIndex)); + found = character == plus || character == minus; + } while (--signIndex >= 0 && !found); + ++signIndex; + } + + if (found) { bool ok; - offset = fromOffsetString(isoString.mid(signIndex), &ok); + offset = fromOffsetString(isoString.mid(signIndex).toString(), &ok); if (!ok) return QDateTime(); isoString = isoString.left(signIndex); diff --git a/src/corelib/tools/qstring.cpp b/src/corelib/tools/qstring.cpp index 3976f2cb6f..d682207314 100644 --- a/src/corelib/tools/qstring.cpp +++ b/src/corelib/tools/qstring.cpp @@ -188,9 +188,23 @@ static int ucstricmp(const ushort *a, const ushort *ae, const uchar *b, const uc return 1; } +#if defined(__mips_dsp) +// From qstring_mips_dsp_asm.S +extern "C" int qt_ucstrncmp_mips_dsp_asm(const ushort *a, + const ushort *b, + unsigned len); +#endif + // Unicode case-sensitive compare two same-sized strings static int ucstrncmp(const QChar *a, const QChar *b, int l) { +#if defined(__mips_dsp) + if (l >= 8) { + return qt_ucstrncmp_mips_dsp_asm(reinterpret_cast<const ushort*>(a), + reinterpret_cast<const ushort*>(b), + l); + } +#endif // __mips_dsp while (l-- && *a == *b) a++,b++; if (l==-1) @@ -3937,6 +3951,10 @@ static inline __m128i mergeQuestionMarks(__m128i chunk) } #endif +#if defined(__mips_dsp) +extern "C" void qt_toLatin1_mips_dsp_asm(uchar *dst, const ushort *src, int length); +#endif + static QByteArray toLatin1_helper(const QChar *data, int length) { QByteArray ba; @@ -3989,10 +4007,14 @@ static QByteArray toLatin1_helper(const QChar *data, int length) length = length % 8; } #endif +#if defined(__mips_dsp) + qt_toLatin1_mips_dsp_asm(dst, src, length); +#else while (length--) { *dst++ = (*src>0xff) ? '?' : (uchar) *src; ++src; } +#endif } return ba; } @@ -4104,6 +4126,12 @@ QVector<uint> QString::toUcs4() const return v; } +#if defined(__mips_dsp) +// From qstring_mips_dsp_asm.S +extern "C" void qt_fromlatin1_mips_asm_unroll4 (ushort*, const char*, uint); +extern "C" void qt_fromlatin1_mips_asm_unroll8 (ushort*, const char*, uint); +#endif + QString::Data *QString::fromLatin1_helper(const char *str, int size) { Data *d; @@ -4144,8 +4172,15 @@ QString::Data *QString::fromLatin1_helper(const char *str, int size) size = size % 16; } #endif +#if defined(__mips_dsp) + if (size > 20) + qt_fromlatin1_mips_asm_unroll8(dst, str, size); + else + qt_fromlatin1_mips_asm_unroll4(dst, str, size); +#else while (size--) *dst++ = (uchar)*str++; +#endif } return d; } diff --git a/src/corelib/tools/qstring_mips_dsp_asm.S b/src/corelib/tools/qstring_mips_dsp_asm.S new file mode 100644 index 0000000000..aee162c290 --- /dev/null +++ b/src/corelib/tools/qstring_mips_dsp_asm.S @@ -0,0 +1,449 @@ +/**************************************************************************** +** +** Copyright (C) 2013 Imagination Technologies Limited, www.imgtec.com +** Contact: http://www.qt-project.org/legal +** +** This file is part of the QtGui 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 Digia. For licensing terms and +** conditions see http://qt.digia.com/licensing. For further information +** use the contact form at http://qt.digia.com/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 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Digia gives you certain additional +** rights. These rights are described in the Digia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "../../gui/painting/qt_mips_asm_dsp_p.h" + +.macro EXTRACT_HALVES_x2 src1, src2, hi_1, hi_2 +#if defined(__MIPSEL) && __MIPSEL + srl \hi_1, \src1, 16 + ext \src1, \src1, 0, 16 + srl \hi_2, \src2, 16 + ext \src2, \src2, 0, 16 +#else + ext \hi_1, \src1, 0, 16 + srl \src1, \src1, 16 + ext \hi_2, \src2, 0, 16 + srl \src2, \src2, 16 +#endif +.endm + + +LEAF_MIPS_DSP(qt_ucstrncmp_mips_dsp_asm) +/* + * Arguments: + * a0 - string_a (uint16_t*) + * a1 - string_b (uint16_t*) + * a2 - length (uint32_t) + * + * Register usage: + * t0 - batches + */ + + move v0, zero /* result = 0 */ + andi t0, a0, 0x3 /* t1 = string_a % 4 */ + andi t1, a1, 0x3 /* t0 = string_b % 4 */ + or t2, t0, t1 /* t2 = t0 | t1 */ + + beqz t2, 5f /* both aligned */ + and t2, t0 ,t1 + beqz t2, 6f /* one aligned */ + nop + + /* + * Both strings are unaligned: read 1 halfword from each, + * then fall-off to continue with the both-aligned case. + */ + lhu t0, 0 (a0) + lhu t1, 0 (a1) + addiu a2, a2, -1 /* len-- */ + sub v0, t0, t1 /* v0 = t0-t1 */ + addiu a0, a0, 2 /* string_a++ */ + bnez v0, 0f /* if (t0-t1): return */ + addiu a1, a1, 2 /* string_b++ */ + beqz a2, 0f /* if !len: return */ + /* next instruction (srl) fills delay branch slot */ + +5: /* Both string pointers are aligned */ + srl t0, a2, 3 /* batches = length / 8 */ + beqz t0, 9f /* if !batches: tail */ + andi a2, a2, 0x7 /* length = length % 8 */ + + SAVE_REGS_ON_STACK 0, s0, s1, s2, s3 + +1: lw t1, 0 (a0) /* [a0 a1] */ + lw t3, 4 (a0) /* [a2 a3] */ + lw t5, 8 (a0) /* [a4 a5] */ + lw t7, 12 (a0) /* [a6 a7] */ + + lw t2, 0 (a1) /* [b0 b1] */ + lw t4, 4 (a1) /* [b2 b3] */ + lw t6, 8 (a1) /* [b4 b5] */ + lw t8, 12 (a1) /* [b6 b7] */ + + /* + * Subtract elements one by one, if the result is zero + * both halves of the registers (shorts) are equal. + */ + subq.ph s0, t1, t2 /* [a0-b0 a1-b1] */ + subq.ph s1, t3, t4 /* [a2-b2 a3-b3] */ + + bnez s0, 1f + subq.ph s2, t5, t6 /* [a4-b4 a5-b5] */ + bnez s1, 2f + subq.ph s3, t7, t8 /* [a6-b6 a7-b7] */ + bnez s2, 3f + addiu t0, t0, -1 /* batches-- */ + bnez s3, 4f + addiu a0, a0, 8*2 /* string_a += 8 */ + + bnez t0, 1b /* if batches: loop */ + addiu a1, a1, 8*2 /* string_b += 8 */ + + RESTORE_REGS_FROM_STACK 0, s0, s1, s2, s3 + + bnez a2, 9f /* if length: tail */ + nop + jr ra + nop + + + 1: /* Check t1 [a0 a1] vs. t2 [b0 b1] */ + EXTRACT_HALVES_x2 t1, t2, t3, t4 /* a0, b0, a1, b1 */ + sub v0, t1, t2 + RESTORE_REGS_FROM_STACK 0, s0, s1, s2, s3 + bnez v0, 0f /* if (a0-b0): return */ + nop + jr ra + sub v0, t3, t4 /* return a1-b1 */ + + 2: /* Check t3 [a2 a3] vs. t4 [b2 b3] */ + EXTRACT_HALVES_x2 t3, t4, t1, t2 /* a2, b2, a3, b3 */ + sub v0, t3, t4 + RESTORE_REGS_FROM_STACK 0, s0, s1, s2, s3 + bnez v0, 0f /* if (a2-b2): return */ + nop + jr ra + sub v0, t1, t2 /* return a3-b3 */ + + 3: /* Check t5 [a4 a5] vs. t6 [b4 b5] */ + EXTRACT_HALVES_x2 t5, t6, t1, t2 /* a4, b4, a5, b5 */ + sub v0, t5, t6 + RESTORE_REGS_FROM_STACK 0, s0, s1, s2, s3 + bnez v0, 0f /* if (a4-b4): return */ + nop + jr ra + sub v0, t1, t2 /* return a5-b5 */ + + 4: /* Check t7 [a6 a7] vs. t8 [b6 b7] */ + EXTRACT_HALVES_x2 t7, t8, t1, t2 /* a6, b6, a7, b7 */ + sub v0, t7, t8 + RESTORE_REGS_FROM_STACK 0, s0, s1, s2, s3 + bnez v0, 0f /* if (a6-b6): return */ + nop + jr ra + sub v0, t1, t2 + + + /* Process remaining tail items. */ +9: lhu t1, 0 (a0) /* a */ + lhu t2, 0 (a1) /* b */ + addiu a2, a2, -1 /* length-- */ + sub v0, t1, t2 /* result = (a - b) */ + + bnez v0, 0f /* if (a - b): return */ + addiu a0, a0, 2 /* string_a++ */ + + bnez a2, 9b /* if length: loop */ + addiu a1, a1, 2 /* string_b++ */ + +0: jr ra + nop + + + /* One of the inputs is unaligned, do unrolled half-word loads */ +6: srl t0, a2, 3 /* batches = length / 8 */ + andi a2, a2, 0x7 /* length = length % 8 */ + +1: lhu t1, 0 (a0) + lhu t2, 0 (a1) + lhu t3, 2 (a0) + lhu t4, 2 (a1) + lhu t5, 4 (a0) + lhu t6, 4 (a1) + lhu t7, 6 (a0) + lhu t8, 6 (a1) + + sub v0, t1, t2 + sub t1, t3, t4 + + bnez v0, 0f + sub t2, t5, t6 + bnez t1, 2f + sub t3, t7, t8 + bnez t2, 3f + lhu t1, 8 (a0) + bnez t3, 4f + lhu t2, 8 (a1) + + lhu t3, 10 (a0) + lhu t4, 10 (a1) + lhu t5, 12 (a0) + lhu t6, 12 (a1) + lhu t7, 14 (a0) + lhu t8, 14 (a1) + + sub v0, t1, t2 + sub t1, t3, t4 + + bnez v0, 0f + sub t2, t5, t6 + bnez t1, 2f + sub t3, t7, t8 + bnez t2, 3f + addiu t0, t0, -1 /* batches-- */ + bnez t3, 4f + addiu a0, a0, 8*2 /* string_a += 8 */ + + bnez t0, 1b + addiu a1, a1, 8*2 /* string_b += 8 */ + + bnez a2, 9b /* if length: tail */ + nop + +0: jr ra + nop +2: jr ra + move v0, t1 +3: jr ra + move v0, t2 +4: jr ra + move v0, t3 + +END(qt_ucstrncmp_mips_dsp_asm) + + +#if defined(__mips_dspr2) +LEAF_MIPS_DSPR2(qt_fromlatin1_mips_asm_unroll8) +#else +LEAF_MIPS_DSP(qt_fromlatin1_mips_asm_unroll8) +#endif + + andi t0, a1, 0x3 + beqz t0, 9f /* check that src is aligned */ + nop + +1: lbu t1, 0 (a1) + addiu a1, a1, 1 + addiu a2, a2, -1 + sh t1, 0 (a0) + beqz a2, 0f + andi t0, a1, 0x3 + bnez t0, 1b + addiu a0, a0, 2 + +9: /* source pointer is aligned: do batches of 8 elements */ + andi t0, a0, 3 /* check if dst is aligned */ + bnez t0, 6f + srl t0, a2, 3 /* batches = len / 8 */ + andi a2, a2, 0x7 /* tail = len % 8 */ + + beqz t0, 8f /* if !batches: tail */ + nop + +1: lw t1, 0 (a1) + lw t2, 4 (a1) + + addiu a1, a1, 8*1 + addiu t0, t0, -1 + + preceu.ph.qbl t3, t1 + preceu.ph.qbr t1, t1 + preceu.ph.qbl t4, t2 + preceu.ph.qbr t2, t2 + +#if defined(__MIPSEL) && __MIPSEL + sw t1, 0 (a0) + sw t3, 4 (a0) + sw t2, 8 (a0) + sw t4, 12 (a0) +#else + sw t3, 0 (a0) + sw t1, 4 (a0) + sw t4, 8 (a0) + sw t2, 12 (a0) +#endif + + bnez t0, 1b + addiu a0, a0, 8*2 + +8: /* process tail items */ + beqz a2, 0f + nop + +1: lbu t1, 0 (a1) + addiu a2, a2, -1 + sh t1, 0 (a0) + addiu a1, a1, 1 + bnez a2, 1b + addiu a0, a0, 2 + +0: jr ra + nop + +6: beqz t0, 8b + andi a2, a2, 7 +7: lw t1, 0(a1) + lw t2, 4(a1) + addiu t0, t0, -1 + addiu a1, a1, 8 + andi t3, t1, 0xff +#if defined(__mips_dspr2) + prepend t1, t2, 8 +#else + sll t4, t4, 24 + srl t1, t1, 8 + or t1, t1, t4 +#endif + srl t2, t2, 8 + preceu.ph.qbr t4, t1 + preceu.ph.qbl t1, t1 + preceu.ph.qbr t5, t2 + srl t2, t2, 16 + sh t3, 0(a0) + sw t4, 2(a0) + sw t1, 6(a0) + sw t5, 10(a0) + sh t2, 14(a0) + bnez t0, 7b + addiu a0, a0, 16 + bnez a2, 1b + nop + + jr ra + nop + +END(qt_fromlatin1_mips_asm_unroll8) + + +LEAF_MIPS_DSP(qt_fromlatin1_mips_asm_unroll4) +/* + * Arguments: + * a0 - dst (uint16_t*) + * a1 - src (const char*) + * a2 - len (unsigned int) + */ + + /* + * QString::fromLatin1_helper() already handles the len==0 + * case: assume that len is never zero. + */ + srl t0, a2, 2 + beqz t0, 9f + andi a2, a2, 0x3 + +1: lbu t1, 0(a1) + lbu t2, 1(a1) + lbu t3, 2(a1) + lbu t4, 3(a1) + sh t1, 0(a0) + sh t2, 2(a0) + sh t3, 4(a0) + sh t4, 6(a0) + addiu t0, t0, -1 + addiu a1, a1, 4 + bnez t0, 1b + addiu a0, a0, 8 + +8: beqz a2, 0f + nop + +9: lbu t1, 0(a1) + addiu a2, a2, -1 + addiu a1, a1, 1 + sh t1, 0(a0) + bnez a2, 9b + addiu a0, a0, 2 + +0: jr ra + nop + +END(qt_fromlatin1_mips_asm_unroll4) + + +LEAF_MIPS_DSP(qt_toLatin1_mips_dsp_asm) + /* + * a0 - dst + * a1 - src + * a2 - length + */ + + addiu t9, zero, 0x3f + srl t8, a2, 2 + beqz t8, 2f + andi a2, a2, 3 +1: + lhu t0, 0(a1) + lhu t1, 2(a1) + lhu t2, 4(a1) + lhu t3, 6(a1) + srl t4, t0, 8 + srl t5, t1, 8 + srl t6, t2, 8 + srl t7, t3, 8 + movn t0, t9, t4 + movn t1, t9, t5 + movn t2, t9, t6 + movn t3, t9, t7 + addiu a1, a1, 8 + addiu t8, t8, -1 + sb t0, 0(a0) + sb t1, 1(a0) + sb t2, 2(a0) + sb t3, 3(a0) + bgtz t8, 1b + addiu a0, a0, 4 +2: beqz a2, 4f + nop +3: + lhu t0, 0(a1) + addiu a1, a1, 2 + addiu a2, a2, -1 + srl t1, t0, 8 + movn t0, t9, t1 + sb t0, 0(a0) + bgtz a2, 3b + addiu a0, a0, 1 +4: + jr ra + nop + +END(qt_toLatin1_mips_dsp_asm) + diff --git a/src/corelib/tools/qvector.h b/src/corelib/tools/qvector.h index f56511edbf..075e8e83e8 100644 --- a/src/corelib/tools/qvector.h +++ b/src/corelib/tools/qvector.h @@ -254,7 +254,10 @@ private: }; #ifdef Q_CC_MSVC -# pragma warning ( disable : 4345 ) // behavior change: an object of POD type constructed with an initializer of the form () will be default-initialized +// behavior change: an object of POD type constructed with an initializer of the form () +// will be default-initialized +# pragma warning ( push ) +# pragma warning ( disable : 4345 ) #endif template <typename T> @@ -270,7 +273,7 @@ void QVector<T>::defaultConstruct(T *from, T *to) } #ifdef Q_CC_MSVC -# pragma warning ( default: 4345 ) +# pragma warning ( pop ) #endif template <typename T> @@ -438,11 +441,15 @@ QVector<T>::QVector(int asize, const T &t) template <typename T> QVector<T>::QVector(std::initializer_list<T> args) { - d = Data::allocate(args.size()); - // std::initializer_list<T>::iterator is guaranteed to be - // const T* ([support.initlist]/1), so can be memcpy'ed away from by copyConstruct - copyConstruct(args.begin(), args.end(), d->begin()); - d->size = int(args.size()); + if (args.size() > 0) { + d = Data::allocate(args.size()); + // std::initializer_list<T>::iterator is guaranteed to be + // const T* ([support.initlist]/1), so can be memcpy'ed away from by copyConstruct + copyConstruct(args.begin(), args.end(), d->begin()); + d->size = int(args.size()); + } else { + d = Data::sharedNull(); + } } #endif diff --git a/src/corelib/tools/tools.pri b/src/corelib/tools/tools.pri index e4a7b02aee..cac596f0bc 100644 --- a/src/corelib/tools/tools.pri +++ b/src/corelib/tools/tools.pri @@ -192,3 +192,7 @@ INCLUDEPATH += ../3rdparty/md5 \ !macx-icc:!vxworks:unix:LIBS_PRIVATE += -lm TR_EXCLUDE += ../3rdparty/* + +# MIPS DSP +MIPS_DSP_ASM += tools/qstring_mips_dsp_asm.S +MIPS_DSP_HEADERS += ../gui/painting/qt_mips_asm_dsp_p.h |